menu: change template parameter from T to ItemT

This commit is contained in:
Andrzej Rybczak
2012-10-06 19:26:14 +02:00
parent d1a0090789
commit 400099a07f

View File

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