From eeb23d5a924a8487b57ab5cbd6e325c03074ce4d Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 12 Jul 2002 23:00:35 +0000 Subject: implemented scrollbar 'dragging' (based largely on painelf's patch) svn-id: r4527 --- gui/ScrollBarWidget.cpp | 124 ++++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 47 deletions(-) (limited to 'gui/ScrollBarWidget.cpp') diff --git a/gui/ScrollBarWidget.cpp b/gui/ScrollBarWidget.cpp index 633a01f270..028e831cad 100644 --- a/gui/ScrollBarWidget.cpp +++ b/gui/ScrollBarWidget.cpp @@ -32,6 +32,7 @@ * - Allow for a horizontal scrollbar, too? */ +#define UP_DOWN_BOX_HEIGHT 10 // Up arrow static uint32 up_arrow[8] = { @@ -58,22 +59,24 @@ static uint32 down_arrow[8] = { }; ScrollBarWidget::ScrollBarWidget(Dialog *boss, int x, int y, int w, int h) - : Widget(boss, x, y, w, h), CommandSender(boss) + : Widget (boss, x, y, w, h), CommandSender(boss) { _flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG; _type = kScrollBarWidget; - + _part = kNoPart; - + _isDraggingSlider = false; + } void ScrollBarWidget::handleClick(int x, int y, int button) { int old_pos = _currentPos; - if (y <= 10) { + + if (y <= UP_DOWN_BOX_HEIGHT) { // Up arrow _currentPos--; - } else if (y >= _h-10) { + } else if (y >= _h - UP_DOWN_BOX_HEIGHT) { // Down arrow _currentPos++; } else if (y < _sliderPos) { @@ -81,16 +84,13 @@ void ScrollBarWidget::handleClick(int x, int y, int button) } else if (y >= _sliderPos + _sliderHeight) { _currentPos += _entriesPerPage; } else { - printf("Slider\n"); + _isDraggingSlider = true; + _sliderDeltaMouseDownPos = y - _sliderPos; } - - // Bound checking - if (_currentPos > _numEntries - _entriesPerPage) - _currentPos = _numEntries - _entriesPerPage; - else if (_currentPos < 0) - _currentPos = 0; - - // Redraw & notify, but only if the position really changed + + // Make sure that _currentPos is still inside the bounds + checkbounds(); + if (old_pos != _currentPos) { recalc(); draw(); @@ -100,58 +100,88 @@ void ScrollBarWidget::handleClick(int x, int y, int button) void ScrollBarWidget::handleMouseMoved(int x, int y, int button) { - int old_part = _part; - if (y <= 10) // Up arrow - _part = kUpArrowPart; - else if (y >= _h-10) // Down arrow - _part = kDownArrowPart; - else if (y < _sliderPos) - _part = kPageUpPart; - else if (y >= _sliderPos + _sliderHeight) - _part = kPageDownPart; - else - _part = kSliderPart; - - if (old_part != _part) - draw(); + if (button == 0) + _isDraggingSlider = false; + + if (_isDraggingSlider) { + int old_pos = _currentPos; + _sliderPos = y - _sliderDeltaMouseDownPos; + + if (_sliderPos < UP_DOWN_BOX_HEIGHT) + _sliderPos = UP_DOWN_BOX_HEIGHT; + + if (_sliderPos > _h - UP_DOWN_BOX_HEIGHT - _sliderHeight + 1) + _sliderPos = _h - UP_DOWN_BOX_HEIGHT - _sliderHeight + 1; + + _currentPos = + (_sliderPos - UP_DOWN_BOX_HEIGHT) * (_numEntries - _entriesPerPage) / (_h - _sliderHeight - + 2 * UP_DOWN_BOX_HEIGHT); + checkbounds(); + + if (_currentPos != old_pos) { + draw(); + sendCommand(kSetPositionCmd, _currentPos); + } + } else { + int old_part = _part; + + if (y <= UP_DOWN_BOX_HEIGHT) // Up arrow + _part = kUpArrowPart; + else if (y >= _h - UP_DOWN_BOX_HEIGHT) // Down arrow + _part = kDownArrowPart; + else if (y < _sliderPos) + _part = kPageUpPart; + else if (y >= _sliderPos + _sliderHeight) + _part = kPageDownPart; + else + _part = kSliderPart; + + if (old_part != _part) + draw(); + } +} + +void ScrollBarWidget::checkbounds() +{ + if (_currentPos > _numEntries - _entriesPerPage) + _currentPos = _numEntries - _entriesPerPage; + else if (_currentPos < 0) + _currentPos = 0; } void ScrollBarWidget::recalc() { - _sliderHeight = (_h-20) * _entriesPerPage / _numEntries; + _sliderHeight = (_h - 2 * UP_DOWN_BOX_HEIGHT) * _entriesPerPage / _numEntries; if (_sliderHeight < 4) _sliderHeight = 4; - - _sliderPos = 10 + (_h-20-_sliderHeight+1) *_currentPos / (_numEntries - _entriesPerPage); + + _sliderPos = + UP_DOWN_BOX_HEIGHT + (_h - 2 * UP_DOWN_BOX_HEIGHT - _sliderHeight + 1) * _currentPos / (_numEntries - + _entriesPerPage); if (_sliderPos < 0) _sliderPos = 0; - } void ScrollBarWidget::drawWidget(bool hilite) { NewGui *gui = _boss->getGui(); - int bottomY = _y + _h; - + int bottomY = _y + _h; + gui->frameRect(_x, _y, _w, _h, gui->_shadowcolor); - + // Up arrow - gui->frameRect(_x, _y, _w, 10, gui->_color); + gui->frameRect(_x, _y, _w, UP_DOWN_BOX_HEIGHT, gui->_color); gui->drawBitmap(up_arrow, _x, _y, - (hilite && _part == kUpArrowPart) ? gui->_textcolorhi : gui->_textcolor); - + (hilite && _part == kUpArrowPart) ? gui->_textcolorhi : gui->_textcolor); + // Down arrow - gui->frameRect(_x, bottomY - 9, _w, 10, gui->_color); - gui->drawBitmap(down_arrow, _x, bottomY - 9, - (hilite && _part == kDownArrowPart) ? gui->_textcolorhi : gui->_textcolor); - + gui->frameRect(_x, bottomY - UP_DOWN_BOX_HEIGHT + 1, _w, UP_DOWN_BOX_HEIGHT, gui->_color); + gui->drawBitmap(down_arrow, _x, bottomY - UP_DOWN_BOX_HEIGHT + 1, + (hilite && _part == kDownArrowPart) ? gui->_textcolorhi : gui->_textcolor); + // Slider - // FIXME - determine slider position and size. This depends on: - // * the number of entries per page - // * total number of entries - // * current scroll position (i.e. index of "first" visible entry) gui->checkerRect(_x, _y + _sliderPos, _w, _sliderHeight, - (hilite && _part == kSliderPart) ? gui->_textcolorhi : gui->_textcolor); + (hilite && _part == kSliderPart) ? gui->_textcolorhi : gui->_textcolor); gui->frameRect(_x, _y + _sliderPos, _w, _sliderHeight, gui->_color); } -- cgit v1.2.3