diff options
Diffstat (limited to 'src/menu.h')
-rw-r--r-- | src/menu.h | 788 |
1 files changed, 313 insertions, 475 deletions
@@ -22,432 +22,299 @@ #define HAVE_MENU_H #include "window.h" -#include "misc.h" +#include "strbuffer.h" -#include <stdexcept> +//include <stdexcept> -enum Location { lLeft, lCenter, lRight }; +//enum Location { lLeft, lCenter, lRight }; -template <class T> -struct Option -{ - Option() : is_static(0), is_bold(0), selected(0), have_separator(0) { } - T item; - bool is_static; - bool is_bold; - bool selected; - bool have_separator; - Location location; +class List +{ + public: + + class InvalidItem { }; + + List() { } + virtual ~List() { }; + virtual void Select(int, bool) = 0; + virtual void Static(int, bool) = 0; + virtual bool isSelected(int = -1) const = 0; + virtual bool isStatic(int = -1) const = 0; + virtual bool hasSelected() const = 0; + virtual void GetSelected(std::vector<size_t> &) const = 0; + virtual void Highlight(size_t) = 0; + virtual size_t Size() const = 0; + virtual size_t Choice() const = 0; + virtual size_t RealChoice() const = 0; }; -template <class T> -class Menu : public Window +template <class T> class Menu : public Window, public List { - typedef typename vector<Option<T> *>::iterator T_iterator; - typedef typename vector<Option<T> *>::const_iterator T_const_iterator; - typedef string (*ItemDisplayer) (const T &, void *, const Menu<T> *); + typedef void (*ItemDisplayer) (const T &, void *, Menu<T> *); + + struct Option + { + Option() : Item(0), isBold(0), isSelected(0), isStatic(0), haveSeparator(0) { } + T *Item; + bool isBold; + bool isSelected; + bool isStatic; + bool haveSeparator; + }; + + typedef typename std::vector<Option>::iterator option_iterator; + typedef typename std::vector<Option>::const_iterator option_const_iterator; public: - Menu(int, int, int, int, const string &, Color, Border); + Menu(size_t, size_t, size_t, size_t, const std::string &, Color, Border); Menu(const Menu &); virtual ~Menu(); void SetItemDisplayer(ItemDisplayer ptr) { itsItemDisplayer = ptr; } void SetItemDisplayerUserData(void *data) { itsItemDisplayerUserdata = data; } - void AddOption(const T &, bool bold = 0, bool is_static = 0, bool separator = 0, Location = lLeft); - void AddSeparator() { AddOption(T(), 0, 1, 1); } - void UpdateOption(int, const T &, Location = lLeft, bool separator = 0); - void RefreshOption(int option = -1) { NeedsRedraw.push_back(option < 0 ? itsHighlight : option); } + void Reserve(size_t size); + void ResizeBuffer(size_t size); + void AddOption(const T &item = T(), bool is_bold = 0, bool is_static = 0, bool have_separator = 0); + void AddSeparator(); + void InsertOption(size_t pos, const T &Item = T(), bool is_bold = 0, bool is_static = 0, bool have_separator = 0); + void InsertSeparator(size_t pos); + void DeleteOption(size_t pos); + void IntoSeparator(size_t pos); + void Swap(size_t, size_t); + + bool isBold(int id = -1); void BoldOption(int, bool); - void MakeStatic(int, bool); - void DeleteOption(int); - void Swap(int, int); - void Insert(int, const T &, bool bold = 0, bool is_static = 0, bool separator = 0, Location location = lLeft); - void InsertSeparator(int where) { Insert(where, T(), 0, 1, 1); } - virtual string GetOption(int i = -1) const; + + virtual void Select(int id, bool value); + virtual void Static(int id, bool value); + virtual bool isSelected(int id = -1) const; + virtual bool isStatic(int id = -1) const; + virtual bool hasSelected() const; + virtual void GetSelected(std::vector<size_t> &v) const; + virtual void Highlight(size_t); + virtual size_t Size() const; + virtual size_t Choice() const; + virtual size_t RealChoice() const; virtual void Refresh(); virtual void Scroll(Where); - virtual void Highlight(int); virtual void Reset(); - virtual void Clear(bool clear_screen = 1); - - virtual void Select(int, bool); - virtual bool Selected(int) const; - virtual bool IsAnySelected() const; - virtual void GetSelectedList(vector<int> &) const; - void SetSelectPrefix(string str) { itsSelectedPrefix = str; } - void SetSelectSuffix(string str) { itsSelectedSuffix = str; } + virtual void Clear(bool clrscr = 1); - void HighlightColor(Color col) { itsHighlightColor = col; NeedsRedraw.push_back(itsHighlight); } - void Highlighting(bool hl) { itsHighlightEnabled = hl; NeedsRedraw.push_back(itsHighlight); Refresh(); } + void SetSelectPrefix(Buffer *b) { itsSelectedPrefix = b; } + void SetSelectSuffix(Buffer *b) { itsSelectedSuffix = b; } - int GetRealChoice() const; - virtual int GetChoice() const { return itsHighlight; } - virtual int Size() const { return itsOptions.size(); } + void HighlightColor(Color col) { itsHighlightColor = col; } + void Highlighting(bool hl) { highlightEnabled = hl; } bool Empty() const { return itsOptions.empty(); } - bool IsBold(int = -1) const; - virtual bool IsStatic(int = -1) const; + + T &Back(); + const T &Back() const; + T &Current(); + const T &Current() const; + T &at(size_t i); + const T &at(size_t i) const; + const T &operator[](size_t i) const; + T &operator[](size_t i); + virtual Menu<T> *Clone() const { return new Menu<T>(*this); } virtual Menu<T> *EmptyClone() const; - T & Back() { return itsOptions.back()->item; } - const T & Back() const { return itsOptions.back()->item; } - T & Current() { return itsOptions.at(itsHighlight)->item; } - const T & Current() const { return itsOptions.at(itsHighlight)->item; } - T & at(int i) { return itsOptions.at(i)->item; } - const T & at(int i) const { return itsOptions.at(i)->item; } - const T & operator[](int i) const { return itsOptions[i]->item; } - T & operator[](int i) { return itsOptions[i]->item; } + //virtual string GetOption(int i = -1) const; protected: - string DisplayOption(const T &t) const; ItemDisplayer itsItemDisplayer; void *itsItemDisplayerUserdata; - vector<Option<T> *> itsOptions; - vector<int> NeedsRedraw; - - string itsSelectedPrefix; - string itsSelectedSuffix; - - int itsStaticsNumber; - - void redraw_screen(); - bool is_static() { return itsOptions[itsHighlight]->is_static; } + std::vector<Option> itsOptions; int itsBeginning; int itsHighlight; Color itsHighlightColor; + bool highlightEnabled; - bool itsHighlightEnabled; + Buffer *itsSelectedPrefix; + Buffer *itsSelectedSuffix; }; -template <class T> -Menu<T>::Menu(int startx, int starty, int width, int height, const string &title, Color color, Border border) : - Window(startx, starty, width, height, title, color, border), - itsItemDisplayer(0), - itsItemDisplayerUserdata(0), - itsSelectedPrefix("[.r]"), - itsSelectedSuffix("[/r]"), - itsStaticsNumber(0), - itsBeginning(0), - itsHighlight(0), - itsHighlightColor(itsBaseColor), - itsHighlightEnabled(1) { } +template <class T> Menu<T>::Menu(size_t startx, + size_t starty, + size_t width, + size_t height, + const std::string &title, + Color color, + Border border) + : Window(startx, starty, width, height, title, color, border), + itsItemDisplayer(0), + itsItemDisplayerUserdata(0), + itsBeginning(0), + itsHighlight(0), + itsHighlightColor(itsBaseColor), + highlightEnabled(1), + itsSelectedPrefix(0), + itsSelectedSuffix(0) +{ +} -template <class T> -Menu<T>::Menu(const Menu &m) : Window(m) +template <class T> Menu<T>::Menu(const Menu &m) : Window(m) { - for (T_const_iterator it = m.itsOptions.begin(); it != m.itsOptions.end(); it++) - { - Option<T> *new_option = new Option<T>(**it); - itsOptions.push_back(new_option); - } + itsOptions = m.itsOptions; itsItemDisplayer = m.itsItemDisplayer; itsItemDisplayerUserdata = m.itsItemDisplayerUserdata; - NeedsRedraw = m.NeedsRedraw; - itsSelectedPrefix = m.itsSelectedPrefix; - itsSelectedSuffix = m.itsSelectedSuffix; - itsStaticsNumber = m.itsStaticsNumber; itsBeginning = m.itsBeginning; itsHighlight = m.itsHighlight; itsHighlightColor = m.itsHighlightColor; - itsHighlightEnabled = m.itsHighlightEnabled; + highlightEnabled = m.highlightEnabled; } -template <class T> -Menu<T>::~Menu() +template <class T> Menu<T>::~Menu() { - for (T_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) - delete *it; + for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) + delete it->Item; } -template <class T> -void Menu<T>::AddOption(const T &item, bool bold, bool is_static, bool separator, Location location) +template <class T> void Menu<T>::Reserve(size_t size) { - Option<T> *new_option = new Option<T>; - new_option->item = item; - new_option->is_bold = bold; - new_option->is_static = is_static; - new_option->have_separator = separator; - new_option->location = location; - if (is_static) - itsStaticsNumber++; - itsOptions.push_back(new_option); - NeedsRedraw.push_back(itsOptions.size()-1); + itsOptions.reserve(size); } -template <class T> -void Menu<T>::UpdateOption(int index, const T &item, Location location, bool separator) +template <class T> void Menu<T>::ResizeBuffer(size_t size) { - try - { - itsOptions.at(index)->location = location; - itsOptions.at(index)->item = item; - itsOptions.at(index)->have_separator = separator; - NeedsRedraw.push_back(index); - } - catch (std::out_of_range) - { - } + itsOptions.resize(size); + for (size_t i = 0; i < size; i++) + if (!itsOptions[i].Item) + itsOptions[i].Item = new T(); } -template <class T> -void Menu<T>::BoldOption(int index, bool bold) +template <class T> void Menu<T>::AddOption(const T &item, bool is_bold, bool is_static, bool have_separator) { - try - { - itsOptions.at(index)->is_bold = bold; - NeedsRedraw.push_back(index); - } - catch (std::out_of_range) - { - } + Option o; + o.Item = new T(item); + o.isBold = is_bold; + o.isStatic = is_static; + o.haveSeparator = have_separator; + itsOptions.push_back(o); } -template <class T> -void Menu<T>::MakeStatic(int index, bool stat) +//template <> void Menu<Buffer>::AddOption(const Buffer &buf, bool is_bold, bool is_static, bool have_separator); + +template <class T> void Menu<T>::AddSeparator() { - try - { - if (stat && !itsOptions.at(index)->is_static) - itsStaticsNumber++; - if (!stat && itsOptions.at(index)->is_static) - itsStaticsNumber--; - itsOptions.at(index)->is_static = stat; - } - catch (std::out_of_range) - { - } + Option o; + o.isStatic = true; + o.haveSeparator = true; + itsOptions.push_back(o); } -template <class T> -string Menu<T>::GetOption(int i) const +template <class T> void Menu<T>::InsertOption(size_t pos, const T &item, bool is_bold, bool is_static, bool have_separator) { - try - { - return DisplayOption(itsOptions.at(i == -1 ? itsHighlight : i)->item); - } - catch (std::out_of_range) - { - return ""; - } + Option o; + o.Item = new T(item); + o.isBold = is_bold; + o.isStatic = is_static; + o.haveSeparator = have_separator; + itsOptions.insert(itsOptions.begin()+pos, o); } -template <class T> -void Menu<T>::DeleteOption(int no) +template <class T> void Menu<T>::InsertSeparator(size_t pos) { - try - { - if (itsOptions.at(no)->is_static) - itsStaticsNumber--; - } - catch (std::out_of_range) - { + Option o; + o.isStatic = true; + o.haveSeparator = true; + itsOptions.insert(itsOptions.begin()+pos, o); +} + +template <class T> void Menu<T>::DeleteOption(size_t pos) +{ + if (itsOptions.empty()) return; - } - delete itsOptions[no]; - itsOptions.erase(itsOptions.begin()+no); - - if (itsHighlight > itsOptions.size()-1) - itsHighlight = itsOptions.size()-1; - - idlok(itsWindow, 1); - scrollok(itsWindow, 1); - int MaxBeginning = itsOptions.size() < itsHeight ? 0 : itsOptions.size()-itsHeight; - if (itsBeginning > MaxBeginning) - { - itsBeginning = MaxBeginning; - wmove(itsWindow, no-itsBeginning, 0); - wdeleteln(itsWindow); - wscrl(itsWindow, -1); - NeedsRedraw.push_back(itsBeginning); - } - else - { - wmove(itsWindow, no-itsBeginning, 0); - wdeleteln(itsWindow); - } - NeedsRedraw.push_back(itsHighlight); - NeedsRedraw.push_back(itsBeginning+itsHeight-1); - scrollok(itsWindow, 0); - idlok(itsWindow, 0); + delete itsOptions.at(pos).Item; + itsOptions.erase(itsOptions.begin()+pos); } -template <class T> -void Menu<T>::Swap(int one, int two) +template <class T> void Menu<T>::IntoSeparator(size_t pos) { - try - { - std::swap<Option<T> *>(itsOptions.at(one), itsOptions.at(two)); - NeedsRedraw.push_back(one); - NeedsRedraw.push_back(two); - } - catch (std::out_of_range) - { - } + if (itsOptions.at(pos).Item) + delete itsOptions[pos].Item; + itsOptions[pos].Item = 0; + itsOptions[pos].isBold = false; + itsOptions[pos].isSelected = false; + itsOptions[pos].isStatic = true; + itsOptions[pos].haveSeparator = true; } -template <class T> -void Menu<T>::Insert(int where, const T &item, bool bold, bool is_static, bool separator, Location location) +template <class T> void Menu<T>::BoldOption(int index, bool bold) { - Option<T> *new_option = new Option<T>; - new_option->item = item; - new_option->location = location; - new_option->have_separator = separator; - new_option->is_static = is_static; - new_option->is_bold = bold; - if (is_static) - itsStaticsNumber++; - itsOptions.insert(itsOptions.begin()+where, new_option); + itsOptions.at(index).isBold = bold; } template <class T> -void Menu<T>::redraw_screen() +void Menu<T>::Swap(size_t one, size_t two) { - NeedsRedraw.clear(); - T_const_iterator it = itsOptions.begin()+itsBeginning; - NeedsRedraw.reserve(itsHeight); - for (int i = itsBeginning; i < itsBeginning+itsHeight && it != itsOptions.end(); i++, it++) - NeedsRedraw.push_back(i); + std::swap(itsOptions.at(one), itsOptions.at(two)); } -template <class T> -void Menu<T>::Refresh() +template <class T> void Menu<T>::Refresh() { - bool redraw_whole_window = 1; - if (!itsOptions.empty() && is_static()) - itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp); - int MaxBeginning = itsOptions.size() < itsHeight ? 0 : itsOptions.size()-itsHeight; - if (itsBeginning > MaxBeginning) + if (itsBeginning < 0) + itsBeginning = 0; + else if (itsBeginning > MaxBeginning) itsBeginning = MaxBeginning; - - if (itsHighlight >= itsOptions.size()-1) - Highlight(itsOptions.size()-1); - - while (itsHighlight-itsBeginning > itsHeight-1) - itsBeginning++; - - if (redraw_whole_window) - { - Window::Clear(); - redraw_screen(); - } - - for (vector<int>::const_iterator it = NeedsRedraw.begin(); it != NeedsRedraw.end(); it++) + if (!itsOptions.empty() && itsHighlight > int(itsOptions.size())-1) + itsHighlight = itsOptions.size()-1; + size_t line = 0; + for (size_t i = itsBeginning; i < itsBeginning+itsHeight; i++) { - try - { - itsOptions.at(*it); - } - catch (std::out_of_range) + GotoXY(0, line); + if (i >= itsOptions.size()) { + for (; line < itsHeight; line++) + mvwhline(itsWindow, line, 0, 32, itsWidth); break; } - - int line = *it-itsBeginning; - - if (line < 0 || line+1 > itsHeight) // do not draw if line should be invisible anyway - continue; - - Color old_basecolor = itsBaseColor; - - if (*it == itsHighlight && itsHighlightEnabled) + if (itsOptions[i].isBold) + Bold(1); + if (int(i) == itsHighlight) { Reverse(1); - SetBaseColor(itsHighlightColor); - SetColor(itsHighlightColor); + *this << itsHighlightColor; } - if (itsOptions[*it]->is_bold) - Bold(1); - - int ch = itsOptions[*it]->have_separator ? 0 : 32; - mvwhline(itsWindow,line, 0, ch, itsWidth); - - string option; - - if (itsOptions[*it]->selected) - option += itsSelectedPrefix; - option += DisplayOption(itsOptions[*it]->item); - if (itsOptions[*it]->selected) - option += itsSelectedSuffix; - - int strlength = option.length(); - - if (strlength) + mvwhline(itsWindow, line, 0, !itsOptions[i].haveSeparator*32, itsWidth); + if (itsOptions[i].isSelected && itsSelectedPrefix) + *this << *itsSelectedPrefix; + if (itsItemDisplayer && itsOptions[i].Item) + itsItemDisplayer(*itsOptions[i].Item, itsItemDisplayerUserdata, this); + if (itsOptions[i].isSelected && itsSelectedSuffix) + *this << *itsSelectedSuffix; + if (int(i) == itsHighlight) { - int x = 0; - - if (itsOptions[*it]->location == lCenter) - { - x = (itsWidth-strlength-(!ch ? 2 : 0))/2; - if (!ch) - { - AltCharset(1); - mvwaddstr(itsWindow, line, x, "u "); - AltCharset(0); - x += 2; - } - } - if (itsOptions[*it]->location == lRight) - { - x = itsWidth-strlength-(!ch ? 2 : 0); - if (!ch) - { - AltCharset(1); - mvwaddstr(itsWindow, line, x, "u "); - AltCharset(0); - x += 2; - } - } - - WriteXY(x, line, itsWidth, TO_WSTRING(option), 0); - - if (!ch && (itsOptions[*it]->location == lCenter || itsOptions[*it]->location == lLeft)) - { - x += strlength; - AltCharset(1); - mvwaddstr(itsWindow, line, x, " t"); - AltCharset(0); - } + *this << clEnd; + Reverse(0); } - - SetBaseColor(old_basecolor); - SetColor(old_basecolor); - while (!itsColors.empty()) // clear color stack and disable bold and reverse as - itsColors.pop(); // some items are too long to close all tags properly - AltCharset(0); - Reverse(0); - Bold(0); + if (itsOptions[i].isBold) + Bold(0); + line++; } - NeedsRedraw.clear(); wrefresh(itsWindow); } -template <class T> -void Menu<T>::Scroll(Where where) +template <class T> void Menu<T>::Scroll(Where where) { - if (Empty()) - return; - int MaxHighlight = itsOptions.size()-1; int MaxBeginning = itsOptions.size() < itsHeight ? 0 : itsOptions.size()-itsHeight; int MaxCurrentHighlight = itsBeginning+itsHeight-1; - idlok(itsWindow, 1); - scrollok(itsWindow, 1); switch (where) { case wUp: { if (itsHighlight <= itsBeginning && itsHighlight > 0) { - itsBeginning--; // for scrolling - wscrl(itsWindow, -1); + itsBeginning--; + //Window::Scroll(wUp); } if (itsHighlight == 0) { @@ -455,12 +322,11 @@ void Menu<T>::Scroll(Where where) } else { - NeedsRedraw.push_back(itsHighlight--); - NeedsRedraw.push_back(itsHighlight); + itsHighlight--; } - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp); + Scroll(itsHighlight == 0 ? wDown : wUp); } break; } @@ -468,8 +334,8 @@ void Menu<T>::Scroll(Where where) { if (itsHighlight >= MaxCurrentHighlight && itsHighlight < MaxHighlight) { - itsBeginning++; // scroll - wscrl(itsWindow, 1); + itsBeginning++; + //Window::Scroll(wDown); } if (itsHighlight == MaxHighlight) { @@ -477,12 +343,11 @@ void Menu<T>::Scroll(Where where) } else { - NeedsRedraw.push_back(itsHighlight++); - NeedsRedraw.push_back(itsHighlight); + itsHighlight++; } - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown); + Scroll(itsHighlight == MaxHighlight ? wUp : wDown); } break; } @@ -496,11 +361,10 @@ void Menu<T>::Scroll(Where where) if (itsHighlight < 0) itsHighlight = 0; } - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp); + Scroll(itsHighlight == 0 ? wDown: wUp); } - redraw_screen(); break; } case wPageDown: @@ -513,209 +377,183 @@ void Menu<T>::Scroll(Where where) if (itsHighlight > MaxHighlight) itsHighlight = MaxHighlight; } - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown); + Scroll(itsHighlight == MaxHighlight ? wUp : wDown); } - redraw_screen(); break; } case wHome: { itsHighlight = 0; itsBeginning = 0; - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == 0 ? Scroll(wDown) : Scroll(wUp); + Scroll(itsHighlight == 0 ? wDown : wUp); } - redraw_screen(); break; } case wEnd: { itsHighlight = MaxHighlight; itsBeginning = MaxBeginning; - if (is_static()) + if (itsOptions[itsHighlight].isStatic) { - itsHighlight == MaxHighlight ? Scroll(wUp) : Scroll(wDown); + Scroll(itsHighlight == MaxHighlight ? wUp : wDown); } - redraw_screen(); break; } } - idlok(itsWindow, 0); - scrollok(itsWindow, 0); } -template <class T> -void Menu<T>::Highlight(int which) +template <class T> void Menu<T>::Reset() { - int old_highlight = itsHighlight; - int old_beginning = itsBeginning; - - if (which < itsOptions.size()) - itsHighlight = which; - else - return; - - if (which >= itsHeight/2 && itsOptions.size() > itsHeight) - { - itsBeginning = itsHighlight-itsHeight/2; - if (itsBeginning > itsOptions.size()-itsHeight) - itsBeginning = itsOptions.size()-itsHeight; - } - else - itsBeginning = 0; - - int howmuch = itsBeginning-old_beginning; - - if (Abs(howmuch) > itsHeight) - redraw_screen(); - else - { - idlok(itsWindow, 1); - scrollok(itsWindow, 1); - if (old_highlight >= itsBeginning && old_highlight < itsBeginning+itsHeight) - NeedsRedraw.push_back(old_highlight); - wscrl(itsWindow, howmuch); - if (howmuch < 0) - for (int i = 0; i < Abs(howmuch); i++) - NeedsRedraw.push_back(itsBeginning+i); - else - for (int i = 0; i < Abs(howmuch); i++) - NeedsRedraw.push_back(itsBeginning+itsHeight-1-i); - NeedsRedraw.push_back(itsHighlight); - scrollok(itsWindow, 0); - idlok(itsWindow, 0); - } -} - -template <class T> -void Menu<T>::Reset() -{ - if (!Empty()) - { - NeedsRedraw.push_back(0); - NeedsRedraw.push_back(itsHighlight); - } itsHighlight = 0; itsBeginning = 0; } -template <class T> -void Menu<T>::Clear(bool clear_screen) +template <class T> void Menu<T>::Clear(bool clrscr) { - for (T_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) - delete *it; + for (option_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) + delete it->Item; itsOptions.clear(); - NeedsRedraw.clear(); - itsStaticsNumber = 0; - if (clear_screen) + if (clrscr) Window::Clear(); } -template <class T> -void Menu<T>::Select(int option, bool selected) +template <class T> bool Menu<T>::isBold(int id) { - try - { - if (itsOptions.at(option)->selected != selected) - NeedsRedraw.push_back(option); - itsOptions.at(option)->selected = selected; - } - catch (std::out_of_range) - { - } + return itsOptions.at(id == -1 ? itsHighlight : id).isBold; } -template <class T> -bool Menu<T>::Selected(int option) const +template <class T> void Menu<T>::Select(int id, bool value) { - try - { - return itsOptions.at(option)->selected; - } - catch (std::out_of_range) - { - return false; - } + itsOptions.at(id).isSelected = value; } -template <class T> -bool Menu<T>::IsAnySelected() const +template <class T> void Menu<T>::Static(int id, bool value) { - bool result = 0; - for (T_const_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) - { - if ((*it)->selected) - { - result = 1; - break; - } - } - return result; + itsOptions.at(id).isStatic = value; } -template <class T> -void Menu<T>::GetSelectedList(vector<int> &v) const +template <class T> bool Menu<T>::isSelected(int id) const +{ + return itsOptions.at(id == -1 ? itsHighlight : id).isSelected; +} + +template <class T> bool Menu<T>::isStatic(int id) const +{ + return itsOptions.at(id == -1 ? itsHighlight : id).isStatic; +} + +template <class T> bool Menu<T>::hasSelected() const +{ + for (option_const_iterator it = itsOptions.begin(); it != itsOptions.end(); it++) + if (it->isSelected) + return true; + return false; +} + +template <class T> void Menu<T>::GetSelected(std::vector<size_t> &v) const { - int i = 0; - for (T_const_iterator it = itsOptions.begin(); it != itsOptions.end(); it++, i++) - if ((*it)->selected) + for (size_t i = 0; i < itsOptions.size(); i++) + if (itsOptions[i].isSelected) v.push_back(i); } -template <class T> -int Menu<T>::GetRealChoice() const +template <class T> void Menu<T>::Highlight(size_t pos) { - int real_choice = 0; - T_const_iterator it = itsOptions.begin(); - for (int i = 0; i < itsHighlight; it++, i++) - if (!(*it)->is_static) real_choice++; - - return real_choice; + itsHighlight = pos; + itsBeginning = pos-itsHeight/2; } -template <class T> -bool Menu<T>::IsBold(int option) const +template <class T> size_t Menu<T>::Size() const { - try - { - return itsOptions.at(option == -1 ? itsHighlight : option)->is_bold; - } - catch (std::out_of_range) - { - return 0; - } + return itsOptions.size(); } -template <class T> -bool Menu<T>::IsStatic(int option) const +template <class T> size_t Menu<T>::Choice() const { - try - { - return itsOptions.at(option == -1 ? itsHighlight : option)->is_static; - } - catch (std::out_of_range) - { - return 1; - } + return itsHighlight; } -template <class T> -Menu<T> *Menu<T>::EmptyClone() const +template <class T> size_t Menu<T>::RealChoice() const { - return new Menu<T>(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder); + size_t result = 0; + for (option_const_iterator it = itsOptions.begin(); it != itsOptions.begin()+itsHighlight; it++) + if (!it->isStatic) + result++; + return result; } -template <class T> -string Menu<T>::DisplayOption(const T &t) const +template <class T> T &Menu<T>::Back() +{ + if (itsOptions.back().Item) + return *itsOptions.back().Item; + else + throw InvalidItem(); +} + +template <class T> const T &Menu<T>::Back() const +{ + if (itsOptions.back().Item) + return *itsOptions.back().Item; + else + throw InvalidItem(); +} + +template <class T> T &Menu<T>::Current() { - return itsItemDisplayer ? itsItemDisplayer(t, itsItemDisplayerUserdata, this) : ""; + if (itsOptions.at(itsHighlight).Item) + return *itsOptions.at(itsHighlight).Item; + else + throw InvalidItem(); } -template <> -string Menu<string>::DisplayOption(const string &str) const; +template <class T> const T &Menu<T>::Current() const +{ + if (itsOptions.at(itsHighlight).Item) + return *itsOptions.at(itsHighlight).Item; + else + throw InvalidItem(); +} + +template <class T> T &Menu<T>::at(size_t i) +{ + if (itsOptions.at(i).Item) + return *itsOptions.at(i).Item; + else + throw InvalidItem(); +} + +template <class T> const T &Menu<T>::at(size_t i) const +{ + if (itsOptions.at(i).Item) + return *itsOptions.at(i).Item; + else + throw InvalidItem(); +} + +template <class T> const T &Menu<T>::operator[](size_t i) const +{ + if (itsOptions[i].Item) + return *itsOptions[i].Item; + else + throw InvalidItem(); +} + +template <class T> T &Menu<T>::operator[](size_t i) +{ + if (itsOptions[i].Item) + return *itsOptions[i].Item; + else + throw InvalidItem(); +} + +template <class T> Menu<T> *Menu<T>::EmptyClone() const +{ + return new Menu<T>(GetStartX(), GetStartY(), GetWidth(), GetHeight(), itsTitle, itsBaseColor, itsBorder); +} #endif |