From d55de707c3352a468a227d69920a56ef2550a7cc Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Wed, 13 Mar 2013 18:46:17 +0100
Subject: Added path lineedit and drive selection (win32) to filebrowser. Made
 a lot of small layout tweaks.

---
 plugingui/Makefile.am           |   7 +-
 plugingui/Makefile.am.plugingui |   3 +-
 plugingui/Makefile.mingw32      |   1 +
 plugingui/combobox.cc           | 153 ++++++++++++++++++++++++++++++++++++++++
 plugingui/combobox.h            |  41 +++++++++++
 plugingui/eventhandler.cc       |  14 ++--
 plugingui/filebrowser.h         |   6 ++
 plugingui/filelineedit.cc       |   1 +
 plugingui/guievent.h            |   3 +
 plugingui/knob.cc               |  18 +++--
 plugingui/lineedit.cc           |  21 +++++-
 plugingui/lineedit.h            |   5 ++
 plugingui/listbox.cc            | 111 ++++++++++++++++++++++-------
 plugingui/listbox.h             |  17 ++++-
 plugingui/plugingui.cc          |  13 +---
 version.h                       |   2 +-
 vst/Makefile.mingw32            |   6 +-
 17 files changed, 365 insertions(+), 57 deletions(-)

diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index 06e6f0a..c3664d9 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -38,7 +38,12 @@ EXTRA_DIST = \
 	plugingui.h \
 	slider.h \
 	widget.h \
-	window.h
+	window.h \
+	listbox.h \
+	knob.h \
+	filebrowser.h \
+	combobox.h
+
 
 ################
 # Test Section #
diff --git a/plugingui/Makefile.am.plugingui b/plugingui/Makefile.am.plugingui
index 6ce79fc..51049c8 100644
--- a/plugingui/Makefile.am.plugingui
+++ b/plugingui/Makefile.am.plugingui
@@ -21,7 +21,8 @@ PLUGIN_GUI_SOURCES = \
 	$(top_srcdir)/plugingui/slider.cc \
 	$(top_srcdir)/plugingui/listbox.cc \
 	$(top_srcdir)/plugingui/knob.cc \
-	$(top_srcdir)/plugingui/filebrowser.cc
+	$(top_srcdir)/plugingui/filebrowser.cc \
+	$(top_srcdir)/plugingui/combobox.cc
 
 PLUGIN_GUI_LIBS = -lX11
 
diff --git a/plugingui/Makefile.mingw32 b/plugingui/Makefile.mingw32
index 08e772e..466619b 100644
--- a/plugingui/Makefile.mingw32
+++ b/plugingui/Makefile.mingw32
@@ -32,6 +32,7 @@ CXX_SOURCES = \
 	$(top_srcdir)/plugingui/listbox.cc \
 	$(top_srcdir)/plugingui/filebrowser.cc \
 	$(top_srcdir)/plugingui/knob.cc \
+	$(top_srcdir)/plugingui/combobox.cc \
 	$(top_srcdir)/src/thread.cc
 
 OBJECTS=$(CXX_SOURCES:.cc=.o) $(C_SOURCES:.c=.o)
diff --git a/plugingui/combobox.cc b/plugingui/combobox.cc
index 483f62c..20779e8 100644
--- a/plugingui/combobox.cc
+++ b/plugingui/combobox.cc
@@ -26,6 +26,159 @@
  */
 #include "combobox.h"
 
