summaryrefslogtreecommitdiff
path: root/plugingui
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-03-06 09:30:52 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2013-03-06 09:30:52 +0100
commita0b7282b31ed31051ee98bf16e8704d5599e5461 (patch)
tree49798ac70adbac0e065781833f045bab8a65bb0b /plugingui
parentdff2ff5b636d9d7007bf8589204e6a7138ee4004 (diff)
Major GUI workover. Hilights: A new filebrowser and new knob widget.
Diffstat (limited to 'plugingui')
-rw-r--r--plugingui/Makefile.am.plugingui5
-rw-r--r--plugingui/Makefile.mingw323
-rw-r--r--plugingui/eventhandler.cc63
-rw-r--r--plugingui/eventhandler.h2
-rw-r--r--plugingui/filebrowser.cc151
-rw-r--r--plugingui/filebrowser.h62
-rw-r--r--plugingui/font.h2
-rw-r--r--plugingui/guievent.h13
-rw-r--r--plugingui/knob.cc167
-rw-r--r--plugingui/knob.h73
-rw-r--r--plugingui/lineedit.cc1
-rw-r--r--plugingui/listbox.cc170
-rw-r--r--plugingui/listbox.h71
-rw-r--r--plugingui/nativewindow.h1
-rw-r--r--plugingui/nativewindow_win32.cc8
-rw-r--r--plugingui/nativewindow_win32.h1
-rw-r--r--plugingui/nativewindow_x11.cc6
-rw-r--r--plugingui/nativewindow_x11.h1
-rw-r--r--plugingui/painter.cc179
-rw-r--r--plugingui/painter.h8
-rw-r--r--plugingui/pixelbuffer.cc29
-rw-r--r--plugingui/pixelbuffer.h6
-rw-r--r--plugingui/plugingui.cc193
-rw-r--r--plugingui/plugingui.h10
-rw-r--r--plugingui/slider.cc14
-rw-r--r--plugingui/widget.cc82
-rw-r--r--plugingui/widget.h15
-rw-r--r--plugingui/window.cc3
-rw-r--r--plugingui/window.h2
29 files changed, 1231 insertions, 110 deletions
diff --git a/plugingui/Makefile.am.plugingui b/plugingui/Makefile.am.plugingui
index 4755ebd..6ce79fc 100644
--- a/plugingui/Makefile.am.plugingui
+++ b/plugingui/Makefile.am.plugingui
@@ -18,7 +18,10 @@ PLUGIN_GUI_SOURCES = \
$(top_srcdir)/plugingui/lineedit.cc \
$(top_srcdir)/plugingui/led.cc \
$(top_srcdir)/plugingui/checkbox.cc \
- $(top_srcdir)/plugingui/slider.cc
+ $(top_srcdir)/plugingui/slider.cc \
+ $(top_srcdir)/plugingui/listbox.cc \
+ $(top_srcdir)/plugingui/knob.cc \
+ $(top_srcdir)/plugingui/filebrowser.cc
PLUGIN_GUI_LIBS = -lX11
diff --git a/plugingui/Makefile.mingw32 b/plugingui/Makefile.mingw32
index 83f4f04..08e772e 100644
--- a/plugingui/Makefile.mingw32
+++ b/plugingui/Makefile.mingw32
@@ -29,6 +29,9 @@ CXX_SOURCES = \
$(top_srcdir)/plugingui/led.cc \
$(top_srcdir)/plugingui/checkbox.cc \
$(top_srcdir)/plugingui/slider.cc \
+ $(top_srcdir)/plugingui/listbox.cc \
+ $(top_srcdir)/plugingui/filebrowser.cc \
+ $(top_srcdir)/plugingui/knob.cc \
$(top_srcdir)/src/thread.cc
OBJECTS=$(CXX_SOURCES:.cc=.o) $(C_SOURCES:.c=.o)
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index fdef990..3570b77 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -37,6 +37,7 @@
GUI::EventHandler::EventHandler(GlobalContext *gctx)
{
this->gctx = gctx;
+ last_click = 0;
#ifdef WIN32
this->gctx->eventhandler = this;
event = NULL;
@@ -66,7 +67,6 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
GUI::EventHandler *handler =
(GUI::EventHandler *) GetWindowLong(hwnd, GWL_USERDATA);
-
switch(msg) {
case WM_SIZE:
{
@@ -142,6 +142,8 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
// fwKeys = wp;
break;
+ case WM_LBUTTONDBLCLK:
+ printf("LBUTTONDBLCLK\n");
case WM_LBUTTONDOWN:
{
GUI::ButtonEvent *e = new GUI::ButtonEvent();
@@ -149,6 +151,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
e->y = (int)(short) HIWORD(lp);
e->button = 0;
e->direction = 1;
+ e->doubleclick = (msg == WM_LBUTTONDBLCLK);
handler->event = e;
}
//xPos = (int)(short) LOWORD(lp);
@@ -157,18 +160,29 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
break;
case WM_MBUTTONUP:
+ {
+ GUI::ButtonEvent *e = new GUI::ButtonEvent();
+ e->x = (int)(short) LOWORD(lp);
+ e->y = (int)(short) HIWORD(lp);
+ e->button = 3;
+ e->direction = -1;
+ e->doubleclick = 0;
+ handler->event = e;
+ }
//xPos = (int)(short) LOWORD(lp);
//yPos = (int)(short) HIWORD(lp);
//fwKeys = wp;
break;
+ case WM_MBUTTONDBLCLK:
case WM_MBUTTONDOWN:
{
GUI::ButtonEvent *e = new GUI::ButtonEvent();
e->x = (int)(short) LOWORD(lp);
e->y = (int)(short) HIWORD(lp);
- e->button = 1;
+ e->button = 3;
e->direction = 1;
+ e->doubleclick = (msg == WM_MBUTTONDBLCLK);
handler->event = e;
}
// xPos = (int)(short) LOWORD(lp);
@@ -183,6 +197,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
e->y = (int)(short) HIWORD(lp);
e->button = 1;
e->direction = -1;
+ e->doubleclick = 0;
handler->event = e;
}
// xPos = (int)(short) LOWORD(lp);
@@ -190,6 +205,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
// fwKeys = wp;
break;
+ case WM_RBUTTONDBLCLK:
case WM_RBUTTONDOWN:
{
GUI::ButtonEvent *e = new GUI::ButtonEvent();
@@ -197,6 +213,7 @@ LRESULT CALLBACK dialogProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
e->y = (int)(short) HIWORD(lp);
e->button = 1;
e->direction = 1;
+ e->doubleclick = (msg == WM_RBUTTONDBLCLK);
handler->event = e;
}
// xPos = (int)(short) LOWORD(lp);
@@ -469,6 +486,10 @@ GUI::Event *GUI::EventHandler::getNextEvent()
e->y = xe.xbutton.y;
e->button = 0;
e->direction = xe.type == ButtonPress?1:-1;
+ e->doubleclick =
+ xe.type == ButtonPress && (xe.xbutton.time - last_click) < 200;
+
+ if(xe.type == ButtonPress) last_click = xe.xbutton.time;
event = e;
}
@@ -542,14 +563,16 @@ void GUI::EventHandler::processEvents(Window *window)
// window->repaint((RepaintEvent*)event);
window->redraw();
break;
- case Event::Resize:{
- // window->repaint((RepaintEvent*)event)
- ResizeEvent *re = (ResizeEvent*)event;
- if(re->width != window->width() || re->height != window->height()) {
- window->resized(re->width, re->height);
- window->repaint_r(NULL);
+ case Event::Resize:
+ {
+ // window->repaint((RepaintEvent*)event)
+ ResizeEvent *re = (ResizeEvent*)event;
+ if(re->width != window->width() || re->height != window->height()) {
+ window->resized(re->width, re->height);
+ window->repaint_r(NULL);
+ }
}
- } break;
+ break;
case Event::MouseMove:
{
MouseMoveEvent *me = (MouseMoveEvent*)event;
@@ -558,21 +581,22 @@ void GUI::EventHandler::processEvents(Window *window)
if(window->buttonDownFocus()) {
Widget *w = window->buttonDownFocus();
+ /*
if(me->x < w->x()) me->x = w->x();
if(me->x > w->x() + w->width()) me->x = w->x() + w->width();
if(me->y < w->y()) me->y = w->y();
if(me->y > w->y() + w->height()) me->y = w->y() + w->height();
-
- me->x -= w->x();
- me->y -= w->y();
+ */
+ me->x -= w->windowX();
+ me->y -= w->windowY();
window->buttonDownFocus()->mouseMoveEvent(me);
break;
}
if(w) {
- me->x -= w->x();
- me->y -= w->y();
+ me->x -= w->windowX();
+ me->y -= w->windowY();
w->mouseMoveEvent(me);
}
}
@@ -586,13 +610,14 @@ void GUI::EventHandler::processEvents(Window *window)
if(window->buttonDownFocus()) {
if(be->direction == -1) {
Widget *w = window->buttonDownFocus();
+ /*
if(be->x < w->x()) be->x = w->x();
if(be->x > w->x() + w->width()) be->x = w->x() + w->width();
if(be->y < w->y()) be->y = w->y();
if(be->y > w->y() + w->height()) be->y = w->y() + w->height();
-
- be->x -= w->x();
- be->y -= w->y();
+ */
+ be->x -= w->windowX();
+ be->y -= w->windowY();
w->buttonEvent(be);
break;
@@ -602,8 +627,8 @@ void GUI::EventHandler::processEvents(Window *window)
}
if(w) {
- be->x -= w->x();
- be->y -= w->y();
+ be->x -= w->windowX();
+ be->y -= w->windowY();
w->buttonEvent(be);
diff --git a/plugingui/eventhandler.h b/plugingui/eventhandler.h
index c63c003..99be2d4 100644
--- a/plugingui/eventhandler.h
+++ b/plugingui/eventhandler.h
@@ -52,7 +52,7 @@ public:
GlobalContext *gctx;
private:
-
+ int last_click;
void (*closeHandler)(void *);
void *closeHandlerPtr;
};
diff --git a/plugingui/filebrowser.cc b/plugingui/filebrowser.cc
new file mode 100644
index 0000000..6582202
--- /dev/null
+++ b/plugingui/filebrowser.cc
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * filebrowser.cc
+ *
+ * Mon Feb 25 21:09:44 CET 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 "filebrowser.h"
+
+#include "painter.h"
+
+#include "button.h"
+#include "listbox.h"
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+struct GUI::FileBrowser::private_data {
+ GUI::ListBox *listbox;
+ void (*filesel_handler)(void *, std::string);
+ void *ptr;
+};
+
+void changeDir(void *ptr)
+{
+ struct GUI::FileBrowser::private_data *prv =
+ (struct GUI::FileBrowser::private_data *)ptr;
+
+ GUI::ListBox *lb = prv->listbox;
+ std::string value = lb->selectedValue();
+
+ char filename[1024];
+ char *c = getcwd(filename, sizeof(filename));
+ (void)c;
+ strcat(filename, "/");
+ strcat(filename, value.c_str());
+
+ struct stat st;
+ if(stat(filename, &st) == 0) {
+ if((st.st_mode & S_IFDIR) != 0) {
+ //printf("'%s' is present and is a directory\n", filename);
+ }
+ if((st.st_mode & S_IFREG) != 0) {
+ //printf("'%s' is present and is a file\n", filename);
+ if(prv->filesel_handler) prv->filesel_handler(prv->ptr, filename);
+ return;
+ }
+ } else {
+ //printf("'%s' is not present or unreadable\n", filename);
+ return;
+ }
+
+ lb->clear();
+ int i = chdir(value.c_str());
+ (void)i;
+ DIR *dir = opendir(".");
+
+ struct dirent *entry;
+ while((entry = readdir(dir)) != NULL) {
+ lb->addItem(entry->d_name, entry->d_name);
+ }
+
+ closedir(dir);
+}
+
+GUI::FileBrowser::FileBrowser(GUI::Widget *parent)
+ : GUI::Widget(parent)
+{
+ prv = new struct GUI::FileBrowser::private_data();
+ prv->filesel_handler = NULL;
+
+#define brd 5 // border
+#define btn_h 12
+
+ listbox = new GUI::ListBox(this);
+ listbox->registerDblClickHandler(changeDir, prv);
+ prv->listbox = listbox;
+
+ btn = new GUI::Button(this);
+ btn->setText("Select");
+ btn->registerClickHandler(changeDir, prv);
+
+ changeDir(prv);
+
+ resize(200, 190);
+}
+
+GUI::FileBrowser::~FileBrowser()
+{
+ delete prv->listbox;
+ delete prv;
+}
+
+void GUI::FileBrowser::resize(size_t w, size_t h)
+{
+ GUI::Widget::resize(w,h);
+
+ listbox->move(brd, brd);
+ listbox->resize(w - 1 - 2*brd, h - btn_h - 3*brd);
+
+ btn->move(brd, h - btn_h - brd);
+ btn->resize(w - 1 - 2*brd, btn_h);
+}
+
+
+void GUI::FileBrowser::registerFileSelectHandler(void (*handler)(void *,
+ std::string),
+ void *ptr)
+{
+ prv->filesel_handler = handler;
+ prv->ptr = ptr;
+}
+
+void GUI::FileBrowser::repaintEvent(GUI::RepaintEvent *e)
+{
+ Painter p(this);
+ p.setColour(Colour(0, 0.8));
+
+ p.drawFilledRectangle(0, 0, width(), height());
+
+ p.setColour(Colour(1, 1));
+
+ for(int i = 1; i < 10; i++) {
+ p.drawLine(0,0,width() / i, height() - 1);
+ p.drawLine(width()-1,0,width() / i, height() - 1);
+ }
+}
diff --git a/plugingui/filebrowser.h b/plugingui/filebrowser.h
new file mode 100644
index 0000000..bdfe98f
--- /dev/null
+++ b/plugingui/filebrowser.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * filebrowser.h
+ *
+ * Mon Feb 25 21:09:43 CET 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.
+ */
+#ifndef __DRUMGIZMO_FILEBROWSER_H__
+#define __DRUMGIZMO_FILEBROWSER_H__
+
+#include "widget.h"
+
+#include "button.h"
+#include "listbox.h"
+
+namespace GUI {
+
+class FileBrowser : public Widget {
+public:
+ struct private_data;
+
+ FileBrowser(Widget *parent);
+ ~FileBrowser();
+
+ bool isFocusable() { return true; }
+
+ void registerFileSelectHandler(void (*handler)(void *, std::string),
+ void *ptr);
+
+ virtual void repaintEvent(RepaintEvent *e);
+
+ virtual void resize(size_t w, size_t h);
+
+private:
+ struct private_data *prv;
+
+ GUI::ListBox *listbox;
+ GUI::Button *btn;
+};
+
+};
+
+#endif/*__DRUMGIZMO_FILEBROWSER_H__*/
diff --git a/plugingui/font.h b/plugingui/font.h
index c83a98f..848b168 100644
--- a/plugingui/font.h
+++ b/plugingui/font.h
@@ -46,7 +46,7 @@ public:
size_t size();
size_t textWidth(std::string text);
- size_t textHeight(std::string text);
+ size_t textHeight(std::string text = "");
PixelBufferAlpha *render(GlobalContext *gctx, std::string text);
diff --git a/plugingui/guievent.h b/plugingui/guievent.h
index 0fb3ef2..d8d6955 100644
--- a/plugingui/guievent.h
+++ b/plugingui/guievent.h
@@ -61,27 +61,28 @@ class MouseMoveEvent : public Event {
public:
Type type() { return MouseMove; }
- size_t x;
- size_t y;
+ int x;
+ int y;
};
class ButtonEvent : public Event {
public:
Type type() { return Button; }
- size_t x;
- size_t y;
+ int x;
+ int y;
int direction;
int button;
+ int doubleclick;
};
class RepaintEvent : public Event {
public:
Type type() { return Repaint; }
- size_t x;
- size_t y;
+ int x;
+ int y;
size_t width;
size_t height;
};
diff --git a/plugingui/knob.cc b/plugingui/knob.cc
new file mode 100644
index 0000000..75a7278
--- /dev/null
+++ b/plugingui/knob.cc
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * knob.cc
+ *
+ * Thu Feb 28 07:37:27 CET 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 "knob.h"
+
+#include "painter.h"
+
+#include <hugin.hpp>
+#include <stdio.h>
+#include <math.h>
+
+GUI::Knob::Knob(Widget *parent)
+ : GUI::Widget(parent)
+{
+ state = up;
+
+ val = 0.0;
+ maximum = 1.0;
+ minimum = 0.0;
+ mouse_offset_x = 0;
+
+ handler = NULL;
+ ptr = NULL;
+}
+
+void GUI::Knob::setValue(float v)
+{
+ val = v;
+ if(handler) handler(ptr);
+ repaintEvent(NULL);
+}
+
+float GUI::Knob::value()
+{
+ return val;
+}
+
+void GUI::Knob::registerClickHandler(void (*handler)(void *), void *ptr)
+{
+ this->handler = handler;
+ this->ptr = ptr;
+}
+
+void GUI::Knob::mouseMoveEvent(MouseMoveEvent *e)
+{
+ if(state == down) {
+ /*
+ DEBUG(slider, "Knob::mouseMoveEvent(mouse_offset_x: %d, e->x: %d)\n",
+ mouse_offset_x, e->x);
+ */
+ if(mouse_offset_x == (e->x + -1*e->y)) return;
+
+ float dval = mouse_offset_x - (e->x + -1*e->y);
+ val -= dval / 300.0;
+
+ if(val < 0) val = 0;
+ if(val > 1) val = 1;
+
+ if(handler) handler(ptr);
+ repaintEvent(NULL);
+
+ mouse_offset_x = e->x + -1*e->y;
+ }
+}
+
+void GUI::Knob::buttonEvent(ButtonEvent *e)
+{
+ if(e->direction == 1) {
+ state = down;
+ mouse_offset_x = e->x + -1*e->y;
+ //val = maximum / (float)width() * (float)e->x;
+ if(handler) handler(ptr);
+ repaintEvent(NULL);
+ }
+ if(e->direction == -1) {
+ state = up;
+ mouse_offset_x = e->x + -1*e->y;
+ //val = maximum / (float)width() * (float)e->x;
+ repaintEvent(NULL);
+ clicked();
+ if(handler) handler(ptr);
+ }
+}
+
+void GUI::Knob::repaintEvent(GUI::RepaintEvent *e)
+{
+ // DEBUG(slider, "Knob::repaintEvent (%f)\n", val);
+
+ Painter p(this);
+
+ float alpha = 0.8;
+
+ p.setColour(Colour(0, 0));
+ p.drawFilledRectangle(0,0,width()-1,height()-1);
+
+ if(hasKeyboardFocus()) {
+ p.setColour(Colour(0.6, alpha));
+ } else {
+ p.setColour(Colour(0.5, alpha));
+ }
+
+ int radius = (width()>height()?height():width()) / 2;
+ int center_x = width() / 2;
+ int center_y = height() / 2;
+
+ p.setColour(Colour(1, alpha));
+
+ 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.setColour(Colour(0.5, 0.5, 1, alpha));
+
+ p.drawCircle(center_x, center_y, radius);
+
+ double padval = val * 0.8 + 0.1;
+ 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, alpha));
+ p.drawLine(border_x * (radius / 2) + center_x,
+ border_y * (radius / 2) + center_y,
+ border_x * radius + center_x,
+ border_y * radius + center_y);
+}
+
+#ifdef TEST_KNOB
+//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_KNOB*/
diff --git a/plugingui/knob.h b/plugingui/knob.h
new file mode 100644
index 0000000..98ccf36
--- /dev/null
+++ b/plugingui/knob.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * knob.h
+ *
+ * Thu Feb 28 07:37:27 CET 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.
+ */
+#ifndef __DRUMGIZMO_KNOB_H__
+#define __DRUMGIZMO_KNOB_H__
+
+#include "widget.h"
+
+namespace GUI {
+
+class Knob : public Widget {
+public:
+ Knob(Widget *parent);
+
+ bool catchMouse() { return true; }
+
+ void setValue(float value);
+ float value();
+
+ void registerClickHandler(void (*handler)(void *), void *ptr);
+
+ //protected:
+ virtual void clicked() {}
+
+ virtual void repaintEvent(RepaintEvent *e);
+ virtual void buttonEvent(ButtonEvent *e);
+ virtual void mouseMoveEvent(MouseMoveEvent *e);
+
+private:
+ typedef enum {
+ up,
+ down
+ } state_t;
+
+ float val;
+ float maximum;
+ float minimum;
+
+ state_t state;
+
+ void (*handler)(void *);
+ void *ptr;
+
+ int mouse_offset_x;
+
+};
+
+};
+
+#endif/*__DRUMGIZMO_KNOB_H__*/
diff --git a/plugingui/lineedit.cc b/plugingui/lineedit.cc
index 033acd1..c799e32 100644
--- a/plugingui/lineedit.cc
+++ b/plugingui/lineedit.cc
@@ -43,6 +43,7 @@ GUI::LineEdit::LineEdit(Widget *parent)
void GUI::LineEdit::setText(std::string text)
{
_text = text;
+ repaintEvent(NULL);
textChanged();
}
diff --git a/plugingui/listbox.cc b/plugingui/listbox.cc
new file mode 100644
index 0000000..dfb5f07
--- /dev/null
+++ b/plugingui/listbox.cc
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * listbox.cc
+ *
+ * Mon Feb 25 21:21:41 CET 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 "listbox.h"
+
+#include "painter.h"
+#include "font.h"
+
+#include <stdio.h>
+
+GUI::ListBox::ListBox(GUI::Widget *parent)
+ : GUI::Widget(parent)
+{
+ padding = 4;
+ btn_size = 14;
+
+ scroll_offset = 0;
+ selected = "";
+
+ dblclk_handler = NULL;
+ ptr = NULL;
+}
+
+GUI::ListBox::~ListBox()
+{
+ // printf("ListBox destroy\n");
+}
+
+void GUI::ListBox::addItem(std::string name, std::string value)
+{
+ items[name] = value;
+ if(selected == "") selected = value;
+}
+
+void GUI::ListBox::clear()
+{
+ items.clear();
+ selected = "";
+ scroll_offset = 0;
+ repaintEvent(NULL);
+}
+
+bool GUI::ListBox::selectItem(std::string name)
+{
+ if(items.find(name) == items.end()) return false;
+ selected = items[name];
+ repaintEvent(NULL);
+ return true;
+}
+
+std::string GUI::ListBox::selectedName()
+{
+ return selected;
+}
+
+std::string GUI::ListBox::selectedValue()
+{
+ return items[selected];
+}
+
+void GUI::ListBox::registerDblClickHandler(void (*handler)(void *), void *ptr)
+{
+ this->dblclk_handler = handler;
+ this->ptr = ptr;
+}
+
+void GUI::ListBox::repaintEvent(GUI::RepaintEvent *e)
+{
+ GUI::Painter p(this);
+
+ p.setColour(Colour(0, 0.5));
+ p.drawFilledRectangle(0, 0, width() - 1, height() - 1);
+
+ p.setColour(Colour(0.5, 1));
+ p.drawRectangle(0, 0, width() - 1, height() - 1);
+
+ int yoffset = padding / 2;
+ int skip = scroll_offset;
+ std::map<std::string, std::string>::iterator i = items.begin();
+ while(i != items.end()) {
+ if(skip) {
+ skip--;
+ i++;
+ continue;
+ }
+ if(i->second == selected) {
+ p.setColour(Colour(1, 0.4));
+ p.drawFilledRectangle(1,
+ yoffset - (padding / 2),
+ width() - 1,
+ yoffset + (font.textHeight() + 1));
+ }
+
+ p.setColour(Colour(1, 1));
+ p.drawText(2, yoffset + font.textHeight(), font, i->first);
+ yoffset += font.textHeight() + padding;
+ i++;
+ }
+
+ p.drawRectangle(width() - btn_size, 0, width() - 1, btn_size);
+ p.drawRectangle(width() - btn_size, height() - btn_size,
+ width() - 1, height() - 1);
+}
+
+void GUI::ListBox::buttonEvent(ButtonEvent *e)
+{
+ //printf("click %d %d [dc: %d]\n", e->x, e->y, e->doubleclick);
+ if(e->direction == 1) {
+ if(e->x > (width() - btn_size) && e->y < (width() - 1)) {
+ if(e->y > 0 && e->y < btn_size) {
+ scroll_offset--;
+ if(scroll_offset < 0) scroll_offset = 0;
+ repaintEvent(NULL);
+ return;
+ }
+
+ if(e->y > (height() - btn_size) && e->y < (height() - 1)) {
+ scroll_offset++;
+ if(scroll_offset > (items.size() - 1))
+ scroll_offset = (items.size() - 1);
+ repaintEvent(NULL);
+ return;
+ }
+ }
+
+ int skip = scroll_offset;
+ size_t yoffset = padding / 2;
+ std::map<std::string, std::string>::iterator i = items.begin();
+ while(i != items.end()) {
+ if(skip) {
+ skip--;
+ i++;
+ continue;
+ }
+ yoffset += font.textHeight() + padding;
+ if(e->y < (int)yoffset - (padding / 2)) {
+ selected = i->second;
+ break;
+ }
+ i++;
+ }
+
+ repaintEvent(NULL);
+
+ if(e->doubleclick && dblclk_handler) dblclk_handler(ptr);
+ }
+}
diff --git a/plugingui/listbox.h b/plugingui/listbox.h
new file mode 100644
index 0000000..2a8dc4f
--- /dev/null
+++ b/plugingui/listbox.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * listbox.h
+ *
+ * Mon Feb 25 21:21:40 CET 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.
+ */
+#ifndef __DRUMGIZMO_LISTBOX_H__
+#define __DRUMGIZMO_LISTBOX_H__
+
+#include <string.h>
+#include <map>
+
+#include "widget.h"
+#include "font.h"
+
+namespace GUI {
+
+class ListBox : public Widget {
+public:
+ ListBox(Widget *parent);
+ ~ListBox();
+
+ bool isFocusable() { return true; }
+
+ void addItem(std::string name, std::string value);
+
+ void clear();
+ bool selectItem(std::string name);
+ std::string selectedName();
+ std::string selectedValue();
+
+ void registerDblClickHandler(void (*handler)(void *), void *ptr);
+
+ virtual void repaintEvent(RepaintEvent *e);
+ virtual void buttonEvent(ButtonEvent *e);
+
+private:
+ std::map<std::string, std::string> items;
+ std::string selected;
+ GUI::Font font;
+ int padding;
+ int btn_size;
+ int scroll_offset;
+
+ void (*dblclk_handler)(void *);
+ void *ptr;
+};
+
+};
+
+#endif/*__DRUMGIZMO_LISTBOX_H__*/
diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h
index 9225f28..848a761 100644
--- a/plugingui/nativewindow.h
+++ b/plugingui/nativewindow.h
@@ -45,6 +45,7 @@ public:
virtual void hide() = 0;
virtual void handleBuffer() = 0;
virtual void redraw() = 0;
+ virtual void grabMouse(bool grab) = 0;
protected:
GlobalContext *gctx;
diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc
index a98ef4c..b1e22c5 100644
--- a/plugingui/nativewindow_win32.cc
+++ b/plugingui/nativewindow_win32.cc
@@ -52,7 +52,7 @@ GUI::NativeWindowWin32::NativeWindowWin32(GlobalContext *gctx,
// object - we need this in the wndproc handler.
wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = 0;//class_style;
+ wcex.style = CS_DBLCLKS;//class_style;
wcex.lpfnWndProc = (WNDPROC)dialogProc;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
// Set data:
@@ -131,4 +131,10 @@ void GUI::NativeWindowWin32::setCaption(const std::string &caption)
{
}
+void GUI::NativeWindowWin32::grabMouse(bool grab)
+{
+ if(grab) SetCapture(gctx->m_hwnd);
+ else ReleaseCapture();
+}
+
#endif/*WIN32*/
diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h
index 6039439..cceff2f 100644
--- a/plugingui/nativewindow_win32.h
+++ b/plugingui/nativewindow_win32.h
@@ -46,6 +46,7 @@ public:
void hide();
void handleBuffer();
void redraw();
+ void grabMouse(bool grab);
private:
GUI::Window *window;
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index 91d7ed6..c7605ef 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -229,5 +229,11 @@ void GUI::NativeWindowX11::setCaption(const std::string &caption)
{
}
+void GUI::NativeWindowX11::grabMouse(bool grab)
+{
+ (void)grab;
+ // Don't need to do anything on this platoform...
+}
+
#endif/*X11*/
diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h
index 2e51861..0cd11da 100644
--- a/plugingui/nativewindow_x11.h
+++ b/plugingui/nativewindow_x11.h
@@ -48,6 +48,7 @@ public:
void hide();
void handleBuffer();
void redraw();
+ void grabMouse(bool grab);
private:
::Window xwindow;
diff --git a/plugingui/painter.cc b/plugingui/painter.cc
index 025363c..b74952f 100644
--- a/plugingui/painter.cc
+++ b/plugingui/painter.cc
@@ -49,6 +49,107 @@ void GUI::Painter::setColour(Colour colour)
this->colour = colour;
}
+void GUI::Painter::plot(int x, int y, double c)
+{
+ // plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1)
+
+ //c += 0.5;
+ //if(c > 1) c = 1;
+
+ pixbuf->addPixel(x, y,
+ (unsigned char)(colour.red * 255.0),
+ (unsigned char)(colour.green * 255.0),
+ (unsigned char)(colour.blue * 255.0),
+ (unsigned char)(colour.alpha * 255 * c));
+
+}
+
+#include <math.h>
+double GUI::Painter::ipart(double x)
+{
+ return floor(x); //integer part of x'
+}
+
+double GUI::Painter::round(double x)
+{
+ return ipart(x + 0.5);
+}
+
+double GUI::Painter::fpart(double x)
+{
+ return x - ipart(x);//'fractional part of x'
+}
+
+double GUI::Painter::rfpart(double x)
+{
+ return 1 - fpart(x);
+}
+
+
+#define SWAP(x, y) { int tmp = x; x = y; y = tmp; }
+void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
+{
+ bool steep = abs(y1 - y0) > abs(x1 - x0);
+
+ if(steep) {
+ SWAP(x0, y0);
+ SWAP(x1, y1);
+ }
+ if(x0 > x1) {
+ SWAP(x0, x1);
+ SWAP(y0, y1);
+ }
+
+ double dx = x1 - x0;
+ double dy = y1 - y0;
+ double gradient = dy / dx;
+
+ // handle first endpoint
+ double xend = round(x0);
+ double yend = y0 + gradient * (xend - x0);
+ double xgap = rfpart(x0 + 0.5);
+ double xpxl1 = xend; //this will be used in the main loop
+ double ypxl1 = ipart(yend);
+ if(steep) {
+ plot(ypxl1, xpxl1, rfpart(yend) * xgap);
+ plot(ypxl1+1, xpxl1, fpart(yend) * xgap);
+ } else {
+ plot(xpxl1, ypxl1 , rfpart(yend) * xgap);
+ plot(xpxl1, ypxl1+1, fpart(yend) * xgap);
+ }
+ double intery = yend + gradient; // first y-intersection for the main loop
+
+ // handle second endpoint
+
+ xend = round(x1);
+ yend = y1 + gradient * (xend - x1);
+ xgap = fpart(x1 + 0.5);
+ double xpxl2 = xend; //this will be used in the main loop
+ double ypxl2 = ipart(yend);
+ if(steep) {
+ plot(ypxl2 , xpxl2, rfpart(yend) * xgap);
+ plot(ypxl2+1, xpxl2, fpart(yend) * xgap);
+ } else {
+ plot(xpxl2, ypxl2, rfpart(yend) * xgap);
+ plot(xpxl2, ypxl2+1, fpart(yend) * xgap);
+ }
+
+ // main loop
+ for(int x = xpxl1 + 1; x <= xpxl2 - 1; x++) {
+ if(steep) {
+ plot(ipart(intery) , x, rfpart(intery));
+ plot(ipart(intery)+1, x, fpart(intery));
+ } else {
+ plot(x, ipart (intery), rfpart(intery));
+ plot(x, ipart (intery)+1, fpart(intery));
+ }
+ intery += gradient;
+ }
+}
+/////////////////////////////////////////////
+
+/*
+// No antialiasing
void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
{
int dx = abs(x1 - x0);
@@ -78,6 +179,7 @@ void GUI::Painter::drawLine(int x0, int y0, int x1, int y1)
}
}
}
+*/
void GUI::Painter::drawRectangle(int x1, int y1, int x2, int y2)
{
@@ -123,6 +225,80 @@ void GUI::Painter::drawPoint(int x, int y)
(unsigned char)(colour.alpha * 255.0));
}
+#if 0
+static double distance(double r, double y)
+{
+ double real_point = sqrt(pow(r, 2) - pow(y, 2));
+ return ceil(real_point) - real_point;
+}
+
+double new_color(double i) {
+ return i * 127;
+}
+
+void GUI::Painter::drawCircle(int cx, int cy, double radius)
+{
+ // wu_circle($image, $r, $color, $offset_x = null, $offset_y = null) {
+ //$red = $color["red"];
+ //$green = $color["green"];
+ //$blue = $color["blue"];
+ int offset_x = cx;
+ int offset_y = cy;
+ int x = radius;
+ // int xx = radius;
+ int y = -1;
+ // int yy = -1;
+ double t = 0;
+ //$color = imagecolorallocate($image, $red, $green, $blue);
+ while(x > y) {
+ y++;
+ double current_distance = distance(radius, y);
+ if(current_distance < t) {
+ x--;
+ }
+
+ double trasparency = new_color(current_distance);
+ double alpha = trasparency;
+ double alpha2 = 127.0 - trasparency;
+
+ double color = 1;
+
+ plot(x + offset_x, y + offset_y, color);
+ plot(x + offset_x - 1, y + offset_y, alpha2 );
+ plot(x + offset_x + 1, y + offset_y, alpha );
+
+ plot(y + offset_x, x + offset_y, color);
+ plot(y + offset_x, x + offset_y - 1, alpha2);
+ plot(y + offset_x, x + offset_y + 1, alpha);
+
+ plot(offset_x - x , y + offset_y, color);
+ plot(offset_x - x + 1, y + offset_y, alpha2);
+ plot(offset_x - x - 1, y + offset_y, alpha);
+
+ plot(offset_x - y, x + offset_y, color);
+ plot(offset_x - y, x + offset_y - 1, alpha2);
+ plot(offset_x - y, x + offset_y + 1, alpha);
+
+ plot(x + offset_x, offset_y - y, color);
+ plot(x + offset_x - 1, offset_y - y, alpha2);
+ plot(x + offset_x + 1, offset_y - y, alpha);
+
+ plot(y + offset_x, offset_y - x, color);
+ plot(y + offset_x, offset_y - x - 1, alpha);
+ plot(y + offset_x, offset_y - x + 1, alpha2);
+
+ plot(offset_x - y, offset_y - x, color);
+ plot(offset_x - y, offset_y - x - 1, alpha);
+ plot(offset_x - y, offset_y - x + 1, alpha2);
+
+ plot(offset_x - x, offset_y - y, color);
+ plot(offset_x - x - 1, offset_y - y, alpha);
+ plot(offset_x - x + 1, offset_y - y, alpha2);
+
+ t = current_distance;
+ }
+}
+#else
static void plot4points(GUI::Painter *p, int cx, int cy, int x, int y)
{
p->drawPoint(cx + x, cy + y);
@@ -131,7 +307,7 @@ static void plot4points(GUI::Painter *p, int cx, int cy, int x, int y)
if(x != 0 && y != 0) p->drawPoint(cx - x, cy - y);
}
-void GUI::Painter::drawCircle(int cx, int cy, int radius)
+void GUI::Painter::drawCircle(int cx, int cy, double radius)
{
int error = -radius;
int x = radius;
@@ -152,6 +328,7 @@ void GUI::Painter::drawCircle(int cx, int cy, int radius)
}
}
}
+#endif
static void plot4lines(GUI::Painter *p, int cx, int cy, int x, int y)
{
diff --git a/plugingui/painter.h b/plugingui/painter.h
index c9fd60d..b45cf3a 100644
--- a/plugingui/painter.h
+++ b/plugingui/painter.h
@@ -64,11 +64,17 @@ public:
void drawRectangle(int x1, int y1, int x2, int y2);
void drawFilledRectangle(int x1, int y1, int x2, int y2);
void drawPoint(int x, int y);
- void drawCircle(int x, int y, int r);
+ void drawCircle(int x, int y, double r);
void drawFilledCircle(int x, int y, int r);
void drawImage(int x, int y, struct __img__ * img);
private:
+ void plot(int x, int y, double c);
+ double ipart(double x);
+ double round(double x);
+ double fpart(double x);
+ double rfpart(double x);
+
Widget *widget;
PixelBufferAlpha *pixbuf;
Colour colour;
diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc
index fb4d05f..e9e376a 100644
--- a/plugingui/pixelbuffer.cc
+++ b/plugingui/pixelbuffer.cc
@@ -62,7 +62,7 @@ GUI::PixelBufferAlpha::PixelBufferAlpha(size_t width, size_t height)
{
this->idx = ::idx++;
buf = NULL;
- x = y = 0;
+ x = y = 10;
realloc(width, height);
}
@@ -84,12 +84,39 @@ void GUI::PixelBufferAlpha::setPixel(size_t x, size_t y,
{
// printf("%d %d %d %d\n", red, green, blue, alpha);
if(x >= width || y >= height) return;
+ /*
+ float a = alpha / 255.0;
+ buf[PX(0)] = (unsigned char)(red * a + buf[PX(0)] * (1-a));
+ buf[PX(1)] = (unsigned char)(green * a + buf[PX(1)] * (1-a));
+ buf[PX(2)] = (unsigned char)(blue * a + buf[PX(2)] * (1-a));
+ buf[PX(3)] = (unsigned char)(alpha * a + buf[PX(3)] * (1-a));
+ */
buf[PX(0)] = red;
buf[PX(1)] = green;
buf[PX(2)] = blue;
buf[PX(3)] = alpha;
}
+void GUI::PixelBufferAlpha::addPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha)
+{
+ // printf("%d %d %d %d\n", red, green, blue, alpha);
+ if(x >= width || y >= height) return;
+
+ if(alpha == 0) return;
+
+ float a = (float)alpha / (float)(alpha + buf[PX(3)]);
+ buf[PX(0)] = (unsigned char)(red * a + buf[PX(0)] * (1-a));
+ buf[PX(1)] = (unsigned char)(green * a + buf[PX(1)] * (1-a));
+ buf[PX(2)] = (unsigned char)(blue * a + buf[PX(2)] * (1-a));
+
+ //buf[PX(3)] = (unsigned char)(alpha * a + buf[PX(3)] * (1-a));
+ buf[PX(3)] = alpha>buf[PX(3)]?alpha:buf[PX(3)];
+}
+
void GUI::PixelBufferAlpha::pixel(size_t x, size_t y,
unsigned char *red,
unsigned char *green,
diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h
index 29cda7f..21a6ceb 100644
--- a/plugingui/pixelbuffer.h
+++ b/plugingui/pixelbuffer.h
@@ -63,6 +63,12 @@ public:
unsigned char blue,
unsigned char alpha);
+ void addPixel(size_t x, size_t y,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha);
+
void pixel(size_t x, size_t y,
unsigned char *red,
unsigned char *green,
diff --git a/plugingui/plugingui.cc b/plugingui/plugingui.cc
index 09045ab..2aded27 100644
--- a/plugingui/plugingui.cc
+++ b/plugingui/plugingui.cc
@@ -30,6 +30,7 @@
#include <stdio.h>
#include "globalcontext.h"
+#include "knob.h"
#ifndef STANDALONE
#include <drumgizmo.h>
@@ -56,16 +57,40 @@ void checkClick(void *ptr)
Conf::enable_velocity_modifier = gui->check->checked();
}
-void sliderChange(void *ptr)
+void knobChange(void *ptr)
{
PluginGUI *gui = (PluginGUI*)ptr;
- Conf::velocity_modifier_weight = gui->slider->value();
+ Conf::velocity_modifier_weight = gui->knob->value();
}
-void sliderChange2(void *ptr)
+void knobChange2(void *ptr)
{
PluginGUI *gui = (PluginGUI*)ptr;
- Conf::velocity_modifier_falloff = gui->slider2->value();
+ Conf::velocity_modifier_falloff = gui->knob2->value();
+}
+
+GUI::FileBrowser *fb;
+void selectFile(void *ptr, std::string filename)
+{
+ GUI::LineEdit *le = (GUI::LineEdit *)ptr;
+ le->setText(filename);
+ fb->hide();
+}
+
+void kitBrowseClick(void *ptr)
+{
+ PluginGUI *gui = (PluginGUI*)ptr;
+
+ fb->registerFileSelectHandler(selectFile, gui->lineedit);
+ fb->show();
+}
+
+void midimapBrowseClick(void *ptr)
+{
+ PluginGUI *gui = (PluginGUI*)ptr;
+
+ fb->registerFileSelectHandler(selectFile, gui->lineedit2);
+ fb->show();
}
void loadKitClick(void *ptr)
@@ -152,66 +177,108 @@ void PluginGUI::init()
window = new GUI::Window(gctx);
window->resize(640, 200);
+ // Enable Velocity
+ GUI::Label *lbl_enable = new GUI::Label(window);
+ lbl_enable->setText("Enable Velocity Modifier");
+ lbl_enable->move(97, 81);
+ lbl_enable->resize(100, 20);
+
check = new GUI::CheckBox(window);
check->move(82,82);
check->resize(16,16);
check->setChecked(Conf::enable_velocity_modifier);
check->registerClickHandler(checkClick, this);
- slider = new GUI::Slider(window);
- slider->move(100,80);
- slider->resize(390, 20);
- slider->setValue(Conf::velocity_modifier_weight);
- slider->registerClickHandler(sliderChange, this);
-
- slider2 = new GUI::Slider(window);
- slider2->move(100,110);
- slider2->resize(390, 20);
- slider2->setValue(Conf::velocity_modifier_falloff);
- slider2->registerClickHandler(sliderChange2, this);
-
- lbl = new GUI::Label(window);
- lbl->setText("Drumkit:");
- lbl->move(10, 10);
- lbl->resize(70, 20);
-
- led = new GUI::LED(window);
- led->move(500,12);
- led->resize(16, 16);
- // led->setState(false);
-
- lineedit = new FileLineEdit(window, led);
- if(drumgizmo) lineedit->setText(drumgizmo->drumkitfile());
- else lineedit->setText("Missing DrumGizmo*");
- lineedit->move(80, 10);
- lineedit->resize(410, 20);
-
- btn_ok = new GUI::Button(window);
- btn_ok->setText("Load Kit");
- btn_ok->move(520, 10);
- btn_ok->resize(100, 20);
- btn_ok->registerClickHandler(loadKitClick, this);
-
- lbl2 = new GUI::Label(window);
- lbl2->setText("Midimap:");
- lbl2->move(10, 45);
- lbl2->resize(70, 20);
-
- led2 = new GUI::LED(window);
- led2->move(500,47);
- led2->resize(16, 16);
- // led2->setState(false);
-
- lineedit2 = new FileLineEdit(window, led2);
- if(drumgizmo) lineedit2->setText(drumgizmo->midimapfile);
- lineedit2->move(80, 45);
- lineedit2->resize(410, 20);
-
- btn_ok2 = new GUI::Button(window);
- btn_ok2->setText("Load Map");
- btn_ok2->move(520, 45);
- btn_ok2->resize(100, 20);
- btn_ok2->registerClickHandler(loadMidimapClick, this);
+ // Velocity Weight Modifier:
+ {
+ int xpos = 180;
+ GUI::Label *lbl_weight = new GUI::Label(window);
+ lbl_weight->setText("Weight Modifier");
+ lbl_weight->move(xpos, 138);
+ lbl_weight->resize(100, 20);
+
+ knob = new GUI::Knob(window);
+ knob->move(xpos + 30, 100);
+ knob->resize(41, 41);
+ knob->setValue(Conf::velocity_modifier_weight);
+ knob->registerClickHandler(knobChange, this);
+ }
+
+ // Velocity Falloff Modifier:
+ {
+ int xpos = 300;
+ GUI::Label *lbl_falloff = new GUI::Label(window);
+ lbl_falloff->setText("Falloff Modifier");
+ lbl_falloff->move(xpos, 138);
+ lbl_falloff->resize(100, 20);
+
+ knob2 = new GUI::Knob(window);
+ knob2->move(xpos + 30, 100);
+ knob2->resize(41, 41);
+ knob2->setValue(Conf::velocity_modifier_falloff);
+ knob2->registerClickHandler(knobChange2, this);
+ }
+
+ // Drumkit file
+ {
+ GUI::Label *lbl = new GUI::Label(window);
+ lbl->setText("Drumkit:");
+ lbl->move(10, 10);
+ lbl->resize(70, 20);
+
+ led = new GUI::LED(window);
+ led->move(500,12);
+ led->resize(16, 16);
+ // led->setState(false);
+
+ lineedit = new FileLineEdit(window, led);
+ if(drumgizmo) lineedit->setText(drumgizmo->drumkitfile());
+ else lineedit->setText("Missing DrumGizmo*");
+ lineedit->move(70, 10);
+ lineedit->resize(408, 20);
+
+ GUI::Button *btn_brw = new GUI::Button(window);
+ btn_brw->setText("...");
+ btn_brw->move(480, 10);
+ btn_brw->resize(20, 20);
+ btn_brw->registerClickHandler(kitBrowseClick, this);
+
+ btn_ok = new GUI::Button(window);
+ btn_ok->setText("Load Kit");
+ btn_ok->move(520, 10);
+ btn_ok->resize(100, 20);
+ btn_ok->registerClickHandler(loadKitClick, this);
+ }
+
+ // Midimap file
+ {
+ lbl2 = new GUI::Label(window);
+ lbl2->setText("Midimap:");
+ lbl2->move(10, 45);
+ lbl2->resize(70, 20);
+
+ led2 = new GUI::LED(window);
+ led2->move(500,47);
+ led2->resize(16, 16);
+ // led2->setState(false);
+
+ lineedit2 = new FileLineEdit(window, led2);
+ if(drumgizmo) lineedit2->setText(drumgizmo->midimapfile);
+ lineedit2->move(70, 45);
+ lineedit2->resize(408, 20);
+
+ GUI::Button *btn_brw = new GUI::Button(window);
+ btn_brw->setText("...");
+ btn_brw->move(480, 45);
+ btn_brw->resize(20, 20);
+ btn_brw->registerClickHandler(midimapBrowseClick, this);
+
+ btn_ok2 = new GUI::Button(window);
+ btn_ok2->setText("Load Map");
+ btn_ok2->move(520, 45);
+ btn_ok2->resize(100, 20);
+ btn_ok2->registerClickHandler(loadMidimapClick, this);
+ }
btn_cancel = new GUI::Button(window);
btn_cancel->setText("Close");
@@ -224,6 +291,13 @@ void PluginGUI::init()
lbl3->move(120, 180);
lbl3->resize(70, 20);
+ // Create filebrowser
+ filebrowser = new GUI::FileBrowser(window);
+ filebrowser->move(0, 0);
+ filebrowser->resize(window->width() - 1, window->height() - 1);
+ filebrowser->hide();
+ fb = filebrowser;
+
window->show();
}
@@ -279,6 +353,7 @@ void stop(void *ptr)
int main()
{
+/*
hug_status_t status = hug_init(HUG_FLAG_OUTPUT_TO_SYSLOG,
HUG_OPTION_SYSLOG_HOST, "192.168.0.10",
HUG_OPTION_SYSLOG_PORT, 514,
@@ -288,7 +363,7 @@ int main()
printf("Error: %d\n", status);
return 1;
}
-
+*/
INFO(example, "We are up and running");
bool running = true;
diff --git a/plugingui/plugingui.h b/plugingui/plugingui.h
index 086a8d5..d6ddde3 100644
--- a/plugingui/plugingui.h
+++ b/plugingui/plugingui.h
@@ -35,7 +35,9 @@
#include "filelineedit.h"
#include "checkbox.h"
#include "button.h"
-#include "slider.h"
+#include "knob.h"
+
+#include "filebrowser.h"
#include "thread.h"
@@ -63,11 +65,13 @@ public:
GUI::Window *window;
GUI::EventHandler *eventhandler;
+ GUI::FileBrowser *filebrowser;
+
DrumGizmo *drumgizmo;
GUI::CheckBox *check;
- GUI::Slider *slider;
- GUI::Slider *slider2;
+ GUI::Knob *knob;
+ GUI::Knob *knob2;
GUI::Button *btn_ok;
GUI::Button *btn_ok2;
diff --git a/plugingui/slider.cc b/plugingui/slider.cc
index b58bde9..953c8e6 100644
--- a/plugingui/slider.cc
+++ b/plugingui/slider.cc
@@ -66,6 +66,10 @@ void GUI::Slider::mouseMoveEvent(MouseMoveEvent *e)
{
if(state == down) {
val = maximum / (float)width() * (float)e->x;
+
+ if(val < 0) val = 0;
+ if(val > 1) val = 1;
+
if(handler) handler(ptr);
repaintEvent(NULL);
}
@@ -76,12 +80,20 @@ void GUI::Slider::buttonEvent(ButtonEvent *e)
if(e->direction == 1) {
state = down;
val = maximum / (float)width() * (float)e->x;
+
+ if(val < 0) val = 0;
+ if(val > 1) val = 1;
+
if(handler) handler(ptr);
repaintEvent(NULL);
}
if(e->direction == -1) {
state = up;
val = maximum / (float)width() * (float)e->x;
+
+ if(val < 0) val = 0;
+ if(val > 1) val = 1;
+
repaintEvent(NULL);
clicked();
if(handler) handler(ptr);
@@ -90,7 +102,7 @@ void GUI::Slider::buttonEvent(ButtonEvent *e)
void GUI::Slider::repaintEvent(GUI::RepaintEvent *e)
{
- DEBUG(slider, "Slider::repaintEvent (%f)\n", val);
+ //DEBUG(slider, "Slider::repaintEvent (%f)\n", val);
Painter p(this);
diff --git a/plugingui/widget.cc b/plugingui/widget.cc
index 4b09732..eb7b0b6 100644
--- a/plugingui/widget.cc
+++ b/plugingui/widget.cc
@@ -27,9 +27,7 @@
#include "widget.h"
#include "globalcontext.h"
-
#include "painter.h"
-
#include "window.h"
#include <stdio.h>
@@ -37,24 +35,41 @@
GUI::Widget::Widget(Widget *parent)
: pixbuf(1, 1)
{
+ _width = _height = 10;
+
this->parent = parent;
if(parent) {
parent->addChild(this);
_window = parent->window();
}
_width = _height = 0;
+ _visible = true;
}
GUI::Widget::~Widget()
{
+ if(parent) parent->removeChild(this);
}
void GUI::Widget::show()
{
+ setVisible(true);
}
void GUI::Widget::hide()
{
+ setVisible(false);
+}
+
+void GUI::Widget::setVisible(bool v)
+{
+ _visible = v;
+ repaintEvent(NULL);
+}
+
+bool GUI::Widget::visible()
+{
+ return _visible;
}
void GUI::Widget::addChild(GUI::Widget *widget)
@@ -62,6 +77,18 @@ void GUI::Widget::addChild(GUI::Widget *widget)
children.push_back(widget);
}
+void GUI::Widget::removeChild(GUI::Widget *widget)
+{
+ std::vector<Widget *>::iterator i = children.begin();
+ while(i != children.end()) {
+ if(*i == widget) {
+ children.erase(i);
+ return;
+ }
+ i++;
+ }
+}
+
void GUI::Widget::resize(size_t width, size_t height)
{
_width = width;
@@ -73,8 +100,16 @@ void GUI::Widget::move(size_t x, size_t y)
{
_x = x;
_y = y;
- pixbuf.x = x;
- pixbuf.y = y;
+ /*
+ Widget *p = parent;
+ while(p) {
+ x += p->pixbuf.x;
+ y += p->pixbuf.y;
+ p = p->parent;
+ }
+ */
+ // pixbuf.x = x;
+ // pixbuf.y = y;
}
size_t GUI::Widget::x() { return _x; }
@@ -82,14 +117,30 @@ size_t GUI::Widget::y() { return _y; }
size_t GUI::Widget::width() { return _width; }
size_t GUI::Widget::height() { return _height; }
+size_t GUI::Widget::windowX()
+{
+ size_t window_x = x();
+ if(parent) window_x += parent->windowX();
+ return window_x;
+}
+
+size_t GUI::Widget::windowY()
+{
+ size_t window_y = y();
+ if(parent) window_y += parent->windowY();
+ return window_y;
+}
+
GUI::Widget *GUI::Widget::find(size_t x, size_t y)
{
- std::vector<Widget*>::iterator i = children.begin();
- while(i != children.end()) {
+ std::vector<Widget*>::reverse_iterator i = children.rbegin();
+ while(i != children.rend()) {
Widget *w = *i;
- if(w->x() <= x && (w->x() + w->width()) >= x &&
- w->y() <= y && w->y() + w->height() >= y)
- return w->find(x - w->x(), y - w->y());
+ if(w->visible()) {
+ if(w->x() <= x && (w->x() + w->width()) >= x &&
+ w->y() <= y && w->y() + w->height() >= y)
+ return w->find(x - w->x(), y - w->y());
+ }
i++;
}
@@ -104,8 +155,10 @@ GUI::Window *GUI::Widget::window()
void GUI::Widget::repaint_r(GUI::RepaintEvent *e)
{
- Painter p(this);
+ Painter p(this); // make sure pixbuf refcount is incremented.
+
repaintEvent(e);
+
std::vector<Widget*>::iterator i = children.begin();
while(i != children.end()) {
Widget *w = *i;
@@ -118,13 +171,18 @@ std::vector<GUI::PixelBufferAlpha *> GUI::Widget::getPixelBuffers()
{
std::vector<PixelBufferAlpha *> pbs;
+ pixbuf.x = windowX();
+ pixbuf.y = windowY();
+
pbs.push_back(&pixbuf);
std::vector<Widget*>::iterator i = children.begin();
while(i != children.end()) {
Widget *w = *i;
- std::vector<PixelBufferAlpha *> pbs0 = w->getPixelBuffers();
- pbs.insert(pbs.end(), pbs0.begin(), pbs0.end());
+ if(w->visible()) {
+ std::vector<PixelBufferAlpha *> pbs0 = w->getPixelBuffers();
+ pbs.insert(pbs.end(), pbs0.begin(), pbs0.end());
+ }
i++;
}
diff --git a/plugingui/widget.h b/plugingui/widget.h
index 6f09533..c0d0a73 100644
--- a/plugingui/widget.h
+++ b/plugingui/widget.h
@@ -27,10 +27,9 @@
#ifndef __DRUMGIZMO_WIDGET_H__
#define __DRUMGIZMO_WIDGET_H__
-#include <vector>
-
#include "guievent.h"
#include "pixelbuffer.h"
+
#include <vector>
namespace GUI {
@@ -50,6 +49,8 @@ public:
virtual size_t x();
virtual size_t y();
+ virtual size_t windowX();
+ virtual size_t windowY();
virtual size_t width();
virtual size_t height();
@@ -57,6 +58,7 @@ public:
virtual bool catchMouse() { return false; }
void addChild(Widget *widget);
+ void removeChild(Widget *widget);
virtual void repaintEvent(RepaintEvent *e) {}
virtual void mouseMoveEvent(MouseMoveEvent *e) {}
@@ -74,11 +76,18 @@ public:
bool hasKeyboardFocus();
+ Widget *parent;
+
+ bool visible();
+ void setVisible(bool visible);
+
protected:
std::vector<Widget*> children;
- Widget *parent;
Window *_window;
size_t _x, _y, _width, _height;
+
+private:
+ bool _visible;
};
};
diff --git a/plugingui/window.cc b/plugingui/window.cc
index bbeffa1..1795d62 100644
--- a/plugingui/window.cc
+++ b/plugingui/window.cc
@@ -104,6 +104,8 @@ size_t GUI::Window::x() { return _x; }
size_t GUI::Window::y() { return _y; }
size_t GUI::Window::width() { return _width; }
size_t GUI::Window::height() { return _height; }
+size_t GUI::Window::windowX() { return 0; }
+size_t GUI::Window::windowY() { return 0; }
void GUI::Window::show()
{
@@ -200,5 +202,6 @@ GUI::Widget *GUI::Window::buttonDownFocus()
void GUI::Window::setButtonDownFocus(GUI::Widget *widget)
{
_buttonDownFocus = widget;
+ native->grabMouse(widget != NULL);
// repaint_r(NULL);
}
diff --git a/plugingui/window.h b/plugingui/window.h
index 8e61603..0820b40 100644
--- a/plugingui/window.h
+++ b/plugingui/window.h
@@ -49,6 +49,8 @@ public:
size_t x();
size_t y();
+ size_t windowX();
+ size_t windowY();
size_t width();
size_t height();