2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2021-2022 Alfonso Sabato Siciliano
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include "bsddialog.h"
31 #include "bsddialog_theme.h"
34 #define GET_COLOR(bg, fg) (COLOR_PAIR(bg * 8 + fg +1))
36 struct bsddialog_theme t;
39 static struct bsddialog_theme bsddialogtheme = {
40 .screen.color = GET_COLOR(COLOR_BLACK, COLOR_CYAN),
42 .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
46 .dialog.delimtitle = true,
47 .dialog.titlecolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
48 .dialog.lineraisecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
49 .dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
50 .dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
51 .dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
52 .dialog.arrowcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
54 .menu.f_selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
55 .menu.selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
56 .menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_YELLOW),
57 .menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
58 .menu.f_namecolor = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
59 .menu.namecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
60 .menu.namesepcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
61 .menu.descsepcolor = GET_COLOR(COLOR_YELLOW, COLOR_WHITE),
62 .menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_YELLOW),
63 .menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
64 .menu.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
66 .form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
67 .form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
68 .form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE),
69 .form.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN),
71 .bar.f_color = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
72 .bar.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
74 .button.minmargin = 1,
75 .button.maxmargin = 5,
76 .button.leftdelim = '[',
77 .button.rightdelim = ']',
78 .button.f_delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
79 .button.delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
80 .button.f_color = GET_COLOR(COLOR_BLACK, COLOR_YELLOW),
81 .button.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
82 .button.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_YELLOW),
83 .button.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE)
86 static struct bsddialog_theme blackwhite = {
87 #define fg COLOR_WHITE
88 #define bk COLOR_BLACK
89 .screen.color = GET_COLOR(fg, bk),
91 .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
95 .dialog.delimtitle = true,
96 .dialog.titlecolor = GET_COLOR(fg, bk),
97 .dialog.lineraisecolor = GET_COLOR(fg, bk),
98 .dialog.linelowercolor = GET_COLOR(fg, bk),
99 .dialog.color = GET_COLOR(fg, bk),
100 .dialog.bottomtitlecolor = GET_COLOR(fg, bk),
101 .dialog.arrowcolor = GET_COLOR(fg, bk),
103 .menu.f_selectorcolor = GET_COLOR(fg, bk) | A_REVERSE,
104 .menu.selectorcolor = GET_COLOR(fg, bk),
105 .menu.f_desccolor = GET_COLOR(fg, bk) | A_REVERSE,
106 .menu.desccolor = GET_COLOR(fg, bk),
107 .menu.f_namecolor = GET_COLOR(fg, bk) | A_REVERSE,
108 .menu.namecolor = GET_COLOR(fg, bk),
109 .menu.namesepcolor = GET_COLOR(fg, bk),
110 .menu.descsepcolor = GET_COLOR(fg, bk),
111 .menu.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
112 .menu.shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE,
113 .menu.bottomdesccolor = GET_COLOR(fg, bk),
115 .form.f_fieldcolor = GET_COLOR(fg, bk) | A_REVERSE,
116 .form.fieldcolor = GET_COLOR(fg, bk),
117 .form.readonlycolor = GET_COLOR(fg, bk),
118 .form.bottomdesccolor = GET_COLOR(fg, bk),
120 .bar.f_color = GET_COLOR(fg, bk) | A_REVERSE,
121 .bar.color = GET_COLOR(fg, bk),
123 .button.minmargin = 1,
124 .button.maxmargin = 5,
125 .button.leftdelim = '[',
126 .button.rightdelim = ']',
127 .button.f_delimcolor = GET_COLOR(fg, bk),
128 .button.delimcolor = GET_COLOR(fg, bk),
129 .button.f_color = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
130 .button.color = GET_COLOR(fg, bk) | A_UNDERLINE,
131 .button.f_shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE | A_REVERSE,
132 .button.shortcutcolor = GET_COLOR(fg, bk) | A_UNDERLINE
135 static struct bsddialog_theme dialogtheme = {
136 .screen.color = GET_COLOR(COLOR_CYAN, COLOR_BLUE) | A_BOLD,
138 .shadow.color = GET_COLOR(COLOR_BLACK, COLOR_BLACK),
142 .dialog.delimtitle = false,
143 .dialog.titlecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
144 .dialog.lineraisecolor = GET_COLOR(COLOR_WHITE, COLOR_WHITE) | A_BOLD,
145 .dialog.linelowercolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
146 .dialog.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
147 .dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE) | A_BOLD,
148 .dialog.arrowcolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
150 .menu.f_selectorcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
151 .menu.selectorcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
152 .menu.f_desccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
153 .menu.desccolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
154 .menu.f_namecolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
155 .menu.namecolor = GET_COLOR(COLOR_BLUE, COLOR_WHITE),
156 .menu.namesepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
157 .menu.descsepcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
158 .menu.f_shortcutcolor = GET_COLOR(COLOR_RED, COLOR_BLUE),
159 .menu.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE),
160 .menu.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
162 .form.f_fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
163 .form.fieldcolor = GET_COLOR(COLOR_WHITE, COLOR_CYAN) | A_BOLD,
164 .form.readonlycolor = GET_COLOR(COLOR_CYAN, COLOR_WHITE)| A_BOLD,
165 .form.bottomdesccolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE),
167 .bar.f_color = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
168 .bar.color = GET_COLOR(COLOR_BLUE, COLOR_WHITE) | A_BOLD,
170 .button.minmargin = 1,
171 .button.maxmargin = 5,
172 .button.leftdelim = '<',
173 .button.rightdelim = '>',
174 .button.f_delimcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
175 .button.delimcolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
176 .button.f_color = GET_COLOR(COLOR_YELLOW, COLOR_BLUE) | A_BOLD,
177 .button.color = GET_COLOR(COLOR_BLACK, COLOR_WHITE),
178 .button.f_shortcutcolor = GET_COLOR(COLOR_WHITE, COLOR_BLUE) | A_BOLD,
179 .button.shortcutcolor = GET_COLOR(COLOR_RED, COLOR_WHITE) | A_BOLD
183 set_theme(struct bsddialog_theme *dst, struct bsddialog_theme *src)
185 dst->screen.color = src->screen.color;
187 dst->shadow.color = src->shadow.color;
188 dst->shadow.y = src->shadow.y;
189 dst->shadow.x = src->shadow.x;
191 dst->dialog.delimtitle = src->dialog.delimtitle;
192 dst->dialog.titlecolor = src->dialog.titlecolor;
193 dst->dialog.lineraisecolor = src->dialog.lineraisecolor;
194 dst->dialog.linelowercolor = src->dialog.linelowercolor;
195 dst->dialog.color = src->dialog.color;
196 dst->dialog.bottomtitlecolor = src->dialog.bottomtitlecolor;
197 dst->dialog.arrowcolor = src->dialog.arrowcolor;
199 dst->menu.f_selectorcolor = src->menu.f_selectorcolor;
200 dst->menu.selectorcolor = src->menu.selectorcolor;
201 dst->menu.f_desccolor = src->menu.f_desccolor;
202 dst->menu.desccolor = src->menu.desccolor;
203 dst->menu.f_namecolor = src->menu.f_namecolor;
204 dst->menu.namecolor = src->menu.namecolor;
205 dst->menu.namesepcolor = src->menu.namesepcolor;
206 dst->menu.descsepcolor = src->menu.descsepcolor;
207 dst->menu.f_shortcutcolor = src->menu.f_shortcutcolor;
208 dst->menu.shortcutcolor = src->menu.shortcutcolor;
209 dst->menu.bottomdesccolor = src->menu.bottomdesccolor;
211 dst->form.f_fieldcolor = src->form.f_fieldcolor;
212 dst->form.fieldcolor = src->form.fieldcolor;
213 dst->form.readonlycolor = src->form.readonlycolor;
214 dst->form.bottomdesccolor = src->form.bottomdesccolor;
216 dst->bar.f_color = src->bar.f_color;
217 dst->bar.color = src->bar.color;
219 dst->button.minmargin = src->button.minmargin;
220 dst->button.maxmargin = src->button.maxmargin;
221 dst->button.leftdelim = src->button.leftdelim;
222 dst->button.rightdelim = src->button.rightdelim;
223 dst->button.f_delimcolor = src->button.f_delimcolor;
224 dst->button.delimcolor = src->button.delimcolor;
225 dst->button.f_color = src->button.f_color;
226 dst->button.color = src->button.color;
227 dst->button.f_shortcutcolor = src->button.f_shortcutcolor;
228 dst->button.shortcutcolor = src->button.shortcutcolor;
230 bkgd(dst->screen.color);
235 int bsddialog_get_theme(struct bsddialog_theme *theme)
238 RETURN_ERROR("theme is NULL");
239 if (sizeof(*theme) != sizeof(struct bsddialog_theme))
240 RETURN_ERROR("Bad suze struct bsddialog_theme");
242 set_theme(theme, &t);
244 return (BSDDIALOG_OK);
247 int bsddialog_set_theme(struct bsddialog_theme *theme)
250 RETURN_ERROR("theme is NULL");
251 if (sizeof(*theme) != sizeof(struct bsddialog_theme))
252 RETURN_ERROR("Bad size struct bsddialog_theme");
254 set_theme(&t, theme);
256 return (BSDDIALOG_OK);
259 int bsddialog_set_default_theme(enum bsddialog_default_theme newtheme)
261 if (newtheme == BSDDIALOG_THEME_FLAT) {
262 bsddialog_set_theme(&dialogtheme);
263 t.dialog.lineraisecolor = t.dialog.linelowercolor;
264 t.dialog.delimtitle = true;
265 t.button.leftdelim = '[';
266 t.button.rightdelim = ']';
267 t.dialog.bottomtitlecolor = GET_COLOR(COLOR_BLACK, COLOR_WHITE);
269 else if (newtheme == BSDDIALOG_THEME_BSDDIALOG)
270 bsddialog_set_theme(&bsddialogtheme);
271 else if (newtheme == BSDDIALOG_THEME_BLACKWHITE)
272 bsddialog_set_theme(&blackwhite);
273 else if (newtheme == BSDDIALOG_THEME_DIALOG)
274 bsddialog_set_theme(&dialogtheme);
276 RETURN_ERROR("Unknow default theme");
278 return (BSDDIALOG_OK);
282 bsddialog_color(enum bsddialog_color foreground,
283 enum bsddialog_color background, unsigned int flags)
285 unsigned int cursesflags = 0;
287 if (flags & BSDDIALOG_BOLD)
288 cursesflags |= A_BOLD;
289 if (flags & BSDDIALOG_REVERSE)
290 cursesflags |= A_REVERSE;
291 if (flags & BSDDIALOG_UNDERLINE)
292 cursesflags |= A_UNDERLINE;
294 return (GET_COLOR(foreground, background) | cursesflags);
298 bsddialog_color_attrs(int color, enum bsddialog_color *foreground,
299 enum bsddialog_color *background, unsigned int *flags)
305 flag |= (color & A_BOLD) ? BSDDIALOG_BOLD : 0U;
306 flag |= (color & A_REVERSE) ? BSDDIALOG_REVERSE : 0U;
307 flag |= (color & A_UNDERLINE) ? BSDDIALOG_UNDERLINE : 0U;
311 if (pair_content(PAIR_NUMBER(color), &f, &b) != OK)
312 RETURN_ERROR("Cannot get color attributes");
313 if (foreground != NULL)
315 if (background != NULL)
318 return (BSDDIALOG_OK);
321 bool bsddialog_hascolors(void)
323 return hastermcolors;