# HG changeset patch # User David Demelier # Date 1602763284 -7200 # Node ID b19d076856d218a68fa31e8794817721e12bf661 # Parent 9733d379be8960ee02258a55a96184702eb73e74 ui: cleanup theme module, closes #2498 diff -r 9733d379be89 -r b19d076856d2 examples/CMakeLists.txt --- a/examples/CMakeLists.txt Thu Oct 15 13:13:38 2020 +0200 +++ b/examples/CMakeLists.txt Thu Oct 15 14:01:24 2020 +0200 @@ -32,6 +32,7 @@ TARGET example-font SOURCES example-font.c LIBRARIES libui + FOLDER examples ) molko_define_executable( @@ -49,6 +50,7 @@ TARGET example-label SOURCES example-label.c LIBRARIES libui + FOLDER examples ) molko_define_executable( @@ -82,3 +84,10 @@ FOLDER examples LIBRARIES libui libadventure ) + +molko_define_executable( + TARGET example-ui + SOURCES example-ui.c + FOLDER examples + LIBRARIES libui +) diff -r 9733d379be89 -r b19d076856d2 examples/example-ui.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example-ui.c Thu Oct 15 14:01:24 2020 +0200 @@ -0,0 +1,157 @@ +/* + * example-action.c -- example on how to use automatic actions + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define W (1280) +#define H (720) + +static struct frame frame = { + .x = 10, + .y = 10, + .w = 400, + .h = 200 +}; + +static struct label title = { + .text = "Preferences", + .x = 10, + .y = 10, + .w = 400, + .h = 200, + .flags = LABEL_FLAGS_SHADOW, + .align = ALIGN_TOP_LEFT +}; + +static struct { + struct checkbox cb; + struct label label; +} autosave = { + .cb = { + .x = 20, + .y = 60, + .w = 20, + .h = 20 + }, + .label = { + .text = "Auto save game", + .x = 20 + 20, + .y = 60, + .w = 200, + .h = 20, + .align = ALIGN_LEFT, + .flags = LABEL_FLAGS_SHADOW + } +}; + +static struct button btquit = { + .text = "Quit", + .w = 50, + .h = 20 +}; + +static void +init(void) +{ + if (!sys_init() || + !window_init("Example - UI", W, H) || + !theme_init()) + panic(); +} + +static void +run(void) +{ + struct clock clock = {0}; + + clock_start(&clock); + + for (;;) { + unsigned int elapsed = clock_elapsed(&clock); + + clock_start(&clock); + + for (union event ev; event_poll(&ev); ) { + switch (ev.type) { + case EVENT_QUIT: + return; + default: + checkbox_handle(&autosave.cb, &ev); + button_handle(&btquit, &ev); + + if (btquit.state == BUTTON_STATE_ACTIVATED) + return; + + break; + } + } + + /* Compute button position at runtime. */ + align(ALIGN_BOTTOM_RIGHT, &btquit.x, &btquit.y, btquit.w, btquit.h, + frame.x, frame.y, frame.w, frame.h); + + btquit.x -= theme_default()->padding; + btquit.y -= theme_default()->padding; + + painter_set_color(0xffffffff); + painter_clear(); + frame_draw(&frame); + label_draw(&title); + checkbox_draw(&autosave.cb); + label_draw(&autosave.label); + button_draw(&btquit); + painter_present(); + + if ((elapsed = clock_elapsed(&clock)) < 20) + delay(20 - elapsed); + } +} + +static void +quit(void) +{ + theme_finish(); + window_finish(); + sys_finish(); +} + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + init(); + run(); + quit(); + + return 0; +} + diff -r 9733d379be89 -r b19d076856d2 libui/ui/button.c --- a/libui/ui/button.c Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/button.c Thu Oct 15 14:01:24 2020 +0200 @@ -20,8 +20,10 @@ #include #include +#include #include "button.h" +#include "label.h" #include "theme.h" static bool @@ -36,6 +38,29 @@ } void +button_draw_default(struct theme *t, const struct button *button) +{ + assert(t); + assert(button); + + (void)t; + + const struct label label = { + .text = button->text, + .x = button->x, + .y = button->y, + .w = button->w, + .h = button->h, + .align = ALIGN_CENTER + }; + + painter_set_color(0x577277ff); + painter_draw_rectangle(button->x, button->y, button->w, button->h); + + label_draw(&label); +} + +void button_handle(struct button *button, const union event *ev) { assert(button); diff -r 9733d379be89 -r b19d076856d2 libui/ui/button.h --- a/libui/ui/button.h Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/button.h Thu Oct 15 14:01:24 2020 +0200 @@ -74,6 +74,17 @@ button_reset(struct button *button); /** + * Default drawing function. + * + * \pre t != NULL + * \pre frame != NULL + * \param t the theme + * \param button the button + */ +void +button_draw_default(struct theme *t, const struct button *button); + +/** * Draw the button. * * \pre button != NULL diff -r 9733d379be89 -r b19d076856d2 libui/ui/checkbox.c --- a/libui/ui/checkbox.c Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/checkbox.c Thu Oct 15 14:01:24 2020 +0200 @@ -20,7 +20,9 @@ #include #include +#include +#include "label.h" #include "checkbox.h" #include "theme.h" @@ -34,6 +36,23 @@ } void +checkbox_draw_default(struct theme *t, const struct checkbox *cb) +{ + assert(t); + assert(cb); + + painter_set_color(0x151d28ff); + painter_draw_rectangle(cb->x, cb->y, cb->w, cb->h); + painter_set_color(0xd7b594ff); + painter_draw_rectangle(cb->x + 1, cb->y + 1, cb->w - 2, cb->h - 2); + + if (cb->checked) { + painter_set_color(0x341c27ff); + painter_draw_rectangle(cb->x + 5, cb->y + 5, cb->w - 10, cb->h - 10); + } +} + +void checkbox_handle(struct checkbox *cb, const union event *ev) { assert(cb); diff -r 9733d379be89 -r b19d076856d2 libui/ui/checkbox.h --- a/libui/ui/checkbox.h Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/checkbox.h Thu Oct 15 14:01:24 2020 +0200 @@ -36,12 +36,22 @@ int y; /*!< (+) Position in y. */ unsigned int w; /*!< (+) Width. */ unsigned int h; /*!< (+) Height. */ - const char *label; /*!< (+&) Text to show. */ bool checked; /*!< (+) Is activated? */ struct theme *theme; /*!< (+&?) Theme to use. */ }; /** + * Default drawing function. + * + * \pre t != NULL + * \pre cb != NULL + * \param t the theme + * \param cb the checkbox + */ +void +checkbox_draw_default(struct theme *t, const struct checkbox *cb); + +/** * Draw the checkbox. * * \pre cb != NULL diff -r 9733d379be89 -r b19d076856d2 libui/ui/frame.c --- a/libui/ui/frame.c Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/frame.c Thu Oct 15 14:01:24 2020 +0200 @@ -18,10 +18,28 @@ #include +#include + #include "frame.h" #include "theme.h" void +frame_draw_default(struct theme *t, const struct frame *frame) +{ + assert(t); + assert(frame); + + (void)t; + + if (frame->style == FRAME_STYLE_BOX) + painter_set_color(0x7a4841ff); + else + painter_set_color(0xad7757ff); + + painter_draw_rectangle(frame->x, frame->y, frame->w, frame->h); +} + +void frame_draw(const struct frame *frame) { assert(frame); diff -r 9733d379be89 -r b19d076856d2 libui/ui/frame.h --- a/libui/ui/frame.h Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/frame.h Thu Oct 15 14:01:24 2020 +0200 @@ -47,6 +47,17 @@ }; /** + * Default drawing function. + * + * \pre t != NULL + * \pre frame != NULL + * \param t the theme + * \param frame the frame + */ +void +frame_draw_default(struct theme *t, const struct frame *frame); + +/** * Draw the frame. * * \pre frame != NULL diff -r 9733d379be89 -r b19d076856d2 libui/ui/label.c --- a/libui/ui/label.c Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/label.c Thu Oct 15 14:01:24 2020 +0200 @@ -18,12 +18,66 @@ #include +#include +#include #include +#include #include "label.h" #include "theme.h" void +label_draw_default(struct theme *t, const struct label *label) +{ + assert(t); + assert(label); + + struct font *font; + struct texture tex; + int x, y, bx, by; + unsigned int tw, th, bw, bh; + + /* Compute real box size according to padding. */ + bx = label->x + t->padding; + by = label->y + t->padding; + bw = label->w - (t->padding * 2); + bh = label->h - (t->padding * 2); + + /* Make a shallow copy of the interface font. */ + font = t->fonts[THEME_FONT_INTERFACE]; + + /* Compute text size. */ + if (!font_box(font, label->text, &tw, &th)) + panic(); + + /* Align if needed. */ + x = label->x; + y = label->y; + + align(label->align, &x, &y, tw, th, bx, by, bw, bh); + + /* Shadow text, only if enabled. */ + if (label->flags & LABEL_FLAGS_SHADOW) { + font->color = t->colors[THEME_COLOR_SHADOW]; + + if (!font_render(font, &tex, label->text)) + panic(); + + texture_draw(&tex, x + 1, y + 1); + texture_finish(&tex); + } + + /* Normal text. */ + font->color = t->colors[THEME_COLOR_NORMAL]; + + if (!font_render(font, &tex, label->text)) + panic(); + + texture_draw(&tex, x, y); + texture_finish(&tex); +} + +void label_draw(const struct label *label) { assert(label); diff -r 9733d379be89 -r b19d076856d2 libui/ui/label.h --- a/libui/ui/label.h Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/label.h Thu Oct 15 14:01:24 2020 +0200 @@ -55,6 +55,17 @@ }; /** + * Default drawing function. + * + * \pre t != NULL + * \pre label != NULL + * \param t the theme + * \param label the label + */ +void +label_draw_default(struct theme *t, const struct label *label); + +/** * Draw the label. * * \pre label != NULL diff -r 9733d379be89 -r b19d076856d2 libui/ui/theme.c --- a/libui/ui/theme.c Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/theme.c Thu Oct 15 14:01:24 2020 +0200 @@ -39,129 +39,9 @@ #define THEME(t) (t ? t : &default_theme) -#define CHECKBOX_W 16 -#define CHECKBOX_H 16 -#define CHECKBOX_RAD 6 - -static void -box(int x, int y, unsigned int w, unsigned int h) -{ - /* Some basic outlines. */ - painter_set_color(0x4d3533ff); - - painter_draw_line(x, y, x + w, y); - painter_draw_line(x, y + h, x + w, y + h); - painter_draw_line(x, y, x, y + h); - painter_draw_line(x + w, y, x + w, y + h); -} - -static void -draw_frame(struct theme *t, const struct frame *frame) -{ - (void)t; - - if (frame->style == FRAME_STYLE_BOX) - painter_set_color(0x6e4c30ff); - else - painter_set_color(0xce9248ff); - - painter_draw_rectangle(frame->x, frame->y, frame->w, frame->h); - box(frame->x, frame->y, frame->w, frame->h); -} - -static void -draw_label(struct theme *t, const struct label *label) -{ - struct font *font; - struct texture tex; - int x, y, bx, by; - unsigned int tw, th, bw, bh; - - /* Compute real box size according to padding. */ - bx = label->x + t->padding; - by = label->y + t->padding; - bw = label->w - (t->padding * 2); - bh = label->h - (t->padding * 2); - - /* Make a shallow copy of the interface font. */ - font = t->fonts[THEME_FONT_INTERFACE]; - - /* Compute text size. */ - if (!font_box(font, label->text, &tw, &th)) - panic(); - - /* Align if needed. */ - x = label->x; - y = label->y; - - align(label->align, &x, &y, tw, th, bx, by, bw, bh); - - /* Shadow text, only if enabled. */ - if (label->flags & LABEL_FLAGS_SHADOW) { - font->color = t->colors[THEME_COLOR_SHADOW]; - - if (!font_render(font, &tex, label->text)) - panic(); - - texture_draw(&tex, x + 1, y + 1); - texture_finish(&tex); - } - - /* Normal text. */ - font->color = t->colors[THEME_COLOR_NORMAL]; - - if (!font_render(font, &tex, label->text)) - panic(); - - texture_draw(&tex, x, y); - texture_finish(&tex); -} - -static void -draw_button(struct theme *t, const struct button *button) -{ - (void)t; - - struct label label = { - .text = button->text, - .x = button->x, - .y = button->y, - .w = button->w, - .h = button->h - }; - - painter_set_color(0xabcdefff); - painter_draw_rectangle(button->x, button->y, button->w, button->h); - - label_draw(&label); - - box(button->x, button->y, button->w, button->h); -} - -static void -draw_checkbox(struct theme *t, const struct checkbox *cb) -{ - box(cb->x, cb->y, CHECKBOX_W, CHECKBOX_H); - - if (cb->checked) - painter_draw_rectangle(cb->x + 5, cb->y + 5, CHECKBOX_W - 9, CHECKBOX_H - 9); - - if (cb->label) { - const unsigned int w = cb->w - (t->padding * 2) - CHECKBOX_W; - const int x = cb->x + (t->padding * 2) + CHECKBOX_W; - - struct label label = { - .text = cb->label, - .align = ALIGN_LEFT, - .x = x, - .y = cb->y, - .w = w, - .h = cb->h - }; - - draw_label(t, &label); - } -} +/* Default font catalog. */ +#define FONT(bin, size, index) \ + { bin, sizeof (bin), size, &default_theme.fonts[index], {0} } /* Default theme. */ static struct theme default_theme = { @@ -171,16 +51,12 @@ [THEME_COLOR_SHADOW] = 0x000000ff }, .padding = 10, - .draw_frame = draw_frame, - .draw_label = draw_label, - .draw_button = draw_button, - .draw_checkbox = draw_checkbox + .draw_frame = frame_draw_default, + .draw_label = label_draw_default, + .draw_button = button_draw_default, + .draw_checkbox = checkbox_draw_default }; -/* Default font catalog. */ -#define FONT(bin, size, index) \ - { bin, sizeof (bin), size, &default_theme.fonts[index], {0} } - static struct font_catalog { const unsigned char *data; const size_t datasz; @@ -189,7 +65,7 @@ struct font font; } default_fonts[] = { FONT(fonts_f25_bank_printer, 10, THEME_FONT_DEBUG), - FONT(fonts_comic_neue, 20, THEME_FONT_INTERFACE) + FONT(fonts_comic_neue, 18, THEME_FONT_INTERFACE) }; bool diff -r 9733d379be89 -r b19d076856d2 libui/ui/theme.h --- a/libui/ui/theme.h Thu Oct 15 13:13:38 2020 +0200 +++ b/libui/ui/theme.h Thu Oct 15 14:01:24 2020 +0200 @@ -138,15 +138,6 @@ theme_shallow(struct theme *dst, const struct theme *src); /** - * Get the desired padding between GUI elements. - * - * \param t the theme to use (may be NULL) - * \return the padding in pixels - */ -unsigned int -theme_padding(const struct theme *t); - -/** * Draw a frame. * * \pre frame != NULL