Add post processor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / style.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-toolkit/devel-api/controls/control-devel.h>
18 #include <dali-toolkit/internal/builder/style.h>
19 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
20 #include <dali-toolkit/public-api/controls/control.h>
21 #include <dali-toolkit/public-api/visuals/visual-properties.h>
22 #include <dali/devel-api/scripting/scripting.h>
23 #include <dali/public-api/object/handle.h>
24
25 namespace Dali
26 {
27 namespace Toolkit
28 {
29 namespace Internal
30 {
31 extern const Dali::Scripting::StringEnum ControlStateTable[];
32 extern const unsigned int                ControlStateTableCount;
33
34 StylePtr Style::New()
35 {
36   StylePtr stylePtr(new Style());
37   return stylePtr;
38 }
39
40 void Style::ApplyVisualsAndPropertiesRecursively(
41   Handle                           handle,
42   const Dictionary<Property::Map>& instancedProperties) const
43 {
44   ApplyVisuals(handle, instancedProperties);
45   ApplyProperties(handle);
46
47   Toolkit::Control control = Toolkit::Control::DownCast(handle);
48   if(control)
49   {
50     std::string                        stateName;
51     Property::Value                    value = control.GetProperty(DevelControl::Property::STATE);
52     Dali::Toolkit::DevelControl::State state = static_cast<Dali::Toolkit::DevelControl::State>(value.Get<int>());
53     stateName                                = Scripting::GetEnumerationName<Toolkit::DevelControl::State>(state, ControlStateTable, ControlStateTableCount);
54
55     if(!stateName.empty())
56     {
57       // Look up state in states table:
58       const StylePtr* stylePtr = subStates.FindConst(stateName);
59       if(stylePtr)
60       {
61         const StylePtr statePtr(*stylePtr);
62
63         // We have a state match.
64         statePtr->ApplyVisuals(handle, instancedProperties);
65         statePtr->ApplyProperties(handle);
66
67         // Apply substate visuals
68         Property::Value value = control.GetProperty(DevelControl::Property::SUB_STATE);
69         std::string     subStateName;
70         if(value.Get(subStateName) && !subStateName.empty())
71         {
72           const StylePtr* stylePtr = statePtr->subStates.FindConst(subStateName);
73           if(stylePtr)
74           {
75             const StylePtr subStatePtr(*stylePtr);
76             // We have a sub-state match.
77             subStatePtr->ApplyVisuals(handle, instancedProperties);
78             subStatePtr->ApplyProperties(handle);
79           }
80         }
81       }
82     }
83   }
84 }
85
86 void Style::ApplyVisuals(
87   Handle                           handle,
88   const Dictionary<Property::Map>& instancedProperties) const
89 {
90   ApplyVisuals(handle, visuals, instancedProperties);
91 }
92
93 void Style::ApplyVisuals(
94   Handle                           handle,
95   const Dictionary<Property::Map>& visualMaps,
96   const Dictionary<Property::Map>& instancedProperties)
97 {
98   for(Dictionary<Property::Map>::iterator iter = visualMaps.Begin(); iter != visualMaps.End(); ++iter)
99   {
100     const std::string& visualName   = (*iter).key;
101     Property::Map      map          = (*iter).entry;
102     Property::Map*     instancedMap = instancedProperties.Find(visualName);
103     ApplyVisual(handle, visualName, map, instancedMap);
104   }
105 }
106
107 void Style::ApplyVisual(
108   Handle               handle,
109   const std::string&   visualName,
110   const Property::Map& visualMap,
111   const Property::Map* instancedProperties)
112 {
113   // Check if this visual name is a valid property of handle
114   Dali::Property::Index index = handle.GetPropertyIndex(visualName);
115   if(index != Property::INVALID_INDEX)
116   {
117     const Property::Map* applyMap = &visualMap;
118     Property::Map        mergedMap;
119
120     // If there are instanced properties, and the visual types match,
121     // merge them into the visual map
122     if(instancedProperties)
123     {
124       Property::Value* instanceTypeValue = instancedProperties->Find(Toolkit::Visual::Property::TYPE);
125       Property::Value* newTypeValue      = visualMap.Find(Toolkit::Visual::Property::TYPE, VISUAL_TYPE);
126       if(instanceTypeValue && newTypeValue)
127       {
128         int instanceVisualType = -1;
129         int newVisualType      = -1;
130         Scripting::GetEnumerationProperty(*instanceTypeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, instanceVisualType);
131         Scripting::GetEnumerationProperty(*newTypeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, newVisualType);
132
133         if(instanceVisualType == newVisualType)
134         {
135           // Same type - merge remaining instance data
136           mergedMap.Merge(visualMap);
137           mergedMap.Merge(*instancedProperties);
138           applyMap = &mergedMap;
139         }
140       }
141     }
142
143     // Apply the visual property map to the handle
144     const Property::Value value(const_cast<Property::Map&>(*applyMap));
145     handle.SetProperty(index, value);
146   }
147 }
148
149 void Style::ApplyProperties(Handle handle) const
150 {
151   for(Property::Map::SizeType i = 0; i < properties.Count(); ++i)
152   {
153     KeyValuePair keyValue = properties.GetKeyValue(i);
154     if(keyValue.first.type == Property::Key::INDEX)
155     {
156       handle.SetProperty(keyValue.first.indexKey, keyValue.second);
157     }
158   }
159 }
160
161 Style::Style()
162 {
163 }
164 Style::~Style()
165 {
166 }
167
168 } // namespace Internal
169 } // namespace Toolkit
170 } // namespace Dali