Replace highlight colors with prefixes and suffixes

This commit is contained in:
Andrzej Rybczak
2017-03-28 11:31:09 +02:00
parent 8134e6e23b
commit 19d32648ed
32 changed files with 364 additions and 155 deletions

View File

@@ -23,22 +23,37 @@
#include <boost/optional.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include "window.h"
#include "curses/window.h"
#include "utility/storage_kind.h"
namespace NC {
struct FormattedColor
{
template <StorageKind storage = StorageKind::Reference>
struct End
{
End(const FormattedColor &fc)
explicit End(const FormattedColor &fc)
: m_fc(fc)
{ }
const FormattedColor &base() const { return m_fc; }
template <StorageKind otherStorage>
bool operator==(const End<otherStorage> &rhs) const
{
return m_fc == rhs.m_fc;
}
explicit operator End<StorageKind::Value>() const
{
return End<StorageKind::Value>(m_fc);
}
private:
const FormattedColor &m_fc;
typename std::conditional<storage == StorageKind::Reference,
const FormattedColor &,
FormattedColor>::type m_fc;
};
typedef std::vector<Format> Formats;
@@ -55,6 +70,12 @@ private:
Formats m_formats;
};
inline bool operator==(const FormattedColor &lhs, const FormattedColor &rhs)
{
return lhs.color() == rhs.color()
&& lhs.formats() == rhs.formats();
}
std::istream &operator>>(std::istream &is, FormattedColor &fc);
template <typename OutputStreamT>
@@ -66,8 +87,9 @@ OutputStreamT &operator<<(OutputStreamT &os, const FormattedColor &fc)
return os;
}
template <typename OutputStreamT>
OutputStreamT &operator<<(OutputStreamT &os, const FormattedColor::End &rfc)
template <typename OutputStreamT, StorageKind storage>
OutputStreamT &operator<<(OutputStreamT &os,
const FormattedColor::End<storage> &rfc)
{
if (rfc.base().color() != Color::Default)
os << Color::End;

View File

@@ -29,9 +29,10 @@
#include <memory>
#include <set>
#include "curses/formatted_color.h"
#include "curses/strbuffer.h"
#include "curses/window.h"
#include "utility/const.h"
#include "strbuffer.h"
#include "window.h"
namespace NC {
@@ -367,11 +368,13 @@ struct Menu: Window, List
/// Note that the passed variable is not deleted along with menu object.
/// @param b pointer to buffer that contains the suffix
void setSelectedSuffix(const Buffer &b) { m_selected_suffix = b; }
/// Sets custom color of highlighted position
/// @param col custom color
void setHighlightColor(Color color) { m_highlight_color = std::move(color); }
void setHighlightPrefix(const Buffer &b) { m_highlight_prefix = b; }
void setHighlightSuffix(const Buffer &b) { m_highlight_suffix = b; }
const Buffer &highlightPrefix() const { return m_highlight_prefix; }
const Buffer &highlightSuffix() const { return m_highlight_suffix; }
/// @return state of highlighting
bool isHighlighted() { return m_highlight_enabled; }
@@ -496,14 +499,16 @@ private:
size_t m_beginning;
size_t m_highlight;
Color m_highlight_color;
bool m_highlight_enabled;
bool m_cyclic_scroll_enabled;
bool m_autocenter_cursor;
size_t m_drawn_position;
Buffer m_highlight_prefix;
Buffer m_highlight_suffix;
Buffer m_selected_prefix;
Buffer m_selected_suffix;
};

View File

@@ -39,16 +39,18 @@ Menu<ItemT>::Menu(size_t startx,
const std::string &title,
Color color,
Border border)
: Window(startx, starty, width, height, title, std::move(color), border)
: Window(startx, starty, width, height, title, color, border)
, m_item_displayer(nullptr)
, m_filter_predicate(nullptr)
, m_beginning(0)
, m_highlight(0)
, m_highlight_color(m_base_color)
, m_highlight_enabled(true)
, m_cyclic_scroll_enabled(false)
, m_autocenter_cursor(false)
{
auto fc = FormattedColor(m_base_color, {Format::Reverse});
m_highlight_prefix << fc;
m_highlight_suffix << FormattedColor::End<>(fc);
m_items = &m_all_items;
}
@@ -59,11 +61,12 @@ Menu<ItemT>::Menu(const Menu &rhs)
, m_filter_predicate(rhs.m_filter_predicate)
, m_beginning(rhs.m_beginning)
, m_highlight(rhs.m_highlight)
, m_highlight_color(rhs.m_highlight_color)
, m_highlight_enabled(rhs.m_highlight_enabled)
, m_cyclic_scroll_enabled(rhs.m_cyclic_scroll_enabled)
, m_autocenter_cursor(rhs.m_autocenter_cursor)
, m_drawn_position(rhs.m_drawn_position)
, m_highlight_prefix(rhs.m_highlight_prefix)
, m_highlight_suffix(rhs.m_highlight_suffix)
, m_selected_prefix(rhs.m_selected_prefix)
, m_selected_suffix(rhs.m_selected_suffix)
{
@@ -83,11 +86,12 @@ Menu<ItemT>::Menu(Menu &&rhs)
, m_filtered_items(std::move(rhs.m_filtered_items))
, m_beginning(rhs.m_beginning)
, m_highlight(rhs.m_highlight)
, m_highlight_color(rhs.m_highlight_color)
, m_highlight_enabled(rhs.m_highlight_enabled)
, m_cyclic_scroll_enabled(rhs.m_cyclic_scroll_enabled)
, m_autocenter_cursor(rhs.m_autocenter_cursor)
, m_drawn_position(rhs.m_drawn_position)
, m_highlight_prefix(std::move(rhs.m_highlight_prefix))
, m_highlight_suffix(std::move(rhs.m_highlight_suffix))
, m_selected_prefix(std::move(rhs.m_selected_prefix))
, m_selected_suffix(std::move(rhs.m_selected_suffix))
{
@@ -107,11 +111,12 @@ Menu<ItemT> &Menu<ItemT>::operator=(Menu rhs)
std::swap(m_filtered_items, rhs.m_filtered_items);
std::swap(m_beginning, rhs.m_beginning);
std::swap(m_highlight, rhs.m_highlight);
std::swap(m_highlight_color, rhs.m_highlight_color);
std::swap(m_highlight_enabled, rhs.m_highlight_enabled);
std::swap(m_cyclic_scroll_enabled, rhs.m_cyclic_scroll_enabled);
std::swap(m_autocenter_cursor, rhs.m_autocenter_cursor);
std::swap(m_drawn_position, rhs.m_drawn_position);
std::swap(m_highlight_prefix, rhs.m_highlight_prefix);
std::swap(m_highlight_suffix, rhs.m_highlight_suffix);
std::swap(m_selected_prefix, rhs.m_selected_prefix);
std::swap(m_selected_suffix, rhs.m_selected_suffix);
if (rhs.m_items == &rhs.m_all_items)
@@ -211,10 +216,7 @@ void Menu<ItemT>::refresh()
continue;
}
if (m_highlight_enabled && m_drawn_position == m_highlight)
{
*this << Format::Reverse;
*this << m_highlight_color;
}
*this << m_highlight_prefix;
if ((*m_items)[m_drawn_position].isSelected())
*this << m_selected_prefix;
*this << NC::TermManip::ClearToEOL;
@@ -223,10 +225,7 @@ void Menu<ItemT>::refresh()
if ((*m_items)[m_drawn_position].isSelected())
*this << m_selected_suffix;
if (m_highlight_enabled && m_drawn_position == m_highlight)
{
*this << Color::End;
*this << Format::NoReverse;
}
*this << m_highlight_suffix;
}
Window::refresh();
}

