2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "tool-bar-impl.h"
22 #include <dali/public-api/animation/constraints.h>
23 #include <dali/public-api/object/type-registry-helper.h>
24 #include <dali/public-api/object/type-registry.h>
27 #include <dali-toolkit/devel-api/controls/alignment/alignment.h>
28 #include <dali-toolkit/devel-api/controls/control-devel.h>
40 return Toolkit::ToolBar::New();
43 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::ToolBar, Toolkit::Control, Create)
44 DALI_TYPE_REGISTRATION_END()
46 const float DEFAULT_RELATIVE_SIZE(0.1f);
47 const Toolkit::Alignment::Type DEFAULT_ALIGNMENT(Toolkit::Alignment::HORIZONTAL_LEFT);
50 Toolkit::ToolBar ToolBar::New()
52 // Create the implementation, temporarily owned on stack
53 IntrusivePtr<ToolBar> internalToolBar = new ToolBar();
55 // Pass ownership to Toolkit::Toolbar
56 Toolkit::ToolBar toolBar(*internalToolBar);
58 // Second-phase init of the implementation
59 // This can only be done after the CustomActor connection has been made...
60 internalToolBar->Initialize();
65 void ToolBar::AddControl(Actor control, float relativeSize, Toolkit::Alignment::Type alignment, const Toolkit::Alignment::Padding& padding)
67 // Work out index and update bases and offsets for further insertions.
68 unsigned int index = 0;
71 case Toolkit::Alignment::HORIZONTAL_LEFT:
79 case Toolkit::Alignment::HORIZONTAL_CENTER:
81 index = mCenterBase + mCenterOffset;
86 case Toolkit::Alignment::HORIZONTAL_RIGHT:
88 index = mRightBase - mRightOffset;
95 DALI_ASSERT_ALWAYS(false);
99 // Create a new column for the new control.
100 mLayout.InsertColumn(index);
102 // Create an alignment container where to place the control.
103 Toolkit::Alignment alignmentContainer = Toolkit::Alignment::New(alignment);
104 alignmentContainer.SetProperty(Actor::Property::SIZE_SCALE_POLICY, SizeScalePolicy::FIT_WITH_ASPECT_RATIO);
105 alignmentContainer.SetPadding(padding);
106 alignmentContainer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
107 alignmentContainer.Add(control);
109 // Insert the control in the table view.
110 mLayout.AddChild(alignmentContainer, Toolkit::TableView::CellPosition(0, index));
111 mLayout.SetRelativeWidth(index, relativeSize);
113 // Relate control and alignmentContainer in order to allow removing controls.
114 mControls[control] = alignmentContainer;
116 // Update accumulated relative space.
117 mAccumulatedRelativeSpace += relativeSize;
119 // Update spaces between left, center and right groups of controls.
122 case Toolkit::Alignment::HORIZONTAL_LEFT:
124 mLeftRelativeSpace -= relativeSize;
125 if(mLeftRelativeSpace < 0.f)
127 mLeftRelativeSpace = 0.f;
131 case Toolkit::Alignment::HORIZONTAL_CENTER:
133 mLeftRelativeSpace -= 0.5f * relativeSize;
134 if(mLeftRelativeSpace < 0.f)
136 mLeftRelativeSpace = 0.f;
138 mRightRelativeSpace -= 0.5f * relativeSize;
139 if(mRightRelativeSpace < 0.f)
141 mRightRelativeSpace = 0.f;
145 case Toolkit::Alignment::HORIZONTAL_RIGHT:
147 mRightRelativeSpace -= relativeSize;
148 if(mRightRelativeSpace < 0.f)
150 mRightRelativeSpace = 0.f;
156 DALI_ASSERT_ALWAYS(false);
160 mLayout.SetRelativeWidth(mLeftOffset, mLeftRelativeSpace);
161 mLayout.SetRelativeWidth(mCenterBase + mCenterOffset, mRightRelativeSpace);
164 void ToolBar::RemoveControl(Actor control)
166 Toolkit::TableView::CellPosition position;
168 // Find the alignment where the control is placed.
169 std::map<Actor, Toolkit::Alignment>::iterator it = mControls.find(control);
171 if((it != mControls.end()) && (mLayout.FindChildPosition(it->second, position)))
173 // Update accumulated relative space.
174 mAccumulatedRelativeSpace -= mLayout.GetRelativeWidth(position.columnIndex);
176 // Update spaces between left, center and right groups of controls.
177 if(1.0 > mAccumulatedRelativeSpace)
179 Toolkit::Alignment::Type alignment = Toolkit::Alignment::HORIZONTAL_LEFT;
180 if(position.columnIndex < mLeftOffset)
182 alignment = Toolkit::Alignment::HORIZONTAL_LEFT;
184 else if((position.columnIndex > mLeftOffset) && (position.columnIndex < mCenterBase + mCenterOffset))
186 alignment = Toolkit::Alignment::HORIZONTAL_CENTER;
188 else if(position.columnIndex > mCenterBase + mCenterOffset)
190 alignment = Toolkit::Alignment::HORIZONTAL_RIGHT;
194 DALI_ASSERT_ALWAYS(false);
197 float relativeSize = mLayout.GetRelativeWidth(position.columnIndex);
201 case Toolkit::Alignment::HORIZONTAL_LEFT:
203 mLeftRelativeSpace += relativeSize;
204 if(mLeftRelativeSpace < 0.f)
206 mLeftRelativeSpace = 0.f;
210 case Toolkit::Alignment::HORIZONTAL_CENTER:
212 mLeftRelativeSpace += 0.5f * relativeSize;
213 if(mLeftRelativeSpace < 0.f)
215 mLeftRelativeSpace = 0.f;
217 mRightRelativeSpace += 0.5f * relativeSize;
218 if(mRightRelativeSpace < 0.f)
220 mRightRelativeSpace = 0.f;
224 case Toolkit::Alignment::HORIZONTAL_RIGHT:
226 mRightRelativeSpace += relativeSize;
227 if(mRightRelativeSpace < 0.f)
229 mRightRelativeSpace = 0.f;
235 DALI_ASSERT_ALWAYS(false);
238 mLayout.SetRelativeWidth(mLeftOffset, mLeftRelativeSpace);
239 mLayout.SetRelativeWidth(mCenterBase + mCenterOffset, mRightRelativeSpace);
242 // Remove alignment as parent of control.
243 it->second.Remove(control);
245 // Remove the relationship between control and alignment.
248 // Remove column from tableview.
249 mLayout.DeleteColumn(position.columnIndex);
251 // Update bases and offsets.
252 if(position.columnIndex < mCenterBase)
254 // Control is on the left side. Decrease left offset and center and right bases.
259 else if(position.columnIndex < mCenterBase + mCenterOffset)
261 // Control is on the center side. Decrease center offset and right base.
267 // Control is on the right side. Decrease right base and right offset.
275 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
282 mLeftRelativeSpace(0.5f),
283 mRightRelativeSpace(0.5f),
284 mAccumulatedRelativeSpace(0.f),
285 mInitializing(false),
294 void ToolBar::OnInitialize()
296 Lock lock(mInitializing);
299 mLayout = Toolkit::TableView::New(1, 1);
300 mLayout.SetProperty(Dali::Actor::Property::NAME, "TOOLBAR_LAYOUT");
301 mLayout.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
302 mLayout.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
306 // Add two default actors to create spaces between controls grouped on the left, center and right.
307 Actor leftSpace = Actor::New();
308 Actor rightSpace = Actor::New();
309 mLayout.AddChild(leftSpace, Toolkit::TableView::CellPosition(0, 0));
310 mLayout.AddChild(rightSpace, Toolkit::TableView::CellPosition(0, 1));
311 mLayout.SetRelativeWidth(0, mLeftRelativeSpace);
312 mLayout.SetRelativeWidth(1, mRightRelativeSpace);
314 Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::TOOL_BAR);
317 void ToolBar::OnChildAdd(Actor& child)
321 // An actor is being added through the Actor's API.
323 // Remove child from tool bar actor and insert it in table view with some 'default' values
324 if(child && child.GetParent())
326 child.GetParent().Remove(child);
329 AddControl(child, DEFAULT_RELATIVE_SIZE, DEFAULT_ALIGNMENT, Toolkit::ToolBar::DEFAULT_PADDING);
332 // No OnChildRemove method required because Actors are added to the mLayout table view, so if an
333 // actor is removed using the Actor::RemoveChild method it will not remove anything because the
334 // actor is in mLayout not in Self().
336 Control::OnChildAdd(child);
339 } // namespace Internal
341 } // namespace Toolkit