// Menu List // // Douglas Thrift // // $Id$ #include #include #include "MenuList.hpp" MenuList *MenuList::previous; MenuList::MenuItem::MenuItem(MenuList *list) : list(list) { } MenuList::MusicItem::MusicItem(Audacious::Audacious &audacious, bool &append, MusicLibrary::Library &library) : audacious(audacious), append(append), library(library) { } MenuList::MenuList(MenuList *parent, Display &display, size_t size) : parent(parent), display(display), cursor(0), list(size) { } MenuList::MenuList(MenuList *parent) : parent(parent), display(parent->display), cursor(0), list(1) { } MenuList::~MenuList() { _foreach (std::vector, item, list) delete *item; if (parent != NULL && parent != this) delete parent; } MenuList *MenuList::Enter() { return Select(list[state.item]); } MenuList *MenuList::Right() { MenuItem *item(list[state.item]); if (dynamic_cast(item)) return Select(item); return this; } MenuList *MenuList::Left() { MenuList *parent(this->parent); if (parent != this) { this->parent = NULL; delete this; } return parent; } void MenuList::Render() { display.SetCursorPosition(19, cursor); size_t size(list.size()); if (this != previous || state != old) { display.Set(0, 0, (state.top != 0 ? '\x1a' : ' ')); display.Set(0, 1, '\x12'); display.Set(0, 2, '\x13'); display.Set(0, 3, (state.bottom < size ? '\x1b' : ' ')); _forall (size_t, index, state.top, state.bottom) if (index < size) { MenuItem *item(list[index]); std::string value(*item); value.resize(18, ' '); if (BoolItem *item_ = dynamic_cast(item)) value += (*item_ ? '\x94' : '\xcf'); else if (dynamic_cast(item)) value += '\x10'; else value += ' '; display.Set(1, _index, value); } else display.Set(1, _index, std::string(19, ' ')); previous = this; } else _forall (size_t, index, state.top, size < state.bottom ? size : state.bottom) if (BoolItem *item = dynamic_cast(list[index])) display.Set(19, _index, (*item ? _B("\x94") : _B("\xcf"))); } MenuList &MenuList::operator ++() { old = state; size_t next(state.item + 1); if (next != list.size()) { if (next == state.bottom) ++state.top, ++state.bottom; else ++cursor; state.item = next; } return *this; } MenuList &MenuList::operator --() { old = state; if (state.item != 0) if (state.item-- == state.top) --state.top, --state.bottom; else --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("Playlist 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::MusicItem::MusicItem(MenuList *list, Audacious::Audacious &audacious, bool &append, MusicLibrary::Library &library) : MenuItem(list), MenuList::MusicItem(audacious, append, library) { } MenuList *TopList::MusicItem::Select() { return new ArtistList(list, audacious, append, library); } TopList::MusicItem::operator std::string() const { return _B("Music"); } TopList::TopList(Display &display, Audacious::Audacious &audacious, bool &append, MusicLibrary::Library &library) : MenuList(this, display, 3) { previous = NULL; list[0] = new AppendItem(this, append); list[1] = new ShuffleItem(this, audacious); list[2] = new MusicItem(this, audacious, append, library); } ArtistList::ArtistList(MenuList *parent, Audacious::Audacious &audacious, bool &append, MusicLibrary::Library &library) : MenuList(parent) { list[0] = new AllItem(this, audacious, append, library); } ArtistList::AllItem::AllItem(MenuList *list, Audacious::Audacious &audacious, bool &append, MusicLibrary::Library &library) : MenuItem(list), MusicItem(audacious, append, library) { } MenuList *ArtistList::AllItem::Select() { _L songs; _foreach (const _L, song, library.GetSongs()) songs.push_back(song->GetPath()); if (audacious.IsRunning()) audacious.Playlist(songs, append); return NULL; } ArtistList::AllItem::operator std::string() const { return _B("All Artists"); }