menu: make m_highlight/m_beginning unsigned
This commit is contained in:
199
src/menu.h
199
src/menu.h
@@ -537,11 +537,16 @@ template <typename T> struct Menu : public Window, public List
|
||||
ReverseIterator Rend() { return ReverseIterator(Begin()); }
|
||||
ConstReverseIterator Rend() const { return ConstReverseIterator(Begin()); }
|
||||
|
||||
protected:
|
||||
private:
|
||||
/// Clears filter, filtered data etc.
|
||||
///
|
||||
void ClearFiltered();
|
||||
|
||||
bool isHighlightable(size_t pos)
|
||||
{
|
||||
return !(*m_options_ptr)[pos]->isSeparator() && !(*m_options_ptr)[pos]->isInactive();
|
||||
}
|
||||
|
||||
ItemDisplayer m_item_displayer;
|
||||
ItemStringifier m_get_string_helper;
|
||||
|
||||
@@ -554,8 +559,8 @@ protected:
|
||||
std::vector<size_t> m_filtered_positions;
|
||||
std::set<size_t> m_found_positions;
|
||||
|
||||
int itsBeginning;
|
||||
int itsHighlight;
|
||||
size_t m_beginning;
|
||||
size_t m_highlight;
|
||||
|
||||
Color m_highlight_color;
|
||||
bool m_highlight_enabled;
|
||||
@@ -585,8 +590,8 @@ template <typename T> Menu<T>::Menu(size_t startx,
|
||||
m_item_displayer(0),
|
||||
m_get_string_helper(0),
|
||||
m_options_ptr(&m_options),
|
||||
itsBeginning(0),
|
||||
itsHighlight(0),
|
||||
m_beginning(0),
|
||||
m_highlight(0),
|
||||
m_highlight_color(itsBaseColor),
|
||||
m_highlight_enabled(1),
|
||||
m_cyclic_scroll_enabled(0),
|
||||
@@ -600,8 +605,8 @@ template <typename T> Menu<T>::Menu(const Menu &m) : Window(m),
|
||||
m_item_displayer(m.m_item_displayer),
|
||||
m_get_string_helper(m.m_get_string_helper),
|
||||
m_options_ptr(m.m_options_ptr),
|
||||
itsBeginning(m.itsBeginning),
|
||||
itsHighlight(m.itsHighlight),
|
||||
m_beginning(m.m_beginning),
|
||||
m_highlight(m.m_highlight),
|
||||
m_highlight_color(m.m_highlight_color),
|
||||
m_highlight_enabled(m.m_highlight_enabled),
|
||||
m_cyclic_scroll_enabled(m.m_cyclic_scroll_enabled),
|
||||
@@ -706,9 +711,9 @@ template <typename T> void Menu<T>::Move(size_t from, size_t to)
|
||||
|
||||
template <typename T> bool Menu<T>::Goto(size_t y)
|
||||
{
|
||||
if (!m_options_ptr->at(itsBeginning+y) || m_options_ptr->at(itsBeginning+y)->isInactive())
|
||||
if (!isHighlightable(m_beginning+y))
|
||||
return false;
|
||||
itsHighlight = itsBeginning+y;
|
||||
m_highlight = m_beginning+y;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -719,63 +724,59 @@ template <typename T> void Menu<T>::Refresh()
|
||||
Window::Refresh();
|
||||
return;
|
||||
}
|
||||
int MaxBeginning = m_options_ptr->size() < itsHeight ? 0 : m_options_ptr->size()-itsHeight;
|
||||
|
||||
if (itsBeginning < itsHighlight-int(itsHeight)+1) // highlighted position is off the screen
|
||||
itsBeginning = itsHighlight-itsHeight+1;
|
||||
size_t max_beginning = m_options_ptr->size() < itsHeight ? 0 : m_options_ptr->size()-itsHeight;
|
||||
m_beginning = std::min(m_beginning, max_beginning);
|
||||
|
||||
if (itsBeginning < 0)
|
||||
itsBeginning = 0;
|
||||
else if (itsBeginning > MaxBeginning)
|
||||
itsBeginning = MaxBeginning;
|
||||
// if highlighted position is off the screen, make it visible
|
||||
m_highlight = std::min(m_highlight, m_beginning+itsHeight-1);
|
||||
// if highlighted position is invalid, correct it
|
||||
m_highlight = std::min(m_highlight, m_options_ptr->size()-1);
|
||||
|
||||
if (!m_options_ptr->empty() && itsHighlight > int(m_options_ptr->size())-1)
|
||||
itsHighlight = m_options_ptr->size()-1;
|
||||
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive()) // it shouldn't be here
|
||||
if (!isHighlightable(m_highlight))
|
||||
{
|
||||
Scroll(wUp);
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
if (isHighlightable(m_highlight))
|
||||
Scroll(wDown);
|
||||
}
|
||||
|
||||
size_t line = 0;
|
||||
for (size_t &i = (m_drawn_position = itsBeginning); i < itsBeginning+itsHeight; ++i)
|
||||
m_drawn_position = m_beginning;
|
||||
for (size_t &i = m_drawn_position; i < m_beginning+itsHeight; ++i, ++line)
|
||||
{
|
||||
GotoXY(0, line);
|
||||
if (i >= m_options_ptr->size())
|
||||
{
|
||||
for (; line < itsHeight; ++line)
|
||||
mvwhline(itsWindow, line, 0, 32, itsWidth);
|
||||
mvwhline(itsWindow, line, 0, KEY_SPACE, itsWidth);
|
||||
break;
|
||||
}
|
||||
if ((*m_options_ptr)[i]->isSeparator())
|
||||
{
|
||||
mvwhline(itsWindow, line++, 0, 0, itsWidth);
|
||||
mvwhline(itsWindow, line, 0, 0, itsWidth);
|
||||
continue;
|
||||
}
|
||||
if ((*m_options_ptr)[i]->isBold())
|
||||
*this << fmtBold;
|
||||
if (m_highlight_enabled && int(i) == itsHighlight)
|
||||
if (m_highlight_enabled && i == m_highlight)
|
||||
{
|
||||
*this << fmtReverse;
|
||||
*this << m_highlight_color;
|
||||
}
|
||||
mvwhline(itsWindow, line, 0, 32, itsWidth);
|
||||
mvwhline(itsWindow, line, 0, KEY_SPACE, itsWidth);
|
||||
if ((*m_options_ptr)[i]->isSelected() && m_selected_prefix)
|
||||
*this << *m_selected_prefix;
|
||||
if (m_item_displayer)
|
||||
m_item_displayer(*this, (*m_options_ptr)[i]->value());
|
||||
if ((*m_options_ptr)[i]->isSelected() && m_selected_suffix)
|
||||
*this << *m_selected_suffix;
|
||||
if (m_highlight_enabled && int(i) == itsHighlight)
|
||||
if (m_highlight_enabled && i == m_highlight)
|
||||
{
|
||||
*this << clEnd;
|
||||
*this << fmtReverseEnd;
|
||||
}
|
||||
if ((*m_options_ptr)[i]->isBold())
|
||||
*this << fmtBoldEnd;
|
||||
line++;
|
||||
}
|
||||
Window::Refresh();
|
||||
}
|
||||
@@ -784,120 +785,96 @@ template <typename T> void Menu<T>::Scroll(Where where)
|
||||
{
|
||||
if (m_options_ptr->empty())
|
||||
return;
|
||||
int MaxHighlight = m_options_ptr->size()-1;
|
||||
int MaxBeginning = m_options_ptr->size() < itsHeight ? 0 : m_options_ptr->size()-itsHeight;
|
||||
int MaxCurrentHighlight = itsBeginning+itsHeight-1;
|
||||
size_t max_highlight = m_options_ptr->size()-1;
|
||||
size_t max_beginning = m_options_ptr->size() < itsHeight ? 0 : m_options_ptr->size()-itsHeight;
|
||||
size_t max_visible_highlight = m_beginning+itsHeight-1;
|
||||
switch (where)
|
||||
{
|
||||
case wUp:
|
||||
{
|
||||
if (itsHighlight <= itsBeginning && itsHighlight > 0)
|
||||
{
|
||||
itsBeginning--;
|
||||
}
|
||||
if (itsHighlight == 0)
|
||||
if (m_highlight <= m_beginning && m_highlight > 0)
|
||||
--m_beginning;
|
||||
if (m_highlight == 0)
|
||||
{
|
||||
if (m_cyclic_scroll_enabled)
|
||||
return Scroll(wEnd);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
itsHighlight--;
|
||||
}
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == 0 && !m_cyclic_scroll_enabled ? wDown : wUp);
|
||||
}
|
||||
--m_highlight;
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(m_highlight == 0 && !m_cyclic_scroll_enabled ? wDown : wUp);
|
||||
break;
|
||||
}
|
||||
case wDown:
|
||||
{
|
||||
if (itsHighlight >= MaxCurrentHighlight && itsHighlight < MaxHighlight)
|
||||
{
|
||||
itsBeginning++;
|
||||
}
|
||||
if (itsHighlight == MaxHighlight)
|
||||
if (m_highlight >= max_visible_highlight && m_highlight < max_highlight)
|
||||
++m_beginning;
|
||||
if (m_highlight == max_highlight)
|
||||
{
|
||||
if (m_cyclic_scroll_enabled)
|
||||
return Scroll(wHome);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
itsHighlight++;
|
||||
}
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == MaxHighlight && !m_cyclic_scroll_enabled ? wUp : wDown);
|
||||
}
|
||||
++m_highlight;
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(m_highlight == max_highlight && !m_cyclic_scroll_enabled ? wUp : wDown);
|
||||
break;
|
||||
}
|
||||
case wPageUp:
|
||||
{
|
||||
if (m_cyclic_scroll_enabled && itsHighlight == 0)
|
||||
if (m_cyclic_scroll_enabled && m_highlight == 0)
|
||||
return Scroll(wEnd);
|
||||
itsHighlight -= itsHeight;
|
||||
itsBeginning -= itsHeight;
|
||||
if (itsBeginning < 0)
|
||||
{
|
||||
itsBeginning = 0;
|
||||
if (itsHighlight < 0)
|
||||
itsHighlight = 0;
|
||||
}
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == 0 && !m_cyclic_scroll_enabled ? wDown : wUp);
|
||||
}
|
||||
if (m_highlight < itsHeight)
|
||||
m_highlight = 0;
|
||||
else
|
||||
m_highlight -= itsHeight;
|
||||
if (m_beginning < itsHeight)
|
||||
m_beginning = 0;
|
||||
else
|
||||
m_beginning -= itsHeight;
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(m_highlight == 0 && !m_cyclic_scroll_enabled ? wDown : wUp);
|
||||
break;
|
||||
}
|
||||
case wPageDown:
|
||||
{
|
||||
if (m_cyclic_scroll_enabled && itsHighlight == MaxHighlight)
|
||||
if (m_cyclic_scroll_enabled && m_highlight == max_highlight)
|
||||
return Scroll(wHome);
|
||||
itsHighlight += itsHeight;
|
||||
itsBeginning += itsHeight;
|
||||
if (itsBeginning > MaxBeginning)
|
||||
{
|
||||
itsBeginning = MaxBeginning;
|
||||
if (itsHighlight > MaxHighlight)
|
||||
itsHighlight = MaxHighlight;
|
||||
}
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == MaxHighlight && !m_cyclic_scroll_enabled ? wUp : wDown);
|
||||
}
|
||||
m_highlight += itsHeight;
|
||||
m_beginning += itsHeight;
|
||||
m_beginning = std::min(m_beginning, max_beginning);
|
||||
m_highlight = std::min(m_highlight, max_highlight);
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(m_highlight == max_highlight && !m_cyclic_scroll_enabled ? wUp : wDown);
|
||||
break;
|
||||
}
|
||||
case wHome:
|
||||
{
|
||||
itsHighlight = 0;
|
||||
itsBeginning = 0;
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == 0 ? wDown : wUp);
|
||||
}
|
||||
m_highlight = 0;
|
||||
m_beginning = 0;
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(wDown);
|
||||
break;
|
||||
}
|
||||
case wEnd:
|
||||
{
|
||||
itsHighlight = MaxHighlight;
|
||||
itsBeginning = MaxBeginning;
|
||||
if ((*m_options_ptr)[itsHighlight]->isSeparator() || (*m_options_ptr)[itsHighlight]->isInactive())
|
||||
{
|
||||
Scroll(itsHighlight == MaxHighlight ? wUp : wDown);
|
||||
}
|
||||
m_highlight = max_highlight;
|
||||
m_beginning = max_beginning;
|
||||
if (!isHighlightable(m_highlight))
|
||||
Scroll(wUp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_autocenter_cursor)
|
||||
Highlight(itsHighlight);
|
||||
Highlight(m_highlight);
|
||||
}
|
||||
|
||||
template <typename T> void Menu<T>::Reset()
|
||||
{
|
||||
itsHighlight = 0;
|
||||
itsBeginning = 0;
|
||||
m_highlight = 0;
|
||||
m_beginning = 0;
|
||||
}
|
||||
|
||||
template <typename T> void Menu<T>::ClearFiltered()
|
||||
@@ -936,8 +913,12 @@ template <typename T> void Menu<T>::GetSelected(std::vector<size_t> &v) const
|
||||
|
||||
template <typename T> void Menu<T>::Highlight(size_t pos)
|
||||
{
|
||||
itsHighlight = pos;
|
||||
itsBeginning = pos-itsHeight/2;
|
||||
m_highlight = pos;
|
||||
size_t half_height = itsHeight/2;
|
||||
if (pos < half_height)
|
||||
m_beginning = 0;
|
||||
else
|
||||
m_beginning = pos-half_height;
|
||||
}
|
||||
|
||||
template <typename T> size_t Menu<T>::Size() const
|
||||
@@ -947,13 +928,13 @@ template <typename T> size_t Menu<T>::Size() const
|
||||
|
||||
template <typename T> size_t Menu<T>::Choice() const
|
||||
{
|
||||
return itsHighlight;
|
||||
return m_highlight;
|
||||
}
|
||||
|
||||
template <typename T> size_t Menu<T>::RealChoice() const
|
||||
{
|
||||
size_t result = 0;
|
||||
for (auto it = m_options_ptr->begin(); it != m_options_ptr->begin()+itsHighlight; ++it)
|
||||
for (auto it = m_options_ptr->begin(); it != m_options_ptr->begin()+m_highlight; ++it)
|
||||
if (!(*it)->isInactive())
|
||||
result++;
|
||||
return result;
|
||||
@@ -990,7 +971,7 @@ template <typename T> void Menu<T>::NextFound(bool wrap)
|
||||
{
|
||||
if (m_found_positions.empty())
|
||||
return;
|
||||
std::set<size_t>::iterator next = m_found_positions.upper_bound(itsHighlight);
|
||||
std::set<size_t>::iterator next = m_found_positions.upper_bound(m_highlight);
|
||||
if (next != m_found_positions.end())
|
||||
Highlight(*next);
|
||||
else if (wrap)
|
||||
@@ -1001,7 +982,7 @@ template <typename T> void Menu<T>::PrevFound(bool wrap)
|
||||
{
|
||||
if (m_found_positions.empty())
|
||||
return;
|
||||
std::set<size_t>::iterator prev = m_found_positions.lower_bound(itsHighlight);
|
||||
std::set<size_t>::iterator prev = m_found_positions.lower_bound(m_highlight);
|
||||
if (prev != m_found_positions.begin())
|
||||
Highlight(*--prev);
|
||||
else if (wrap)
|
||||
@@ -1045,10 +1026,10 @@ template <typename T> const std::string &Menu<T>::GetFilter()
|
||||
|
||||
template <typename T> std::string Menu<T>::GetItem(size_t pos)
|
||||
{
|
||||
if (m_options_ptr->at(pos) && m_get_string_helper)
|
||||
return m_get_string_helper((*m_options_ptr)[pos]->value());
|
||||
else
|
||||
return "";
|
||||
std::string result;
|
||||
if (m_get_string_helper)
|
||||
result = m_get_string_helper((*m_options_ptr)[pos]->value());
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T> typename Menu<T>::Item &Menu<T>::Back()
|
||||
@@ -1063,12 +1044,12 @@ template <typename T> const typename Menu<T>::Item &Menu<T>::Back() const
|
||||
|
||||
template <typename T> typename Menu<T>::Item &Menu<T>::Current()
|
||||
{
|
||||
return *(*m_options_ptr)[itsHighlight];
|
||||
return *(*m_options_ptr)[m_highlight];
|
||||
}
|
||||
|
||||
template <typename T> const typename Menu<T>::Item &Menu<T>::Current() const
|
||||
{
|
||||
return *(*m_options_ptr)[itsHighlight];
|
||||
return *(*m_options_ptr)[m_highlight];
|
||||
}
|
||||
|
||||
template <typename T> typename Menu<T>::Item &Menu<T>::at(size_t pos)
|
||||
@@ -1083,11 +1064,13 @@ template <typename T> const typename Menu<T>::Item &Menu<T>::at(size_t pos) cons
|
||||
|
||||
template <typename T> const typename Menu<T>::Item &Menu<T>::operator[](size_t pos) const
|
||||
{
|
||||
assert(m_options_ptr->size() > pos);
|
||||
return *(*m_options_ptr)[pos];
|
||||
}
|
||||
|
||||
template <typename T> typename Menu<T>::Item &Menu<T>::operator[](size_t pos)
|
||||
{
|
||||
assert(m_options_ptr->size() > pos);
|
||||
return *(*m_options_ptr)[pos];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user