diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-09-21 15:25:01 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-09-27 14:59:31 -0500 |
commit | 9cc40aafa0dd06f1449c81fcbccd4a5eb971115d (patch) | |
tree | 8ecc30156d63ff12289383f9f951879fde167870 /libs/surfaces/push2/menu.cc | |
parent | 0610e1dc8d5fd2a8edb912df2ef82c3f64083fb3 (diff) |
push2: menu presentation now working
Diffstat (limited to 'libs/surfaces/push2/menu.cc')
-rw-r--r-- | libs/surfaces/push2/menu.cc | 281 |
1 files changed, 173 insertions, 108 deletions
diff --git a/libs/surfaces/push2/menu.cc b/libs/surfaces/push2/menu.cc index da1c98ac04..a31e485e18 100644 --- a/libs/surfaces/push2/menu.cc +++ b/libs/surfaces/push2/menu.cc @@ -39,188 +39,253 @@ using namespace ArdourCanvas; #include "pbd/i18n.h" #include "menu.h" -Push2Menu::Push2Menu (Item* parent) +Push2Menu::Push2Menu (Item* parent, vector<string> s) : Container (parent) , baseline (-1) + , ncols (0) + , nrows (0) + , wrap (true) + , first (0) + , last (0) + , _active (UINT32_MAX) { - Pango::FontDescription fd2 ("Sans 10"); + Pango::FontDescription fd ("Sans 10"); if (baseline < 0) { Push2Canvas* p2c = dynamic_cast<Push2Canvas*> (canvas()); Glib::RefPtr<Pango::Layout> throwaway = Pango::Layout::create (p2c->image_context()); - throwaway->set_font_description (fd2); + throwaway->set_font_description (fd); throwaway->set_text (X_("Hg")); /* ascender + descender) */ int h, w; throwaway->get_pixel_size (w, h); baseline = h; - // nrows = Push2::rows / baseline; } + active_bg = new Rectangle (this); - for (int n = 0; n < 8; ++n) { + for (vector<string>::iterator si = s.begin(); si != s.end(); ++si) { Text* t = new Text (this); - t->set_font_description (fd2); - t->set_color (rgba_to_color (0.23, 0.0, 0.349, 1.0)); + t->set_font_description (fd); + t->set (*si); + displays.push_back (t); + } - const double x = 10.0 + (n * Push2Canvas::inter_button_spacing()); - const double y = 2.0; - t->set_position (Duple (x, y)); +} - Rectangle* r = new Rectangle (this); - r->set (Rect (x, y, x + Push2Canvas::inter_button_spacing(), y + baseline)); +void +Push2Menu::set_layout (int c, int r) +{ + ncols = c; + nrows = r; - columns[n].lines = t; - columns[n].active_bg = r; - columns[n].top = -1; - columns[n].active = -1; - } + set_active (_active); + rearrange (_active); } void -Push2Menu::fill_column (int col, vector<string> v) +Push2Menu::rearrange (uint32_t initial_display) { - if (col < 0 || col > 7) { + if (initial_display >= displays.size()) { return; } - columns[col].text = v; + vector<Text*>::iterator i = displays.begin(); - if (v.empty()) { - columns[col].active = -1; - } else { - columns[col].active = 0; + /* move to first */ + + for (uint32_t n = 0; n < initial_display; ++n) { + (*i)->hide (); + ++i; } - set_text (col, 0); -} + uint32_t index = initial_display; + uint32_t col = 0; + uint32_t row = 0; + bool active_shown = false; -void -Push2Menu::set_text (int col, int top_row) -{ - if (top_row > (int) columns[col].text.size() - nrows || top_row < 0) { - return; - } + while (i != displays.end()) { - if (top_row == columns[col].top) { - return; - } + Coord x = col * Push2Canvas::inter_button_spacing(); + Coord y = 2 + (row * baseline); + (*i)->set_position (Duple (x, y)); - vector<string>::iterator s = columns[col].text.begin(); - s += top_row; + if (index == _active) { + active_bg->set (Rect (x - 1, y - 1, + x - 1 + Push2Canvas::inter_button_spacing(), y - 1 + baseline)); + active_bg->show (); + active_shown = true; + } - string rows; + (*i)->show (); + last = index; + ++i; + ++index; - while (true) { - rows += *s; - ++s; - if (s != columns[col].text.end()) { - rows += '\n'; - } else { - break; + if (++row >= nrows) { + row = 0; + if (++col >= ncols) { + /* no more to display */ + break; + } } + } - columns[col].lines->set (rows); - columns[col].top = top_row; + while (i != displays.end()) { + (*i)->hide (); + ++i; + } + + if (!active_shown) { + active_bg->hide (); + } - redraw (); + first = initial_display; + + Rearranged (); /* EMIT SIGNAL */ } void -Push2Menu::scroll (int col, int dir) +Push2Menu::scroll (Direction dir, bool page) { - if (dir > 0) { - set_text (col, columns[col].top + 1); - } else { - set_text (col, columns[col].top - 1); + switch (dir) { + case DirectionUp: + if (_active == 0) { + if (wrap) { + set_active (displays.size() - 1); + } + } else { + set_active (_active - 1); + } + break; + + case DirectionDown: + if (_active == displays.size() - 1) { + if (wrap) { + set_active (0); + } + } else { + set_active (_active + 1); + } + break; + + case DirectionLeft: + if (page) { + set_active (max (0, (int) (first - (nrows * ncols)))); + } else { + if (_active / nrows == 0) { + /* in the first column, go to last column, same row */ + if (wrap) { + set_active (displays.size() - 1 - active_row ()); + } + } else { + /* move to same row, previous column */ + set_active (_active - nrows); + } + } + break; + + case DirectionRight: + if (page) { + set_active (min ((uint32_t) displays.size(), first + (nrows * ncols))); + } else { + if (_active / nrows == ncols) { + /* in the last column, go to same row in first column */ + if (wrap) { + set_active (active_row()); + } + } else { + /* move to same row, next column */ + set_active (_active + nrows); + } + } + break; } +} - redraw (); +void +Push2Menu::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const +{ + render_children (area, context); } void -Push2Menu::set_active (int col, int index) +Push2Menu::set_active (uint32_t index) { - if (col < 0 || col > 7) { - columns[col].active_bg->hide (); + if (index == _active) { return; } - if (index < 0 || index > (int) columns[col].text.size()) { - columns[col].active_bg->hide (); + if (index >= displays.size()) { + active_bg->hide (); return; } - columns[col].active = index; - int effective_row = columns[col].active - columns[col].top; + /* set text color for old active item, and the new one */ - /* Move active bg */ + if (_active <= displays.size()) { + displays[_active]->set_color (text_color); + } - Duple p (columns[col].active_bg->position()); + displays[index]->set_color (contrast_color); - columns[col].active_bg->set (Rect (p.x, p.y + (effective_row * baseline), - p.x + Push2Canvas::inter_button_spacing(), p.y + baseline)); - columns[col].active_bg->show (); + Duple p = displays[index]->position (); - if (columns[col].active < nrows/2) { - set_text (col, 0); - } else { - set_text (col, columns[col].active - (nrows/2) + 1); - } + active_bg->set (Rect (p.x - 1, p.y - 1, p.x - 1 + Push2Canvas::inter_button_spacing(), p.y - 1 + baseline )); + active_bg->show (); + _active = index; - ActiveChanged (); /* emit signal */ + if (_active < first) { - redraw (); -} + /* we jumped before current visible range : try to put its column first + */ -void -Push2Menu::step_active (int col, int dir) -{ - if (col < 0 || col > 7) { - return; - } + rearrange (active_top()); - if (columns[col].text.empty()) { - return; + } else if (_active > last) { + + /* we jumped after current visible range : try putting its + * column last + */ + + rearrange (active_top() - ((ncols - 1) * nrows)); } + ActiveChanged (); /* EMIT SIGNAL */ +} - if (dir < 0) { - if (columns[col].active == -1) { - set_active (col, -1); - } else { - columns[col].active = columns[col].active - 1; - if (columns[col].active < 0) { - set_active (col, columns[col].text.size() - 1); - } - } - } else { - if (columns[col].active == -1) { - set_active (col, 0); - } else { - columns[col].active = columns[col].active + 1; - if (columns[col].active >= (int) columns[col].text.size()) { - set_active (col, 0); - } - } +void +Push2Menu::set_text_color (Color c) +{ + text_color = c; + + for (vector<Text*>::iterator t = displays.begin(); t != displays.end(); ++t) { + (*t)->set_color (c); } - redraw (); } -int -Push2Menu::get_active (int col) +void +Push2Menu::set_active_color (Color c) { - if (col < 0 || col > 7) { - return -1; + active_color = c; + contrast_color = contrasting_text_color (active_color); + if (active_bg) { + active_bg->set_fill_color (c); } - return columns[col].active; + if (_active < displays.size()) { + displays[_active]->set_color (contrast_color); + } } void -Push2Menu::render (Rect const& area, Cairo::RefPtr<Cairo::Context> context) const +Push2Menu::set_font_description (Pango::FontDescription fd) { - render_children (area, context); + font_description = fd; + + for (vector<Text*>::iterator t = displays.begin(); t != displays.end(); ++t) { + (*t)->set_font_description (fd); + } } |