nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "Layout.h" 00025 #include "HLayout.h" 00026 #include "VLayout.h" 00027 #include "VScrollBar.h" 00028 00029 namespace nux 00030 { 00031 00032 const int VSCROLLBAR_WIDTH = 5; 00033 const int VSCROLLBAR_HEIGHT = 10; 00034 00035 VScrollBar::VScrollBar (NUX_FILE_LINE_DECL) 00036 : ScrollBar (NUX_FILE_LINE_PARAM) 00037 { 00038 content_width_ = 0; 00039 content_height_ = 0; 00040 container_width_ = 0; 00041 container_height_ = 0; 00042 m_TrackWidth = 0; 00043 m_TrackHeight = 0; 00044 m_SlideBarOffsetX = 0; 00045 m_SlideBarOffsetY = 0; 00046 content_offset_x_ = 0; 00047 content_offset_y_ = 0; 00048 b_MouseUpTimer = false; 00049 b_MouseDownTimer = false; 00050 m_color_factor = 1.0f; 00051 m_UpTimerHandler = 0; 00052 m_DownTimerHandler = 0; 00053 00054 vlayout = new VLayout (NUX_TRACKER_LOCATION); 00055 _scroll_up_button = new InputArea (NUX_TRACKER_LOCATION); 00056 _track = new InputArea (NUX_TRACKER_LOCATION); 00057 _scroll_down_button = new InputArea (NUX_TRACKER_LOCATION); 00058 _slider = new InputArea (NUX_TRACKER_LOCATION); 00059 _slider->SetParentObject(this); 00060 00061 // Set Original State 00062 SetMinimumSize (VSCROLLBAR_WIDTH, AREA_MIN_HEIGHT); 00063 SetMaximumSize (VSCROLLBAR_WIDTH, AREA_MAX_HEIGHT); 00064 00065 // Set Signals 00066 //_scroll_down_button->mouse_down.connect ( sigc::mem_fun (this, &VScrollBar::RecvStartScrollDown) ); 00067 //_scroll_down_button->mouse_up.connect ( sigc::mem_fun (this, &VScrollBar::RecvEndScrollDown) ); 00068 //_scroll_up_button->mouse_down.connect ( sigc::mem_fun (this, &VScrollBar::RecvStartScrollUp) ); 00069 //_scroll_up_button->mouse_up.connect ( sigc::mem_fun (this, &VScrollBar::RecvEndScrollUp) ); 00070 00071 _slider->mouse_down.connect ( sigc::mem_fun (this, &VScrollBar::OnSliderMouseDown) ); 00072 _slider->mouse_up.connect ( sigc::mem_fun (this, &VScrollBar::OnSliderMouseUp) ); 00073 _slider->mouse_drag.connect ( sigc::mem_fun (this, &VScrollBar::OnSliderMouseDrag) ); 00074 00075 _track->mouse_down.connect ( sigc::mem_fun (this, &VScrollBar::RecvTrackMouseDown) ); 00076 _track->mouse_up.connect ( sigc::mem_fun (this, &VScrollBar::RecvTrackMouseUp) ); 00077 _track->mouse_drag.connect ( sigc::mem_fun (this, &VScrollBar::RecvTrackMouseDrag) ); 00078 00079 //_track->mouse_down.connect( sigc::mem_fun(this, &VScrollBar::OnSliderMouseDown)); 00080 00081 // Set Geometry 00082 _scroll_down_button->SetMinimumSize (VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); 00083 _scroll_down_button->SetMaximumSize (VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); 00084 _scroll_down_button->SetGeometry (Geometry (0, 0, VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT) ); 00085 _scroll_up_button->SetMinimumSize (VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); 00086 _scroll_up_button->SetMaximumSize (VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT); 00087 _scroll_up_button->SetGeometry (Geometry (0, 0, VSCROLLBAR_WIDTH, VSCROLLBAR_HEIGHT) ); 00088 00089 vlayout->AddView (_scroll_up_button, 0, eCenter, eFix); 00090 vlayout->AddView (_track, 1, eCenter, eFull); 00091 vlayout->AddView (_scroll_down_button, 0, eCenter, eFix); 00092 00093 callback = new TimerFunctor; 00094 callback->OnTimerExpired.connect (sigc::mem_fun (this, &VScrollBar::VScrollBarHandler) ); 00095 up_callback = new TimerFunctor; 00096 up_callback->OnTimerExpired.connect (sigc::mem_fun (this, &VScrollBar::ScrollUp) ); 00097 down_callback = new TimerFunctor; 00098 down_callback->OnTimerExpired.connect (sigc::mem_fun (this, &VScrollBar::ScrollDown) ); 00099 trackup_callback = new TimerFunctor; 00100 trackup_callback->OnTimerExpired.connect (sigc::mem_fun (this, &VScrollBar::TrackUp) ); 00101 trackdown_callback = new TimerFunctor; 00102 trackdown_callback->OnTimerExpired.connect (sigc::mem_fun (this, &VScrollBar::TrackDown) ); 00103 00104 SetLayout(vlayout); 00105 SetAcceptMouseWheelEvent(true); 00106 } 00107 00108 00109 VScrollBar::~VScrollBar() 00110 { 00111 _slider->UnReference(); 00112 delete callback; 00113 delete up_callback; 00114 delete trackup_callback; 00115 delete down_callback; 00116 delete trackdown_callback; 00117 } 00118 00119 void VScrollBar::VScrollBarHandler (void *v) 00120 { 00121 VScrollBar *scrollbar = static_cast<VScrollBar *> (v); 00122 00123 if (scrollbar->b_MouseUpTimer && scrollbar->m_color_factor < 1) 00124 { 00125 scrollbar->m_color_factor += 0.1f; 00126 00127 if (scrollbar->m_color_factor >= 1) 00128 { 00129 scrollbar->m_color_factor = 1; 00130 scrollbar->b_MouseUpTimer = false; 00131 } 00132 else 00133 { 00134 scrollbar->QueueDraw(); 00135 GetTimer().AddTimerHandler (10, callback, scrollbar); 00136 } 00137 } 00138 00139 if (scrollbar->b_MouseDownTimer && scrollbar->m_color_factor > 0) 00140 { 00141 scrollbar->m_color_factor -= 0.09f; 00142 00143 if (scrollbar->m_color_factor <= 0) 00144 { 00145 scrollbar->m_color_factor = 0; 00146 scrollbar->b_MouseUpTimer = false; 00147 } 00148 else 00149 { 00150 scrollbar->QueueDraw(); 00151 GetTimer().AddTimerHandler (10, callback, scrollbar); 00152 } 00153 } 00154 00155 QueueDraw(); 00156 } 00157 00158 void VScrollBar::ScrollDown (void *v) 00159 { 00160 OnScrollDown.emit (m_ScrollUnit, 1); 00161 00162 if (AtMaximum() ) 00163 RecvEndScrollDown (0, 0, 0, 0); 00164 else 00165 m_DownTimerHandler = GetTimer().AddTimerHandler (10, down_callback, this); 00166 00167 QueueDraw(); 00168 } 00169 00170 void VScrollBar::ScrollUp (void *v) 00171 { 00172 OnScrollUp.emit (m_ScrollUnit, 1); 00173 00174 if (AtMaximum() ) 00175 RecvEndScrollUp (0, 0, 0, 0); 00176 else 00177 m_UpTimerHandler = GetTimer().AddTimerHandler (10, up_callback, this); 00178 00179 QueueDraw(); 00180 } 00181 00182 void VScrollBar::TrackUp (void *v) 00183 { 00184 if (m_TrackMouseCoord.y < _slider->GetBaseY() - _track->GetBaseY() ) 00185 { 00186 OnScrollUp.emit (container_height_, 1); 00187 m_TrackUpTimerHandler = GetTimer().AddTimerHandler (10, trackup_callback, this); 00188 QueueDraw(); 00189 } 00190 } 00191 00192 void VScrollBar::TrackDown (void *v) 00193 { 00194 if (m_TrackMouseCoord.y > _slider->GetBaseY() + _slider->GetBaseHeight() - _track->GetBaseY() ) 00195 { 00196 OnScrollDown.emit (container_height_, 1); 00197 m_TrackDownTimerHandler = GetTimer().AddTimerHandler (10, trackdown_callback, this); 00198 QueueDraw(); 00199 } 00200 } 00201 00202 void VScrollBar::RecvStartScrollUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 00203 { 00204 if (!AtMinimum ()) 00205 ScrollUp (this); 00206 } 00207 00208 void VScrollBar::RecvEndScrollUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 00209 { 00210 if (m_UpTimerHandler.IsValid ()) 00211 { 00212 GetTimer().RemoveTimerHandler (m_UpTimerHandler); 00213 m_UpTimerHandler = 0; 00214 } 00215 } 00216 00217 void VScrollBar::RecvStartScrollDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00218 { 00219 if (!AtMaximum ()) 00220 ScrollDown (this); 00221 } 00222 00223 void VScrollBar::RecvEndScrollDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00224 { 00225 if (m_DownTimerHandler.IsValid ()) 00226 { 00227 GetTimer().RemoveTimerHandler (m_DownTimerHandler); 00228 m_DownTimerHandler = 0; 00229 } 00230 } 00231 00232 void VScrollBar::RecvTrackMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00233 { 00234 m_TrackMouseCoord = Point (x, y); 00235 00236 int Y = _slider->GetBaseY () - _track->GetBaseY (); 00237 00238 if (y < Y) 00239 { 00240 // move the slide bar up 00241 TrackUp (this); 00242 } 00243 else 00244 { 00245 TrackDown (this); 00246 // move the slide bar down 00247 } 00248 } 00249 00250 void VScrollBar::RecvTrackMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 00251 { 00252 if (m_TrackUpTimerHandler.IsValid ()) 00253 GetTimer ().RemoveTimerHandler (m_TrackUpTimerHandler); 00254 00255 if (m_TrackDownTimerHandler.IsValid ()) 00256 GetTimer ().RemoveTimerHandler (m_TrackDownTimerHandler); 00257 00258 m_TrackUpTimerHandler = 0; 00259 m_TrackDownTimerHandler = 0; 00260 } 00261 00262 void VScrollBar::RecvTrackMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) 00263 { 00264 00265 } 00266 00267 long VScrollBar::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00268 { 00269 long ret; 00270 ret = _scroll_down_button->OnEvent (ievent, TraverseInfo, ProcessEventInfo); 00271 ret = _scroll_up_button->OnEvent (ievent, ret, ProcessEventInfo); 00272 ret = _slider->OnEvent (ievent, ret, ProcessEventInfo); 00273 ret = _track->OnEvent (ievent, ret, ProcessEventInfo); 00274 ret = PostProcessEvent2 (ievent, ret, ProcessEventInfo); 00275 return ret; 00276 } 00277 00278 Area* VScrollBar::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type) 00279 { 00280 bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type); 00281 00282 if(mouse_inside == false) 00283 return NULL; 00284 00285 NUX_RETURN_VALUE_IF_TRUE(_scroll_down_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_down_button); 00286 NUX_RETURN_VALUE_IF_TRUE(_scroll_up_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_up_button); 00287 NUX_RETURN_VALUE_IF_TRUE(_slider->TestMousePointerInclusion(mouse_position, event_type), _slider); 00288 NUX_RETURN_VALUE_IF_TRUE(_track->TestMousePointerInclusion(mouse_position, event_type), _track); 00289 00290 if((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent())) 00291 return NULL; 00292 return this; 00293 } 00294 00295 void VScrollBar::Draw (GraphicsEngine &GfxContext, bool force_draw) 00296 { 00297 Geometry base = GetGeometry(); 00298 GetPainter().PaintBackground (GfxContext, base); 00299 00300 base.OffsetPosition (0, VSCROLLBAR_HEIGHT); 00301 base.OffsetSize (0, -2 * VSCROLLBAR_HEIGHT); 00302 //GetPainter().PaintShape (GfxContext, base, Color (COLOR_SCROLLBAR_TRACK), eVSCROLLBAR, false); 00303 //GfxContext.QRP_Color (base.x, base.y, base.width, base.height, Color (COLOR_SCROLLBAR_TRACK)); 00304 00305 //GetPainter().PaintShape (GfxContext, _scroll_up_button->GetGeometry(), Color (0xFFFFFFFF), eSCROLLBAR_TRIANGLE_UP); 00306 //GetPainter().PaintShape (GfxContext, _scroll_down_button->GetGeometry(), Color (0xFFFFFFFF), eSCROLLBAR_TRIANGLE_DOWN); 00307 00308 /*GetPainter().PaintShape (GfxContext, _slider->GetGeometry(), 00309 Color (0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f), 00310 eVSCROLLBAR, true);*/ 00311 00312 if (content_height_ > container_height_) 00313 { 00314 Geometry slider_geo = _slider->GetGeometry (); 00315 GfxContext.QRP_Color (slider_geo.x, slider_geo.y, slider_geo.width, slider_geo.height, 00316 Color (1.0f, 1.0f, 1.0f, 0.8f)); 00317 } 00318 //Color (0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f)); 00319 } 00320 00321 void VScrollBar::SetContainerSize (int x, int y, int w, int h) 00322 { 00323 container_width_ = w; 00324 container_height_ = h; 00325 ComputeScrolling(); 00326 } 00327 00328 void VScrollBar::SetContentSize (int x, int y, int w, int h) 00329 { 00330 // x and y are not needed 00331 content_width_ = w; 00332 content_height_ = h; 00333 ComputeScrolling(); 00334 } 00335 00336 void VScrollBar::SetContentOffset (float dx, float dy) 00337 { 00338 content_offset_x_ = dx; 00339 content_offset_y_ = dy; 00340 ComputeScrolling(); 00341 } 00342 00343 void VScrollBar::ComputeScrolling() 00344 { 00345 if (content_height_ == 0) 00346 { 00347 visibility_percentage_ = 100.0f; 00348 } 00349 else 00350 { 00351 visibility_percentage_ = Clamp<float>(100.0f * (float) container_height_ / (float) content_height_, 0.0f, 100.0f); 00352 } 00353 00354 m_TrackHeight = _track->GetBaseHeight(); 00355 00356 int slider_width = _scroll_up_button->GetBaseWidth(); 00357 int slider_height = m_TrackHeight * visibility_percentage_ / 100.0f; 00358 00359 if (slider_height < 15) 00360 { 00361 slider_height = 15; 00362 } 00363 00364 _slider->SetBaseWidth (slider_width); 00365 _slider->SetBaseHeight (slider_height); 00366 _slider->SetBaseX (_scroll_up_button->GetBaseX() ); 00367 00368 float pct; 00369 00370 if (content_height_ - container_height_ > 0) 00371 pct = - (float) content_offset_y_ / (float) (content_height_ - container_height_); 00372 else 00373 pct = 0; 00374 00375 int y = _track->GetBaseY() + pct * (m_TrackHeight - slider_height); 00376 _slider->SetBaseY (y); 00377 } 00378 00380 // RECEIVERS // 00382 void VScrollBar::SetValue (float value) 00383 { 00384 //m_ValueString.setCaption(value); 00385 } 00386 void VScrollBar::SetParameterName (const char *parameter_name) 00387 { 00388 //m_ParameterName.setCaption(parameter_name); 00389 } 00390 00392 // EMITTERS // 00394 //void VScrollBar::EmitScrollUp(int x, int y, unsigned long button_flags, unsigned long key_flags) 00395 //{ 00396 // OnScrollUp.emit(m_ScrollUnit, 1); 00397 //} 00398 //void VScrollBar::EmitScrollDown(int x, int y, unsigned long button_flags, unsigned long key_flags) 00399 //{ 00400 // OnScrollDown.emit(m_ScrollUnit, 1); 00401 //} 00402 00403 void VScrollBar::OnSliderMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags) 00404 { 00405 m_SliderDragPositionX = x; 00406 m_SliderDragPositionY = y; 00407 //sigVScrollBarSliderMouseDown.emit(); 00408 b_MouseDownTimer = true; 00409 b_MouseUpTimer = false; 00410 GetTimer().AddTimerHandler (10, callback, this); 00411 } 00412 00413 void VScrollBar::OnSliderMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags) 00414 { 00415 b_MouseDownTimer = false; 00416 b_MouseUpTimer = true; 00417 GetTimer().AddTimerHandler (10, callback, this); 00418 } 00419 00420 void VScrollBar::OnSliderMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) 00421 { 00422 if (_track->GetBaseHeight() - _slider->GetBaseHeight() > 0) 00423 { 00424 stepY = (float) (content_height_ - container_height_) / (float) (_track->GetBaseHeight() - _slider->GetBaseHeight() ); 00425 } 00426 else 00427 { 00428 return; 00429 } 00430 00431 if ( (dy > 0) && (y > m_SliderDragPositionY) ) 00432 { 00433 OnScrollDown.emit (stepY, y - m_SliderDragPositionY); 00434 } 00435 00436 if ( (dy < 0) && (y < m_SliderDragPositionY) ) 00437 { 00438 OnScrollUp.emit (stepY, m_SliderDragPositionY - y); 00439 } 00440 00441 QueueDraw(); 00442 } 00443 00444 bool VScrollBar::AtMaximum() 00445 { 00446 if (_slider->GetBaseY() + _slider->GetBaseHeight() == _track->GetBaseY() + _track->GetBaseHeight() ) 00447 return TRUE; 00448 00449 return FALSE; 00450 } 00451 00452 bool VScrollBar::AtMinimum() 00453 { 00454 if (_slider->GetBaseY() == _track->GetBaseY() ) 00455 return TRUE; 00456 00457 return FALSE; 00458 } 00459 00460 long VScrollBar::PostLayoutManagement (long LayoutResult) 00461 { 00462 long ret = ScrollBar::PostLayoutManagement (LayoutResult); 00463 ComputeScrolling(); 00464 return ret; 00465 } 00466 00467 00468 }