1 /*
2 GWEN
3 Copyright (c) 2010 Facepunch Studios
4 See license in Gwen.h
5 */
6
7 #include "Gwen/Controls/ScrollControl.h"
8 #include "Gwen/Controls/ScrollBar.h"
9 #include "Gwen/Controls/VerticalScrollBar.h"
10 #include "Gwen/Controls/HorizontalScrollBar.h"
11 #include "Gwen/Utility.h"
12
13 using namespace Gwen;
14 using namespace Gwen::Controls;
15 using namespace Gwen::ControlsInternal;
16
GWEN_CONTROL_CONSTRUCTOR(ScrollControl)17 GWEN_CONTROL_CONSTRUCTOR(ScrollControl)
18 {
19 SetMouseInputEnabled(false);
20
21 m_VerticalScrollBar = new VerticalScrollBar(this);
22 m_VerticalScrollBar->Dock(Pos::Right);
23 m_VerticalScrollBar->onBarMoved.Add(this, &ScrollControl::VBarMoved);
24 m_VerticalScrollBar->SetNudgeAmount(30);
25 m_bCanScrollV = true;
26
27 m_HorizontalScrollBar = new HorizontalScrollBar(this);
28 m_HorizontalScrollBar->Dock(Pos::Bottom);
29 m_HorizontalScrollBar->onBarMoved.Add(this, &ScrollControl::HBarMoved);
30 m_bCanScrollH = true;
31 m_HorizontalScrollBar->SetNudgeAmount(30);
32
33 m_InnerPanel = new Base(this);
34 m_InnerPanel->SetPos(0, 0);
35 m_InnerPanel->SetMargin(Margin(5, 5, 5, 5));
36 m_InnerPanel->SendToBack();
37 m_InnerPanel->SetMouseInputEnabled(false);
38
39 m_bAutoHideBars = false;
40 }
41
SetScroll(bool h,bool v)42 void ScrollControl::SetScroll(bool h, bool v)
43 {
44 m_bCanScrollV = v;
45 m_bCanScrollH = h;
46 m_VerticalScrollBar->SetHidden(!m_bCanScrollV);
47 m_HorizontalScrollBar->SetHidden(!m_bCanScrollH);
48 }
49
SetInnerSize(int w,int h)50 void ScrollControl::SetInnerSize(int w, int h)
51 {
52 m_InnerPanel->SetSize(w, h);
53 }
54
VBarMoved(Controls::Base *)55 void ScrollControl::VBarMoved(Controls::Base* /*control*/)
56 {
57 Invalidate();
58 }
59
HBarMoved(Controls::Base *)60 void ScrollControl::HBarMoved(Controls::Base* /*control*/)
61 {
62 Invalidate();
63 }
64
OnChildBoundsChanged(Gwen::Rect,Base *)65 void ScrollControl::OnChildBoundsChanged(Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/)
66 {
67 UpdateScrollBars();
68 }
69
Layout(Skin::Base * skin)70 void ScrollControl::Layout(Skin::Base* skin)
71 {
72 UpdateScrollBars();
73 BaseClass::Layout(skin);
74 }
75
OnMouseWheeled(int iDelta)76 bool ScrollControl::OnMouseWheeled(int iDelta)
77 {
78 if (CanScrollV() && m_VerticalScrollBar->Visible())
79 {
80 if (m_VerticalScrollBar->SetScrolledAmount(m_VerticalScrollBar->GetScrolledAmount() - m_VerticalScrollBar->GetNudgeAmount() * ((float)iDelta / 60.0f), true))
81 return true;
82 }
83
84 if (CanScrollH() && m_HorizontalScrollBar->Visible())
85 {
86 if (m_HorizontalScrollBar->SetScrolledAmount(m_HorizontalScrollBar->GetScrolledAmount() - m_HorizontalScrollBar->GetNudgeAmount() * ((float)iDelta / 60.0f), true))
87 return true;
88 }
89
90 return false;
91 }
Render(Skin::Base * skin)92 void ScrollControl::Render(Skin::Base* skin)
93 {
94 #if 0
95
96 // Debug render - this shouldn't render ANYTHING REALLY - it should be up to the parent!
97
98 Gwen::Rect rect = GetRenderBounds();
99 Gwen::Renderer::Base* render = skin->GetRender();
100
101 render->SetDrawColor( Gwen::Color( 255, 255, 0, 100 ) );
102 render->DrawFilledRect( rect );
103
104 render->SetDrawColor( Gwen::Color( 255, 0, 0, 100 ) );
105 render->DrawFilledRect( m_InnerPanel->GetBounds() );
106
107 render->RenderText( skin->GetDefaultFont(), Gwen::Point( 0, 0 ), Utility::Format( L"Offset: %i %i", m_InnerPanel->X(), m_InnerPanel->Y() ) );
108
109 #else //0
110
111 (void)skin;
112
113 #endif //0
114 }
115
UpdateScrollBars()116 void ScrollControl::UpdateScrollBars()
117 {
118 if (!m_InnerPanel)
119 return;
120
121 int childrenWidth = 0;
122 int childrenHeight = 0;
123
124 //Get the max size of all our children together
125 for (Base::List::iterator iter = m_InnerPanel->Children.begin(); iter != m_InnerPanel->Children.end(); ++iter)
126 {
127 Base* pChild = *iter;
128
129 childrenWidth = Utility::Max(childrenWidth, pChild->Right());
130 childrenHeight = Utility::Max(childrenHeight, pChild->Bottom());
131 }
132
133 m_InnerPanel->SetSize(Utility::Max(Width(), childrenWidth), Utility::Max(Height(), childrenHeight));
134
135 float hg = (float)(childrenWidth + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()));
136 if (hg == 0.f)
137 hg = 0.00001f;
138 float wPercent = (float)Width() / hg;
139 hg = (float)(childrenHeight + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
140 if (hg == 0.f)
141 hg = 0.00001f;
142 float hPercent = (float)Height() / hg;
143
144 if (m_bCanScrollV)
145 SetVScrollRequired(hPercent >= 1);
146 else
147 m_VerticalScrollBar->SetHidden(true);
148
149 if (m_bCanScrollH)
150 SetHScrollRequired(wPercent >= 1);
151 else
152 m_HorizontalScrollBar->SetHidden(true);
153
154 m_VerticalScrollBar->SetContentSize(m_InnerPanel->Height());
155 m_VerticalScrollBar->SetViewableContentSize(Height() - (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height()));
156
157 m_HorizontalScrollBar->SetContentSize(m_InnerPanel->Width());
158 m_HorizontalScrollBar->SetViewableContentSize(Width() - (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width()));
159
160 int newInnerPanelPosX = 0;
161 int newInnerPanelPosY = 0;
162
163 if (CanScrollV() && !m_VerticalScrollBar->Hidden())
164 {
165 newInnerPanelPosY = -((m_InnerPanel->Height()) - Height() + (m_HorizontalScrollBar->Hidden() ? 0 : m_HorizontalScrollBar->Height())) * m_VerticalScrollBar->GetScrolledAmount();
166 }
167 if (CanScrollH() && !m_HorizontalScrollBar->Hidden())
168 {
169 newInnerPanelPosX = -((m_InnerPanel->Width()) - Width() + (m_VerticalScrollBar->Hidden() ? 0 : m_VerticalScrollBar->Width())) * m_HorizontalScrollBar->GetScrolledAmount();
170 }
171
172 m_InnerPanel->SetPos(newInnerPanelPosX, newInnerPanelPosY);
173 }
174
SetVScrollRequired(bool req)175 void ScrollControl::SetVScrollRequired(bool req)
176 {
177 if (req)
178 {
179 m_VerticalScrollBar->SetScrolledAmount(0, true);
180 m_VerticalScrollBar->SetDisabled(true);
181
182 if (m_bAutoHideBars)
183 m_VerticalScrollBar->SetHidden(true);
184 }
185 else
186 {
187 m_VerticalScrollBar->SetHidden(false);
188 m_VerticalScrollBar->SetDisabled(false);
189 }
190 }
191
SetHScrollRequired(bool req)192 void ScrollControl::SetHScrollRequired(bool req)
193 {
194 if (req)
195 {
196 m_HorizontalScrollBar->SetScrolledAmount(0, true);
197 m_HorizontalScrollBar->SetDisabled(true);
198 if (m_bAutoHideBars)
199 m_HorizontalScrollBar->SetHidden(true);
200 }
201 else
202 {
203 m_HorizontalScrollBar->SetHidden(false);
204 m_HorizontalScrollBar->SetDisabled(true);
205 }
206 }
207
ScrollToBottom()208 void ScrollControl::ScrollToBottom()
209 {
210 if (CanScrollV())
211 {
212 UpdateScrollBars();
213 m_VerticalScrollBar->ScrollToBottom();
214 }
215 }
ScrollToTop()216 void ScrollControl::ScrollToTop()
217 {
218 if (CanScrollV())
219 {
220 UpdateScrollBars();
221 m_VerticalScrollBar->ScrollToTop();
222 }
223 }
ScrollToLeft()224 void ScrollControl::ScrollToLeft()
225 {
226 if (CanScrollH())
227 {
228 UpdateScrollBars();
229 m_HorizontalScrollBar->ScrollToLeft();
230 }
231 }
ScrollToRight()232 void ScrollControl::ScrollToRight()
233 {
234 if (CanScrollH())
235 {
236 UpdateScrollBars();
237 m_HorizontalScrollBar->ScrollToRight();
238 }
239 }
240
Clear()241 void ScrollControl::Clear()
242 {
243 m_InnerPanel->RemoveAllChildren();
244 }