summaryrefslogtreecommitdiff
path: root/plugingui/listboxbasic.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-04-04 21:19:58 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2013-04-04 21:19:58 +0200
commit77b3943b751bed43d230de6db322a750bfd1fc8e (patch)
treecd7d98bc8c06c660558a52f2b6b6ed73982efdf2 /plugingui/listboxbasic.cc
parent0e436ebcd7faacb557ab94952765cb6bcfd7d259 (diff)
New message system. New common midi input class. Some compiler warning fixes. New ListBoxBasic class used by both LustBox and ComboBox. New embossed font.
Diffstat (limited to 'plugingui/listboxbasic.cc')
-rw-r--r--plugingui/listboxbasic.cc311
1 files changed, 311 insertions, 0 deletions
diff --git a/plugingui/listboxbasic.cc b/plugingui/listboxbasic.cc
new file mode 100644
index 0000000..25b3daf
--- /dev/null
+++ b/plugingui/listboxbasic.cc
@@ -0,0 +1,311 @@
+/* -*- 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>
+
+GUI::ListBoxBasic::ListBoxBasic(GUI::Widget *parent)
+ : GUI::Widget(parent)
+{
+ padding = 4;
+ btn_size = 14;
+
+ scroll_offset = 0;
+ selected = -1;
+ marked = -1;
+
+ clk_handler = NULL;
+ clk_ptr = NULL;
+
+ sel_handler = NULL;
+ sel_ptr = NULL;
+
+ valch_handler = NULL;
+ valch_ptr = NULL;
+
+ bg_img = new GUI::Image(":widget_c.png");
+}
+
+GUI::ListBoxBasic::~ListBoxBasic()
+{
+ delete bg_img;
+}
+
+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)
+{
+ struct item i;
+ i.name = name;
+ i.value = value;
+
+ items.push_back(i);
+
+ // sort
+ for(int x = 0; x < (int)items.size() - 1; x++) {
+ for(int y = 0; y < (int)items.size() - 1; y++) {
+ if(items[x].name < items[y].name) {
+
+ if(x == selected) setSelection(y);
+ else if(selected == y) setSelection(x);
+
+ struct item tmp = items[x];
+ items[x] = items[y];
+ items[y] = tmp;
+ }
+ }
+ }
+
+ if(selected == -1) setSelection((int)items.size() - 1);
+}
+
+void GUI::ListBoxBasic::clear()
+{
+ items.clear();
+ setSelection(-1);
+ scroll_offset = 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::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)
+{
+ 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);
+
+ int yoffset = padding / 2;
+ int skip = scroll_offset;
+ for(int idx = skip; idx < (int)items.size(); idx++) {
+ struct item *i = &items[idx];
+ if(idx == selected) {
+ p.setColour(Colour(0.6, 0.9));
+ p.drawFilledRectangle(1,
+ yoffset - (padding / 2),
+ width() - 1,
+ yoffset + (font.textHeight() + 1));
+ }
+
+ if(idx == marked) {
+ p.setColour(Colour(1, 0.9));
+ p.drawRectangle(1,
+ yoffset - (padding / 2),
+ width() - 1,
+ yoffset + (font.textHeight() + 1));
+ }
+
+ p.setColour(Colour(1, 1));
+ p.drawText(2, yoffset + font.textHeight(), font, i->name);
+ yoffset += font.textHeight() + padding;
+ }
+
+ p.drawRectangle(width() - btn_size, 0, width() - 1, btn_size);
+ p.drawRectangle(width() - btn_size, height() - btn_size,
+ width() - 1, height() - 1);
+}
+
+void GUI::ListBoxBasic::scrollEvent(ScrollEvent *e)
+{
+ scroll_offset += e->delta;
+ if(scroll_offset < 0) scroll_offset = 0;
+ if(scroll_offset > ((int)items.size() - 1))
+ scroll_offset = ((int)items.size() - 1);
+ repaintEvent(NULL);
+}
+
+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_offset) {
+ scroll_offset = marked;
+ if(scroll_offset < 0) scroll_offset = 0;
+ }
+ }
+ 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_offset + numitems - 1)) {
+ scroll_offset = marked - numitems + 1;
+ if(scroll_offset > ((int)items.size() - 1))
+ scroll_offset = ((int)items.size() - 1);
+ }
+ }
+ break;
+ case GUI::KeyEvent::KEY_HOME:
+ marked = 0;
+ if(marked < scroll_offset) {
+ scroll_offset = marked;
+ if(scroll_offset < 0) scroll_offset = 0;
+ }
+ 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_offset + numitems - 1)) {
+ scroll_offset = marked - numitems + 1;
+ if(scroll_offset > ((int)items.size() - 1))
+ scroll_offset = ((int)items.size() - 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_offset--;
+ if(scroll_offset < 0) scroll_offset = 0;
+ repaintEvent(NULL);
+ return;
+ }
+
+ if(e->y > ((int)height() - btn_size) && e->y < ((int)height() - 1)) {
+ if(e->direction == -1) return;
+ scroll_offset++;
+ if(scroll_offset > ((int)items.size() - 1))
+ scroll_offset = ((int)items.size() - 1);
+ repaintEvent(NULL);
+ return;
+ }
+ }
+
+ if(e->direction == -1) {
+ int skip = scroll_offset;
+ 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_offset;
+ 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);
+}