mirror of
https://github.com/labwc/labwc.git
synced 2025-11-04 13:30:07 -05:00
Support svg buttons
In the theme directory add close-{active,inactive}.svg instead of
close.xbm - and similarly for iconify, menu and max.
This commit is contained in:
parent
a386133068
commit
c62df26c2a
10 changed files with 137 additions and 5 deletions
|
|
@ -54,7 +54,7 @@ png_load(const char *button_name, struct lab_data_buffer **buffer)
|
|||
|
||||
char path[4096] = { 0 };
|
||||
button_filename(button_name, path, sizeof(path));
|
||||
if (!file_exists(path) || !ispng(path)) {
|
||||
if (!ispng(path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
71
src/button/button-svg.c
Normal file
71
src/button/button-svg.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) Johan Malm 2023
|
||||
*/
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <cairo.h>
|
||||
#include <librsvg/rsvg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include "buffer.h"
|
||||
#include "button/button-svg.h"
|
||||
#include "button/common.h"
|
||||
#include "common/file-helpers.h"
|
||||
#include "labwc.h"
|
||||
#include "theme.h"
|
||||
|
||||
void
|
||||
button_svg_load(const char *button_name, struct lab_data_buffer **buffer,
|
||||
int size)
|
||||
{
|
||||
if (*buffer) {
|
||||
wlr_buffer_drop(&(*buffer)->base);
|
||||
*buffer = NULL;
|
||||
}
|
||||
|
||||
char filename[4096] = { 0 };
|
||||
button_filename(button_name, filename, sizeof(filename));
|
||||
|
||||
GError *err = NULL;
|
||||
RsvgRectangle viewport = { .width = size, .height = size };
|
||||
RsvgHandle *svg = rsvg_handle_new_from_file(filename, &err);
|
||||
if (err) {
|
||||
wlr_log(WLR_DEBUG, "error reading svg %s-%s\n", filename, err->message);
|
||||
g_error_free(err);
|
||||
/*
|
||||
* rsvg_handle_new_from_file() returns NULL if an error occurs,
|
||||
* so there is no need to free svg here.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_surface_t *image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
|
||||
cairo_t *cr = cairo_create(image);
|
||||
|
||||
rsvg_handle_render_document(svg, cr, &viewport, &err);
|
||||
if (err) {
|
||||
wlr_log(WLR_ERROR, "error rendering svg %s-%s\n", filename, err->message);
|
||||
g_error_free(err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cairo_surface_status(image)) {
|
||||
wlr_log(WLR_ERROR, "error reading svg button '%s'", filename);
|
||||
goto error;
|
||||
}
|
||||
cairo_surface_flush(image);
|
||||
|
||||
double w = cairo_image_surface_get_width(image);
|
||||
double h = cairo_image_surface_get_height(image);
|
||||
*buffer = buffer_create_cairo((int)w, (int)h, 1.0, /* free_on_destroy */ true);
|
||||
cairo_t *cairo = (*buffer)->cairo;
|
||||
cairo_set_source_surface(cairo, image, 0, 0);
|
||||
cairo_paint_with_alpha(cairo, 1.0);
|
||||
|
||||
error:
|
||||
cairo_destroy(cr);
|
||||
cairo_surface_destroy(image);
|
||||
g_object_unref(svg);
|
||||
}
|
||||
|
|
@ -3,3 +3,10 @@ labwc_sources += files(
|
|||
'button-xbm.c',
|
||||
'common.c',
|
||||
)
|
||||
|
||||
if svg.found()
|
||||
labwc_sources += files(
|
||||
'button-svg.c',
|
||||
)
|
||||
endif
|
||||
|
||||
|
|
|
|||
33
src/theme.c
33
src/theme.c
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "config.h"
|
||||
#include <cairo.h>
|
||||
#include <ctype.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
|
@ -25,6 +26,11 @@
|
|||
#include "common/string-helpers.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "button/button-png.h"
|
||||
|
||||
#if HAVE_RSVG
|
||||
#include "button/button-svg.h"
|
||||
#endif
|
||||
|
||||
#include "button/button-xbm.h"
|
||||
#include "theme.h"
|
||||
#include "buffer.h"
|
||||
|
|
@ -39,6 +45,15 @@ struct button {
|
|||
} active, inactive;
|
||||
};
|
||||
|
||||
static void
|
||||
drop(struct lab_data_buffer **buffer)
|
||||
{
|
||||
if (*buffer) {
|
||||
wlr_buffer_drop(&(*buffer)->base);
|
||||
*buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load_buttons(struct theme *theme)
|
||||
{
|
||||
|
|
@ -97,13 +112,29 @@ load_buttons(struct theme *theme)
|
|||
for (size_t i = 0; i < sizeof(buttons) / sizeof(buttons[0]); ++i) {
|
||||
struct button *b = &buttons[i];
|
||||
|
||||
drop(b->active.buffer);
|
||||
drop(b->inactive.buffer);
|
||||
|
||||
/* Try png icon first */
|
||||
snprintf(filename, sizeof(filename), "%s-active.png", b->name);
|
||||
png_load(filename, b->active.buffer);
|
||||
snprintf(filename, sizeof(filename), "%s-inactive.png", b->name);
|
||||
png_load(filename, b->inactive.buffer);
|
||||
|
||||
/* If there were no png buttons, use xbm */
|
||||
#if HAVE_RSVG
|
||||
/* Then try svg icon */
|
||||
int size = theme->title_height - 2 * theme->padding_height;
|
||||
if (!*b->active.buffer) {
|
||||
snprintf(filename, sizeof(filename), "%s-active.svg", b->name);
|
||||
button_svg_load(filename, b->active.buffer, size);
|
||||
}
|
||||
if (!*b->inactive.buffer) {
|
||||
snprintf(filename, sizeof(filename), "%s-inactive.svg", b->name);
|
||||
button_svg_load(filename, b->inactive.buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If there were no png/svg buttons, use xbm */
|
||||
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
|
||||
if (!*b->active.buffer) {
|
||||
button_xbm_load(filename, b->active.buffer,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue