summaryrefslogtreecommitdiff
path: root/plugingui/listboxbasic.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugingui/listboxbasic.cc')
-rw-r--r--plugingui/listboxbasic.cc334
1 files changed, 334 insertions, 0 deletions
diff --git a/plugingui/listboxbasic.cc b/plugingui/listboxbasic.cc
new file mode 100644
index 0000000..df7877d
--- /dev/null
+++ b/plugingui/listboxbasic.cc
@@ -0,0 +1,334 @@
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * listboxbasic.cc
+ *
+ * Thu Apr 4 20:28:10 CEST 2013
+ * Copyright 2013 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "listboxbasic.h"
+
+#include "painter.h"
+#include "font.h"
+
+#include <stdio.h>
+#include <hugin.hpp>
+
+void scrolled(void *ptr)
+{
+ GUI::ListBoxBasic *l = (GUI::ListBoxBasic *)ptr;
+ l->repaintEvent(NULL);
+}
+
+GUI::ListBoxBasic::ListBoxBasic(GUI::Widget *parent)
+ : GUI::Widget(parent), scroll(this), bg_img(":widget_c.png")
+{
+ scroll.move(0,0);
+ scroll.resize(18, 100);
+
+ scroll.registerValueChangeHandler(scrolled, this);
+
+ padding = 4;
+ btn_size = 18;
+
+ selected = -1;
+ marked = -1;
+
+ clk_handler = NULL;
+ clk_ptr = NULL;
+
+ sel_handler = NULL;
+ sel_ptr = NULL;
+
+ valch_handler = NULL;
+ valch_ptr = NULL;
+}
+
+GUI::ListBoxBasic::~ListBoxBasic()
+{
+}
+
+void GUI::ListBoxBasic::setSelection(int index)
+{
+ selected = index;
+ if(valch_handler) valch_handler(valch_ptr);
+}
+
+void GUI::ListBoxBasic::addItem(std::string name, std::string value)
+{
+ std::vector<GUI::ListBoxBasic::Item> items;
+ GUI::ListBoxBasic::Item item;
+ item.name = name;
+ item.value = value;
+ items.push_back(item);
+ addItems(items);
+}
+
+void GUI::ListBoxBasic::addItems(std::vector<GUI::ListBoxBasic::Item> &is)
+{
+ // DEBUG(list, "addItems %lu\n", is.size());
+ std::vector<GUI::ListBoxBasic::Item>::iterator i = is.begin();
+ while(i != is.end()) {
+ items.push_back(*i);
+ i++;
+ }
+
+/*
+ // sort
+ for(int x = 0; x < (int)items.size(); x++) {
+ for(int y = 0; y < (int)items.size(); y++) {
+ if(items[x].name < items[y].name) {
+ if(x == selected) setSelection(y);
+ else if(selected == y) setSelection(x);
+
+ GUI::ListBoxBasic::Item tmp = items[x];
+ items[x] = items[y];
+ items[y] = tmp;
+ }
+ }
+ }
+*/
+
+ if(selected == -1) setSelection((int)items.size() - 1);
+ setSelection(0);
+
+ int numitems = height() / (font.textHeight() + padding);
+ scroll.setRange(numitems);
+ scroll.setMaximum(items.size());
+}
+
+void GUI::ListBoxBasic::clear()
+{
+ items.clear();
+ setSelection(-1);
+ scroll.setValue(0);
+ repaintEvent(NULL);
+}
+
+bool GUI::ListBoxBasic::selectItem(int index)
+{
+ if(index < 0 || index > (int)items.size() - 1) return false;
+ setSelection(index);
+ repaintEvent(NULL);
+ return true;
+}
+
+std::string GUI::ListBoxBasic::selectedName()
+{
+ if(selected < 0 || selected > (int)items.size() - 1) return "";
+ return items[selected].name;
+}
+
+std::string GUI::ListBoxBasic::selectedValue()
+{
+ if(selected < 0 || selected > (int)items.size() - 1) return "";
+ return items[selected].value;
+}
+
+void GUI::ListBoxBasic::clearSelectedValue()
+{
+ setSelection(-1);
+}
+
+void GUI::ListBoxBasic::registerClickHandler(void (*handler)(void *), void *ptr)
+{
+ this->clk_handler = handler;
+ this->clk_ptr = ptr;
+}
+
+void GUI::ListBoxBasic::registerSelectHandler(void (*handler)(void *), void *ptr)
+{
+ this->sel_handler = handler;
+ this->sel_ptr = ptr;
+}
+
+void GUI::ListBoxBasic::registerValueChangeHandler(void (*handler)(void *),
+ void *ptr)
+{
+ this->valch_handler = handler;
+ this->valch_ptr = ptr;
+}
+
+void GUI::ListBoxBasic::repaintEvent(GUI::RepaintEvent *e)
+{
+ DEBUG(list, "repaint\n");
+ GUI::Painter p(this);
+
+ p.clear();
+
+ int w = width();
+ int h = height();
+ if(w == 0 || h == 0) return;
+
+ p.drawImageStretched(0, 0, &bg_img, w, h);
+
+ p.setColour(GUI::Colour(183.0/255.0, 219.0/255.0 , 255.0/255.0, 1));
+
+ int yoffset = padding / 2;
+ int skip = scroll.value();
+ int numitems = height() / (font.textHeight() + padding) + 1;
+ for(int idx = skip; idx < (int)items.size() && idx < skip + numitems; idx++) {
+ GUI::ListBoxBasic::Item *i = &items[idx];
+ if(idx == selected) {
+ p.setColour(GUI::Colour(183.0/255.0, 219.0/255.0 , 255.0/255.0, 0.5));
+ p.drawFilledRectangle(0,
+ yoffset - (padding / 2),
+ width() - 1,
+ yoffset + (font.textHeight() + 1));
+ }
+
+ if(idx == marked) {
+ p.drawRectangle(0,
+ yoffset - (padding / 2),
+ width() - 1,
+ yoffset + (font.textHeight() + 1));
+ }
+
+ p.setColour(GUI::Colour(183.0/255.0, 219.0/255.0 , 255.0/255.0, 1));
+
+ p.drawText(2, yoffset + font.textHeight(), font, i->name);
+ yoffset += font.textHeight() + padding;
+ }
+}
+
+void GUI::ListBoxBasic::scrollEvent(ScrollEvent *e)
+{
+ scroll.scrollEvent(e);
+}
+
+void GUI::ListBoxBasic::keyEvent(GUI::KeyEvent *e)
+{
+ if(e->direction != -1) return;
+
+ switch(e->keycode) {
+ case GUI::KeyEvent::KEY_UP:
+ {
+ marked--;
+ if(marked < 0) marked = 0;
+
+ if(marked < scroll.value()) {
+ scroll.setValue(marked);
+ }
+ }
+ break;
+ case GUI::KeyEvent::KEY_DOWN:
+ {
+ // Number of items that can be displayed at a time.
+ int numitems = height() / (font.textHeight() + padding);
+
+ marked++;
+ if(marked > ((int)items.size() - 1)) marked = (int)items.size() - 1;
+
+ if(marked > (scroll.value() + numitems - 1)) {
+ scroll.setValue(marked - numitems + 1);
+ }
+ }
+ break;
+ case GUI::KeyEvent::KEY_HOME:
+ marked = 0;
+ if(marked < scroll.value()) {
+ scroll.setValue(marked);
+ }
+ break;
+ case GUI::KeyEvent::KEY_END:
+ {
+ // Number of items that can be displayed at a time.
+ int numitems = height() / (font.textHeight() + padding);
+
+ marked = (int)items.size() - 1;
+ if(marked > (scroll.value() + numitems - 1)) {
+ scroll.setValue(marked - numitems + 1);
+ }
+ }
+ break;
+ case GUI::KeyEvent::KEY_CHARACTER:
+ if(e->text == " ") {
+ setSelection(marked);
+ // if(sel_handler) sel_handler(sel_ptr);
+ }
+ break;
+ case GUI::KeyEvent::KEY_ENTER:
+ setSelection(marked);
+ if(sel_handler) sel_handler(sel_ptr);
+ break;
+ default:
+ break;
+ }
+
+ repaintEvent(NULL);
+}
+
+void GUI::ListBoxBasic::buttonEvent(ButtonEvent *e)
+{
+ if(e->x > ((int)width() - btn_size) && e->y < ((int)width() - 1)) {
+ if(e->y > 0 && e->y < btn_size) {
+ if(e->direction == -1) return;
+ scroll.setValue(scroll.value() - 1);
+ return;
+ }
+
+ if(e->y > ((int)height() - btn_size) && e->y < ((int)height() - 1)) {
+ if(e->direction == -1) return;
+ scroll.setValue(scroll.value() + 1);
+ return;
+ }
+ }
+
+ if(e->direction == -1) {
+ 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)) {
+ setSelection(idx);
+ marked = selected;
+ if(clk_handler) clk_handler(clk_ptr);
+ break;
+ }
+ }
+
+ repaintEvent(NULL);
+ }
+
+ if(e->direction != -1) {
+ 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)) {
+ marked = idx;
+ break;
+ }
+ }
+
+ repaintEvent(NULL);
+ }
+
+ if(e->doubleclick && sel_handler) sel_handler(sel_ptr);
+}
+
+void GUI::ListBoxBasic::resize(int w, int h)
+{
+ GUI::Widget::resize(w,h);
+ scroll.move(w - scroll.width(), 0);
+ scroll.resize(scroll.width(), h);
+}