diff --git a/data/gui/themes/celes/widgets/toggle_button_radio.cfg b/data/gui/themes/celes/widgets/toggle_button_radio.cfg index 5b102e155c4..ae65d6c5ffd 100644 --- a/data/gui/themes/celes/widgets/toggle_button_radio.cfg +++ b/data/gui/themes/celes/widgets/toggle_button_radio.cfg @@ -18,20 +18,23 @@ #define _GUI_RADIO_BG COLOR [circle] x = 10 - y = 10 - radius = 10 + y = 13 + radius = 11 border_thickness = 2 border_color = {COLOR} fill_color = "28, 45, 64, 255" [/circle] #enddef -#define _GUI_RADIO_DOT IPF - [image] - x = 6 - y = 6 - name = "buttons/modern/dot.png{IPF}" - [/image] +#define _GUI_RADIO_DOT COLOR + [circle] + x = 10 + y = 13 + radius = 5 + border_thickness = 0 + border_color = "0, 0, 0, 0" + fill_color = {COLOR} + [/circle] #enddef #define _GUI_RESOLUTION RESOLUTION WIDTH HEIGHT EXTRA_WIDTH FONT_SIZE @@ -96,7 +99,7 @@ [draw] {_GUI_RADIO_BG ({GUI__COLOR_TOGGLE_ENABLED})} - {_GUI_RADIO_DOT ()} + {_GUI_RADIO_DOT ("255, 225, 104, 255")} {_GUI_TEXT ({EXTRA_WIDTH}) ({FONT_SIZE}) ({GUI__FONT_COLOR_ENABLED__TITLE}) } [/draw] @@ -108,7 +111,7 @@ [draw] {_GUI_RADIO_BG ({GUI__COLOR_TOGGLE_DISABLED})} - {_GUI_RADIO_DOT "~GS()"} + {_GUI_RADIO_DOT ("179, 179, 179, 255")} {_GUI_TEXT ({EXTRA_WIDTH}) ({FONT_SIZE}) ({GUI__FONT_COLOR_DISABLED__TITLE}) } [/draw] @@ -120,7 +123,7 @@ [draw] {_GUI_RADIO_BG ({GUI__FONT_COLOR_ENABLED__BRIGHT})} - {_GUI_RADIO_DOT ()} + {_GUI_RADIO_DOT ("255, 225, 104, 255")} {_GUI_TEXT ({EXTRA_WIDTH}) ({FONT_SIZE}) ({GUI__FONT_COLOR_ENABLED__TITLE}) } [/draw] @@ -136,7 +139,7 @@ id = "radio" description = "Radio button." - {_GUI_RESOLUTION () 32 24 25 ({GUI_FONT_SIZE_SMALL}) } + {_GUI_RESOLUTION () 36 26 25 ({GUI_FONT_SIZE_SMALL}) } [/toggle_button_definition] @@ -145,7 +148,7 @@ id = "radio_no_label" description = "Radio button." - {_GUI_RESOLUTION () 32 24 25 ({GUI_FONT_SIZE_SMALL}) } + {_GUI_RESOLUTION () 36 26 25 ({GUI_FONT_SIZE_SMALL}) } [/toggle_button_definition] diff --git a/images/buttons/modern/dot.png b/images/buttons/modern/dot.png deleted file mode 100644 index 55e5655d463..00000000000 Binary files a/images/buttons/modern/dot.png and /dev/null differ diff --git a/images/buttons/modern/radiobox-pressed.png b/images/buttons/modern/radiobox-pressed.png deleted file mode 100644 index af45091bf4d..00000000000 Binary files a/images/buttons/modern/radiobox-pressed.png and /dev/null differ diff --git a/images/buttons/modern/radiobox.png b/images/buttons/modern/radiobox.png deleted file mode 100644 index 1d83d555577..00000000000 Binary files a/images/buttons/modern/radiobox.png and /dev/null differ diff --git a/src/draw.cpp b/src/draw.cpp index 136f451c105..bd939c64063 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -15,14 +15,17 @@ #include "draw.hpp" #include "color.hpp" +#include "font/cairo.hpp" #include "log.hpp" #include "sdl/rect.hpp" #include "sdl/texture.hpp" #include "sdl/utils.hpp" // sdl::runtime_at_least #include "video.hpp" +#include #include #include +#include static lg::log_domain log_draw("draw"); #define DBG_D LOG_STREAM(debug, log_draw) @@ -308,6 +311,67 @@ void draw::disc(int cx, int cy, int r, uint8_t octants) } } +/********************/ +/* Cairo primitives */ +/********************/ + +void draw::cairo_circle(int cx, int cy, int r, const color_t& c, int thickness) +{ + if (r <= 0) { + return; + } + + int size = 2*r; + surface sdl_surf(size, size); + auto cairo_surface = cairo::create_surface( + reinterpret_cast(sdl_surf->pixels), ::point(sdl_surf->w, sdl_surf->h)); + auto cairo_context = cairo::create_context(cairo_surface); + cairo_t* ctx = cairo_context.get(); + + cairo_set_antialias(ctx, CAIRO_ANTIALIAS_BEST); + + cairo_set_source_rgba(ctx, 0.0, 0.0, 0.0, 0.0); + cairo_paint(ctx); + + cairo_set_line_width(ctx, thickness); + cairo_set_source_rgba(ctx, + c.r / 255.0, + c.g / 255.0, + c.b / 255.0, + c.a / 255.0 + ); + cairo_arc(ctx, r, r, r-thickness, 0, 2*boost::math::constants::pi()); + cairo_stroke(ctx); + + draw::blit(texture(sdl_surf), ::rect(cx-r, cy-r, size, size)); +} + +void draw::cairo_disc(int cx, int cy, int r, const color_t& c) +{ + if (r <= 0) { + return; + } + + int size = 2*r; + surface sdl_surf(size, size); + auto cairo_surface = cairo::create_surface( + reinterpret_cast(sdl_surf->pixels), ::point(sdl_surf->w, sdl_surf->h)); + auto cairo_context = cairo::create_context(cairo_surface); + cairo_t* ctx = cairo_context.get(); + + cairo_set_antialias(ctx, CAIRO_ANTIALIAS_BEST); + + cairo_set_source_rgba(ctx, + c.r / 255.0, + c.g / 255.0, + c.b / 255.0, + c.a / 255.0 + ); + cairo_arc(ctx, r, r, r, 0, 2*2*boost::math::constants::pi()); + cairo_fill(ctx); + + draw::blit(texture(sdl_surf), ::rect(cx-r, cy-r, size, size)); +} /*******************/ /* texture drawing */ diff --git a/src/draw.hpp b/src/draw.hpp index 934079eb18e..f5af2399d97 100644 --- a/src/draw.hpp +++ b/src/draw.hpp @@ -32,10 +32,10 @@ #include "sdl/rect.hpp" #include "sdl/texture.hpp" +#include #include #include -#include struct color_t; @@ -210,6 +210,12 @@ void circle(int x, int y, int r, uint8_t octants = 0xff); void disc(int x, int y, int r, const color_t& c, uint8_t octants = 0xff); void disc(int x, int y, int r, uint8_t octants = 0xff); +/** Draw outline of circle using Cairo */ +void cairo_circle(int cx, int cy, int r, const color_t& c, int thickness); + +/** Draw filled circle using Cairo */ +void cairo_disc(int cx, int cy, int r, const color_t& c); + /*******************/ /* texture drawing */ diff --git a/src/font/cairo.hpp b/src/font/cairo.hpp index e8078333e31..39e2dba1e83 100644 --- a/src/font/cairo.hpp +++ b/src/font/cairo.hpp @@ -27,7 +27,7 @@ using context_ptr = std::unique_ptr; /** Color format for cairo surfaces. Should be equivalent to the format used by SDL. */ constexpr cairo_format_t format = CAIRO_FORMAT_ARGB32; -surface_ptr create_surface(uint8_t* buffer, const point& size) +inline surface_ptr create_surface(uint8_t* buffer, const point& size) { const auto& [width, height] = size; const int stride = cairo_format_stride_for_width(format, width); @@ -38,7 +38,7 @@ surface_ptr create_surface(uint8_t* buffer, const point& size) }; } -context_ptr create_context(const surface_ptr& surf) +inline context_ptr create_context(const surface_ptr& surf) { return { cairo_create(surf.get()), diff --git a/src/gui/core/canvas.cpp b/src/gui/core/canvas.cpp index 4a5cf81c3d4..3877ff76592 100644 --- a/src/gui/core/canvas.cpp +++ b/src/gui/core/canvas.cpp @@ -36,13 +36,12 @@ #include "picture.hpp" #include "sdl/point.hpp" #include "sdl/rect.hpp" +#include "sdl/surface.hpp" #include "sdl/texture.hpp" #include "sdl/utils.hpp" // blur_surface #include "video.hpp" // read_pixels_low_res, only used for blurring #include "wml_exception.hpp" -#include - namespace gui2 { @@ -219,22 +218,18 @@ void circle_shape::draw(wfl::map_formula_callable& variables) * silly unless there has been a resize. So to optimize we should use an * extra flag or do the calculation in a separate routine. */ - const int x = x_(variables); const int y = y_(variables); const unsigned radius = radius_(variables); - - DBG_GUI_D << "Circle: drawn at " << x << ',' << y << " radius " << radius << "."; - const color_t fill_color = fill_color_(variables); - if(!fill_color.null() && radius) { - draw::disc(x, y, radius, fill_color); + if (!fill_color.null()) { + draw::cairo_disc(x, y, radius, fill_color); } const color_t border_color = border_color_(variables); - for(unsigned int i = 0; i < border_thickness_; i++) { - draw::circle(x, y, radius - i, border_color); - } + draw::cairo_circle(x, y, radius, border_color, border_thickness_); + + DBG_GUI_D << "Circle: drawn at " << x << ',' << y << " radius " << radius << "."; } /***** ***** ***** ***** ***** IMAGE ***** ***** ***** ***** *****/