Support attaching format information to selected color variables
This commit is contained in:
83
src/curses/formatted_color.cpp
Normal file
83
src/curses/formatted_color.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2008-2016 by Andrzej Rybczak *
|
||||
* electricityispower@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include "formatted_color.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void verifyFormats(const NC::FormattedColor::Formats &formats)
|
||||
{
|
||||
for (auto &fmt : formats)
|
||||
{
|
||||
if (fmt == NC::Format::NoBold
|
||||
|| fmt == NC::Format::NoUnderline
|
||||
|| fmt == NC::Format::NoReverse
|
||||
|| fmt == NC::Format::NoAltCharset)
|
||||
throw std::logic_error("FormattedColor can't hold disabling formats");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NC::FormattedColor::FormattedColor(Color color_, Formats formats_)
|
||||
{
|
||||
if (color_ == NC::Color::End)
|
||||
throw std::logic_error("FormattedColor can't hold Color::End");
|
||||
m_color = std::move(color_);
|
||||
verifyFormats(formats_);
|
||||
m_formats = std::move(formats_);
|
||||
}
|
||||
|
||||
std::istream &NC::operator>>(std::istream &is, NC::FormattedColor &fc)
|
||||
{
|
||||
NC::Color c;
|
||||
is >> c;
|
||||
if (!is.eof() && is.peek() == ':')
|
||||
{
|
||||
is.get();
|
||||
NC::FormattedColor::Formats formats;
|
||||
while (!is.eof() && isalpha(is.peek()))
|
||||
{
|
||||
char flag = is.get();
|
||||
switch (flag)
|
||||
{
|
||||
case 'b':
|
||||
formats.push_back(NC::Format::Bold);
|
||||
break;
|
||||
case 'u':
|
||||
formats.push_back(NC::Format::Underline);
|
||||
break;
|
||||
case 'r':
|
||||
formats.push_back(NC::Format::Reverse);
|
||||
break;
|
||||
case 'a':
|
||||
formats.push_back(NC::Format::AltCharset);
|
||||
break;
|
||||
default:
|
||||
is.setstate(std::ios::failbit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fc = NC::FormattedColor(c, std::move(formats));
|
||||
}
|
||||
else
|
||||
fc = NC::FormattedColor(c, {});
|
||||
return is;
|
||||
}
|
||||
81
src/curses/formatted_color.h
Normal file
81
src/curses/formatted_color.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2008-2016 by Andrzej Rybczak *
|
||||
* electricityispower@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef NCMPCPP_FORMATTED_COLOR_H
|
||||
#define NCMPCPP_FORMATTED_COLOR_H
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include "window.h"
|
||||
|
||||
namespace NC {
|
||||
|
||||
struct FormattedColor
|
||||
{
|
||||
struct End
|
||||
{
|
||||
End(const FormattedColor &fc)
|
||||
: m_fc(fc)
|
||||
{ }
|
||||
|
||||
const FormattedColor &base() const { return m_fc; }
|
||||
|
||||
private:
|
||||
const FormattedColor &m_fc;
|
||||
};
|
||||
|
||||
typedef std::vector<Format> Formats;
|
||||
|
||||
FormattedColor() { }
|
||||
|
||||
FormattedColor(Color color_, Formats formats_);
|
||||
|
||||
const Color &color() const { return m_color; }
|
||||
const Formats &formats() const { return m_formats; }
|
||||
|
||||
private:
|
||||
Color m_color;
|
||||
Formats m_formats;
|
||||
};
|
||||
|
||||
std::istream &operator>>(std::istream &is, FormattedColor &fc);
|
||||
|
||||
template <typename OutputStreamT>
|
||||
OutputStreamT &operator<<(OutputStreamT &os, const FormattedColor &fc)
|
||||
{
|
||||
os << fc.color();
|
||||
for (auto &fmt : fc.formats())
|
||||
os << fmt;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename OutputStreamT>
|
||||
OutputStreamT &operator<<(OutputStreamT &os, const FormattedColor::End &rfc)
|
||||
{
|
||||
if (rfc.base().color() != Color::Default)
|
||||
os << Color::End;
|
||||
for (auto &fmt : boost::adaptors::reverse(rfc.base().formats()))
|
||||
os << reverseFormat(fmt);
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // NCMPCPP_FORMATTED_COLOR_H
|
||||
@@ -259,36 +259,67 @@ std::istream &operator>>(std::istream &is, Color &c)
|
||||
}
|
||||
return result;
|
||||
};
|
||||
std::string sc;
|
||||
is >> sc;
|
||||
|
||||
auto get_color = [](std::istream &is_) {
|
||||
std::string result;
|
||||
while (!is_.eof() && isalnum(is_.peek()))
|
||||
result.push_back(is_.get());
|
||||
return result;
|
||||
};
|
||||
|
||||
std::string sc = get_color(is);
|
||||
|
||||
if (sc == "default")
|
||||
c = Color::Default;
|
||||
c = Color::Default;
|
||||
else if (sc == "end")
|
||||
c = Color::End;
|
||||
else
|
||||
{
|
||||
short value = get_single_color(sc, false);
|
||||
if (value != -1)
|
||||
c = Color(value, NC::Color::transparent);
|
||||
else
|
||||
short fg = get_single_color(sc, false);
|
||||
if (fg == -1)
|
||||
is.setstate(std::ios::failbit);
|
||||
// Check if there is background color
|
||||
else if (!is.eof() && is.peek() == '_')
|
||||
{
|
||||
size_t underscore = sc.find('_');
|
||||
if (underscore != std::string::npos)
|
||||
{
|
||||
short fg = get_single_color(sc.substr(0, underscore), false);
|
||||
short bg = get_single_color(sc.substr(underscore+1), true);
|
||||
if (fg != -1 && bg != -1)
|
||||
c = Color(fg, bg);
|
||||
else
|
||||
is.setstate(std::ios::failbit);
|
||||
}
|
||||
else
|
||||
is.get();
|
||||
sc = get_color(is);
|
||||
short bg = get_single_color(sc, true);
|
||||
if (bg == -1)
|
||||
is.setstate(std::ios::failbit);
|
||||
else
|
||||
c = Color(fg, bg);
|
||||
}
|
||||
else
|
||||
c = Color(fg, NC::Color::transparent);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
NC::Format reverseFormat(NC::Format fmt)
|
||||
{
|
||||
switch (fmt)
|
||||
{
|
||||
case NC::Format::Bold:
|
||||
return NC::Format::NoBold;
|
||||
case NC::Format::NoBold:
|
||||
return NC::Format::Bold;
|
||||
case NC::Format::Underline:
|
||||
return NC::Format::NoUnderline;
|
||||
case NC::Format::NoUnderline:
|
||||
return NC::Format::Underline;
|
||||
case NC::Format::Reverse:
|
||||
return NC::Format::NoReverse;
|
||||
case NC::Format::NoReverse:
|
||||
return NC::Format::Reverse;
|
||||
case NC::Format::AltCharset:
|
||||
return NC::Format::NoAltCharset;
|
||||
case NC::Format::NoAltCharset:
|
||||
return NC::Format::AltCharset;
|
||||
}
|
||||
// Unreachable, silence GCC.
|
||||
return fmt;
|
||||
}
|
||||
|
||||
namespace Mouse {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -149,7 +149,7 @@ struct Color
|
||||
static const short transparent;
|
||||
static const short previous;
|
||||
|
||||
Color() : m_impl(0, transparent, true, false) { }
|
||||
Color() : m_impl(0, 0, true, false) { }
|
||||
Color(short foreground_value, short background_value,
|
||||
bool is_default = false, bool is_end = false)
|
||||
: m_impl(foreground_value, background_value, is_default, is_end)
|
||||
@@ -201,6 +201,8 @@ enum class Format {
|
||||
AltCharset, NoAltCharset
|
||||
};
|
||||
|
||||
NC::Format reverseFormat(NC::Format fmt);
|
||||
|
||||
/// This indicates how much the window has to be scrolled
|
||||
enum class Scroll { Up, Down, PageUp, PageDown, Home, End };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user