00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef _uilistbox_cpp
00041 #define _uilistbox_cpp
00042
00043 #include "uilistbox.h"
00044 #include "uimanager.h"
00045 #include "uilayer.h"
00046 #include "uiscreen.h"
00047 #include "uicaption.h"
00048 #include "uirectangle.h"
00049 #include "uiscrollbar.h"
00050 #include "uiviewportupdatetool.h"
00051 #include "inputquerytool.h"
00052 #include "metacode.h"
00053 #include "world.h"
00054
00055 #include <cmath>
00056
00057 namespace Mezzanine
00058 {
00059 namespace UI
00060 {
00061 ListBox::ListBox(ConstString& name, const RenderableRect& Rect, const UI::ScrollbarStyle& ScrollStyle, Layer* PLayer)
00062 : Widget(name,PLayer),
00063 Selected(NULL),
00064 AutoHideScroll(true),
00065 LastScrollValue(0),
00066 MaxDisplay(3),
00067 SelectionsAdded(1)
00068 {
00069
00070
00071
00072
00073
00074 Type = Widget::W_ListBox;
00075
00076
00077 SelectionTemplate.BackgroundColour = ColourValue(1.0,1.0,1.0,1.0);
00078 SelectionTemplate.TextColour = ColourValue(0.0,0.0,0.0,1.0);
00079 SelectionTemplate.TextScale = 1.0;
00080 SelectionTemplate.CursorOffset = 0.0;
00081 SelectionTemplate.HorizontalAlign = UI::Txt_Middle;
00082 SelectionTemplate.VerticalAlign = UI::Txt_Center;
00083 SelectionTemplate.Priority = UI::RP_Medium;
00084
00085 RenderableRect ScrollRect, BoxRect;
00086 const Vector2& WinDim = ParentLayer->GetParent()->GetViewportDimensions();
00087 if(Rect.Relative)
00088 {
00089 RelPosition = Rect.Position;
00090 RelSize = Rect.Size;
00091
00092 SelectionTemplate.Size = Rect.Size * WinDim;
00093
00094 ScrollRect.Position = Vector2((RelPosition.X + RelSize.X) - ((Rect.Size.Y * WinDim.Y) / WinDim.X),RelPosition.Y);
00095 ScrollRect.Size = Vector2((Rect.Size.Y * WinDim.Y) / WinDim.X,RelSize.Y * MaxDisplay);
00096 ScrollRect.Relative = Rect.Relative;
00097 }else{
00098 RelPosition = Rect.Position / WinDim;
00099 RelSize = Rect.Size / WinDim;
00100
00101 SelectionTemplate.Size = Rect.Size;
00102
00103 ScrollRect.Position = Vector2((Rect.Position.X + Rect.Size.X) - Rect.Size.Y,Rect.Position.Y);
00104 ScrollRect.Size = Vector2(Rect.Size.Y,Rect.Size.Y * MaxDisplay);
00105 ScrollRect.Relative = Rect.Relative;
00106 }
00107 BoxRect.Position = Rect.Position;
00108 BoxRect.Size.X = Rect.Size.X;
00109 BoxRect.Size.Y = Rect.Size.Y * MaxDisplay;
00110 BoxRect.Relative = Rect.Relative;
00111
00112 BoxBack = new Rectangle(BoxRect,ParentLayer);
00113 VertScroll = new Scrollbar(Name+"Scr",ScrollRect,ScrollStyle,ParentLayer);
00114 VertScroll->Hide();
00115
00116 AddSubRenderable(0,RenderablePair(BoxBack,NULL));
00117 AddSubRenderable(1,RenderablePair(NULL,VertScroll));
00118 }
00119
00120 ListBox::~ListBox()
00121 {
00122 delete BoxBack;
00123 if(!Selections.empty())
00124 {
00125 for( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
00126 {
00127 delete (*it);
00128 }
00129 Selections.clear();
00130 }
00131 VisibleSelections.clear();
00132 }
00133
00134 void ListBox::ScrollerSizeCheck()
00135 {
00136 Real ScrollerSize = (Real)MaxDisplay / (Real)Selections.size();
00137 VertScroll->SetScrollerSize(ScrollerSize);
00138 }
00139
00140 void ListBox::ScrollHideCheck()
00141 {
00142 if(!IsVisible())
00143 {
00144 VertScroll->Hide();
00145 return;
00146 }
00147 if(!AutoHideScroll)
00148 {
00149 VertScroll->Show();
00150 return;
00151 }
00152 if(Selections.size() > MaxDisplay)
00153 VertScroll->Show();
00154 else
00155 VertScroll->Hide();
00156 }
00157
00158 void ListBox::SelectionSizeCheck(UI::Caption* Selection)
00159 {
00160 const Vector2& WinDim = ParentLayer->GetParent()->GetViewportDimensions();
00161 Vector2 CurrSize = Selection->GetActualSize();
00162 Vector2 TargetSize;
00163 if(VertScroll->IsVisible())
00164 TargetSize = Vector2(SelectionTemplate.Size.X - VertScroll->GetActualSize().X,SelectionTemplate.Size.Y);
00165 else
00166 TargetSize = SelectionTemplate.Size;
00167 if(CurrSize != TargetSize)
00168 {
00169 Selection->SetActualSize(TargetSize);
00170 }
00171 }
00172
00173 void ListBox::SetArea(const Vector2& Area)
00174 {
00175 RelSize = Area / ParentLayer->GetParent()->GetViewportDimensions();
00176 BoxBack->SetActualSize(Area);
00177 Vector2 ScrollP((GetActualPosition().X + Area.X) - VertScroll->GetActualSize().X,GetActualPosition().Y);
00178 Vector2 ScrollS(VertScroll->GetActualSize().X,Area.Y);
00179 VertScroll->SetActualPosition(ScrollP);
00180 VertScroll->SetActualSize(ScrollS);
00181 }
00182
00183 void ListBox::DrawList()
00184 {
00185 if(Selections.empty())
00186 return;
00187 ScrollHideCheck();
00188 VisibleSelections.clear();
00189 Whole FirstCaption = 0;
00190 if(MaxDisplay < Selections.size())
00191 {
00192 Real ToBeRounded = VertScroll->GetScrollerValue() * (Real)(Selections.size() - MaxDisplay);
00193 FirstCaption = (Whole)(ToBeRounded + 0.5);
00194 }
00195 Vector2 SelectionPos = GetActualPosition();
00196 Real ActualInc = SelectionTemplate.Size.Y;
00197
00198 for( Whole w = 0 ; w < FirstCaption ; ++w )
00199 {
00200 Selections[w]->SetPosition(GetPosition());
00201 Selections[w]->Hide();
00202 SelectionSizeCheck(Selections[w]);
00203 }
00204 Whole Displayed = FirstCaption+MaxDisplay > Selections.size() ? Selections.size() : FirstCaption+MaxDisplay;
00205 for( Whole x = FirstCaption ; x < Displayed ; ++x )
00206 {
00207 VisibleSelections.push_back(Selections[x]);
00208 Selections[x]->SetVisible(this->IsVisible());
00209 }
00210 for( Whole y = Displayed ; y < Selections.size() ; ++y )
00211 {
00212 Selections[y]->SetPosition(GetPosition());
00213 Selections[y]->Hide();
00214 SelectionSizeCheck(Selections[y]);
00215 }
00216 for( Whole z = 0 ; z < VisibleSelections.size() ; ++z )
00217 {
00218 VisibleSelections[z]->SetActualPosition(SelectionPos);
00219 SelectionPos.Y+=ActualInc;
00220 SelectionSizeCheck(VisibleSelections[z]);
00221 }
00222 }
00223
00224 void ListBox::UpdateImpl(bool Force)
00225 {
00226 MetaCode::ButtonState State = InputQueryTool::GetMouseButtonState(1);
00227 if(HoveredCaption)
00228 {
00229 if(MetaCode::BUTTON_PRESSING == State)
00230 {
00231 SetSelected(HoveredCaption);
00232 }
00233 }
00234 if(LastScrollValue != VertScroll->GetScrollerValue())
00235 {
00236 DrawList();
00237 LastScrollValue = VertScroll->GetScrollerValue();
00238 }
00239 }
00240
00241 void ListBox::SetVisibleImpl(bool visible)
00242 {
00243 BoxBack->SetVisible(visible);
00244 DrawList();
00245 }
00246
00247 bool ListBox::CheckMouseHoverImpl()
00248 {
00249 for( std::vector<Caption*>::iterator it = VisibleSelections.begin() ; it != VisibleSelections.end() ; it++ )
00250 {
00251 if((*it)->CheckMouseHover())
00252 {
00253 HoveredSubWidget = NULL;
00254 HoveredButton = NULL;
00255 HoveredCaption = (*it);
00256 return true;
00257 }
00258 }
00259 if(VertScroll->CheckMouseHover())
00260 {
00261 HoveredSubWidget = VertScroll;
00262 HoveredButton = VertScroll->GetHoveredButton();
00263 HoveredCaption = NULL;
00264 return true;
00265 }
00266 else if(BoxBack->CheckMouseHover())
00267 {
00268 HoveredSubWidget = NULL;
00269 HoveredButton = NULL;
00270 HoveredCaption = NULL;
00271 return true;
00272 }
00273 HoveredCaption = NULL;
00274 return false;
00275 }
00276
00277 ListBox& ListBox::SetTemplateSize(const Vector2& Size, bool Relative)
00278 {
00279 const Vector2& WinDim = ParentLayer->GetParent()->GetViewportDimensions();
00280 if(Relative)
00281 {
00282 this->SelectionTemplate.Size = Size * WinDim;
00283 Vector2 NewSize = Vector2(Size.X,Size.Y * MaxDisplay);
00284 SetArea(NewSize * WinDim);
00285 }else{
00286 this->SelectionTemplate.Size = Size;
00287 Vector2 NewSize = Vector2(Size.X,Size.Y * MaxDisplay);
00288 SetArea(NewSize);
00289 }
00290 return *this;
00291 }
00292
00293 ListBox& ListBox::SetTemplateGlyphIndex(const Whole& Glyph)
00294 {
00295 this->SelectionTemplate.GlyphIndex = Glyph;
00296 return *this;
00297 }
00298
00299 ListBox& ListBox::SetTemplateTextColour(const ColourValue& TextColour)
00300 {
00301 this->SelectionTemplate.TextColour = TextColour;
00302 return *this;
00303 }
00304
00305 ListBox& ListBox::SetTemplateTextScale(const Real& Scale)
00306 {
00307 this->SelectionTemplate.TextScale = Scale;
00308 return *this;
00309 }
00310
00311 ListBox& ListBox::SetTemplateCursorOffset(const Whole& Offset)
00312 {
00313 this->SelectionTemplate.CursorOffset = Offset;
00314 return *this;
00315 }
00316
00317 ListBox& ListBox::SetTemplateBackgroundColour(const ColourValue& BackgroundColour)
00318 {
00319 this->SelectionTemplate.BackgroundColour = BackgroundColour;
00320 return *this;
00321 }
00322
00323 ListBox& ListBox::SetTemplateHorizontalAlign(const UI::TextHorizontalAlign& HorAlign)
00324 {
00325 this->SelectionTemplate.HorizontalAlign = HorAlign;
00326 return *this;
00327 }
00328
00329 ListBox& ListBox::SetTemplateVerticalAlign(const UI::TextVerticalAlign& VertAlign)
00330 {
00331 this->SelectionTemplate.VerticalAlign = VertAlign;
00332 return *this;
00333 }
00334
00335 ListBox& ListBox::SetTemplateRenderPriority(const UI::RenderPriority& Priority)
00336 {
00337 this->SelectionTemplate.Priority = Priority;
00338 return *this;
00339 }
00340
00341 const UI::TemplateParams& ListBox::GetTemplateInfo()
00342 {
00343 return this->SelectionTemplate;
00344 }
00345
00346 Caption* ListBox::AddSelection(ConstString& name, ConstString &Text, ConstString& BackgroundSprite)
00347 {
00348 SelectionsAdded++;
00349 RenderableRect SelectionRect(RelPosition,SelectionTemplate.Size / ParentLayer->GetParent()->GetViewportDimensions(),true);
00350 Caption* Select = new Caption(name,SelectionRect,SelectionTemplate.GlyphIndex,Text,ParentLayer);
00351 if(!BackgroundSprite.empty())
00352 Select->SetBackgroundSprite(BackgroundSprite);
00353 if(SelectionTemplate.BackgroundColour != ColourValue(1.0,1.0,1.0,1.0))
00354 Select->SetBackgroundColour(SelectionTemplate.BackgroundColour);
00355 if(SelectionTemplate.CursorOffset != 0)
00356 Select->SetCursorOffset(SelectionTemplate.CursorOffset);
00357 if(SelectionTemplate.TextScale != 1)
00358 Select->SetTextScale(SelectionTemplate.TextScale);
00359 Select->SetTextColour(SelectionTemplate.TextColour);
00360 Select->HorizontallyAlign(SelectionTemplate.HorizontalAlign);
00361 Select->VerticallyAlign(SelectionTemplate.VerticalAlign);
00362 Select->SetRenderPriority(SelectionTemplate.Priority);
00363 Select->Hide();
00364 Selections.push_back(Select);
00365 AddSubRenderable(SelectionsAdded,RenderablePair(Select,NULL));
00366 ScrollerSizeCheck();
00367 DrawList();
00368 return Select;
00369 }
00370
00371 Caption* ListBox::GetSelection(ConstString &Name)
00372 {
00373 for ( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
00374 {
00375 if ( Name == (*it)->GetName() )
00376 {
00377 UI::Caption* button = (*it);
00378 return button;
00379 }
00380 }
00381 return 0;
00382 }
00383
00384 void ListBox::DestroySelection(Caption* ToBeDestroyed)
00385 {
00386 for ( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
00387 {
00388 if ( ToBeDestroyed == (*it) )
00389 {
00390 Selections.erase(it);
00391 break;
00392 }
00393 }
00394 for ( RenderableMap::iterator it = SubRenderables.begin() ; it != SubRenderables.end() ; ++it )
00395 {
00396 if( (*it).second.first == ToBeDestroyed )
00397 {
00398 SubRenderables.erase(it);
00399 break;
00400 }
00401 }
00402 delete ToBeDestroyed;
00403 }
00404
00405 void ListBox::DestroySelection(String& ToBeDestroyed)
00406 {
00407 for ( std::vector<Caption*>::iterator it = Selections.begin() ; it != Selections.end() ; it++ )
00408 {
00409 if ( ToBeDestroyed == (*it)->GetName() )
00410 {
00411 delete (*it);
00412 Selections.erase(it);
00413 return;
00414 }
00415 }
00416 }
00417
00418 void ListBox::SetSelected(Caption* ToBeSelected)
00419 {
00420
00421 Selected = ToBeSelected;
00422 }
00423
00424 void ListBox::SetMaxDisplayedSelections(const Whole& MaxSelections)
00425 {
00426 MaxDisplay = MaxSelections;
00427 Vector2 NewBackSize = SelectionTemplate.Size;
00428 NewBackSize.Y*=MaxDisplay;
00429 SetArea(NewBackSize);
00430 ScrollerSizeCheck();
00431 }
00432
00433 void ListBox::SetAutoHideScroll(bool AutoHide)
00434 {
00435 AutoHideScroll = AutoHide;
00436 ScrollHideCheck();
00437 }
00438
00439 void ListBox::SetPosition(const Vector2& Position)
00440 {
00441 RelPosition = Position;
00442 Vector2 ScrollOffset = VertScroll->GetPosition() - RelPosition;
00443 BoxBack->SetPosition(Position);
00444 VertScroll->SetPosition(Position + ScrollOffset);
00445 DrawList();
00446 }
00447
00448 void ListBox::SetActualPosition(const Vector2& Position)
00449 {
00450 RelPosition = Position / ParentLayer->GetParent()->GetViewportDimensions();
00451 Vector2 ScrollOffset = VertScroll->GetActualPosition() - (RelPosition * ParentLayer->GetParent()->GetViewportDimensions());
00452 BoxBack->SetActualPosition(Position);
00453 VertScroll->SetActualPosition(Position + ScrollOffset);
00454 DrawList();
00455 }
00456
00457 void ListBox::SetSize(const Vector2& Size)
00458 {
00459
00460 }
00461
00462 void ListBox::SetActualSize(const Vector2& Size)
00463 {
00464
00465 }
00466
00467 void ListBox::UpdateDimensions()
00468 {
00469
00470
00471
00472
00473 WidgetResult Result = ViewportUpdateTool::UpdateWidget(this);
00474 RelPosition = Result.first / ViewportUpdateTool::GetNewSize();
00475 RelSize = Result.second / ViewportUpdateTool::GetNewSize();
00476 Real Scale = ViewportUpdateTool::GetNewSize().Y / ViewportUpdateTool::GetOldSize().Y;
00477 BoxBack->UpdateDimensions();
00478 VertScroll->UpdateDimensions();
00479 SelectionTemplate.Size*=Scale;
00480 DrawList();
00481 SetPosition(RelPosition);
00482 }
00483
00484 Caption* ListBox::GetSelected()
00485 {
00486 return Selected;
00487 }
00488
00489 Rectangle* ListBox::GetBoxBack()
00490 {
00491 return BoxBack;
00492 }
00493
00494 UI::Scrollbar* ListBox::GetVertScroll()
00495 {
00496 return VertScroll;
00497 }
00498 }
00499 }
00500
00501 #endif