1 // Copyright (C) 2008 Mark Pustjens <pustjens@dds.nl>
2 // Copyright (C) 2010-2015 Petr Pavlu <setup@dagobah.cz>
4 // This file is part of CenterIM.
6 // CenterIM is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // CenterIM is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with CenterIM. If not, see <http://www.gnu.org/licenses/>.
20 /// ColorScheme class implementation.
22 /// @ingroup cppconsui
24 #include "ColorScheme.h"
26 #include "CoreManager.h"
37 int ColorScheme::getAttributes(
38 int scheme
, int property
, int subproperty
, int *out_attrs
, Error
&error
)
40 assert(out_attrs
!= nullptr);
42 PropertyPair
property_pair(property
, subproperty
);
43 Schemes::const_iterator i
;
44 Properties::const_iterator j
;
45 if ((i
= schemes_
.find(scheme
)) != schemes_
.end() &&
46 (j
= i
->second
.find(property_pair
)) != i
->second
.end()) {
48 if (getColorPair(c
, out_attrs
, error
) != 0)
49 return error
.getCode();
50 *out_attrs
|= c
.attrs
;
51 #ifdef SAVE_COLOR_PAIRS
52 // Save updated color in case it got inverted.
53 schemes_
[scheme
][property_pair
] = c
;
54 #endif // SAVE_COLOR_PAIRS
62 #ifdef SAVE_COLOR_PAIRS
63 int ColorScheme::getColorPair(Color
&c
, int *out_attrs
, Error
&error
)
65 int ColorScheme::getColorPair(const Color
&c
, int *out_attrs
, Error
&error
)
66 #endif // SAVE_COLOR_PAIRS
68 assert(out_attrs
!= nullptr);
70 ColorPairs::const_iterator i
;
71 int fg
= c
.foreground
;
72 int bg
= c
.background
;
73 ColorPair
color_pair(fg
, bg
);
75 // Check if the pair already exists.
76 if ((i
= pairs_
.find(color_pair
)) != pairs_
.end()) {
77 *out_attrs
= i
->second
;
81 #ifdef SAVE_COLOR_PAIRS
82 // Check if the inverse pairs exists.
83 if ((i
= pairs_
.find(color_pair
)) != pairs_
.end()) {
84 // If the inverse pair exists, use that one and flip the REVERSE bit.
87 c
.out_attrs
^= Curses::Attr::REVERSE
;
88 *out_attrs
= i
->second
;
91 #endif // SAVE_COLOR_PAIRS
93 // Add a new color pair to the palette.
94 if (Curses::initColorPair(pairs_
.size() + 1, fg
, bg
, out_attrs
, error
) != 0)
95 return error
.getCode();
97 pairs_
[color_pair
] = *out_attrs
;
101 bool ColorScheme::setAttributes(int scheme
, int property
, int foreground
,
102 int background
, int attrs
, bool overwrite
)
104 return setAttributesExt(
105 scheme
, property
, 0, foreground
, background
, attrs
, overwrite
);
108 bool ColorScheme::setAttributesExt(int scheme
, int property
, int subproperty
,
109 int foreground
, int background
, int attrs
, bool overwrite
)
111 PropertyPair
property_pair(property
, subproperty
);
112 Schemes::const_iterator i
;
113 if (!overwrite
&& (i
= schemes_
.find(scheme
)) != schemes_
.end() &&
114 i
->second
.find(property_pair
) != i
->second
.end())
117 schemes_
[scheme
][property_pair
] = Color(foreground
, background
, attrs
);
121 void ColorScheme::freeScheme(int scheme
)
123 Schemes::const_iterator i
= schemes_
.find(scheme
);
124 if (i
== schemes_
.end())
127 schemes_
.erase(scheme
);
130 void ColorScheme::clear()
136 const char *ColorScheme::propertyToWidgetName(int property
)
138 switch (static_cast<Property
>(property
)) {
139 case PROPERTY_BUTTON_FOCUS
:
140 case PROPERTY_BUTTON_NORMAL
:
142 case PROPERTY_CHECKBOX_FOCUS
:
143 case PROPERTY_CHECKBOX_NORMAL
:
145 case PROPERTY_CONTAINER_BACKGROUND
:
147 case PROPERTY_HORIZONTALLINE_LINE
:
148 return "horizontalline";
149 case PROPERTY_LABEL_TEXT
:
151 case PROPERTY_PANEL_LINE
:
152 case PROPERTY_PANEL_TITLE
:
154 case PROPERTY_TEXTEDIT_TEXT
:
156 case PROPERTY_TEXTVIEW_TEXT
:
157 case PROPERTY_TEXTVIEW_SCROLLBAR
:
159 case PROPERTY_VERTICALLINE_LINE
:
160 return "verticalline";
161 case PROPERTY_TREEVIEW_LINE
:
167 const char *ColorScheme::propertyToPropertyName(int property
)
169 switch (static_cast<Property
>(property
)) {
170 case PROPERTY_BUTTON_FOCUS
:
171 case PROPERTY_CHECKBOX_FOCUS
:
173 case PROPERTY_BUTTON_NORMAL
:
174 case PROPERTY_CHECKBOX_NORMAL
:
176 case PROPERTY_CONTAINER_BACKGROUND
:
178 case PROPERTY_HORIZONTALLINE_LINE
:
179 case PROPERTY_PANEL_LINE
:
180 case PROPERTY_VERTICALLINE_LINE
:
181 case PROPERTY_TREEVIEW_LINE
:
183 case PROPERTY_LABEL_TEXT
:
184 case PROPERTY_TEXTEDIT_TEXT
:
185 case PROPERTY_TEXTVIEW_TEXT
:
187 case PROPERTY_PANEL_TITLE
:
189 case PROPERTY_TEXTVIEW_SCROLLBAR
:
195 ColorScheme::PropertyConversionResult
ColorScheme::stringPairToPropertyPair(
196 const char *widget
, const char *property
, int *out_property
,
197 int *out_subproperty
)
199 assert(out_property
!= nullptr);
200 assert(out_subproperty
!= nullptr);
202 *out_subproperty
= 0;
204 if (std::strcmp(widget
, "button") == 0) {
205 if (std::strcmp(property
, "focus") == 0) {
206 *out_property
= PROPERTY_BUTTON_FOCUS
;
207 return CONVERSION_SUCCESS
;
209 if (std::strcmp(property
, "normal") == 0) {
210 *out_property
= PROPERTY_BUTTON_NORMAL
;
211 return CONVERSION_SUCCESS
;
213 return CONVERSION_ERROR_PROPERTY
;
215 else if (std::strcmp(widget
, "checkbox") == 0) {
216 if (std::strcmp(property
, "focus") == 0) {
217 *out_property
= PROPERTY_CHECKBOX_FOCUS
;
218 return CONVERSION_SUCCESS
;
220 if (std::strcmp(property
, "normal") == 0) {
221 *out_property
= PROPERTY_CHECKBOX_NORMAL
;
222 return CONVERSION_SUCCESS
;
224 return CONVERSION_ERROR_PROPERTY
;
226 else if (std::strcmp(widget
, "container") == 0) {
227 if (std::strcmp(property
, "background") == 0) {
228 *out_property
= PROPERTY_CONTAINER_BACKGROUND
;
229 return CONVERSION_SUCCESS
;
231 return CONVERSION_ERROR_PROPERTY
;
233 else if (std::strcmp(widget
, "horizontalline") == 0) {
234 if (std::strcmp(property
, "line") == 0) {
235 *out_property
= PROPERTY_HORIZONTALLINE_LINE
;
236 return CONVERSION_SUCCESS
;
238 return CONVERSION_ERROR_PROPERTY
;
240 else if (std::strcmp(widget
, "label") == 0) {
241 if (std::strcmp(property
, "text") == 0) {
242 *out_property
= PROPERTY_LABEL_TEXT
;
243 return CONVERSION_SUCCESS
;
245 return CONVERSION_ERROR_PROPERTY
;
247 else if (std::strcmp(widget
, "panel") == 0) {
248 if (std::strcmp(property
, "line") == 0) {
249 *out_property
= PROPERTY_PANEL_LINE
;
250 return CONVERSION_SUCCESS
;
252 if (std::strcmp(property
, "title") == 0) {
253 *out_property
= PROPERTY_PANEL_TITLE
;
254 return CONVERSION_SUCCESS
;
256 return CONVERSION_ERROR_PROPERTY
;
258 else if (std::strcmp(widget
, "textedit") == 0) {
259 if (std::strcmp(property
, "text") == 0) {
260 *out_property
= PROPERTY_TEXTEDIT_TEXT
;
261 return CONVERSION_SUCCESS
;
263 return CONVERSION_ERROR_PROPERTY
;
265 else if (std::strcmp(widget
, "textview") == 0) {
266 if (std::strcmp(property
, "text") == 0) {
267 *out_property
= PROPERTY_TEXTVIEW_TEXT
;
268 return CONVERSION_SUCCESS
;
270 if (std::strcmp(property
, "scrollbar") == 0) {
271 *out_property
= PROPERTY_TEXTVIEW_SCROLLBAR
;
272 return CONVERSION_SUCCESS
;
275 // Handle text_<number> and color<number> properties. The latter one is
276 // recognized only for backward compatibility.
277 if (std::strncmp(property
, "text_", 5) != 0 &&
278 std::strncmp(property
, "color", 5) != 0)
279 return CONVERSION_ERROR_PROPERTY
;
282 if (!std::isdigit((unsigned char)*property
))
283 return CONVERSION_ERROR_PROPERTY
;
287 long i
= std::strtol(property
, &endptr
, 10);
289 if (*endptr
!= '\0' || errno
== ERANGE
|| i
> INT_MAX
)
290 return CONVERSION_ERROR_PROPERTY
;
292 *out_property
= PROPERTY_TEXTVIEW_TEXT
;
293 *out_subproperty
= i
;
294 return CONVERSION_SUCCESS
;
296 else if (std::strcmp(widget
, "verticalline") == 0) {
297 if (std::strcmp(property
, "line") == 0) {
298 *out_property
= PROPERTY_VERTICALLINE_LINE
;
299 return CONVERSION_SUCCESS
;
302 else if (std::strcmp(widget
, "treeview") == 0) {
303 if (std::strcmp(property
, "line") == 0) {
304 *out_property
= PROPERTY_TREEVIEW_LINE
;
305 return CONVERSION_SUCCESS
;
309 return CONVERSION_ERROR_WIDGET
;
312 } // namespace CppConsUI
314 // vim: set tabstop=2 shiftwidth=2 textwidth=80 expandtab: