window: change internal color representation
This commit is contained in:
@@ -58,7 +58,7 @@ Clock::Clock()
|
|||||||
Width = Config.clock_display_seconds ? 60 : 40;
|
Width = Config.clock_display_seconds ? 60 : 40;
|
||||||
|
|
||||||
m_pane = NC::Window(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::Border::None);
|
m_pane = NC::Window(0, MainStartY, COLS, MainHeight, "", Config.main_color, NC::Border::None);
|
||||||
w = NC::Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, NC::Border(Config.main_color));
|
w = NC::Window((COLS-Width)/2, (MainHeight-Height)/2+MainStartY, Width, Height-1, "", Config.main_color, NC::Border(Config.main_color.foreground()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clock::resize()
|
void Clock::resize()
|
||||||
@@ -129,9 +129,9 @@ void Clock::update()
|
|||||||
|
|
||||||
char buf[64];
|
char buf[64];
|
||||||
std::strftime(buf, 64, "%x", &time);
|
std::strftime(buf, 64, "%x", &time);
|
||||||
attron(COLOR_PAIR(int(Config.main_color)));
|
color_set(Config.main_color.pairNumber(), nullptr);
|
||||||
mvprintw(w.getStarty()+w.getHeight(), w.getStartX()+(w.getWidth()-strlen(buf))/2, "%s", buf);
|
mvprintw(w.getStarty()+w.getHeight(), w.getStartX()+(w.getWidth()-strlen(buf))/2, "%s", buf);
|
||||||
attroff(COLOR_PAIR(int(Config.main_color)));
|
standend();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
for (int k = 0; k < 6; ++k)
|
for (int k = 0; k < 6; ++k)
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ void showSongs(NC::Menu<T> &menu, const MPD::Song &s, const ProxySongList &pl, c
|
|||||||
else if (isdigit(*it)) // color
|
else if (isdigit(*it)) // color
|
||||||
{
|
{
|
||||||
if (!discard_colors)
|
if (!discard_colors)
|
||||||
menu << NC::Color(*it-'0');
|
menu << charToColor(*it);
|
||||||
}
|
}
|
||||||
else if (*it == 'R') // right align
|
else if (*it == 'R') // right align
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "utility/string.h"
|
#include "utility/string.h"
|
||||||
|
#include "utility/type_conversions.h"
|
||||||
#include "utility/wide_string.h"
|
#include "utility/wide_string.h"
|
||||||
|
|
||||||
template <typename Iterator, typename PredicateT>
|
template <typename Iterator, typename PredicateT>
|
||||||
@@ -344,7 +345,7 @@ void stringToBuffer(Iterator first, Iterator last, NC::BasicBuffer<typename Iter
|
|||||||
}
|
}
|
||||||
else if (isdigit(*it))
|
else if (isdigit(*it))
|
||||||
{
|
{
|
||||||
buf << NC::Color(*it-'0');
|
buf << charToColor(*it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
|
|
||||||
/// Sets custom color of highlighted position
|
/// Sets custom color of highlighted position
|
||||||
/// @param col custom color
|
/// @param col custom color
|
||||||
void setHighlightColor(Color color) { m_highlight_color = color; }
|
void setHighlightColor(Color color) { m_highlight_color = std::move(color); }
|
||||||
|
|
||||||
/// @return state of highlighting
|
/// @return state of highlighting
|
||||||
bool isHighlighted() { return m_highlight_enabled; }
|
bool isHighlighted() { return m_highlight_enabled; }
|
||||||
@@ -323,7 +323,7 @@ Menu<ItemT>::Menu(size_t startx,
|
|||||||
const std::string &title,
|
const std::string &title,
|
||||||
Color color,
|
Color color,
|
||||||
Border border)
|
Border border)
|
||||||
: Window(startx, starty, width, height, title, color, border),
|
: Window(startx, starty, width, height, title, std::move(color), border),
|
||||||
m_item_displayer(0),
|
m_item_displayer(0),
|
||||||
m_beginning(0),
|
m_beginning(0),
|
||||||
m_highlight(0),
|
m_highlight(0),
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ int main(int argc, char **argv)
|
|||||||
cerr_buffer = std::cerr.rdbuf();
|
cerr_buffer = std::cerr.rdbuf();
|
||||||
std::cerr.rdbuf(errorlog.rdbuf());
|
std::cerr.rdbuf(errorlog.rdbuf());
|
||||||
|
|
||||||
NC::initScreen("ncmpcpp ver. " VERSION, Config.colors_enabled);
|
NC::initScreen(Config.colors_enabled);
|
||||||
|
|
||||||
Actions::OriginalStatusbarVisibility = Config.statusbar_visibility;
|
Actions::OriginalStatusbarVisibility = Config.statusbar_visibility;
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ using Global::myInactiveScreen;
|
|||||||
|
|
||||||
void drawSeparator(int x)
|
void drawSeparator(int x)
|
||||||
{
|
{
|
||||||
attron(COLOR_PAIR(int(Config.main_color)));
|
color_set(Config.main_color.pairNumber(), nullptr);
|
||||||
mvvline(Global::MainStartY, x, 0, Global::MainHeight);
|
mvvline(Global::MainStartY, x, 0, Global::MainHeight);
|
||||||
attroff(COLOR_PAIR(int(Config.main_color)));
|
standend();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void Scrollpad::clear()
|
|||||||
delwin(m_window);
|
delwin(m_window);
|
||||||
m_window = newpad(m_height, m_width);
|
m_window = newpad(m_height, m_width);
|
||||||
setTimeout(m_window_timeout);
|
setTimeout(m_window_timeout);
|
||||||
setColor(m_color, m_bg_color);
|
setColor(m_color);
|
||||||
keypad(m_window, 1);
|
keypad(m_window, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ void Scrollpad::reset()
|
|||||||
|
|
||||||
bool Scrollpad::setProperties(Color begin, const std::string &s, Color end, size_t id, boost::regex::flag_type flags)
|
bool Scrollpad::setProperties(Color begin, const std::string &s, Color end, size_t id, boost::regex::flag_type flags)
|
||||||
{
|
{
|
||||||
return regexSearch(m_buffer, begin, s, end, id, flags);
|
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 id, boost::regex::flag_type flags)
|
bool Scrollpad::setProperties(Format begin, const std::string &s, Format end, size_t id, boost::regex::flag_type flags)
|
||||||
|
|||||||
@@ -671,19 +671,18 @@ void Status::Changes::flags()
|
|||||||
|
|
||||||
// this is done by raw ncurses because creating another
|
// this is done by raw ncurses because creating another
|
||||||
// window only for handling this is quite silly
|
// window only for handling this is quite silly
|
||||||
attrset(A_BOLD|COLOR_PAIR(int(Config.state_line_color)));
|
attrset(A_BOLD);
|
||||||
|
color_set(Config.state_line_color.pairNumber(), nullptr);
|
||||||
mvhline(1, 0, 0, COLS);
|
mvhline(1, 0, 0, COLS);
|
||||||
if (!switch_state.empty())
|
if (!switch_state.empty())
|
||||||
{
|
{
|
||||||
mvprintw(1, COLS-switch_state.length()-3, "[");
|
mvprintw(1, COLS-switch_state.length()-3, "[");
|
||||||
attroff(COLOR_PAIR(int(Config.state_line_color)));
|
color_set(Config.state_flags_color.pairNumber(), nullptr);
|
||||||
attron(COLOR_PAIR(int(Config.state_flags_color)));
|
|
||||||
mvprintw(1, COLS-switch_state.length()-2, "%s", switch_state.c_str());
|
mvprintw(1, COLS-switch_state.length()-2, "%s", switch_state.c_str());
|
||||||
attroff(COLOR_PAIR(int(Config.state_flags_color)));
|
color_set(Config.state_line_color.pairNumber(), nullptr);
|
||||||
attron(COLOR_PAIR(int(Config.state_line_color)));
|
|
||||||
mvprintw(1, COLS-2, "]");
|
mvprintw(1, COLS-2, "]");
|
||||||
}
|
}
|
||||||
attrset(0);
|
standend();
|
||||||
refresh();
|
refresh();
|
||||||
break;
|
break;
|
||||||
case Design::Alternative:
|
case Design::Alternative:
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ template <typename CharT> class BasicBuffer
|
|||||||
enum class Type { Color, Format };
|
enum class Type { Color, Format };
|
||||||
|
|
||||||
Property(size_t position_, NC::Color color_, int id_)
|
Property(size_t position_, NC::Color color_, int id_)
|
||||||
: m_type(Type::Color), m_position(position_), m_color(color_), m_id(id_) { }
|
: m_type(Type::Color), m_position(position_), m_color(std::move(color_)), m_id(id_) { }
|
||||||
Property(size_t position_, NC::Format format_, int id_)
|
Property(size_t position_, NC::Format format_, int id_)
|
||||||
: m_type(Type::Format), m_position(position_), m_format(format_), m_id(id_) { }
|
: m_type(Type::Format), m_position(position_), m_format(format_), m_id(id_) { }
|
||||||
|
|
||||||
@@ -94,15 +94,15 @@ public:
|
|||||||
const Properties &properties() const { return m_properties; }
|
const Properties &properties() const { return m_properties; }
|
||||||
|
|
||||||
template <typename PropertyT>
|
template <typename PropertyT>
|
||||||
void setProperty(size_t position, PropertyT property, size_t id = -1)
|
void setProperty(size_t position, PropertyT &&property, size_t id = -1)
|
||||||
{
|
{
|
||||||
m_properties.insert(Property(position, property, id));
|
m_properties.insert(Property(position, std::forward<PropertyT>(property), id));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PropertyT>
|
template <typename PropertyT>
|
||||||
bool removeProperty(size_t position, PropertyT property, size_t id = -1)
|
bool removeProperty(size_t position, PropertyT &&property, size_t id = -1)
|
||||||
{
|
{
|
||||||
auto it = m_properties.find(Property(position, property, id));
|
auto it = m_properties.find(Property(position, std::forward<PropertyT>(property), id));
|
||||||
bool found = it != m_properties.end();
|
bool found = it != m_properties.end();
|
||||||
if (found)
|
if (found)
|
||||||
m_properties.erase(it);
|
m_properties.erase(it);
|
||||||
|
|||||||
@@ -21,6 +21,35 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include "utility/type_conversions.h"
|
#include "utility/type_conversions.h"
|
||||||
|
|
||||||
|
NC::Color charToColor(char c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '0':
|
||||||
|
return NC::Color::Default;
|
||||||
|
case '1':
|
||||||
|
return NC::Color::Black;
|
||||||
|
case '2':
|
||||||
|
return NC::Color::Red;
|
||||||
|
case '3':
|
||||||
|
return NC::Color::Green;
|
||||||
|
case '4':
|
||||||
|
return NC::Color::Yellow;
|
||||||
|
case '5':
|
||||||
|
return NC::Color::Blue;
|
||||||
|
case '6':
|
||||||
|
return NC::Color::Magenta;
|
||||||
|
case '7':
|
||||||
|
return NC::Color::Cyan;
|
||||||
|
case '8':
|
||||||
|
return NC::Color::White;
|
||||||
|
case '9':
|
||||||
|
return NC::Color::End;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("invalid character");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NC::Color stringToColor(const std::string &color)
|
NC::Color stringToColor(const std::string &color)
|
||||||
{
|
{
|
||||||
NC::Color result = NC::Color::Default;
|
NC::Color result = NC::Color::Default;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
|
||||||
|
NC::Color charToColor(char c);
|
||||||
|
|
||||||
NC::Color stringToColor(const std::string &color);
|
NC::Color stringToColor(const std::string &color);
|
||||||
NC::Border stringToBorder(const std::string &border);
|
NC::Border stringToBorder(const std::string &border);
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ const int fps = 25;
|
|||||||
|
|
||||||
// toColor: a scaling function for coloring. For numbers 0 to max this function returns
|
// toColor: a scaling function for coloring. For numbers 0 to max this function returns
|
||||||
// a coloring from the lowest color to the highest, and colors will not loop from 0 to max.
|
// a coloring from the lowest color to the highest, and colors will not loop from 0 to max.
|
||||||
NC::Color toColor(size_t number, size_t max, bool wrap = true)
|
const NC::Color &toColor(size_t number, size_t max, bool wrap = true)
|
||||||
{
|
{
|
||||||
const auto colors_size = Config.visualizer_colors.size();
|
const auto colors_size = Config.visualizer_colors.size();
|
||||||
const auto index = (number * colors_size) / max;
|
const auto index = (number * colors_size) / max;
|
||||||
|
|||||||
200
src/window.cpp
200
src/window.cpp
@@ -38,6 +38,7 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
namespace rl {
|
namespace rl {
|
||||||
|
|
||||||
bool aborted;
|
bool aborted;
|
||||||
@@ -194,43 +195,43 @@ int add_base()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NC {//
|
namespace NC {
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, Color c)
|
Color Color::Default(0, -1, true, false);
|
||||||
|
Color Color::Black(COLOR_BLACK, -1);
|
||||||
|
Color Color::Red(COLOR_RED, -1);
|
||||||
|
Color Color::Green(COLOR_GREEN, -1);
|
||||||
|
Color Color::Yellow(COLOR_YELLOW, -1);
|
||||||
|
Color Color::Blue(COLOR_BLUE, -1);
|
||||||
|
Color Color::Magenta(COLOR_MAGENTA, -1);
|
||||||
|
Color Color::Cyan(COLOR_CYAN, -1);
|
||||||
|
Color Color::White(COLOR_WHITE, -1);
|
||||||
|
Color Color::End(0, 0, false, true);
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const Color &c)
|
||||||
{
|
{
|
||||||
switch (c)
|
if (c.isDefault())
|
||||||
{
|
os << "default";
|
||||||
case Color::Default:
|
else if (c == Color::Black)
|
||||||
os << "default";
|
os << "black";
|
||||||
break;
|
else if (c == Color::Red)
|
||||||
case Color::Black:
|
os << "red";
|
||||||
os << "black";
|
else if (c == Color::Green)
|
||||||
break;
|
os << "green";
|
||||||
case Color::Red:
|
else if (c == Color::Yellow)
|
||||||
os << "red";
|
os << "yellow";
|
||||||
break;
|
else if (c == Color::Blue)
|
||||||
case Color::Green:
|
os << "blue";
|
||||||
os << "green";
|
else if (c == Color::Magenta)
|
||||||
break;
|
os << "magenta";
|
||||||
case Color::Yellow:
|
else if (c == Color::Cyan)
|
||||||
os << "yellow";
|
os << "cyan";
|
||||||
break;
|
else if (c == Color::White)
|
||||||
case Color::Blue:
|
os << "white";
|
||||||
os << "blue";
|
else if (c.isEnd())
|
||||||
break;
|
os << "color_end";
|
||||||
case Color::Magenta:
|
else
|
||||||
os << "magenta";
|
os << "color_" << c.foreground() << "_" << c.background();
|
||||||
break;
|
|
||||||
case Color::Cyan:
|
|
||||||
os << "cyan";
|
|
||||||
break;
|
|
||||||
case Color::White:
|
|
||||||
os << "white";
|
|
||||||
break;
|
|
||||||
case Color::End:
|
|
||||||
os << "color_end";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,31 +387,19 @@ std::ostream &operator<<(std::ostream &os, Scroll s)
|
|||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initScreen(GNUC_UNUSED const char *window_title, bool enable_colors)
|
void initScreen(bool enable_colors)
|
||||||
{
|
{
|
||||||
const int ColorsTable[] =
|
|
||||||
{
|
|
||||||
COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
|
|
||||||
COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE
|
|
||||||
};
|
|
||||||
# ifdef XCURSES
|
|
||||||
Xinitscr(1, const_cast<char **>(&window_title));
|
|
||||||
# else
|
|
||||||
initscr();
|
initscr();
|
||||||
# endif // XCURSES
|
|
||||||
if (has_colors() && enable_colors)
|
if (has_colors() && enable_colors)
|
||||||
{
|
{
|
||||||
start_color();
|
start_color();
|
||||||
use_default_colors();
|
use_default_colors();
|
||||||
int num = 1;
|
int npair = 1;
|
||||||
# ifdef USE_PDCURSES
|
for (int bg = -1; bg < COLORS; ++bg)
|
||||||
int i = 0;
|
{
|
||||||
# else
|
for (int fg = 0; npair < COLOR_PAIRS && fg < COLORS; ++fg, ++npair)
|
||||||
int i = -1;
|
init_pair(npair, fg, bg);
|
||||||
# endif // USE_PDCURSES
|
}
|
||||||
for (; i < 8; ++i)
|
|
||||||
for (int j = 0; j < 8; ++j)
|
|
||||||
init_pair(num++, ColorsTable[j], i < 0 ? i : ColorsTable[i]);
|
|
||||||
}
|
}
|
||||||
raw();
|
raw();
|
||||||
nonl();
|
nonl();
|
||||||
@@ -450,6 +439,22 @@ void destroyScreen()
|
|||||||
endwin();
|
endwin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Color::pairNumber() const
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
if (isDefault())
|
||||||
|
result = 0;
|
||||||
|
else if (isEnd())
|
||||||
|
throw std::logic_error("'end' doesn't have a corresponding pair number");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = background();
|
||||||
|
result *= COLORS;
|
||||||
|
result += foreground();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Window::Window(size_t startx,
|
Window::Window(size_t startx,
|
||||||
size_t starty,
|
size_t starty,
|
||||||
size_t width,
|
size_t width,
|
||||||
@@ -465,9 +470,7 @@ Window::Window(size_t startx,
|
|||||||
m_height(height),
|
m_height(height),
|
||||||
m_window_timeout(-1),
|
m_window_timeout(-1),
|
||||||
m_color(color),
|
m_color(color),
|
||||||
m_bg_color(Color::Default),
|
|
||||||
m_base_color(color),
|
m_base_color(color),
|
||||||
m_base_bg_color(Color::Default),
|
|
||||||
m_border(border),
|
m_border(border),
|
||||||
m_prompt_hook(0),
|
m_prompt_hook(0),
|
||||||
m_title(title),
|
m_title(title),
|
||||||
@@ -513,9 +516,7 @@ Window::Window(const Window &rhs)
|
|||||||
, m_height(rhs.m_height)
|
, m_height(rhs.m_height)
|
||||||
, m_window_timeout(rhs.m_window_timeout)
|
, m_window_timeout(rhs.m_window_timeout)
|
||||||
, m_color(rhs.m_color)
|
, m_color(rhs.m_color)
|
||||||
, m_bg_color(rhs.m_bg_color)
|
|
||||||
, m_base_color(rhs.m_base_color)
|
, m_base_color(rhs.m_base_color)
|
||||||
, m_base_bg_color(rhs.m_base_bg_color)
|
|
||||||
, m_border(rhs.m_border)
|
, m_border(rhs.m_border)
|
||||||
, m_prompt_hook(rhs.m_prompt_hook)
|
, m_prompt_hook(rhs.m_prompt_hook)
|
||||||
, m_title(rhs.m_title)
|
, m_title(rhs.m_title)
|
||||||
@@ -538,9 +539,7 @@ Window::Window(Window &&rhs)
|
|||||||
, m_height(rhs.m_height)
|
, m_height(rhs.m_height)
|
||||||
, m_window_timeout(rhs.m_window_timeout)
|
, m_window_timeout(rhs.m_window_timeout)
|
||||||
, m_color(rhs.m_color)
|
, m_color(rhs.m_color)
|
||||||
, m_bg_color(rhs.m_bg_color)
|
|
||||||
, m_base_color(rhs.m_base_color)
|
, m_base_color(rhs.m_base_color)
|
||||||
, m_base_bg_color(rhs.m_base_bg_color)
|
|
||||||
, m_border(rhs.m_border)
|
, m_border(rhs.m_border)
|
||||||
, m_prompt_hook(rhs.m_prompt_hook)
|
, m_prompt_hook(rhs.m_prompt_hook)
|
||||||
, m_title(std::move(rhs.m_title))
|
, m_title(std::move(rhs.m_title))
|
||||||
@@ -566,9 +565,7 @@ Window &Window::operator=(Window rhs)
|
|||||||
std::swap(m_height, rhs.m_height);
|
std::swap(m_height, rhs.m_height);
|
||||||
std::swap(m_window_timeout, rhs.m_window_timeout);
|
std::swap(m_window_timeout, rhs.m_window_timeout);
|
||||||
std::swap(m_color, rhs.m_color);
|
std::swap(m_color, rhs.m_color);
|
||||||
std::swap(m_bg_color, rhs.m_bg_color);
|
|
||||||
std::swap(m_base_color, rhs.m_base_color);
|
std::swap(m_base_color, rhs.m_base_color);
|
||||||
std::swap(m_base_bg_color, rhs.m_base_bg_color);
|
|
||||||
std::swap(m_border, rhs.m_border);
|
std::swap(m_border, rhs.m_border);
|
||||||
std::swap(m_prompt_hook, rhs.m_prompt_hook);
|
std::swap(m_prompt_hook, rhs.m_prompt_hook);
|
||||||
std::swap(m_title, rhs.m_title);
|
std::swap(m_title, rhs.m_title);
|
||||||
@@ -588,23 +585,20 @@ Window::~Window()
|
|||||||
delwin(m_border_window);
|
delwin(m_border_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setColor(Color fg, Color bg)
|
void Window::setColor(Color c)
|
||||||
{
|
{
|
||||||
if (fg == Color::Default)
|
if (c.isDefault())
|
||||||
fg = m_base_color;
|
c = m_base_color;
|
||||||
|
if (c != Color::Default)
|
||||||
if (fg != Color::Default)
|
wcolor_set(m_window, c.pairNumber(), nullptr);
|
||||||
wattron(m_window, COLOR_PAIR(int(bg)*8+int(fg)));
|
|
||||||
else
|
else
|
||||||
wattroff(m_window, COLOR_PAIR(int(m_color)));
|
wcolor_set(m_window, m_base_color.pairNumber(), nullptr);
|
||||||
m_color = fg;
|
m_color = std::move(c);
|
||||||
m_bg_color = bg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setBaseColor(Color fg, Color bg)
|
void Window::setBaseColor(Color c)
|
||||||
{
|
{
|
||||||
m_base_color = fg;
|
m_base_color = std::move(c);
|
||||||
m_base_bg_color = bg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setBorder(Border border)
|
void Window::setBorder(Border border)
|
||||||
@@ -663,7 +657,7 @@ void Window::recreate(size_t width, size_t height)
|
|||||||
delwin(m_window);
|
delwin(m_window);
|
||||||
m_window = newpad(height, width);
|
m_window = newpad(height, width);
|
||||||
setTimeout(m_window_timeout);
|
setTimeout(m_window_timeout);
|
||||||
setColor(m_color, m_bg_color);
|
setColor(m_color);
|
||||||
keypad(m_window, 1);
|
keypad(m_window, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +706,7 @@ void Window::refreshBorder() const
|
|||||||
if (m_border != Border::None)
|
if (m_border != Border::None)
|
||||||
attron(COLOR_PAIR(int(m_border)));
|
attron(COLOR_PAIR(int(m_border)));
|
||||||
else
|
else
|
||||||
attron(COLOR_PAIR(int(m_base_color)));
|
wcolor_set(m_border_window, m_base_color.pairNumber(), nullptr);
|
||||||
mvhline(m_start_y-1, m_start_x, 0, m_width);
|
mvhline(m_start_y-1, m_start_x, 0, m_width);
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
mvhline(m_start_y-2, m_start_x, 32, m_width); // clear title line
|
mvhline(m_start_y-2, m_start_x, 32, m_width); // clear title line
|
||||||
@@ -961,7 +955,7 @@ const std::string &Window::getTitle() const
|
|||||||
return m_title;
|
return m_title;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color Window::getColor() const
|
const Color &Window::getColor() const
|
||||||
{
|
{
|
||||||
return m_color;
|
return m_color;
|
||||||
}
|
}
|
||||||
@@ -1002,43 +996,27 @@ void Window::scroll(Scroll where)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Window &Window::operator<<(Colors colors)
|
Window &Window::operator<<(const Color &c)
|
||||||
{
|
{
|
||||||
if (colors.fg == Color::End || colors.bg == Color::End)
|
if (c.isDefault())
|
||||||
{
|
{
|
||||||
*this << Color::End;
|
while (!m_color_stack.empty())
|
||||||
return *this;
|
m_color_stack.pop();
|
||||||
|
setColor(m_base_color);
|
||||||
}
|
}
|
||||||
m_color_stack.push(colors);
|
else if (c.isEnd())
|
||||||
setColor(colors.fg, colors.bg);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Window &Window::operator<<(Color color)
|
|
||||||
{
|
|
||||||
switch (color)
|
|
||||||
{
|
{
|
||||||
case Color::Default:
|
if (!m_color_stack.empty())
|
||||||
while (!m_color_stack.empty())
|
m_color_stack.pop();
|
||||||
m_color_stack.pop();
|
if (!m_color_stack.empty())
|
||||||
setColor(m_base_color, m_base_bg_color);
|
setColor(m_color_stack.top());
|
||||||
break;
|
else
|
||||||
case Color::End:
|
setColor(m_base_color);
|
||||||
if (!m_color_stack.empty())
|
}
|
||||||
m_color_stack.pop();
|
else
|
||||||
if (!m_color_stack.empty())
|
{
|
||||||
setColor(m_color_stack.top().fg, m_color_stack.top().bg);
|
setColor(c);
|
||||||
else
|
m_color_stack.push(c);
|
||||||
setColor(m_base_color, m_base_bg_color);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Color bg;
|
|
||||||
if (m_color_stack.empty())
|
|
||||||
bg = m_bg_color;
|
|
||||||
else
|
|
||||||
bg = m_color_stack.top().bg;
|
|
||||||
m_color_stack.push(Colors(color, bg));
|
|
||||||
setColor(m_color_stack.top().fg, m_color_stack.top().bg);
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -1090,7 +1068,7 @@ Window &Window::operator<<(int (*f)(WINDOW *))
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window &Window::operator<<(XY coords)
|
Window &Window::operator<<(const XY &coords)
|
||||||
{
|
{
|
||||||
goToXY(coords.x, coords.y);
|
goToXY(coords.x, coords.y);
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
154
src/window.h
154
src/window.h
@@ -35,6 +35,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <tuple>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
// define some Ctrl-? keys
|
// define some Ctrl-? keys
|
||||||
@@ -125,11 +126,66 @@ private:
|
|||||||
std::string m_prompt;
|
std::string m_prompt;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Colors used by NCurses
|
struct Color
|
||||||
enum class Color { Default, Black, Red, Green, Yellow, Blue, Magenta, Cyan, White, End };
|
{
|
||||||
|
Color() : m_rep(0, -1, true, false) { }
|
||||||
|
Color(short foregound_value, short background_value = -1,
|
||||||
|
bool is_default = false, bool is_end = false)
|
||||||
|
: m_rep(foregound_value + 1, background_value + 1, is_default, is_end)
|
||||||
|
{
|
||||||
|
if (isDefault() && isEnd())
|
||||||
|
throw std::logic_error("Color flag can't be marked as both 'default' and 'end'");
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, Color c);
|
bool operator==(const Color &rhs) const
|
||||||
std::istream &operator>>(std::istream &is, Color &c);
|
{
|
||||||
|
return m_rep == rhs.m_rep;
|
||||||
|
}
|
||||||
|
bool operator!=(const Color &rhs) const
|
||||||
|
{
|
||||||
|
return m_rep != rhs.m_rep;
|
||||||
|
}
|
||||||
|
bool operator<(const Color &rhs) const
|
||||||
|
{
|
||||||
|
return m_rep < rhs.m_rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
short foreground() const
|
||||||
|
{
|
||||||
|
return std::get<0>(m_rep);
|
||||||
|
}
|
||||||
|
short background() const
|
||||||
|
{
|
||||||
|
return std::get<1>(m_rep);
|
||||||
|
}
|
||||||
|
bool isDefault() const
|
||||||
|
{
|
||||||
|
return std::get<2>(m_rep);
|
||||||
|
}
|
||||||
|
bool isEnd() const
|
||||||
|
{
|
||||||
|
return std::get<3>(m_rep);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pairNumber() const;
|
||||||
|
|
||||||
|
static Color Default;
|
||||||
|
static Color Black;
|
||||||
|
static Color Red;
|
||||||
|
static Color Green;
|
||||||
|
static Color Yellow;
|
||||||
|
static Color Blue;
|
||||||
|
static Color Magenta;
|
||||||
|
static Color Cyan;
|
||||||
|
static Color White;
|
||||||
|
static Color End;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::tuple<short, short, bool, bool> m_rep;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, const Color &c);
|
||||||
|
std::istream &operator>>(std::istream &is, Color &f);
|
||||||
|
|
||||||
/// Format flags used by NCurses
|
/// Format flags used by NCurses
|
||||||
enum class Format {
|
enum class Format {
|
||||||
@@ -154,22 +210,12 @@ enum class Scroll { Up, Down, PageUp, PageDown, Home, End };
|
|||||||
std::ostream &operator<<(std::ostream &os, Scroll s);
|
std::ostream &operator<<(std::ostream &os, Scroll s);
|
||||||
|
|
||||||
/// Initializes curses screen and sets some additional attributes
|
/// Initializes curses screen and sets some additional attributes
|
||||||
/// @param window_title title of the window (has an effect only if pdcurses lib is used)
|
|
||||||
/// @param enable_colors enables colors
|
/// @param enable_colors enables colors
|
||||||
void initScreen(const char *window_title, bool enable_colors);
|
void initScreen(bool enable_colors);
|
||||||
|
|
||||||
/// Destroys the screen
|
/// Destroys the screen
|
||||||
void destroyScreen();
|
void destroyScreen();
|
||||||
|
|
||||||
/// Struct used to set color of both foreground and background of window
|
|
||||||
/// @see Window::operator<<()
|
|
||||||
struct Colors
|
|
||||||
{
|
|
||||||
Colors(Color one, Color two = Color::Default) : fg(one), bg(two) { }
|
|
||||||
Color fg;
|
|
||||||
Color bg;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Struct used for going to given coordinates
|
/// Struct used for going to given coordinates
|
||||||
/// @see Window::operator<<()
|
/// @see Window::operator<<()
|
||||||
struct XY
|
struct XY
|
||||||
@@ -244,7 +290,7 @@ struct Window
|
|||||||
const std::string &getTitle() const;
|
const std::string &getTitle() const;
|
||||||
|
|
||||||
/// @return current window's color
|
/// @return current window's color
|
||||||
Color getColor() const;
|
const Color &getColor() const;
|
||||||
|
|
||||||
/// @return current window's border
|
/// @return current window's border
|
||||||
Border getBorder() const;
|
Border getBorder() const;
|
||||||
@@ -301,7 +347,7 @@ struct Window
|
|||||||
/// Sets window's base color
|
/// Sets window's base color
|
||||||
/// @param fg foregound base color
|
/// @param fg foregound base color
|
||||||
/// @param bg background base color
|
/// @param bg background base color
|
||||||
void setBaseColor(Color fg, Color bg = Color::Default);
|
void setBaseColor(Color c);
|
||||||
|
|
||||||
/// Sets window's border
|
/// Sets window's border
|
||||||
/// @param border new window's border
|
/// @param border new window's border
|
||||||
@@ -365,89 +411,25 @@ struct Window
|
|||||||
virtual void scroll(Scroll where);
|
virtual void scroll(Scroll where);
|
||||||
|
|
||||||
/// Applies function of compatible prototype to internal WINDOW pointer
|
/// Applies function of compatible prototype to internal WINDOW pointer
|
||||||
/// The mostly used function in this case seem to be wclrtoeol(), which
|
|
||||||
/// clears the window from current cursor position to the end of line.
|
|
||||||
/// Note that delwin() also matches that prototype, but I wouldn't
|
|
||||||
/// recommend anyone passing this pointer here ;)
|
|
||||||
/// @param f pointer to function to call with internal WINDOW pointer
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(int (*f)(WINDOW *));
|
Window &operator<<(int (*f)(WINDOW *));
|
||||||
|
Window &operator<<(const Color &color);
|
||||||
/// Applies foreground and background colors to window
|
|
||||||
/// @param colors struct that holds new colors information
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(Colors colors);
|
|
||||||
|
|
||||||
/// Applies foregound color to window. Note that colors applied
|
|
||||||
/// that way are stacked, i.e if you applied Color::Red, then Color::Green
|
|
||||||
/// and Color::End, current color would be Color::Red. If you want to discard
|
|
||||||
/// all colors and fall back to base one, pass Color::Default.
|
|
||||||
/// @param color new color value
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(Color color);
|
|
||||||
|
|
||||||
/// Applies format flag to window. Note that these attributes are
|
|
||||||
/// also stacked, so if you applied Format::Bold twice, to get rid of
|
|
||||||
/// it you have to pass Format::NoBold also twice.
|
|
||||||
/// @param format format flag
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(Format format);
|
Window &operator<<(Format format);
|
||||||
|
Window &operator<<(const XY &coords);
|
||||||
/// Moves current cursor position to given coordinates.
|
|
||||||
/// @param coords struct that holds information about new coordinations
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(XY coords);
|
|
||||||
|
|
||||||
/// Prints string to window
|
|
||||||
/// @param s const pointer to char array to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(const char *s);
|
Window &operator<<(const char *s);
|
||||||
|
|
||||||
/// Prints single character to window
|
|
||||||
/// @param c character to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(char c);
|
Window &operator<<(char c);
|
||||||
|
|
||||||
/// Prints wide string to window
|
|
||||||
/// @param ws const pointer to wchar_t array to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(const wchar_t *ws);
|
Window &operator<<(const wchar_t *ws);
|
||||||
|
|
||||||
/// Prints single wide character to window
|
|
||||||
/// @param wc wide character to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(wchar_t wc);
|
Window &operator<<(wchar_t wc);
|
||||||
|
|
||||||
/// Prints int to window
|
|
||||||
/// @param i integer value to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(int i);
|
Window &operator<<(int i);
|
||||||
|
|
||||||
/// Prints double to window
|
|
||||||
/// @param d double value to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(double d);
|
Window &operator<<(double d);
|
||||||
|
|
||||||
/// Prints size_t to window
|
|
||||||
/// @param s size value to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(size_t s);
|
Window &operator<<(size_t s);
|
||||||
|
|
||||||
/// Prints std::string to window
|
|
||||||
/// @param s string to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(const std::string &s);
|
Window &operator<<(const std::string &s);
|
||||||
|
|
||||||
/// Prints std::wstring to window
|
|
||||||
/// @param ws wide string to be printed
|
|
||||||
/// @return reference to itself
|
|
||||||
Window &operator<<(const std::wstring &ws);
|
Window &operator<<(const std::wstring &ws);
|
||||||
protected:
|
protected:
|
||||||
/// Sets colors of window (interal use only)
|
/// Sets colors of window (interal use only)
|
||||||
/// @param fg foregound color
|
/// @param fg foregound color
|
||||||
/// @param bg background color
|
/// @param bg background color
|
||||||
///
|
///
|
||||||
void setColor(Color fg, Color bg = Color::Default);
|
void setColor(Color c);
|
||||||
|
|
||||||
/// Refreshes window's border
|
/// Refreshes window's border
|
||||||
///
|
///
|
||||||
@@ -485,11 +467,9 @@ protected:
|
|||||||
|
|
||||||
/// current colors
|
/// current colors
|
||||||
Color m_color;
|
Color m_color;
|
||||||
Color m_bg_color;
|
|
||||||
|
|
||||||
/// base colors
|
/// base colors
|
||||||
Color m_base_color;
|
Color m_base_color;
|
||||||
Color m_base_bg_color;
|
|
||||||
|
|
||||||
/// current border
|
/// current border
|
||||||
Border m_border;
|
Border m_border;
|
||||||
@@ -524,7 +504,7 @@ private:
|
|||||||
std::string m_title;
|
std::string m_title;
|
||||||
|
|
||||||
/// stack of colors
|
/// stack of colors
|
||||||
std::stack<Colors> m_color_stack;
|
std::stack<Color> m_color_stack;
|
||||||
|
|
||||||
/// input queue of a window. you can put characters there using
|
/// input queue of a window. you can put characters there using
|
||||||
/// PushChar and they will be immediately consumed and
|
/// PushChar and they will be immediately consumed and
|
||||||
|
|||||||
Reference in New Issue
Block a user