// Menu List // // Douglas Thrift // // $Id$ #include #include #include "MenuList.hpp" MenuList *MenuList::previous; MenuList::MenuItem::MenuItem(MenuList *list) : list(list) { } MenuList::MenuList(MenuList *parent, Display &display, size_t size) : parent(parent), display(display), list(size) { } MenuList::~MenuList() { _foreach (std::vector, item, list) delete *item; } MenuList *MenuList::Enter() { return list[state.item]->Select(); } MenuList *MenuList::Right() { MenuItem *item(list[state.item]); if (dynamic_cast(item)) return item->Select(); return this; } MenuList *MenuList::Left() { return parent; } void MenuList::Render() { if (this != previous || state != old) { # define Cursor(index) (state.cursor == index ? _B("\x1f") : _B(" ")) display.Set(0, 0, (state.bottom != 0 ? '\x1a' : ' ') + Cursor(0)); display.Set(0, 1, '\x12' + Cursor(1)); display.Set(0, 2, '\x13' + Cursor(2)); display.Set(0, 3, (state.top < list.size() ? '\x1b' : ' ') + Cursor(3)); # undef Cursor _forall (size_t, index, state.bottom, state.top) { MenuItem *item(list[index]); std::string value(*item); value.resize(17, ' '); if (BoolItem *item_ = dynamic_cast(item)) value += (*item_ ? '\x94' : '\xcf'); else if (dynamic_cast(item)) value += '\x10'; else value += ' '; display.Set(2, _index, value); } } else { if (state.cursor != old.cursor) { display.Set(1, old.cursor, _B(" ")); display.Set(1, state.cursor, _B("\x1f")); } _forall (size_t, index, state.bottom, state.top) if (BoolItem *item = dynamic_cast(list[index])) display.Set(19, _index, (*item ? _B("\x94") : _B("\xcf"))); } } MenuList &MenuList::operator ++() { size_t next(state.item + 1); if (next != list.size()) { if (next == state.bottom) ++state.top, ++state.bottom; else ++state.cursor; state.item = next; } return *this; } MenuList &MenuList::operator --() { if (state.item != 0) if (state.item-- == state.top) --state.top, --state.bottom; else --state.cursor; return *this; } TopList::AppendItem::AppendItem(MenuList *list, bool &append) : MenuItem(list), append(append) { } MenuList *TopList::AppendItem::Select() { append = !append; return list; } TopList::AppendItem::operator std::string() const { return _B("Append"); } TopList::AppendItem::operator bool() const { return append; } TopList::ShuffleItem::ShuffleItem(MenuList *list, Audacious::Audacious &audacious) : MenuItem(list), audacious(audacious) { } MenuList *TopList::ShuffleItem::Select() { if (audacious.IsRunning()) audacious.ToggleShuffle(); return list; } TopList::ShuffleItem::operator std::string() const { return _B("Shuffle"); } TopList::ShuffleItem::operator bool() const { return audacious.IsRunning() ? audacious.IsShuffle() : false; } TopList::TopList(Audacious::Audacious &audacious, Display &display, bool &append) : MenuList(this, display, 3) { previous = NULL; list[0] = new AppendItem(this, append); list[1] = new ShuffleItem(this, audacious); }