nux-1.16.0
VScrollBar.cpp
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 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends