Back to index

nux  3.0.0
VScrollBar.cpp
Go to the documentation of this file.
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->time_expires.connect(sigc::mem_fun(this, &VScrollBar::VScrollBarHandler));
00095     up_callback = new TimerFunctor;
00096     up_callback->time_expires.connect(sigc::mem_fun(this, &VScrollBar::ScrollUp));
00097     down_callback = new TimerFunctor;
00098     down_callback->time_expires.connect(sigc::mem_fun(this, &VScrollBar::ScrollDown));
00099     trackup_callback = new TimerFunctor;
00100     trackup_callback->time_expires.connect(sigc::mem_fun(this, &VScrollBar::TrackUp));
00101     trackdown_callback = new TimerFunctor;
00102     trackdown_callback->time_expires.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   Area* VScrollBar::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type)
00268   {
00269     bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
00270 
00271     if (mouse_inside == false)
00272       return NULL;
00273 
00274     NUX_RETURN_VALUE_IF_TRUE(_scroll_down_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_down_button);
00275     NUX_RETURN_VALUE_IF_TRUE(_scroll_up_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_up_button);
00276     NUX_RETURN_VALUE_IF_TRUE(_slider->TestMousePointerInclusion(mouse_position, event_type), _slider);
00277     NUX_RETURN_VALUE_IF_TRUE(_track->TestMousePointerInclusion(mouse_position, event_type), _track);
00278 
00279     if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent()))
00280       return NULL;
00281     return this;
00282   }
00283 
00284   void VScrollBar::Draw(GraphicsEngine &graphics_engine, bool force_draw)
00285   {
00286     Geometry base = GetGeometry();
00287     GetPainter().PaintBackground(graphics_engine, base);
00288 
00289     base.OffsetPosition(0, VSCROLLBAR_HEIGHT);
00290     base.OffsetSize(0, -2 * VSCROLLBAR_HEIGHT);
00291     //GetPainter().PaintShape(graphics_engine, base, Color(COLOR_SCROLLBAR_TRACK), eVSCROLLBAR, false);
00292     //graphics_engine.QRP_Color(base.x, base.y, base.width, base.height, Color(COLOR_SCROLLBAR_TRACK));
00293 
00294     //GetPainter().PaintShape(graphics_engine, _scroll_up_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_UP);
00295     //GetPainter().PaintShape(graphics_engine, _scroll_down_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_DOWN);
00296 
00297     /*GetPainter().PaintShape(graphics_engine, _slider->GetGeometry(),
00298                          Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f),
00299                          eVSCROLLBAR, true);*/
00300 
00301     if (content_height_ > container_height_)
00302     {
00303       Geometry slider_geo = _slider->GetGeometry();
00304       graphics_engine.QRP_Color(slider_geo.x, slider_geo.y, slider_geo.width, slider_geo.height,
00305           Color(1.0f, 1.0f, 1.0f, 0.8f));
00306     }
00307       //Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f));
00308   }
00309 
00310   void VScrollBar::SetContainerSize(int x, int y, int w, int h)
00311   {
00312     container_width_ = w;
00313     container_height_ = h;
00314     ComputeScrolling();
00315   }
00316 
00317   void VScrollBar::SetContentSize(int x, int y, int w, int h)
00318   {
00319     // x and y are not needed
00320     content_width_ = w;
00321     content_height_ = h;
00322     ComputeScrolling();
00323   }
00324 
00325   void VScrollBar::SetContentOffset(float dx, float dy)
00326   {
00327     content_offset_x_ = dx;
00328     content_offset_y_ = dy;
00329     ComputeScrolling();
00330   }
00331 
00332   void VScrollBar::ComputeScrolling()
00333   {
00334     if (content_height_ == 0)
00335     {
00336       visibility_percentage_ = 100.0f;
00337     }
00338     else
00339     {
00340       visibility_percentage_ = Clamp<float>(100.0f * (float) container_height_ / (float) content_height_, 0.0f, 100.0f);
00341     }
00342 
00343     m_TrackHeight = _track->GetBaseHeight();
00344 
00345     int slider_width = _scroll_up_button->GetBaseWidth();
00346     int slider_height = m_TrackHeight * visibility_percentage_ / 100.0f;
00347 
00348     if (slider_height < 15)
00349     {
00350       slider_height = 15;
00351     }
00352 
00353     _slider->SetBaseWidth(slider_width);
00354     _slider->SetBaseHeight(slider_height);
00355     _slider->SetBaseX(_scroll_up_button->GetBaseX());
00356 
00357     float pct;
00358 
00359     if (content_height_ - container_height_ > 0)
00360       pct = - (float) content_offset_y_ / (float) (content_height_ - container_height_);
00361     else
00362       pct = 0;
00363 
00364     int y = _track->GetBaseY() + pct * (m_TrackHeight - slider_height);
00365     _slider->SetBaseY(y);
00366   }
00367 
00369 //  RECEIVERS  //
00371   void VScrollBar::SetValue(float value)
00372   {
00373     //m_ValueString.setCaption(value);
00374   }
00375   void VScrollBar::SetParameterName(const char *parameter_name)
00376   {
00377     //m_ParameterName.setCaption(parameter_name);
00378   }
00379 
00381 //  EMITTERS  //
00383 //void VScrollBar::EmitScrollUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
00384 //{
00385 //    OnScrollUp.emit(m_ScrollUnit, 1);
00386 //}
00387 //void VScrollBar::EmitScrollDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
00388 //{
00389 //    OnScrollDown.emit(m_ScrollUnit, 1);
00390 //}
00391 
00392   void VScrollBar::OnSliderMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
00393   {
00394     m_SliderDragPositionX = x;
00395     m_SliderDragPositionY = y;
00396     //sigVScrollBarSliderMouseDown.emit();
00397     b_MouseDownTimer = true;
00398     b_MouseUpTimer = false;
00399     GetTimer().AddTimerHandler(10, callback, this);
00400   }
00401 
00402   void VScrollBar::OnSliderMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
00403   {
00404     b_MouseDownTimer = false;
00405     b_MouseUpTimer = true;
00406     GetTimer().AddTimerHandler(10, callback, this);
00407   }
00408 
00409   void VScrollBar::OnSliderMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00410   {
00411     if (_track->GetBaseHeight() - _slider->GetBaseHeight() > 0)
00412     {
00413       stepY = (float) (content_height_ - container_height_) / (float) (_track->GetBaseHeight() - _slider->GetBaseHeight());
00414     }
00415     else
00416     {
00417       return;
00418     }
00419 
00420     if ((dy > 0) && (y > m_SliderDragPositionY))
00421     {
00422       OnScrollDown.emit(stepY, y - m_SliderDragPositionY);
00423     }
00424 
00425     if ((dy < 0) && (y < m_SliderDragPositionY))
00426     {
00427       OnScrollUp.emit(stepY, m_SliderDragPositionY - y);
00428     }
00429 
00430     QueueDraw();
00431   }
00432 
00433   bool VScrollBar::AtMaximum()
00434   {
00435     if (_slider->GetBaseY() + _slider->GetBaseHeight() == _track->GetBaseY() + _track->GetBaseHeight())
00436       return TRUE;
00437 
00438     return FALSE;
00439   }
00440 
00441   bool VScrollBar::AtMinimum()
00442   {
00443     if (_slider->GetBaseY() == _track->GetBaseY())
00444       return TRUE;
00445 
00446     return FALSE;
00447   }
00448 
00449   long VScrollBar::PostLayoutManagement(long LayoutResult)
00450   {
00451     long ret = ScrollBar::PostLayoutManagement(LayoutResult);
00452     ComputeScrolling();
00453     return ret;
00454   }
00455 
00456 
00457 }