View File

@@ -22,12 +22,14 @@
#include <boost/regex.hpp>
#include <iostream>
#include "scrollpad.h"
#include "curses/scrollpad.h"
#include "utility/storage_kind.h"
namespace {
template <typename PropT>
bool regexSearch(NC::Buffer &buf, PropT begin, const std::string &ws, PropT end, boost::regex::flag_type flags, size_t id)
template <typename BeginT, typename EndT>
bool regexSearch(NC::Buffer &buf, const BeginT &begin, const std::string &ws,
const EndT &end, boost::regex::flag_type flags, size_t id)
{
try {
boost::regex rx(ws, flags);
@@ -269,16 +271,29 @@ void Scrollpad::reset()
m_beginning = 0;
}
bool Scrollpad::setProperties(Color begin, const std::string &s, Color end, size_t flags, size_t id)
bool Scrollpad::setProperties(const Color &begin, const std::string &s,
const Color &end, size_t flags, size_t id)
{
return regexSearch(m_buffer, std::move(begin), s, std::move(end), id, flags);
}
bool Scrollpad::setProperties(Format begin, const std::string &s, Format end, size_t flags, size_t id)
bool Scrollpad::setProperties(const Format &begin, const std::string &s,
const Format &end, size_t flags, size_t id)
{
return regexSearch(m_buffer, begin, s, end, flags, id);
}
bool Scrollpad::setProperties(const FormattedColor &fc, const std::string &s,
size_t flags, size_t id)
{
return regexSearch(m_buffer,
fc,
s,
FormattedColor::End<StorageKind::Value>(fc),
flags,
id);
}
void Scrollpad::removeProperties(size_t id)
{
m_buffer.removeProperties(id);

View File

@@ -21,8 +21,8 @@
#ifndef NCMPCPP_SCROLLPAD_H
#define NCMPCPP_SCROLLPAD_H
#include "window.h"
#include "strbuffer.h"
#include "curses/window.h"
#include "curses/strbuffer.h"
namespace NC {
@@ -46,9 +46,11 @@ struct Scrollpad: public Window
void flush();
void reset();
bool setProperties(Color begin, const std::string &s, Color end,
bool setProperties(const Color &begin, const std::string &s, const Color &end,
size_t flags, size_t id = -2);
bool setProperties(Format begin, const std::string &s, Format end,
bool setProperties(const Format &begin, const std::string &s, const Format &end,
size_t flags, size_t id = -2);
bool setProperties(const FormattedColor &fc, const std::string &s,
size_t flags, size_t id = -2);
void removeProperties(size_t id = -2);

View File

@@ -24,7 +24,8 @@
#include <boost/lexical_cast.hpp>
#include <boost/variant.hpp>
#include <map>
#include "window.h"
#include "curses/formatted_color.h"
#include "curses/window.h"
namespace NC {
@@ -40,6 +41,11 @@ template <typename CharT> class BasicBuffer
size_t id() const { return m_id; }
bool operator==(const Property &rhs) const
{
return m_id == rhs.m_id && m_impl == rhs.m_impl;
}
template <typename OutputStreamT>
friend OutputStreamT &operator<<(OutputStreamT &os, const Property &p)
{
@@ -48,7 +54,11 @@ template <typename CharT> class BasicBuffer
}
private:
boost::variant<Color, Format> m_impl;
boost::variant<Color,
Format,
FormattedColor,
FormattedColor::End<StorageKind::Value>
> m_impl;
size_t m_id;
};
@@ -131,18 +141,18 @@ public:
return *this;
}
BasicBuffer<CharT> &operator<<(Color color)
BasicBuffer<CharT> &operator<<(const Color &color)
{
addProperty(m_string.size(), color);
return *this;
}
BasicBuffer<CharT> &operator<<(Format format)
BasicBuffer<CharT> &operator<<(const Format &format)
{
addProperty(m_string.size(), format);
return *this;
}
// static variadic initializer. used instead of a proper constructor because
// it's too polymorphic and would end up invoked as a copy/move constructor.
template <typename... Args>
@@ -169,6 +179,14 @@ private:
typedef BasicBuffer<char> Buffer;
typedef BasicBuffer<wchar_t> WBuffer;
template <typename CharT>
bool operator==(const BasicBuffer<CharT> &lhs, const BasicBuffer<CharT> &rhs)
{
return lhs.str() == rhs.str()
&& lhs.properties() == rhs.properties();
}
template <typename OutputStreamT, typename CharT>
OutputStreamT &operator<<(OutputStreamT &os, const BasicBuffer<CharT> &buffer)
{

View File

@@ -510,6 +510,7 @@ Window::Window(const Window &rhs)
, m_reverse_counter(rhs.m_reverse_counter)
, m_alt_charset_counter(rhs.m_alt_charset_counter)
{
setColor(m_color);
}
Window::Window(Window &&rhs)