+#include "painter.h"
+#include "font.h"
+
+#include <stdio.h>
+
+#define BORDER 10
+
+void listboxSelectHandler(void *ptr)
+{
+  GUI::ComboBox *c = (GUI::ComboBox*)ptr;
+  GUI::ButtonEvent e;
+  e.direction = 1;
+  c->buttonEvent(&e);
+}
+
+GUI::ComboBox::ComboBox(GUI::Widget *parent)
+  : GUI::Widget(parent)
+{
+  handler = NULL;
+  ptr = NULL;
+
+  listbox = new GUI::ListBox(parent);
+  listbox->registerSelectHandler(listboxSelectHandler, this);
+  listbox->registerClickHandler(listboxSelectHandler, this);
+  listbox->hide();
+}
+
+GUI::ComboBox::~ComboBox()
+{
+}
+
+void GUI::ComboBox::addItem(std::string name, std::string value)
+{
+  listbox->addItem(name, value);
+}
+
+void GUI::ComboBox::clear()
+{
+  listbox->clear();
+  repaintEvent(NULL);
+}
+
+bool GUI::ComboBox::selectItem(int index)
+{
+  listbox->selectItem(index);
+  repaintEvent(NULL);
+  return true;
+}
+
+std::string GUI::ComboBox::selectedName()
+{
+  return listbox->selectedName();
+}
+
+std::string GUI::ComboBox::selectedValue()
+{
+  return listbox->selectedValue();
+}
+
+void GUI::ComboBox::registerValueChangedHandler(void (*handler)(void *),
+                                                void *ptr)
+{
+  this->handler = handler;
+  this->ptr = ptr;
+}
+
+void GUI::ComboBox::repaintEvent(GUI::RepaintEvent *e)
+{
+  Painter p(this);
+  
+  int h = 16;
+
+  std::string _text = selectedName();
+
+  p.setColour(Colour(0, 0.4));
+  p.drawFilledRectangle(3,3,width()-3,h-3);
+
+  p.setColour(Colour(1,1,1));
+  p.drawRectangle(0,0,width()-1,h-1);
+  p.drawRectangle(2,2,width()-3,h-3);
+  p.drawText(BORDER - 4, h/2+5 + 1, font, _text);
+}
+
+void GUI::ComboBox::scrollEvent(ScrollEvent *e)
+{
+  /*
+  scroll_offset += e->delta;
+  if(scroll_offset < 0) scroll_offset = 0;
+  if(scroll_offset > (items.size() - 1))
+    scroll_offset = (items.size() - 1);
+  repaintEvent(NULL);
+  */
+}
+
+void GUI::ComboBox::keyEvent(GUI::KeyEvent *e)
+{
+  if(e->direction != -1) return;
+
+  /*
+  switch(e->keycode) {
+  case GUI::KeyEvent::KEY_UP:
+    {
+      selected--;
+      if(selected < 0) selected = 0;
+      if(selected < scroll_offset) {
+        scroll_offset = selected;
+        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);
+
+      selected++;
+      if(selected > (items.size() - 1))
+        selected = (items.size() - 1);
+      if(selected > (scroll_offset + numitems - 1)) {
+        scroll_offset = selected - numitems + 1;
+        if(scroll_offset > (items.size() - 1))
+          scroll_offset = (items.size() - 1);
+      }
+    }
+    break;
+  case GUI::KeyEvent::KEY_HOME:
+    selected = 0;
+    break;
+  case GUI::KeyEvent::KEY_END:
+    selected = items.size() - 1;
+    break;
+  default:
+    break;
+  }
+  
+  repaintEvent(NULL);
+  */
+}
+
+void GUI::ComboBox::buttonEvent(ButtonEvent *e)
+{
+  if(e->direction != 1) return;
+
+  if(!listbox->visible()) {
+    listbox->resize(width() - 1, 100);
+    listbox->move(x(), y() + 16);
+  } else {
+    if(handler) handler(ptr);
+  }
+
+  listbox->setVisible(!listbox->visible());
+}
+
 #ifdef TEST_COMBOBOX
 //Additional dependency files
 //deps:
diff --git a/plugingui/combobox.h b/plugingui/combobox.h
index df45ca7..1c80496 100644
--- a/plugingui/combobox.h
+++ b/plugingui/combobox.h
@@ -26,4 +26,45 @@
  */
 #ifndef __DRUMGIZMO_COMBOBOX_H__
 #define __DRUMGIZMO_COMBOBOX_H__
+
+#include <string.h>
+#include <vector>
+
+#include "widget.h"
+#include "font.h"
+#include "listbox.h"
+
+namespace GUI {
+
+class ComboBox : public Widget {
+public:
+  ComboBox(Widget *parent);
+  ~ComboBox();
+
+  bool isFocusable() { return true; }
+
+  void addItem(std::string name, std::string value);
+
+  void clear();
+  bool selectItem(int index);
+  std::string selectedName();
+  std::string selectedValue();
+
+  void registerValueChangedHandler(void (*handler)(void *), void *ptr);
+
+  virtual void repaintEvent(RepaintEvent *e);
+  virtual void buttonEvent(ButtonEvent *e);
+  virtual void scrollEvent(ScrollEvent *e);
+  virtual void keyEvent(KeyEvent *e);
+
+private:
+  GUI::Font font;
+  GUI::ListBox *listbox;
+
+  void (*handler)(void *);
+  void *ptr;
+};
+
+};
+
 #endif/*__DRUMGIZMO_COMBOBOX_H__*/
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index b971b15..017434e 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -122,10 +122,6 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
 
       last_x = e->x;
       last_y = e->y;
-
-      //		xPos = (int)(short) LOWORD(lp);
-      //		yPos = (int)(short) HIWORD(lp);
-      //		fwKeys = wp;
     }
 		break;
 
@@ -202,6 +198,9 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
       case 46: e->keycode = GUI::KeyEvent::KEY_DELETE; break;
       case 36: e->keycode = GUI::KeyEvent::KEY_HOME; break;
       case 35: e->keycode = GUI::KeyEvent::KEY_END; break;
+      case 33: e->keycode = GUI::KeyEvent::KEY_PGUP; break;
+      case 34: e->keycode = GUI::KeyEvent::KEY_PGDOWN; break;
+      case 13: e->keycode = GUI::KeyEvent::KEY_ENTER; break;
       default: e->keycode = GUI::KeyEvent::KEY_UNKNOWN; break;
       }
       e->text = "";
@@ -212,7 +211,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
 
 	case WM_CHAR:
     {
-      printf("WM_CHAR %d %d\n", (int)lp, (int)wp);
+      //printf("WM_CHAR %d %d\n", (int)lp, (int)wp);
       if(wp >= ' ') { // Filter control chars.
         GUI::KeyEvent *e = new GUI::KeyEvent();
         e->keycode = GUI::KeyEvent::KEY_CHARACTER;
@@ -356,7 +355,7 @@ GUI::Event *GUI::EventHandler::getNextEvent()
   }
 
   if(xe.type == KeyPress || xe.type == KeyRelease) {
-    // printf("key: %d\n", xe.xkey.keycode);
+    //printf("key: %d\n", xe.xkey.keycode);
     KeyEvent *e = new KeyEvent();
     e->window_id = xe.xkey.window;
 
@@ -369,6 +368,9 @@ GUI::Event *GUI::EventHandler::getNextEvent()
     case 22: e->keycode = KeyEvent::KEY_BACKSPACE; break;
     case 110: e->keycode = KeyEvent::KEY_HOME; break;
     case 115: e->keycode = KeyEvent::KEY_END; break;
+    case 117: e->keycode = KeyEvent::KEY_PGDOWN; break;
+    case 112: e->keycode = KeyEvent::KEY_PGUP; break;
+    case 36: e->keycode = KeyEvent::KEY_ENTER; break;
     default: e->keycode = KeyEvent::KEY_UNKNOWN; break;
     }
 
diff --git a/plugingui/filebrowser.h b/plugingui/filebrowser.h
index 011c9d7..7d3b3bb 100644
--- a/plugingui/filebrowser.h
+++ b/plugingui/filebrowser.h
@@ -31,6 +31,8 @@
 
 #include "button.h"
 #include "listbox.h"
+#include "combobox.h"
+#include "lineedit.h"
 
 namespace GUI {
 
@@ -55,9 +57,13 @@ public:
 private:
   struct private_data *prv;
 
+  GUI::LineEdit *lineedit;
   GUI::ListBox *listbox;
   GUI::Button *btn_sel;
   GUI::Button *btn_esc;
+
+  // Only used on win32
+  GUI::ComboBox *drv;
 };
 
 };
