Back to index

nux  3.0.0
HScrollBar.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 "HScrollBar.h"
00028 
00029 namespace nux
00030 {
00031 
00032   const int HSCROLLBAR_WIDTH = 10;
00033   const int HSCROLLBAR_HEIGHT = 10;
00034 
00035   HScrollBar::HScrollBar(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_LeftTimerHandler  = 0;
00052     m_RightTimerHandler = 0;
00053 
00054     hlayout = new HLayout(NUX_TRACKER_LOCATION);
00055     _scroll_left_button = new InputArea(NUX_TRACKER_LOCATION);
00056     _track = new InputArea(NUX_TRACKER_LOCATION);
00057     _scroll_right_button = new InputArea(NUX_TRACKER_LOCATION);
00058     _slider = new InputArea(NUX_TRACKER_LOCATION);
00059     _slider->SetParentObject(this);
00060 
00061     // Set Original State
00062     SetMinimumSize(AREA_MIN_WIDTH, HSCROLLBAR_HEIGHT);
00063     SetMaximumSize(AREA_MAX_WIDTH, HSCROLLBAR_HEIGHT);
00064 
00065     // Set Signals
00066     _scroll_right_button->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvStartScrollRight));
00067     _scroll_right_button->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvEndScrollRight));
00068     _scroll_left_button->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvStartScrollLeft));
00069     _scroll_left_button->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvEndScrollLeft));
00070 
00071     _slider->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseDown));
00072     _slider->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseUp));
00073     _slider->mouse_drag.connect(sigc::mem_fun(this, &HScrollBar::OnSliderMouseDrag));
00074 
00075     _track->mouse_down.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseDown));
00076     _track->mouse_up.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseUp));
00077     _track->mouse_drag.connect(sigc::mem_fun(this, &HScrollBar::RecvTrackMouseDrag));
00078 
00079     // Set Geometry
00080     _scroll_right_button->SetMinimumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT);
00081     _scroll_right_button->SetMaximumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT);
00082     _scroll_right_button->SetGeometry(Geometry(0, 0, HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT));
00083     _scroll_left_button->SetMinimumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT);
00084     _scroll_left_button->SetMaximumSize(HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT);
00085     _scroll_left_button->SetGeometry(Geometry(0, 0, HSCROLLBAR_WIDTH, HSCROLLBAR_HEIGHT));
00086 
00087 
00088     hlayout->AddView(_scroll_left_button, 0, eCenter, eFix);
00089     hlayout->AddView(_track, 1, eCenter, eFull);
00090     hlayout->AddView(_scroll_right_button, 0, eCenter, eFix);
00091 
00092     callback = new TimerFunctor;
00093     callback->time_expires.connect(sigc::mem_fun(this, &HScrollBar::HScrollBarHandler));
00094     left_callback = new TimerFunctor;
00095     left_callback->time_expires.connect(sigc::mem_fun(this, &HScrollBar::ScrollLeft));
00096     right_callback = new TimerFunctor;
00097     right_callback->time_expires.connect(sigc::mem_fun(this, &HScrollBar::ScrollRight));
00098     trackleft_callback = new TimerFunctor;
00099     trackleft_callback->time_expires.connect(sigc::mem_fun(this, &HScrollBar::TrackLeft));
00100     trackright_callback = new TimerFunctor;
00101     trackright_callback->time_expires.connect(sigc::mem_fun(this, &HScrollBar::TrackRight));
00102 
00103     SetLayout(hlayout);
00104     SetAcceptMouseWheelEvent(true);
00105   }
00106 
00107   HScrollBar::~HScrollBar()
00108   {
00109     _slider->UnReference();
00110     delete callback;
00111     delete left_callback;
00112     delete trackleft_callback;
00113     delete right_callback;
00114     delete trackright_callback;
00115   }
00116 
00117   void HScrollBar::HScrollBarHandler(void *v)
00118   {
00119     HScrollBar *scrollbar = static_cast<HScrollBar *> (v);
00120 
00121     if (scrollbar->b_MouseUpTimer && scrollbar->m_color_factor < 1)
00122     {
00123       scrollbar->m_color_factor += 0.1f;
00124 
00125       if (scrollbar->m_color_factor >= 1)
00126       {
00127         scrollbar->m_color_factor = 1;
00128         scrollbar->b_MouseUpTimer = false;
00129       }
00130       else
00131       {
00132         scrollbar->QueueDraw();
00133         GetTimer().AddTimerHandler(10, callback, scrollbar);
00134       }
00135     }
00136 
00137     if (scrollbar->b_MouseDownTimer && scrollbar->m_color_factor > 0)
00138     {
00139       scrollbar->m_color_factor -= 0.09f;
00140 
00141       if (scrollbar->m_color_factor <= 0)
00142       {
00143         scrollbar->m_color_factor = 0;
00144         scrollbar->b_MouseUpTimer = false;
00145       }
00146       else
00147       {
00148         scrollbar->QueueDraw();
00149         GetTimer().AddTimerHandler(10, callback, scrollbar);
00150       }
00151     }
00152   }
00153 
00154   void HScrollBar::ScrollRight(void *v)
00155   {
00156     OnScrollRight.emit(m_ScrollUnit, 1);
00157 
00158     if (AtMaximum())
00159       RecvEndScrollRight(0, 0, 0, 0);
00160     else
00161       m_RightTimerHandler = GetTimer().AddTimerHandler(10, right_callback, this);
00162 
00163     QueueDraw();
00164   }
00165 
00166   void HScrollBar::ScrollLeft(void *v)
00167   {
00168     OnScrollLeft.emit(m_ScrollUnit, 1);
00169 
00170     if (AtMaximum())
00171       RecvEndScrollLeft(0, 0, 0, 0);
00172     else
00173       m_LeftTimerHandler = GetTimer().AddTimerHandler(10, left_callback, this);
00174 
00175     QueueDraw();
00176   }
00177 
00178   void HScrollBar::TrackLeft(void *v)
00179   {
00180     if (m_TrackMouseCoord.x < _slider->GetBaseX() - _track->GetBaseX())
00181     {
00182       OnScrollLeft.emit(container_width_, 1);
00183       m_TrackLeftTimerHandler  = GetTimer().AddTimerHandler(10, trackleft_callback, this);
00184       QueueDraw();
00185     }
00186   }
00187 
00188   void HScrollBar::TrackRight(void *v)
00189   {
00190     if (m_TrackMouseCoord.x > _slider->GetBaseX() + _slider->GetBaseWidth() - _track->GetBaseX())
00191     {
00192       OnScrollRight.emit(container_width_, 1);
00193       m_TrackRightTimerHandler  = GetTimer().AddTimerHandler(10, trackright_callback, this);
00194       QueueDraw();
00195     }
00196   }
00197 
00198   void HScrollBar::RecvStartScrollLeft(int x, int y, unsigned long button_flags, unsigned long key_flags)
00199   {
00200     if (!AtMinimum())
00201       ScrollLeft(this);
00202   }
00203 
00204   void HScrollBar::RecvStartScrollRight(int x, int y, unsigned long button_flags, unsigned long key_flags)
00205   {
00206     if (!AtMaximum())
00207       ScrollRight(this);
00208   }
00209 
00210   void HScrollBar::RecvEndScrollRight(int x, int y, unsigned long button_flags, unsigned long key_flags)
00211   {
00212     if (m_RightTimerHandler.IsValid())
00213       GetTimer().RemoveTimerHandler(m_RightTimerHandler);
00214 
00215     m_RightTimerHandler = 0;
00216   }
00217 
00218   void HScrollBar::RecvEndScrollLeft(int x, int y, unsigned long button_flags, unsigned long key_flags)
00219   {
00220     if (m_LeftTimerHandler.IsValid())
00221       GetTimer().RemoveTimerHandler(m_LeftTimerHandler);
00222 
00223     m_LeftTimerHandler = 0;
00224   }
00225 
00226   void HScrollBar::RecvTrackMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
00227   {
00228     m_TrackMouseCoord = Point(x, y);
00229 
00230     int X = _slider->GetBaseX() - _track->GetBaseX();
00231 
00232     if (x < X)
00233     {
00234       // move the slide bar up
00235       TrackLeft(this);
00236     }
00237     else
00238     {
00239       TrackRight(this);
00240       // move the slide bar down
00241     }
00242   }
00243 
00244   void HScrollBar::RecvTrackMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
00245   {
00246     if (m_TrackLeftTimerHandler.IsValid())
00247       GetTimer().RemoveTimerHandler(m_TrackLeftTimerHandler);
00248 
00249     if (m_TrackRightTimerHandler.IsValid())
00250       GetTimer().RemoveTimerHandler(m_TrackRightTimerHandler);
00251 
00252     m_TrackLeftTimerHandler = 0;
00253     m_TrackRightTimerHandler = 0;
00254   }
00255 
00256   void HScrollBar::RecvTrackMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00257   {
00258 
00259   }
00260 
00261   Area* HScrollBar::FindAreaUnderMouse(const Point& mouse_position, NuxEventType event_type)
00262   {
00263     bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
00264 
00265     if (mouse_inside == false)
00266       return NULL;
00267 
00268     NUX_RETURN_VALUE_IF_TRUE(_scroll_right_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_right_button);
00269     NUX_RETURN_VALUE_IF_TRUE(_scroll_left_button->TestMousePointerInclusion(mouse_position, event_type), _scroll_left_button);
00270     NUX_RETURN_VALUE_IF_TRUE(_slider->TestMousePointerInclusion(mouse_position, event_type), _slider);
00271     NUX_RETURN_VALUE_IF_TRUE(_track->TestMousePointerInclusion(mouse_position, event_type), _track);
00272 
00273     if ((event_type == NUX_MOUSE_WHEEL) && (!AcceptMouseWheelEvent()))
00274       return NULL;
00275     return this;
00276   }
00277 
00278   void HScrollBar::Draw(GraphicsEngine &graphics_engine, bool force_draw)
00279   {
00280     Geometry base = GetGeometry();
00281     GetPainter().PaintBackground(graphics_engine, base);
00282     base.OffsetPosition(HSCROLLBAR_WIDTH, 0);
00283     base.OffsetSize(-2 * HSCROLLBAR_WIDTH, 0);
00284     GetPainter().PaintShape(graphics_engine, base,
00285                          Color(COLOR_SCROLLBAR_TRACK), eHSCROLLBAR, false);
00286 
00287     GetPainter().PaintShape(graphics_engine, _scroll_left_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_LEFT);
00288     GetPainter().PaintShape(graphics_engine, _scroll_right_button->GetGeometry(), Color(0xFFFFFFFF), eSCROLLBAR_TRIANGLE_RIGHT);
00289 
00290     GetPainter().PaintShape(graphics_engine, _slider->GetGeometry(),
00291                          Color(0.2156 * m_color_factor, 0.2156 * m_color_factor, 0.2156 * m_color_factor, 1.0f),
00292                          eHSCROLLBAR, true);
00293   };
00294 
00295   void HScrollBar::SetContainerSize(int x, int y, int w, int h)
00296   {
00297     // x and y are not needed
00298     container_width_ = w;
00299     container_height_ = h;
00300     ComputeScrolling();
00301   }
00302 
00303   void HScrollBar::SetContentSize(int x, int y, int w, int h)
00304   {
00305     // x and y are not needed
00306     content_width_ = w;
00307     content_height_ = h;
00308     ComputeScrolling();
00309   }
00310 
00311   void HScrollBar::SetContentOffset(float dx, float dy)
00312   {
00313     content_offset_x_ = dx;
00314     content_offset_y_ = dy;
00315     ComputeScrolling();
00316   }
00317 
00318   void HScrollBar::ComputeScrolling()
00319   {
00320     if (content_width_ == 0)
00321     {
00322       visibility_percentage_ = 100.0f;
00323     }
00324     else
00325     {
00326       visibility_percentage_ = Clamp<float>(100.0f * (float) container_width_ / (float) content_width_, 0.0f, 100.0f);
00327     }
00328 
00329     m_TrackWidth = _track->GetBaseWidth();
00330 
00331     int slider_height = _scroll_left_button->GetBaseHeight();
00332     int slider_width = m_TrackWidth * visibility_percentage_ / 100.0f;
00333 
00334     if (slider_width < 15)
00335     {
00336       slider_width = 15;
00337     }
00338 
00339     _slider->SetBaseWidth(slider_width);
00340     _slider->SetBaseHeight(slider_height);
00341     _slider->SetBaseY(_scroll_left_button->GetBaseY());
00342 
00343 
00344     float pct;
00345 
00346     if (content_width_ - container_width_ > 0)
00347       pct = - (float) content_offset_x_ / (float) (content_width_ - container_width_);
00348     else
00349       pct = 0;
00350 
00351     int x = _track->GetBaseX() + pct * (m_TrackWidth - slider_width);
00352     _slider->SetBaseX(x);
00353   }
00354 
00355 
00357 //  RECEIVERS  //
00359   void HScrollBar::SetValue(float value)
00360   {
00361     //m_ValueString.setCaption(value);
00362   }
00363 
00364   void HScrollBar::SetParameterName(const char *parameter_name)
00365   {
00366     //m_ParameterName.setCaption(parameter_name);
00367   }
00368 
00370 //  EMITTERS  //
00372 
00373   void HScrollBar::OnSliderMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
00374   {
00375     m_SliderDragPositionX = x;
00376     m_SliderDragPositionY = y;
00377     //sigVScrollBarSliderMouseDown.emit();
00378     b_MouseDownTimer = true;
00379     b_MouseUpTimer = false;
00380     GetTimer().AddTimerHandler(10, callback, this);
00381   }
00382 
00383   void HScrollBar::OnSliderMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
00384   {
00385     b_MouseDownTimer = false;
00386     b_MouseUpTimer = true;
00387     GetTimer().AddTimerHandler(10, callback, this);
00388   }
00389 
00390   void HScrollBar::OnSliderMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
00391   {
00392     if (_track->GetBaseWidth() - _slider->GetBaseWidth() > 0)
00393     {
00394       stepX = (float) (content_width_ - container_width_) / (float) (_track->GetBaseWidth() - _slider->GetBaseWidth());
00395     }
00396     else
00397     {
00398       return;
00399     }
00400 
00401     if ((dx > 0) && (x > m_SliderDragPositionX))
00402     {
00403       OnScrollRight.emit(stepX, x - m_SliderDragPositionX);
00404     }
00405 
00406     if ((dx < 0) && (x < m_SliderDragPositionX))
00407     {
00408       OnScrollLeft.emit(stepX, m_SliderDragPositionX - x);
00409     }
00410   }
00411 
00412   bool HScrollBar::AtMaximum()
00413   {
00414     if (_slider->GetBaseX() + _slider->GetBaseWidth() == _track->GetBaseX() + _track->GetBaseWidth())
00415       return TRUE;
00416 
00417     return FALSE;
00418   }
00419 
00420   bool HScrollBar::AtMinimum()
00421   {
00422     if (_slider->GetBaseX() == _track->GetBaseX())
00423       return TRUE;
00424 
00425     return FALSE;
00426   }
00427 
00428   long HScrollBar::PostLayoutManagement(long LayoutResult)
00429   {
00430     long ret = ScrollBar::PostLayoutManagement(LayoutResult);
00431     ComputeScrolling();
00432     return ret;
00433   }
00434 
00435 }