MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
listbox.cpp
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _uilistbox_cpp
41 #define _uilistbox_cpp
42 
43 #include "UI/listbox.h"
44 #include "UI/uimanager.h"
45 #include "UI/screen.h"
46 #include "UI/scrollbar.h"
47 #include "Input/inputmanager.h"
48 #include "Input/metacode.h"
49 #include "Input/mouse.h"
50 #include "entresol.h"
51 
52 #include <cmath>
53 
54 namespace Mezzanine
55 {
56  namespace UI
57  {
58  ///////////////////////////////////////////////////////////////////////////////
59  // ListBox Static Members
60 
61  const String ListBox::TypeName = "ListBox";
62 
63  ///////////////////////////////////////////////////////////////////////////////
64  // ListBox Methods
65 
67  Widget(Parent)
68  {
69 
70  }
71 
72  ListBox::ListBox(const String& RendName, Screen* Parent) :
73  Widget(RendName,Parent)
74  {
75 
76  }
77 
78  ListBox::ListBox(const String& RendName, const UnifiedRect& RendRect, Screen* Parent) :
79  Widget(RendName,RendRect,Parent)
80  {
81 
82  }
83 
84  ListBox::ListBox(const XML::Node& XMLNode, Screen* Parent) :
85  Widget(Parent)
86  {
87 
88  }
89 
91  {
92 
93  }
94 
95  ///////////////////////////////////////////////////////////////////////////////
96  // Utility Methods
97 
98  ///////////////////////////////////////////////////////////////////////////////
99  // ListBox Properties
100 
101  ///////////////////////////////////////////////////////////////////////////////
102  // ListBox Configuration
103 
104  ///////////////////////////////////////////////////////////////////////////////
105  // Serialization
106 
108  {
109  this->Widget::ProtoSerializeProperties(SelfRoot);
110  }
111 
113  {
114  this->Widget::ProtoDeSerializeProperties(SelfRoot);
115  }
116 
118  {
119  return ListBox::TypeName;
120  }
121 
122  ///////////////////////////////////////////////////////////////////////////////
123  // Internal Event Methods
124 
125  ///////////////////////////////////////////////////////////////////////////////
126  // Internal Methods
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137  /*ListBox::ListBox(ConstString& name, const Rect& RendRect, const UI::ScrollbarStyle& ScrollStyle, Screen* PScreen) :
138  Widget(name,PScreen),
139  Selected(NULL),
140  AutoHideScroll(true),
141  LastScrollValue(0),
142  MaxDisplay(3),
143  SelectionsAdded(1)
144  {
145  /// @todo Currently this class has little support for a border around the selections.
146  /// Ideally when the UI system is more complete we'll be able to seemlessly move
147  /// objects around different layers and thus have more control over z-order. When
148  /// that happens we should add a rect to this class be be placed over the selections
149  /// for use with a border or other kind of decoration.
150  Type = Widget::W_ListBox;
151 
152  // Set some sane template defaults
153  SelectionTemplate.BackgroundColour = ColourValue(1.0,1.0,1.0,1.0);
154  SelectionTemplate.TextColour = ColourValue(0.0,0.0,0.0,1.0);
155  SelectionTemplate.TextScale = 1.0;
156  SelectionTemplate.CursorOffset = 0.0;
157  SelectionTemplate.HorizontalAlign = UI::Txt_Middle;
158  SelectionTemplate.VerticalAlign = UI::Txt_Center;
159  SelectionTemplate.Priority = UI::RP_Medium;
160 
161  Rect ScrollRect, BoxRect;
162  const Vector2& WinDim = ParentScreen->GetViewportDimensions();
163  if(RendRect.Relative)
164  {
165  RelPosition = RendRect.Position;
166  RelSize = RendRect.Size;
167 
168  SelectionTemplate.Size = RendRect.Size * WinDim;
169 
170  ScrollRect.Position = Vector2((RelPosition.X + RelSize.X) - ((RendRect.Size.Y * WinDim.Y) / WinDim.X),RelPosition.Y);
171  ScrollRect.Size = Vector2((RendRect.Size.Y * WinDim.Y) / WinDim.X,RelSize.Y * MaxDisplay);
172  ScrollRect.Relative = RendRect.Relative;
173  }else{
174  RelPosition = RendRect.Position / WinDim;
175  RelSize = RendRect.Size / WinDim;
176 
177  SelectionTemplate.Size = RendRect.Size;
178 
179  ScrollRect.Position = Vector2((RendRect.Position.X + RendRect.Size.X) - RendRect.Size.Y,RendRect.Position.Y);
180  ScrollRect.Size = Vector2(RendRect.Size.Y,RendRect.Size.Y * MaxDisplay);
181  ScrollRect.Relative = RendRect.Relative;
182  }
183  BoxRect.Position = RendRect.Position;
184  BoxRect.Size.X = RendRect.Size.X;
185  BoxRect.Size.Y = RendRect.Size.Y * MaxDisplay;
186  BoxRect.Relative = RendRect.Relative;
187 
188  BoxBack = ParentScreen->CreateRectangle(BoxRect);
189  VertScroll = ParentScreen->CreateScrollbar(Name+"Scr",ScrollRect,ScrollStyle);
190  VertScroll->Hide();
191 
192  AddSubRenderable(0,BoxBack);
193  AddSubRenderable(1,VertScroll);
194  }
195 
196  ListBox::~ListBox()
197  {
198  ParentScreen->DestroyBasicRenderable(BoxBack);
199  if(!Selections.empty())
200  {
201  for( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
202  {
203  ParentScreen->DestroyBasicRenderable( *it );
204  }
205  Selections.clear();
206  }
207  VisibleSelections.clear();
208  }
209 
210  void ListBox::ScrollerSizeCheck()
211  {
212  Real ScrollerSize = (Real)MaxDisplay / (Real)Selections.size();
213  VertScroll->SetScrollerSize(ScrollerSize);
214  }
215 
216  void ListBox::ScrollHideCheck()
217  {
218  if(!IsVisible())
219  {
220  VertScroll->Hide();
221  return;
222  }
223  if(!AutoHideScroll)
224  {
225  VertScroll->Show();
226  return;
227  }
228  if(Selections.size() > MaxDisplay)
229  VertScroll->Show();
230  else
231  VertScroll->Hide();
232  }
233 
234  void ListBox::SelectionSizeCheck(UI::Caption* Selection)
235  {
236  const Vector2& WinDim = ParentScreen->GetViewportDimensions();
237  Vector2 CurrSize = Selection->GetActualSize();
238  Vector2 TargetSize;
239  if(VertScroll->IsVisible())
240  TargetSize = Vector2(SelectionTemplate.Size.X - VertScroll->GetActualSize().X,SelectionTemplate.Size.Y);
241  else
242  TargetSize = SelectionTemplate.Size;
243  if(CurrSize != TargetSize)
244  {
245  Selection->SetActualSize(TargetSize);
246  }
247  }
248 
249  ListBox& ListBox::SetTemplateSize(const Vector2& Size, bool Relative)
250  {
251  const Vector2& WinDim = ParentScreen->GetViewportDimensions();
252  if(Relative)
253  {
254  this->SelectionTemplate.Size = Size * WinDim;
255  Vector2 NewSize = Vector2(Size.X,Size.Y * MaxDisplay);
256  SetArea(NewSize * WinDim);
257  }else{
258  this->SelectionTemplate.Size = Size;
259  Vector2 NewSize = Vector2(Size.X,Size.Y * MaxDisplay);
260  SetArea(NewSize);
261  }
262  return *this;
263  }
264 
265  ListBox& ListBox::SetTemplateGlyphIndex(const Whole& Glyph)
266  {
267  this->SelectionTemplate.GlyphIndex = Glyph;
268  return *this;
269  }
270 
271  ListBox& ListBox::SetTemplateTextColour(const ColourValue& TextColour)
272  {
273  this->SelectionTemplate.TextColour = TextColour;
274  return *this;
275  }
276 
277  ListBox& ListBox::SetTemplateTextScale(const Real& Scale)
278  {
279  this->SelectionTemplate.TextScale = Scale;
280  return *this;
281  }
282 
283  ListBox& ListBox::SetTemplateCursorOffset(const Whole& Offset)
284  {
285  this->SelectionTemplate.CursorOffset = Offset;
286  return *this;
287  }
288 
289  ListBox& ListBox::SetTemplateBackgroundColour(const ColourValue& BackgroundColour)
290  {
291  this->SelectionTemplate.BackgroundColour = BackgroundColour;
292  return *this;
293  }
294 
295  ListBox& ListBox::SetTemplateHorizontalAlign(const UI::TextHorizontalAlign& HorAlign)
296  {
297  this->SelectionTemplate.HorizontalAlign = HorAlign;
298  return *this;
299  }
300 
301  ListBox& ListBox::SetTemplateVerticalAlign(const UI::TextVerticalAlign& VertAlign)
302  {
303  this->SelectionTemplate.VerticalAlign = VertAlign;
304  return *this;
305  }
306 
307  ListBox& ListBox::SetTemplateRenderPriority(const UI::RenderPriority& Priority)
308  {
309  this->SelectionTemplate.Priority = Priority;
310  return *this;
311  }
312 
313  const UI::TemplateParams& ListBox::GetTemplateInfo()
314  {
315  return this->SelectionTemplate;
316  }
317 
318  Caption* ListBox::AddSelection(ConstString& name, ConstString &Text, ConstString& BackgroundSprite)
319  {
320  SelectionsAdded++;
321  Rect SelectionRect(RelPosition,SelectionTemplate.Size / ParentScreen->GetViewportDimensions(),true);
322  Caption* Select = ParentScreen->CreateCaption(name,SelectionRect,SelectionTemplate.GlyphIndex,Text);
323  if(!BackgroundSprite.empty())
324  Select->SetBackgroundSprite(BackgroundSprite);
325  if(SelectionTemplate.BackgroundColour != ColourValue(1.0,1.0,1.0,1.0))
326  Select->SetBackgroundColour(SelectionTemplate.BackgroundColour);
327  if(SelectionTemplate.CursorOffset != 0)
328  Select->SetCursorOffset(SelectionTemplate.CursorOffset);
329  if(SelectionTemplate.TextScale != 1)
330  Select->SetTextScale(SelectionTemplate.TextScale);
331  Select->SetTextColour(SelectionTemplate.TextColour);
332  Select->HorizontallyAlign(SelectionTemplate.HorizontalAlign);
333  Select->VerticallyAlign(SelectionTemplate.VerticalAlign);
334  Select->SetRenderPriority(SelectionTemplate.Priority);
335  Select->Hide();
336  Selections.push_back(Select);
337  AddSubRenderable(SelectionsAdded,Select);
338  ScrollerSizeCheck();
339  DrawList();
340  return Select;
341  }
342 
343  Caption* ListBox::GetSelection(ConstString &Name)
344  {
345  for ( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
346  {
347  if ( Name == (*it)->GetName() )
348  {
349  UI::Caption* button = (*it);
350  return button;
351  }
352  }
353  return 0;
354  }
355 
356  void ListBox::DestroySelection(Caption* ToBeDestroyed)
357  {
358  for ( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
359  {
360  if ( ToBeDestroyed == (*it) )
361  {
362  Selections.erase(it);
363  break;
364  }
365  }
366  for ( RenderableIterator it = SubRenderables.begin() ; it != SubRenderables.end() ; ++it )
367  {
368  if( (*it) == ToBeDestroyed )
369  {
370  SubRenderables.erase(it);
371  break;
372  }
373  }
374  ParentScreen->DestroyBasicRenderable(ToBeDestroyed);
375  }//*/
376  }//UI
377 }//Mezzanine
378 
379 #endif