diff --git a/plugingui/filelineedit.cc b/plugingui/filelineedit.cc
index e4794b0..cf9ac3a 100644
--- a/plugingui/filelineedit.cc
+++ b/plugingui/filelineedit.cc
@@ -32,6 +32,7 @@ FileLineEdit::FileLineEdit(GUI::Widget *parent, GUI::LED *led)
   : LineEdit(parent)
 {
   this->led = led;
+  setReadOnly(false);
 }
 
 void FileLineEdit::textChanged()
diff --git a/plugingui/guievent.h b/plugingui/guievent.h
index df2db26..4732101 100644
--- a/plugingui/guievent.h
+++ b/plugingui/guievent.h
@@ -116,6 +116,9 @@ public:
     KEY_BACKSPACE = 6,
     KEY_HOME      = 7,
     KEY_END       = 8,
+    KEY_PGDOWN    = 9,
+    KEY_PGUP      = 10,
+    KEY_ENTER     = 11,
     KEY_CHARACTER = 0xffff // character data is stored in 'text'
   };
 };
diff --git a/plugingui/knob.cc b/plugingui/knob.cc
index d50d5c2..1a0148f 100644
--- a/plugingui/knob.cc
+++ b/plugingui/knob.cc
@@ -170,8 +170,8 @@ void GUI::Knob::repaintEvent(GUI::RepaintEvent *e)
   char buf[64];
   sprintf(buf, "%.2f", val * maximum);
   Font font;
-  p.drawText(center_x - font.textWidth(buf) / 2,
-             center_y + font.textHeight(buf) / 2, font, buf);
+  p.drawText(center_x - font.textWidth(buf) / 2 + 1,
+             center_y + font.textHeight(buf) / 2 + 1, font, buf);
 
   p.setColour(Colour(1, alpha));
 
@@ -182,11 +182,15 @@ void GUI::Knob::repaintEvent(GUI::RepaintEvent *e)
   double border_x = sin((-1 * padval + 1) * 2 * M_PI);
   double border_y = cos((-1 * padval + 1) * 2 * M_PI);
 
-  p.setColour(Colour(1, 0, 0, 1));
-  p.drawLine(border_x * (radius / 2) + center_x,
-             border_y * (radius / 2) + center_y,
-             border_x * radius + center_x,
-             border_y * radius + center_y);
+  p.setColour(Colour(1, 0, 0, 0.6));
+  for(int _x = -1; _x < 2; _x++) {
+    for(int _y = -1; _y < 2; _y++) {
+      p.drawLine(border_x * (radius / 2) + center_x + _x,
+                 border_y * (radius / 2) + center_y + _y,
+                 border_x * radius + center_x + _x,
+                 border_y * radius + center_y + _y);
+    }
+  }
 }
 
 #ifdef TEST_KNOB
diff --git a/plugingui/lineedit.cc b/plugingui/lineedit.cc
index 66d1e59..17174b9 100644
--- a/plugingui/lineedit.cc
+++ b/plugingui/lineedit.cc
@@ -38,6 +38,17 @@ GUI::LineEdit::LineEdit(Widget *parent)
   : GUI::Widget(parent)
 {
   pos = 0;
+  setReadOnly(false);
+}
+
+void GUI::LineEdit::setReadOnly(bool ro)
+{
+  readonly = ro;
+}
+
+bool GUI::LineEdit::readOnly()
+{
+  return readonly;
 }
 
 void GUI::LineEdit::setText(std::string text)
