1 /***********************************************************************
2     created:    02/8/2010
3     author:     Martin Preisler
4 
5     purpose:    Implements the Layout Container base class
6 *************************************************************************/
7 /***************************************************************************
8  *   Copyright (C) 2004 - 2010 Paul D Turner & The CEGUI Development Team
9  *
10  *   Permission is hereby granted, free of charge, to any person obtaining
11  *   a copy of this software and associated documentation files (the
12  *   "Software"), to deal in the Software without restriction, including
13  *   without limitation the rights to use, copy, modify, merge, publish,
14  *   distribute, sublicense, and/or sell copies of the Software, and to
15  *   permit persons to whom the Software is furnished to do so, subject to
16  *   the following conditions:
17  *
18  *   The above copyright notice and this permission notice shall be
19  *   included in all copies or substantial portions of the Software.
20  *
21  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  *   OTHER DEALINGS IN THE SOFTWARE.
28  ***************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 #   include "config.h"
31 #endif
32 
33 #include "CEGUI/widgets/SequentialLayoutContainer.h"
34 #include "CEGUI/WindowManager.h"
35 
36 // Start of CEGUI namespace section
37 namespace CEGUI
38 {
39 const String SequentialLayoutContainer::EventNamespace("SequentialLayoutContainer");
40 const String SequentialLayoutContainer::EventChildOrderChanged("ChildOrderChanged");
41 
42 //----------------------------------------------------------------------------//
SequentialLayoutContainer(const String & type,const String & name)43 SequentialLayoutContainer::SequentialLayoutContainer(const String& type,
44                                                      const String& name):
45     LayoutContainer(type, name)
46 {}
47 
48 //----------------------------------------------------------------------------//
~SequentialLayoutContainer(void)49 SequentialLayoutContainer::~SequentialLayoutContainer(void)
50 {}
51 
52 //----------------------------------------------------------------------------//
getPositionOfChild(Window * wnd) const53 size_t SequentialLayoutContainer::getPositionOfChild(Window* wnd) const
54 {
55     return getIdxOfChild(wnd);
56 }
57 
58 //----------------------------------------------------------------------------//
getPositionOfChild(const String & wnd) const59 size_t SequentialLayoutContainer::getPositionOfChild(const String& wnd) const
60 {
61     return getPositionOfChild(getChild(wnd));
62 }
63 
64 //----------------------------------------------------------------------------//
getChildAtPosition(size_t position) const65 Window* SequentialLayoutContainer::getChildAtPosition(size_t position) const
66 {
67     return getChildAtIdx(position);
68 }
69 
70 //----------------------------------------------------------------------------//
swapChildPositions(size_t wnd1,size_t wnd2)71 void SequentialLayoutContainer::swapChildPositions(size_t wnd1, size_t wnd2)
72 {
73     if (wnd1 < d_children.size() && wnd2 < d_children.size())
74     {
75         std::swap(d_children[wnd1], d_children[wnd2]);
76 
77         WindowEventArgs args(this);
78         onChildOrderChanged(args);
79     }
80 }
81 
82 //----------------------------------------------------------------------------//
swapChildren(Window * wnd1,Window * wnd2)83 void SequentialLayoutContainer::swapChildren(Window* wnd1, Window* wnd2)
84 {
85     if (isChild(wnd1) && isChild(wnd2))
86     {
87         swapChildPositions(getPositionOfChild(wnd1),
88                            getPositionOfChild(wnd2));
89     }
90 }
91 
92 //----------------------------------------------------------------------------//
swapChildren(const String & wnd1,Window * wnd2)93 void SequentialLayoutContainer::swapChildren(const String& wnd1,
94                                              Window* wnd2)
95 {
96     swapChildren(getChild(wnd1), wnd2);
97 }
98 
99 //----------------------------------------------------------------------------//
swapChildren(Window * wnd1,const String & wnd2)100 void SequentialLayoutContainer::swapChildren(Window* wnd1,
101                                              const String& wnd2)
102 {
103     swapChildren(wnd1, getChild(wnd2));
104 }
105 
106 //----------------------------------------------------------------------------//
swapChildren(const String & wnd1,const String & wnd2)107 void SequentialLayoutContainer::swapChildren(const String& wnd1,
108                                              const String& wnd2)
109 {
110     swapChildren(getChild(wnd1), getChild(wnd2));
111 }
112 
113 //----------------------------------------------------------------------------//
moveChildToPosition(Window * wnd,size_t position)114 void SequentialLayoutContainer::moveChildToPosition(Window* wnd,
115                                                           size_t position)
116 {
117     if (!isChild(wnd))
118         return;
119 
120     position = std::min(position, d_children.size() - 1);
121 
122     const size_t oldPosition = getPositionOfChild(wnd);
123 
124     if (oldPosition == position)
125     {
126         return;
127     }
128 
129     // we get the iterator of the old position
130     ChildList::iterator it = d_children.begin();
131     std::advance(it, oldPosition);
132 
133     // we are the window from it's old position
134     d_children.erase(it);
135 
136     // if the window comes before the point we want to insert to,
137     // we have to decrement the position
138     if (oldPosition < position)
139     {
140         --position;
141     }
142 
143     // find iterator of the new position
144     it = d_children.begin();
145     std::advance(it, position);
146     // and insert the window there
147     d_children.insert(it, wnd);
148 
149     WindowEventArgs args(this);
150     onChildOrderChanged(args);
151 }
152 
153 //----------------------------------------------------------------------------//
moveChildToPosition(const String & wnd,size_t position)154 void SequentialLayoutContainer::moveChildToPosition(const String& wnd,
155                                                           size_t position)
156 {
157     moveChildToPosition(getChild(wnd), position);
158 }
159 
160 //----------------------------------------------------------------------------//
moveChild(Window * window,int delta)161 void SequentialLayoutContainer::moveChild(Window* window, int delta)
162 {
163     const size_t oldPosition = getPositionOfChild(window);
164     int newPosition = oldPosition + delta;
165     newPosition = std::max(newPosition, 0);
166     // this is handled by moveChildToPosition itself
167     //newPosition = std::min(newPosition, (int)(d_children.size() - 1));
168 
169     moveChildToPosition(window, newPosition);
170 }
171 
172 //----------------------------------------------------------------------------//
addChildToPosition(Window * window,size_t position)173 void SequentialLayoutContainer::addChildToPosition(Window* window,
174                                                          size_t position)
175 {
176     addChild(window);
177 
178     moveChildToPosition(window, position);
179 }
180 
181 //----------------------------------------------------------------------------//
removeChildFromPosition(size_t position)182 void SequentialLayoutContainer::removeChildFromPosition(size_t position)
183 {
184     removeChild(getChildAtPosition(position));
185 }
186 
187 //----------------------------------------------------------------------------//
onChildOrderChanged(WindowEventArgs & e)188 void SequentialLayoutContainer::onChildOrderChanged(WindowEventArgs& e)
189 {
190     markNeedsLayouting();
191 
192     fireEvent(EventChildOrderChanged, e, EventNamespace);
193 }
194 
195 } // End of  CEGUI namespace section
196 
197