Refactored text editor/field to reduce loc
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / common-text-utils.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dali/public-api/actors/layer.h>
18
19 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
20 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
21 #include <dali-toolkit/internal/text/text-view.h>
22
23 namespace Dali::Toolkit::Internal
24 {
25 void CommonTextUtils::RenderText(
26   Actor                            textActor,
27   Text::RendererPtr                renderer,
28   Text::ControllerPtr              controller,
29   Text::DecoratorPtr               decorator,
30   float                            alignmentOffset,
31   Actor&                           renderableActor,
32   Actor&                           backgroundActor,
33   Toolkit::Control&                stencil,
34   std::vector<Actor>&              clippingDecorationActors,
35   Text::Controller::UpdateTextType updateTextType)
36 {
37   Actor newRenderableActor;
38
39   if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType))
40   {
41     if(renderer)
42     {
43       newRenderableActor = renderer->Render(controller->GetView(),
44                                             textActor,
45                                             Property::INVALID_INDEX, // Animatable property not supported
46                                             alignmentOffset,
47                                             DepthIndex::CONTENT);
48     }
49
50     if(renderableActor != newRenderableActor)
51     {
52       UnparentAndReset(backgroundActor);
53       UnparentAndReset(renderableActor);
54       renderableActor = newRenderableActor;
55
56       if(renderableActor)
57       {
58         backgroundActor = controller->CreateBackgroundActor();
59       }
60     }
61   }
62
63   if(renderableActor)
64   {
65     const Vector2& scrollOffset = controller->GetTextModel()->GetScrollPosition();
66
67     float renderableActorPositionX, renderableActorPositionY;
68
69     if(stencil)
70     {
71       renderableActorPositionX = scrollOffset.x + alignmentOffset;
72       renderableActorPositionY = scrollOffset.y;
73     }
74     else
75     {
76       Extents padding;
77       padding = textActor.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
78
79       // Support Right-To-Left of padding
80       Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(textActor.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
81       if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
82       {
83         std::swap(padding.start, padding.end);
84       }
85
86       renderableActorPositionX = scrollOffset.x + alignmentOffset + padding.start;
87       renderableActorPositionY = scrollOffset.y + padding.top;
88     }
89
90     renderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
91
92     // Make sure the actors are parented correctly with/without clipping
93     Actor self = stencil ? stencil : textActor;
94
95     Actor highlightActor;
96
97     for(std::vector<Actor>::iterator it    = clippingDecorationActors.begin(),
98                                      endIt = clippingDecorationActors.end();
99         it != endIt;
100         ++it)
101     {
102       self.Add(*it);
103       it->LowerToBottom();
104
105       if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
106       {
107         highlightActor = *it;
108       }
109     }
110     clippingDecorationActors.clear();
111
112     self.Add(renderableActor);
113
114     if(backgroundActor)
115     {
116       if(decorator && decorator->IsHighlightVisible())
117       {
118         self.Add(backgroundActor);
119         backgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
120         backgroundActor.LowerBelow(highlightActor);
121       }
122       else
123       {
124         renderableActor.Add(backgroundActor);
125         backgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
126         backgroundActor.LowerToBottom();
127       }
128     }
129   }
130 }
131
132 } // namespace Dali::Toolkit::Internal