@@ -54,6 +65,8 @@ std::string GUI::LineEdit::text()
 
 void GUI::LineEdit::buttonEvent(ButtonEvent *e)
 {
+  if(readOnly()) return;
+
   if(e->direction == 1) {
     for(int i = 0; i < (int)_text.length(); i++) {
       if(e->x < (int)(font.textWidth(_text.substr(0, i)) + BORDER)) {
@@ -67,6 +80,8 @@ void GUI::LineEdit::buttonEvent(ButtonEvent *e)
 
 void GUI::LineEdit::keyEvent(GUI::KeyEvent *e)
 {
+  if(readOnly()) return;
+
   bool change = false;
   
   if(e->direction == -1) {
@@ -124,12 +139,14 @@ void GUI::LineEdit::repaintEvent(GUI::RepaintEvent *e)
   p.setColour(Colour(1,1,1));
   p.drawRectangle(0,0,width()-1,height()-1);
   p.drawRectangle(2,2,width()-3,height()-3);
-  p.drawText(BORDER, height()/2+5, font, _text);
+  p.drawText(BORDER - 4, height()/2+5 + 1, font, _text);
+
+  if(readOnly()) return;
 
   if(hasKeyboardFocus()) {
     size_t px = font.textWidth(_text.substr(0, pos));
     p.setColour(Colour(0.8));
-    p.drawLine(px + BORDER - 1, 4, px + BORDER - 1, height() - 5);
+    p.drawLine(px + BORDER - 1 - 4, 4, px + BORDER - 1 - 4, height() - 5);
   }
 }
 
diff --git a/plugingui/lineedit.h b/plugingui/lineedit.h
index 46fa5bc..fa327ca 100644
--- a/plugingui/lineedit.h
+++ b/plugingui/lineedit.h
@@ -44,6 +44,9 @@ public:
   std::string text();
   void setText(std::string text);
 
+  void setReadOnly(bool readonly);
+  bool readOnly();
+
   //protected:
   virtual void keyEvent(KeyEvent *e);
   virtual void repaintEvent(RepaintEvent *e);
@@ -57,6 +60,8 @@ private:
 
   std::string _text;
   size_t pos;
+
+  bool readonly;
 };
 
 };
diff --git a/plugingui/listbox.cc b/plugingui/listbox.cc
index e8d6b0e..1ad5860 100644
--- a/plugingui/listbox.cc
+++ b/plugingui/listbox.cc
@@ -39,15 +39,28 @@ GUI::ListBox::ListBox(GUI::Widget *parent)
 
   scroll_offset = 0;
   selected = -1;
+  marked = -1;
 
-  dblclk_handler = NULL;
-  ptr = NULL;
+  clk_handler = NULL;
+  clk_ptr = NULL;
+
+  sel_handler = NULL;
+  sel_ptr = NULL;
+
+  valch_handler = NULL;
+  valch_ptr = NULL;
 }
 
 GUI::ListBox::~ListBox()
 {
 }
 
+void GUI::ListBox::setSelection(int index)
+{
+  selected = index;
+  if(valch_handler) valch_handler(valch_ptr);
+}
+
 void GUI::ListBox::addItem(std::string name, std::string value)
 {
   struct item i;
@@ -61,8 +74,8 @@ void GUI::ListBox::addItem(std::string name, std::string value)
     for(int y = 0; y < (int)items.size() - 1; y++) {
       if(items[x].name < items[y].name) {
 
-        if(x == selected) selected = y;
-        else if(selected == y) selected = x;
+        if(x == selected) setSelection(y);
+        else if(selected == y) setSelection(x);
 
         struct item tmp = items[x];
         items[x] = items[y];
@@ -71,13 +84,13 @@ void GUI::ListBox::addItem(std::string name, std::string value)
     }
   }
 
-  if(selected == -1) selected = items.size() - 1;
+  if(selected == -1) setSelection(items.size() - 1);
 }
 
 void GUI::ListBox::clear()
 {
   items.clear();
-  selected = -1;
+  setSelection(-1);
   scroll_offset = 0;
   repaintEvent(NULL);
 }
@@ -85,7 +98,7 @@ void GUI::ListBox::clear()
 bool GUI::ListBox::selectItem(int index)
 {
   if(index < 0 || index > (int)items.size() - 1) return false;
-  selected = index;
+  setSelection(index);
   repaintEvent(NULL);
   return true;
 }
@@ -102,17 +115,30 @@ std::string GUI::ListBox::selectedValue()
   return items[selected].value;
 }
 
-void GUI::ListBox::registerDblClickHandler(void (*handler)(void *), void *ptr)
+void GUI::ListBox::registerClickHandler(void (*handler)(void *), void *ptr)
 {
-  this->dblclk_handler = handler;
-  this->ptr = ptr;
+  this->clk_handler = handler;
+  this->clk_ptr = ptr;
+}
+
+void GUI::ListBox::registerSelectHandler(void (*handler)(void *), void *ptr)
+{
+  this->sel_handler = handler;
+  this->sel_ptr = ptr;
+}
+
+void GUI::ListBox::registerValueChangeHandler(void (*handler)(void *),
+                                              void *ptr)
+{
+  this->valch_handler = handler;
+  this->valch_ptr = ptr;
 }
 
 void GUI::ListBox::repaintEvent(GUI::RepaintEvent *e)
 {
   GUI::Painter p(this);
 
-  p.setColour(Colour(0, 0.5));
+  p.setColour(Colour(0, 0.7));
   p.drawFilledRectangle(0, 0, width() - 1, height() - 1);
 
   p.setColour(Colour(0.5, 1));
@@ -130,6 +156,14 @@ void GUI::ListBox::repaintEvent(GUI::RepaintEvent *e)
                             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;
@@ -156,10 +190,11 @@ void GUI::ListBox::keyEvent(GUI::KeyEvent *e)
   switch(e->keycode) {
   case GUI::KeyEvent::KEY_UP:
     {
-      selected--;
-      if(selected < 0) selected = 0;
-      if(selected < scroll_offset) {
-        scroll_offset = selected;
+      marked--;
+      if(marked < 0) marked = 0;
+
+      if(marked < scroll_offset) {
+        scroll_offset = marked;
         if(scroll_offset < 0) scroll_offset = 0;
       }
     }
@@ -169,21 +204,45 @@ void GUI::ListBox::keyEvent(GUI::KeyEvent *e)
       // Number of items that can be displayed at a time.
       int numitems = height() / (font.textHeight() + padding);
 
-      selected++;
-      if(selected > (items.size() - 1))
-        selected = (items.size() - 1);
-      if(selected > (scroll_offset + numitems - 1)) {
-        scroll_offset = selected - numitems + 1;
+      marked++;
+      if(marked > (items.size() - 1)) marked = items.size() - 1;
+
+      if(marked > (scroll_offset + numitems - 1)) {
+        scroll_offset = marked - numitems + 1;
         if(scroll_offset > (items.size() - 1))
           scroll_offset = (items.size() - 1);
       }
     }
     break;
   case GUI::KeyEvent::KEY_HOME:
-    selected = 0;
+    marked = 0;
+    if(marked < scroll_offset) {
+      scroll_offset = marked;
+      if(scroll_offset < 0) scroll_offset = 0;
+    }
     break;
   case GUI::KeyEvent::KEY_END:
-    selected = items.size() - 1;
+    {
+      // Number of items that can be displayed at a time.
+      int numitems = height() / (font.textHeight() + padding);
+
+      marked = items.size() - 1;
+      if(marked > (scroll_offset + numitems - 1)) {
+        scroll_offset = marked - numitems + 1;
+        if(scroll_offset > (items.size() - 1))
+          scroll_offset = (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;
@@ -214,10 +273,12 @@ void GUI::ListBox::buttonEvent(ButtonEvent *e)
 
     int skip = scroll_offset;
     size_t yoffset = padding / 2;
-    for(int idx = skip; idx < (int)items.size() - 1; idx++) {
+    for(int idx = skip; idx < (int)items.size(); idx++) {
       yoffset += font.textHeight() + padding;
       if(e->y < (int)yoffset - (padding / 2)) {
-        selected = idx;
+        setSelection(idx);
+        marked = selected;
+        if(clk_handler) clk_handler(clk_ptr);
         break;
       }
     }
@@ -225,5 +286,5 @@ void GUI::ListBox::buttonEvent(ButtonEvent *e)
     repaintEvent(NULL);
   }
 
-  if(e->doubleclick && dblclk_handler) dblclk_handler(ptr);
+  if(e->doubleclick && sel_handler) sel_handler(sel_ptr);
 }
diff --git a/plugingui/listbox.h b/plugingui/listbox.h
index d7a5021..842a00f 100644
--- a/plugingui/listbox.h
+++ b/plugingui/listbox.h
@@ -49,7 +49,9 @@ public:
   std::string selectedName();
   std::string selectedValue();
 
-  void registerDblClickHandler(void (*handler)(void *), void *ptr);
+  void registerSelectHandler(void (*handler)(void *), void *ptr);
+  void registerClickHandler(void (*handler)(void *), void *ptr);
+  void registerValueChangeHandler(void (*handler)(void *), void *ptr);
 
   virtual void repaintEvent(RepaintEvent *e);
   virtual void buttonEvent(ButtonEvent *e);
@@ -57,6 +59,8 @@ public:
   virtual void keyEvent(KeyEvent *e);
 
 private:
+  void setSelection(int index);
+
   struct item {
     std::string name;
     std::string value;
@@ -64,13 +68,20 @@ private:
 
   std::vector<struct item> items;
   int selected;
+  int marked;
   GUI::Font font;
   int padding;
   int btn_size;
   int scroll_offset;
 
-  void (*dblclk_handler)(void *);
-  void *ptr;
+  void (*sel_handler)(void *);
+  void *sel_ptr;
+
+  void (*clk_handler)(void *);
+  void *clk_ptr;
+
+  void (*valch_handler)(void *);
+  void *valch_ptr;
 };
 
 };
diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc
index ea0e4ad..7e4bb59 100644
--- a/plugingui/plugingui.cc
+++ b/plugingui/plugingui.cc
@@ -178,11 +178,12 @@ void PluginGUI::init()
   //  printf("%p\n", eventhandler);
   window = new GUI::Window(gctx);
   window->resize(640, 200);
-
+  window->setCaption("DrumGizmo v"VERSION);
+  
   // Enable Velocity
   check = new GUI::CheckBox(window);
   check->setText("Enable Velocity Modifier");
-  check->move(210,82);
+  check->move(215,82);
   check->resize(200,16);
   check->setChecked(Conf::enable_velocity_modifier);
   check->registerClickHandler(checkClick, this);
@@ -266,14 +267,6 @@ void PluginGUI::init()
     btn_brw->registerClickHandler(midimapBrowseClick, this);
   }
 
-  /*
-  btn_cancel = new GUI::Button(window);
-  btn_cancel->setText("Close");
-  btn_cancel->move(520, 160);
-  btn_cancel->resize(100, 20);
-  btn_cancel->registerClickHandler(closeClick, this);
-  */
-
   GUI::Label *lbl3 = new GUI::Label(window);
   lbl3->setText("v"VERSION);
   lbl3->move(120, 180);
diff --git a/version.h b/version.h
index 97cf2a3..ca85956 100644
--- a/version.h
+++ b/version.h
@@ -1 +1 @@
-#define VERSION "0.9.1"
+#define VERSION "0.9.2"
diff --git a/vst/Makefile.mingw32 b/vst/Makefile.mingw32
index 8fd99b1..261a44e 100644
--- a/vst/Makefile.mingw32
+++ b/vst/Makefile.mingw32
@@ -48,7 +48,11 @@ GUI_SRC = \
 	$(DG_BASE)/plugingui/lineedit.cc \
 	$(DG_BASE)/plugingui/led.cc \
 	$(DG_BASE)/plugingui/checkbox.cc \
-	$(DG_BASE)/plugingui/slider.cc
+	$(DG_BASE)/plugingui/slider.cc \
+	$(DG_BASE)/plugingui/listbox.cc \
+	$(DG_BASE)/plugingui/knob.cc \
+	$(DG_BASE)/plugingui/filebrowser.cc \
+	$(DG_BASE)/plugingui/combobox.cc
 
 GUI_CFLAGS=-I../plugingui -DUSE_THREAD
 GUI_LIBS=-lgdi32 -lsetupapi -lws2_32
-- 
cgit v1.2.3