diff --git a/src/menu.h b/src/menu.h index b3a2e2c3..bf723f88 100644 --- a/src/menu.h +++ b/src/menu.h @@ -36,24 +36,24 @@ namespace NC { /// This template class is generic menu capable of /// holding any std::vector compatible values. -template class Menu : public Window +template class Menu : public Window { struct ItemProxy; public: struct Item { - typedef T Type; + typedef ItemT Type; - friend class Menu; + friend class Menu; Item() : m_is_bold(false), m_is_selected(false), m_is_inactive(false), m_is_separator(false) { } - Item(T value_, bool is_bold, bool is_inactive) + Item(ItemT value_, bool is_bold, bool is_inactive) : m_value(value_), m_is_bold(is_bold), m_is_selected(false), m_is_inactive(is_inactive), m_is_separator(false) { } - T &value() { return m_value; } - const T &value() const { return m_value; } + ItemT &value() { return m_value; } + const ItemT &value() const { return m_value; } void setBold(bool is_bold) { m_is_bold = is_bold; } void setSelected(bool is_selected) { m_is_selected = is_selected; } @@ -73,7 +73,7 @@ public: return item; } - T m_value; + ItemT m_value; bool m_is_bold; bool m_is_selected; bool m_is_inactive; @@ -83,7 +83,7 @@ public: template class ItemIterator : public std::iterator { - friend class Menu; + friend class Menu; BaseIterator m_it; explicit ItemIterator(BaseIterator it) : m_it(it) { } @@ -160,10 +160,10 @@ public: typedef std::reverse_iterator ConstReverseIterator; typedef ItemIterator< - T, typename std::vector::iterator + ItemT, typename std::vector::iterator > ValueIterator; typedef ItemIterator< - typename std::add_const::type, typename std::vector::const_iterator + typename std::add_const::type, typename std::vector::const_iterator > ConstValueIterator; typedef std::reverse_iterator ReverseValueIterator; @@ -172,20 +172,12 @@ public: /// Function helper prototype used to display each option on the screen. /// If not set by setItemDisplayer(), menu won't display anything. /// @see setItemDisplayer() - typedef std::function &)> ItemDisplayer; + typedef std::function &)> ItemDisplayer; typedef std::function FilterFunction; Menu() { } - /// Constructs an empty menu with given parameters - /// @param startx X position of left upper corner of constructed menu - /// @param starty Y position of left upper corner of constructed menu - /// @param width width of constructed menu - /// @param height height of constructed menu - /// @param title title of constructed menu - /// @param color base color of constructed menu - /// @param border border of constructed menu Menu(size_t startx, size_t starty, size_t width, size_t height, const std::string &title, Color color, Border border); @@ -209,7 +201,7 @@ public: /// @param item object that has to be added /// @param is_bold defines the initial state of bold attribute /// @param is_inactive defines the initial state of static attribute - void addItem(T item, bool is_bold = 0, bool is_inactive = 0); + void addItem(ItemT item, bool is_bold = 0, bool is_inactive = 0); /// Adds separator to list void addSeparator(); @@ -219,7 +211,7 @@ public: /// @param item object that has to be inserted /// @param is_bold defines the initial state of bold attribute /// @param is_inactive defines the initial state of static attribute - void insertItem(size_t pos, const T &Item, bool is_bold = 0, bool is_inactive = 0); + void insertItem(size_t pos, const ItemT &Item, bool is_bold = 0, bool is_inactive = 0); /// Inserts separator to list at given position /// @param pos initial position of inserted separator @@ -343,35 +335,35 @@ public: /// @return reference to last item on the list /// @throw List::InvalidItem if requested item is separator - Menu::Item &back() { return *m_options_ptr->back(); } + Menu::Item &back() { return *m_options_ptr->back(); } /// @return const reference to last item on the list /// @throw List::InvalidItem if requested item is separator - const Menu::Item &back() const { return *m_options_ptr->back(); } + const Menu::Item &back() const { return *m_options_ptr->back(); } /// @return reference to curently highlighted object - Menu::Item ¤t() { return *(*m_options_ptr)[m_highlight]; } + Menu::Item ¤t() { return *(*m_options_ptr)[m_highlight]; } /// @return const reference to curently highlighted object - const Menu::Item ¤t() const { return *(*m_options_ptr)[m_highlight]; } + const Menu::Item ¤t() const { return *(*m_options_ptr)[m_highlight]; } /// @param pos requested position /// @return reference to item at given position /// @throw std::out_of_range if given position is out of range - Menu::Item &at(size_t pos) { return *m_options_ptr->at(pos); } + Menu::Item &at(size_t pos) { return *m_options_ptr->at(pos); } /// @param pos requested position /// @return const reference to item at given position /// @throw std::out_of_range if given position is out of range - const Menu::Item &at(size_t pos) const { return *m_options_ptr->at(pos); } + const Menu::Item &at(size_t pos) const { return *m_options_ptr->at(pos); } /// @param pos requested position /// @return const reference to item at given position - const Menu::Item &operator[](size_t pos) const { return *(*m_options_ptr)[pos]; } + const Menu::Item &operator[](size_t pos) const { return *(*m_options_ptr)[pos]; } /// @param pos requested position /// @return const reference to item at given position - Menu::Item &operator[](size_t pos) { return *(*m_options_ptr)[pos]; } + Menu::Item &operator[](size_t pos) { return *(*m_options_ptr)[pos]; } Iterator currentI() { return Iterator(m_options_ptr->begin() + m_highlight); } ConstIterator currentI() const { return ConstIterator(m_options_ptr->begin() + m_highlight); } @@ -417,7 +409,8 @@ private: bool isHighlightable(size_t pos) { - return !(*m_options_ptr)[pos]->isSeparator() && !(*m_options_ptr)[pos]->isInactive(); + return !(*m_options_ptr)[pos]->isSeparator() + && !(*m_options_ptr)[pos]->isInactive(); } ItemDisplayer m_item_displayer; @@ -445,7 +438,8 @@ private: Buffer m_selected_suffix; }; -template Menu::Menu(size_t startx, +template +Menu::Menu(size_t startx, size_t starty, size_t width, size_t height, @@ -464,7 +458,8 @@ template Menu::Menu(size_t startx, { } -template Menu::Menu(const Menu &rhs) +template +Menu::Menu(const Menu &rhs) : Window(rhs) , m_item_displayer(rhs.m_item_displayer) , m_filter(rhs.m_filter) @@ -488,7 +483,8 @@ template Menu::Menu(const Menu &rhs) m_options_ptr = &m_options; } -template Menu::Menu(Menu &&rhs) +template +Menu::Menu(Menu &&rhs) : Window(rhs) , m_item_displayer(rhs.m_item_displayer) , m_filter(rhs.m_filter) @@ -512,7 +508,8 @@ template Menu::Menu(Menu &&rhs) m_options_ptr = &m_filtered_options; } -template Menu &Menu::operator=(Menu rhs) +template +Menu &Menu::operator=(Menu rhs) { std::swap(static_cast(*this), static_cast(rhs)); std::swap(m_item_displayer, rhs.m_item_displayer); @@ -537,12 +534,14 @@ template Menu &Menu::operator=(Menu rhs) return *this; } -template void Menu::reserve(size_t size_) +template +void Menu::reserve(size_t size_) { m_options.reserve(size_); } -template void Menu::resizeList(size_t new_size) +template +void Menu::resizeList(size_t new_size) { if (new_size > m_options.size()) { @@ -555,34 +554,40 @@ template void Menu::resizeList(size_t new_size) m_options.resize(new_size); } -template void Menu::addItem(T item, bool is_bold, bool is_inactive) +template +void Menu::addItem(ItemT item, bool is_bold, bool is_inactive) { - m_options.push_back(Item(std::forward(item), is_bold, is_inactive)); + m_options.push_back(Item(std::forward(item), is_bold, is_inactive)); } -template void Menu::addSeparator() +template +void Menu::addSeparator() { m_options.push_back(Item::mkSeparator()); } -template void Menu::insertItem(size_t pos, const T &item, bool is_bold, bool is_inactive) +template +void Menu::insertItem(size_t pos, const ItemT &item, bool is_bold, bool is_inactive) { m_options.insert(m_options.begin()+pos, Item(item, is_bold, is_inactive)); } -template void Menu::insertSeparator(size_t pos) +template +void Menu::insertSeparator(size_t pos) { m_options.insert(m_options.begin()+pos, Item::mkSeparator()); } -template void Menu::deleteItem(size_t pos) +template +void Menu::deleteItem(size_t pos) { assert(m_options_ptr != &m_filtered_options); assert(pos < m_options.size()); m_options.erase(m_options.begin()+pos); } -template bool Menu::Goto(size_t y) +template +bool Menu::Goto(size_t y) { if (!isHighlightable(m_beginning+y)) return false; @@ -590,7 +595,8 @@ template bool Menu::Goto(size_t y) return true; } -template void Menu::refresh() +template +void Menu::refresh() { if (m_options_ptr->empty()) { @@ -599,7 +605,9 @@ template void Menu::refresh() return; } - size_t max_beginning = m_options_ptr->size() < m_height ? 0 : m_options_ptr->size()-m_height; + size_t max_beginning = 0; + if (m_options_ptr->size() > m_height) + max_beginning = m_options_ptr->size() - m_height; m_beginning = std::min(m_beginning, max_beginning); // if highlighted position is off the screen, make it visible @@ -655,7 +663,8 @@ template void Menu::refresh() Window::refresh(); } -template void Menu::scroll(Scroll where) +template +void Menu::scroll(Scroll where) { if (m_options_ptr->empty()) return; @@ -745,13 +754,15 @@ template void Menu::scroll(Scroll where) highlight(m_highlight); } -template void Menu::reset() +template +void Menu::reset() { m_highlight = 0; m_beginning = 0; } -template void Menu::clear() +template +void Menu::clear() { clearFilterResults(); m_options.clear(); @@ -759,7 +770,8 @@ template void Menu::clear() m_options_ptr = &m_options; } -template void Menu::highlight(size_t pos) +template +void Menu::highlight(size_t pos) { assert(pos < m_options_ptr->size()); m_highlight = pos; @@ -770,14 +782,15 @@ template void Menu::highlight(size_t pos) m_beginning = pos-half_height; } -template size_t Menu::choice() const +template +size_t Menu::choice() const { assert(!empty()); return m_highlight; } -template -void Menu::filter(ConstIterator first, ConstIterator last, const FilterFunction &f) +template +void Menu::filter(ConstIterator first, ConstIterator last, const FilterFunction &f) { assert(m_options_ptr != &m_filtered_options); clearFilterResults(); @@ -791,27 +804,29 @@ void Menu::filter(ConstIterator first, ConstIterator last, const FilterFuncti m_options_ptr = &m_filtered_options; } -template -void Menu::applyCurrentFilter(ConstIterator first, ConstIterator last) +template +void Menu::applyCurrentFilter(ConstIterator first, ConstIterator last) { assert(m_filter); filter(first, last, m_filter); } -template void Menu::clearFilterResults() +template +void Menu::clearFilterResults() { m_filtered_options.clear(); m_options_ptr = &m_options; } -template void Menu::clearFilter() +template +void Menu::clearFilter() { m_filter = 0; } -template -bool Menu::search(ConstIterator first, ConstIterator last, const FilterFunction &f) +template +bool Menu::search(ConstIterator first, ConstIterator last, const FilterFunction &f) { m_found_positions.clear(); m_searcher = f; @@ -826,12 +841,14 @@ bool Menu::search(ConstIterator first, ConstIterator last, const FilterFuncti return !m_found_positions.empty(); } -template void Menu::clearSearchResults() +template +void Menu::clearSearchResults() { m_found_positions.clear(); } -template void Menu::nextFound(bool wrap) +template +void Menu::nextFound(bool wrap) { if (m_found_positions.empty()) return; @@ -842,7 +859,8 @@ template void Menu::nextFound(bool wrap) highlight(*m_found_positions.begin()); } -template void Menu::prevFound(bool wrap) +template +void Menu::prevFound(bool wrap) { if (m_found_positions.empty()) return;