From f11a61a36fa5e21b0c6c2362af2952a3f87408a0 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 14 Nov 2015 18:36:55 +0100 Subject: Refactor ScrollBar, and fix keyboard navigation in listbox. --- plugingui/listboxbasic.cc | 67 ++++++++------ plugingui/listboxbasic.h | 22 +++-- plugingui/scrollbar.cc | 226 +++++++++++++++++++++++++--------------------- plugingui/scrollbar.h | 57 ++++++------ 4 files changed, 199 insertions(+), 173 deletions(-) (limited to 'plugingui') diff --git a/plugingui/listboxbasic.cc b/plugingui/listboxbasic.cc index 0d854ab..4f66046 100644 --- a/plugingui/listboxbasic.cc +++ b/plugingui/listboxbasic.cc @@ -31,12 +31,6 @@ namespace GUI { -void scrolled(void *ptr) -{ - ListBoxBasic *l = (ListBoxBasic *)ptr; - l->repaintEvent(NULL); -} - ListBoxBasic::ListBoxBasic(Widget *parent) : Widget(parent) , scroll(this) @@ -45,7 +39,8 @@ ListBoxBasic::ListBoxBasic(Widget *parent) scroll.move(0,0); scroll.resize(18, 100); - scroll.registerValueChangeHandler(scrolled, this); + CONNECT(&scroll, valueChangeNotifier, + this, &ListBoxBasic::onScrollBarValueChange); padding = 4; btn_size = 18; @@ -61,10 +56,14 @@ ListBoxBasic::~ListBoxBasic() void ListBoxBasic::setSelection(int index) { selected = index; + if(marked == -1) + { + marked = index; + } valueChangedNotifier(); } -void ListBoxBasic::addItem(std::string name, std::string value) +void ListBoxBasic::addItem(const std::string& name, const std::string& value) { std::vector items; ListBoxBasic::Item item; @@ -74,7 +73,7 @@ void ListBoxBasic::addItem(std::string name, std::string value) addItems(items); } -void ListBoxBasic::addItems(std::vector &newItems) +void ListBoxBasic::addItems(const std::vector& newItems) { for(auto& item : newItems) { @@ -83,11 +82,10 @@ void ListBoxBasic::addItems(std::vector &newItems) if(selected == -1) { - setSelection((int)items.size() - 1); + //setSelection((int)items.size() - 1); + setSelection(0); } - setSelection(0); - int numitems = height() / (font.textHeight() + padding); scroll.setRange(numitems); scroll.setMaximum(items.size()); @@ -98,6 +96,7 @@ void ListBoxBasic::clear() { items.clear(); setSelection(-1); + marked = -1; scroll.setValue(0); repaintEvent(nullptr); } @@ -140,7 +139,12 @@ void ListBoxBasic::clearSelectedValue() setSelection(-1); } -void ListBoxBasic::repaintEvent(RepaintEvent *e) +void ListBoxBasic::onScrollBarValueChange(int value) +{ + repaintEvent(NULL); +} + +void ListBoxBasic::repaintEvent(RepaintEvent* repaintEvent) { Painter p(*this); @@ -189,19 +193,20 @@ void ListBoxBasic::repaintEvent(RepaintEvent *e) } } -void ListBoxBasic::scrollEvent(ScrollEvent *e) +void ListBoxBasic::scrollEvent(ScrollEvent* scrollEvent) { - scroll.scrollEvent(e); + // forward scroll event to scroll bar. + scroll.scrollEvent(scrollEvent); } -void ListBoxBasic::keyEvent(KeyEvent *e) +void ListBoxBasic::keyEvent(KeyEvent* keyEvent) { - if(e->direction != KeyEvent::Up) + if(keyEvent->direction != KeyEvent::Down) { return; } - switch(e->keycode) { + switch(keyEvent->keycode) { case KeyEvent::KeyUp: if(marked == 0) { @@ -257,7 +262,7 @@ void ListBoxBasic::keyEvent(KeyEvent *e) break; case KeyEvent::KeyCharacter: - if(e->text == " ") + if(keyEvent->text == " ") { setSelection(marked); //selectionNotifier(); @@ -276,13 +281,14 @@ void ListBoxBasic::keyEvent(KeyEvent *e) repaintEvent(nullptr); } -void ListBoxBasic::buttonEvent(ButtonEvent *e) +void ListBoxBasic::buttonEvent(ButtonEvent* buttonEvent) { - if((e->x > ((int)width() - btn_size)) && (e->y < ((int)width() - 1))) + if((buttonEvent->x > ((int)width() - btn_size)) && + (buttonEvent->y < ((int)width() - 1))) { - if(e->y > 0 && e->y < btn_size) + if(buttonEvent->y > 0 && buttonEvent->y < btn_size) { - if(e->direction == ButtonEvent::Up) + if(buttonEvent->direction == ButtonEvent::Up) { return; } @@ -290,9 +296,10 @@ void ListBoxBasic::buttonEvent(ButtonEvent *e) return; } - if(e->y > ((int)height() - btn_size) && e->y < ((int)height() - 1)) + if(buttonEvent->y > ((int)height() - btn_size) && + buttonEvent->y < ((int)height() - 1)) { - if(e->direction == ButtonEvent::Up) + if(buttonEvent->direction == ButtonEvent::Up) { return; } @@ -301,14 +308,14 @@ void ListBoxBasic::buttonEvent(ButtonEvent *e) } } - if(e->direction == ButtonEvent::Up) + if(buttonEvent->direction == ButtonEvent::Up) { int skip = scroll.value(); size_t yoffset = padding / 2; for(int idx = skip; idx < (int)items.size(); idx++) { yoffset += font.textHeight() + padding; - if(e->y < (int)yoffset - (padding / 2)) + if(buttonEvent->y < (int)yoffset - (padding / 2)) { setSelection(idx); marked = selected; @@ -320,14 +327,14 @@ void ListBoxBasic::buttonEvent(ButtonEvent *e) repaintEvent(nullptr); } - if(e->direction != ButtonEvent::Up) + if(buttonEvent->direction != ButtonEvent::Up) { int skip = scroll.value(); size_t yoffset = padding / 2; for(int idx = skip; idx < (int)items.size(); idx++) { yoffset += font.textHeight() + padding; - if(e->y < ((int)yoffset - (padding / 2))) + if(buttonEvent->y < ((int)yoffset - (padding / 2))) { marked = idx; break; @@ -337,7 +344,7 @@ void ListBoxBasic::buttonEvent(ButtonEvent *e) repaintEvent(nullptr); } - if(e->doubleclick) + if(buttonEvent->doubleclick) { selectionNotifier(); } diff --git a/plugingui/listboxbasic.h b/plugingui/listboxbasic.h index ef6aceb..1ada745 100644 --- a/plugingui/listboxbasic.h +++ b/plugingui/listboxbasic.h @@ -48,8 +48,8 @@ public: ListBoxBasic(Widget *parent); ~ListBoxBasic(); - void addItem(std::string name, std::string value); - void addItems(std::vector &items); + void addItem(const std::string& name, const std::string& value); + void addItems(const std::vector& items); void clear(); bool selectItem(int index); @@ -58,19 +58,23 @@ public: void clearSelectedValue(); + Notifier<> selectionNotifier; + Notifier<> clickNotifier; + Notifier<> valueChangedNotifier; + + // From Widget: + virtual void resize(int w, int h) override; + +protected: + void onScrollBarValueChange(int value); + // From Widget: bool isFocusable() override { return true; } virtual void repaintEvent(RepaintEvent *e) override; virtual void buttonEvent(ButtonEvent *e) override; - virtual void scrollEvent(ScrollEvent *e) override; virtual void keyEvent(KeyEvent *e) override; - virtual void resize(int w, int h) override; - - Notifier<> selectionNotifier; - Notifier<> clickNotifier; - Notifier<> valueChangedNotifier; + virtual void scrollEvent(ScrollEvent *e) override; -private: ScrollBar scroll; Image bg_img; diff --git a/plugingui/scrollbar.cc b/plugingui/scrollbar.cc index c175720..7e6d47a 100644 --- a/plugingui/scrollbar.cc +++ b/plugingui/scrollbar.cc @@ -30,162 +30,180 @@ #include "painter.h" -GUI::ScrollBar::ScrollBar(GUI::Widget *parent) - : GUI::Widget(parent), bg_img(":widget_c.png") +namespace GUI { + +ScrollBar::ScrollBar(Widget *parent) + : Widget(parent) + , bg_img(":widget_c.png") { - handler = NULL; - ptr = NULL; } -void GUI::ScrollBar::setRange(int r) +void ScrollBar::setRange(int r) { - DEBUG(scroll, "%d\n", r); - ran = r; - setValue(value()); - repaintEvent(NULL); + rangeValue = r; + setValue(value()); + repaintEvent(nullptr); } -int GUI::ScrollBar::range() +int ScrollBar::range() { - return ran; + return rangeValue; } -void GUI::ScrollBar::setMaximum(int m) +void ScrollBar::setMaximum(int m) { - DEBUG(scroll, "%d\n", m); - max = m; - if(max < ran) ran = max; - setValue(value()); - repaintEvent(NULL); + maxValue = m; + if(maxValue < rangeValue) + { + rangeValue = maxValue; + } + setValue(value()); + repaintEvent(nullptr); } -int GUI::ScrollBar::maximum() +int ScrollBar::maximum() { - return max; + return maxValue; } -void GUI::ScrollBar::setValue(int value) +void ScrollBar::addValue(int delta) { - if(value > max - ran) value = max - ran; - if(value < 0) value = 0; + setValue(value() + delta); +} - if(val == value) - { - return; - } +void ScrollBar::setValue(int value) +{ + if(value > (maxValue - rangeValue)) + { + value = maxValue - rangeValue; + } - val = value; + if(value < 0) + { + value = 0; + } - if(handler) handler(ptr); + if(currentValue == value) + { + return; + } - repaintEvent(NULL); -} + currentValue = value; -int GUI::ScrollBar::value() -{ - return val; + valueChangeNotifier(value); + + repaintEvent(nullptr); } -void GUI::ScrollBar::registerValueChangeHandler(void (*handler)(void *), - void *ptr) +int ScrollBar::value() { - this->handler = handler; - this->ptr = ptr; + return currentValue; } -static void drawArrow(GUI::Painter &p, int x, int y, int w, int h) +//! Draw an up/down arrow at (x,y) with the bounding box size (w,h) +//! If h is negative the arrow will point down, if positive it will point up. +static void drawArrow(Painter &p, int x, int y, int w, int h) { - if(h < 0) y -= h; + if(h < 0) + { + y -= h; + } - p.drawLine(x, y, x+(w/2), y+h); - p.drawLine(x+(w/2), y+h, x+w, y); + p.drawLine(x, y, x + (w / 2), y + h); + p.drawLine(x + (w / 2), y + h, x + w, y); - y++; - p.drawLine(x, y, x+(w/2), y+h); - p.drawLine(x+(w/2), y+h, x+w, y); + ++y; + p.drawLine(x, y, x + (w / 2), y + h); + p.drawLine(x + (w / 2), y + h, x + w, y); } -void GUI::ScrollBar::repaintEvent(RepaintEvent *e) +void ScrollBar::repaintEvent(RepaintEvent* repaintEvent) { - GUI::Painter p(*this); + Painter p(*this); - p.clear(); + p.clear(); - p.drawImageStretched(0, 0, bg_img, width(), height()); + p.drawImageStretched(0, 0, bg_img, width(), height()); - p.setColour(GUI::Colour(183.0/255.0, 219.0/255.0 , 255.0/255.0, 1)); - if(!max) return; + p.setColour(Colour(183.0/255.0, 219.0/255.0 , 255.0/255.0, 1)); + if(!maxValue) + { + return; + } - { - int h = height() - 2 * width() - 3; - int offset = width() + 2; + { + int h = height() - 2 * width() - 3; + int offset = width() + 2; - int y_val1 = (val * h) / max; - int y_val2 = ((val + ran) * h) / max; + int y_val1 = (currentValue * h) / maxValue; + int y_val2 = ((currentValue + rangeValue) * h) / maxValue; - p.drawFilledRectangle(2, y_val1 + offset, width() - 1, y_val2 + offset); - } + p.drawFilledRectangle(2, y_val1 + offset, width() - 1, y_val2 + offset); + } - p.drawLine(0, 0, 0, height()); + p.drawLine(0, 0, 0, height()); - drawArrow(p, width()/4, width()/4, width()/2, -1 * (width()/3)); - p.drawLine(0, width(), width(), width()); + drawArrow(p, width()/4, width()/4, width()/2, -1 * (width()/3)); + p.drawLine(0, width(), width(), width()); - drawArrow(p, width()/4, height() - width() + width()/4, width()/2, width()/3); - p.drawLine(0, height() - width(), width(), height() - width()); + drawArrow(p, width()/4, height() - width() + width()/4, width()/2, width()/3); + p.drawLine(0, height() - width(), width(), height() - width()); } -void GUI::ScrollBar::scrollEvent(ScrollEvent *e) +void ScrollBar::scrollEvent(ScrollEvent* scrollEvent) { - setValue(value() + e->delta); + setValue(value() + scrollEvent->delta); } -void GUI::ScrollBar::mouseMoveEvent(MouseMoveEvent *e) +void ScrollBar::mouseMoveEvent(MouseMoveEvent* mouseMoveEvent) { - if(!dragging) return; + if(!dragging) + { + return; + } - float delta = yoffset - e->y; + float delta = yOffset - mouseMoveEvent->y; - int h = height() - 2 * width() - 3; - delta /= (float)h / (float)max; + int h = height() - 2 * width() - 3; + delta /= (float)h / (float)maxValue; - int newval = value_offset - delta; - if(newval != value()) setValue(newval); + int newval = valueOffset - delta; + if(newval != value()) + { + setValue(newval); + } } -void GUI::ScrollBar::buttonEvent(ButtonEvent *e) +void ScrollBar::buttonEvent(ButtonEvent* buttonEvent) { - if(e->y < (int)width() && e->y > 0) { - if(e->direction == ButtonEvent::Up) setValue(value() - 1); - return; - } - - if(e->y > (int)height() - (int)width() && e->y < (int)height()) { - if(e->direction == ButtonEvent::Up) setValue(value() + 1); - return; - } - - if(e->direction == ButtonEvent::Down) { - yoffset = e->y; - value_offset = value(); - } - - dragging = (e->direction == ButtonEvent::Down); + if((buttonEvent->y < (int)width()) && buttonEvent->y > 0) + { + if(buttonEvent->direction == ButtonEvent::Down) + { + addValue(-1); + } + + return; + } + + if((buttonEvent->y > ((int)height() - (int)width())) && + (buttonEvent->y < (int)height())) + { + if(buttonEvent->direction == ButtonEvent::Down) + { + addValue(1); + } + + return; + } + + if(buttonEvent->direction == ButtonEvent::Down) + { + yOffset = buttonEvent->y; + valueOffset = value(); + } + + dragging = (buttonEvent->direction == ButtonEvent::Down); } -#ifdef TEST_SCROLLBAR -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). - -TEST_END; - -#endif/*TEST_SCROLLBAR*/ +} // GUI:: diff --git a/plugingui/scrollbar.h b/plugingui/scrollbar.h index 52acf9d..42e504e 100644 --- a/plugingui/scrollbar.h +++ b/plugingui/scrollbar.h @@ -24,52 +24,49 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_SCROLLBAR_H__ -#define __DRUMGIZMO_SCROLLBAR_H__ +#pragma once #include "widget.h" #include "image.h" +#include "notifier.h" namespace GUI { class ScrollBar : public Widget { + friend class ListBoxBasic; public: - ScrollBar(Widget *parent); + ScrollBar(Widget *parent); - bool catchMouse() { return true; } + void setRange(int range); + int range(); - void setRange(int range); - int range(); + void setMaximum(int max); + int maximum(); - void setMaximum(int max); - int maximum(); + void addValue(int delta); + void setValue(int value); + int value(); - void setValue(int value); - int value(); + Notifier valueChangeNotifier; // (int value) - void registerValueChangeHandler(void (*handler)(void *), void *ptr); - - void repaintEvent(RepaintEvent *e); - void scrollEvent(ScrollEvent *e); - void buttonEvent(ButtonEvent *e); - void mouseMoveEvent(MouseMoveEvent *e); +protected: + // From Widget: + bool catchMouse() override { return true; } + void scrollEvent(ScrollEvent* scrollEvent) override; + void repaintEvent(RepaintEvent* repaintEvent) override; + void buttonEvent(ButtonEvent* buttonEvent) override; + void mouseMoveEvent(MouseMoveEvent* mouseMoveEvent) override; private: - int max; - int val; - int ran; - - int yoffset; - int value_offset; - bool dragging; + int maxValue; + int currentValue; + int rangeValue; - Image bg_img; + int yOffset; + int valueOffset; + bool dragging; - void (*handler)(void *); - void *ptr; + Image bg_img; }; -}; - - -#endif/*__DRUMGIZMO_SCROLLBAR_H__*/ +} // GUI:: -- cgit v1.2.3