summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-03-09 19:34:07 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2013-03-09 19:34:07 +0100
commit1fe04afd8dd8addcc8902ea3c1c0f77d148cd1b7 (patch)
treea5d6804482f18d03e8d8d6bcebb3a4cd0e032850
parente03c36f2435c7b14b974d96d2081e608040a5f66 (diff)
Fix keyboard navigation logic in listbox.
-rw-r--r--plugingui/listbox.cc137
-rw-r--r--plugingui/listbox.h13
2 files changed, 78 insertions, 72 deletions
diff --git a/plugingui/listbox.cc b/plugingui/listbox.cc
index 3dec8bc..e8d6b0e 100644
--- a/plugingui/listbox.cc
+++ b/plugingui/listbox.cc
@@ -38,7 +38,7 @@ GUI::ListBox::ListBox(GUI::Widget *parent)
btn_size = 14;
scroll_offset = 0;
- selected = "";
+ selected = -1;
dblclk_handler = NULL;
ptr = NULL;
@@ -46,39 +46,60 @@ GUI::ListBox::ListBox(GUI::Widget *parent)
GUI::ListBox::~ListBox()
{
- // printf("ListBox destroy\n");
}
void GUI::ListBox::addItem(std::string name, std::string value)
{
- items[name] = value;
- if(selected == "") selected = 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) selected = y;
+ else if(selected == y) selected = x;
+
+ struct item tmp = items[x];
+ items[x] = items[y];
+ items[y] = tmp;
+ }
+ }
+ }
+
+ if(selected == -1) selected = items.size() - 1;
}
void GUI::ListBox::clear()
{
items.clear();
- selected = "";
+ selected = -1;
scroll_offset = 0;
repaintEvent(NULL);
}
-bool GUI::ListBox::selectItem(std::string name)
+bool GUI::ListBox::selectItem(int index)
{
- if(items.find(name) == items.end()) return false;
- selected = items[name];
+ if(index < 0 || index > (int)items.size() - 1) return false;
+ selected = index;
repaintEvent(NULL);
return true;
}
std::string GUI::ListBox::selectedName()
{
- return selected;
+ if(selected < 0 || selected > (int)items.size() - 1) return "";
+ return items[selected].name;
}
std::string GUI::ListBox::selectedValue()
{
- return items[selected];
+ if(selected < 0 || selected > (int)items.size() - 1) return "";
+ return items[selected].value;
}
void GUI::ListBox::registerDblClickHandler(void (*handler)(void *), void *ptr)
@@ -99,14 +120,9 @@ void GUI::ListBox::repaintEvent(GUI::RepaintEvent *e)
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) {
+ for(int idx = skip; idx < (int)items.size(); idx++) {
+ struct item *i = &items[idx];
+ if(idx == selected) {
p.setColour(Colour(1, 0.4));
p.drawFilledRectangle(1,
yoffset - (padding / 2),
@@ -115,9 +131,8 @@ void GUI::ListBox::repaintEvent(GUI::RepaintEvent *e)
}
p.setColour(Colour(1, 1));
- p.drawText(2, yoffset + font.textHeight(), font, i->first);
+ p.drawText(2, yoffset + font.textHeight(), font, i->name);
yoffset += font.textHeight() + padding;
- i++;
}
p.drawRectangle(width() - btn_size, 0, width() - 1, btn_size);
@@ -136,52 +151,45 @@ void GUI::ListBox::scrollEvent(ScrollEvent *e)
void GUI::ListBox::keyEvent(GUI::KeyEvent *e)
{
- // printf("!\n");
-
- if(e->direction == -1) {
- switch(e->keycode) {
- case GUI::KeyEvent::KEY_UP:
- {
- std::map<std::string, std::string>::reverse_iterator i = items.rbegin();
- while(i != items.rend()) {
- if(i->second == selected) break;
- i++;
- }
- i++;
- scroll_offset--;
+ 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;
- selected = i->second;
}
- break;
- case GUI::KeyEvent::KEY_DOWN:
- {
- std::map<std::string, std::string>::iterator i = items.begin();
- while(i != items.end()) {
- if(i->second == selected) break;
- i++;
- }
- i++;
- scroll_offset++;
+ }
+ 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);
- selected = i->second;
}
- break;
- case GUI::KeyEvent::KEY_HOME:
- selected = items.begin()->second;
- break;
- case GUI::KeyEvent::KEY_END:
- selected = items.rbegin()->second;
- break;
- default:
- break;
}
-
- // printf("sel: %s\n", selected.c_str());
-
- repaintEvent(NULL);
+ 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::ListBox::buttonEvent(ButtonEvent *e)
@@ -206,19 +214,12 @@ void GUI::ListBox::buttonEvent(ButtonEvent *e)
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;
- }
+ for(int idx = skip; idx < (int)items.size() - 1; idx++) {
yoffset += font.textHeight() + padding;
if(e->y < (int)yoffset - (padding / 2)) {
- selected = i->second;
+ selected = idx;
break;
}
- i++;
}
repaintEvent(NULL);
diff --git a/plugingui/listbox.h b/plugingui/listbox.h
index 26d104b..d7a5021 100644
--- a/plugingui/listbox.h
+++ b/plugingui/listbox.h
@@ -28,7 +28,7 @@
#define __DRUMGIZMO_LISTBOX_H__
#include <string.h>
-#include <map>
+#include <vector>
#include "widget.h"
#include "font.h"
@@ -45,7 +45,7 @@ public:
void addItem(std::string name, std::string value);
void clear();
- bool selectItem(std::string name);
+ bool selectItem(int index);
std::string selectedName();
std::string selectedValue();
@@ -57,8 +57,13 @@ public:
virtual void keyEvent(KeyEvent *e);
private:
- std::map<std::string, std::string> items;
- std::string selected;
+ struct item {
+ std::string name;
+ std::string value;
+ };
+
+ std::vector<struct item> items;
+ int selected;
GUI::Font font;
int padding;
int btn_size;