decorations: Use a single spritesheet for window borders

This commit is contained in:
K. Lange 2021-09-13 18:03:53 +09:00
parent d9d3f52fa8
commit 9d609d15df
23 changed files with 108 additions and 55 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

View File

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 223 B

View File

Before

Width:  |  Height:  |  Size: 152 B

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

View File

@ -1,12 +1,13 @@
/* vim: tabstop=4 shiftwidth=4 noexpandtab
/**
* @file lib/decor-fancy.c
* @brief "Fancy" decoration theme; the default.
*
* This is based on an old GTK theme I used to use back in ~2010.
*
* @copyright
* This file is part of ToaruOS and is released under the terms
* of the NCSA / University of Illinois License - see LICENSE.md
* Copyright (C) 2016-2018 K. Lange
*
* The default "fancy" decorations theme.
*
* Based on an old gtk-window-decorator theme I used to use many,
* many years ago.
* Copyright (C) 2016-2021 K. Lange
*/
#include <stdint.h>
#include <dlfcn.h>
@ -16,38 +17,98 @@
#include <toaru/decorations.h>
#include <toaru/text.h>
#define INACTIVE 10
#define TTK_FANCY_PATH "/usr/share/ttk/fancy/"
#define TTK_FANCY_PATH "/usr/share/ttk/"
#define TITLEBAR_HEIGHT 33
#define BASE_SIZE 10
#define TOTAL_SCALE 1
#define OUTER_SIZE 6
/* Color for the extra border lines drawn in tiled mode. */
#define BORDER_COLOR rgb(62,62,62)
/* Button and title colors */
#define ACTIVE_COLOR rgb(226,226,226)
#define INACTIVE_COLOR rgb(147,147,147)
static int u_height = TITLEBAR_HEIGHT * TOTAL_SCALE;
static int ul_width = BASE_SIZE * TOTAL_SCALE;
static int ur_width = BASE_SIZE * TOTAL_SCALE;
static int ml_width = BASE_SIZE * TOTAL_SCALE;
static int mr_width = BASE_SIZE * TOTAL_SCALE;
static int l_height = BASE_SIZE * TOTAL_SCALE;
static int ll_width = BASE_SIZE * TOTAL_SCALE;
static int lr_width = BASE_SIZE * TOTAL_SCALE;
static int u_height = 33;
static int ul_width = 10;
static int ur_width = 10;
static int mr_width = 6;
static int l_height = 9;
static int ll_width = 9;
static int lr_width = 9;
static struct TT_Font * _tt_font = NULL;
#define BUTTON_CLOSE 0
#define BUTTON_MAXIMIZE 1
#define ACTIVE 2
#define INACTIVE 11
static sprite_t * sprites[20];
#define TEXT_OFFSET ((window->decorator_flags & DECOR_FLAG_TILED) ? 5 : 10)
#define BUTTON_OFFSET ((window->decorator_flags & DECOR_FLAG_TILED) ? 5 : 0)
/**
* Replaces an old graphics API function from the
* very early days of ToaruOS...
*/
static void init_sprite(int id, char * path) {
sprites[id] = malloc(sizeof(sprite_t));
load_sprite(sprites[id], path);
}
/**
* Make a new sprite by cropping down @p from.
*/
static sprite_t * sprite_crop(sprite_t * from, int x, int y, int w, int h) {
sprite_t * dest = create_sprite(w,h,ALPHA_EMBEDDED);
gfx_context_t * sctx = init_graphics_sprite(dest);
draw_fill(sctx, rgba(0,0,0,0));
draw_sprite(sctx, from, -x, -y);
free(sctx);
return dest;
}
/**
* Chop up a spritesheet into edge/corner pieces.
*/
static void create_borders_from_spritesheet(int spriteIndex, const char * path) {
sprite_t tmp;
load_sprite(&tmp, path);
int um_width = 1; /* These need to always be 1... tmp.width - ul_width - ur_width; */
int m_height = 1; /* These need to always be 1... tmp.height - u_height - l_height; */
int lm_width = 1; /* These need to always be 1... tmp.width - ll_width - lr_width; */
int c = ul_width;
int r = tmp.width - ur_width;
int m = u_height;
int l = tmp.height - l_height;
sprites[spriteIndex + 0] = sprite_crop(&tmp, 0, 0, ul_width, u_height);
sprites[spriteIndex + 1] = sprite_crop(&tmp, c, 0, um_width, u_height);
sprites[spriteIndex + 2] = sprite_crop(&tmp, r, 0, ur_width, u_height);
sprites[spriteIndex + 3] = sprite_crop(&tmp, 0, m, ml_width, m_height);
sprites[spriteIndex + 4] = sprite_crop(&tmp, r, m, mr_width, m_height);
sprites[spriteIndex + 5] = sprite_crop(&tmp, 0, l, ll_width, l_height);
sprites[spriteIndex + 6] = sprite_crop(&tmp, c, l, lm_width, l_height);
sprites[spriteIndex + 7] = sprite_crop(&tmp, r, l, lr_width, l_height);
free(tmp.bitmap);
}
static int get_bounds_fancy(yutani_window_t * window, struct decor_bounds * bounds) {
if (window == NULL || !(window->decorator_flags & DECOR_FLAG_TILED)) {
bounds->top_height = 33;
bounds->bottom_height = 6;
bounds->left_width = 6;
bounds->right_width = 6;
bounds->top_height = TITLEBAR_HEIGHT * TOTAL_SCALE;
bounds->bottom_height = OUTER_SIZE * TOTAL_SCALE;
bounds->left_width = OUTER_SIZE * TOTAL_SCALE;
bounds->right_width = OUTER_SIZE * TOTAL_SCALE;
} else {
/* Any "exposed" edge gets an extra pixel. */
bounds->top_height = 27 + !(window->decorator_flags & DECOR_FLAG_TILE_UP);
bounds->top_height = 27 * TOTAL_SCALE + !(window->decorator_flags & DECOR_FLAG_TILE_UP);
bounds->bottom_height = !(window->decorator_flags & DECOR_FLAG_TILE_DOWN);
bounds->left_width = !(window->decorator_flags & DECOR_FLAG_TILE_LEFT);
bounds->right_width = !(window->decorator_flags & DECOR_FLAG_TILE_RIGHT);
@ -71,14 +132,14 @@ static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * c
}
}
if (decors_active == DECOR_INACTIVE) decors_active = INACTIVE;
decors_active = (decors_active == DECOR_INACTIVE) ? INACTIVE : ACTIVE;
if ((window->decorator_flags & DECOR_FLAG_TILED)) {
for (int i = 0; i < width; ++i) {
draw_sprite(ctx, sprites[decors_active + 1], i, -6 + !(window->decorator_flags & DECOR_FLAG_TILE_UP));
draw_sprite(ctx, sprites[decors_active + 1], i, -6 * TOTAL_SCALE + !(window->decorator_flags & DECOR_FLAG_TILE_UP));
}
uint32_t clear_color = rgb(62,62,62);
uint32_t clear_color = BORDER_COLOR;
if (!(window->decorator_flags & DECOR_FLAG_TILE_DOWN)) {
/* Draw bottom line */
for (int i = 0; i < (int)window->width; ++i) {
@ -140,10 +201,11 @@ static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * c
#define EXTRA_SPACE 120
uint32_t title_color = (decors_active == 0) ? rgb(226,226,226) : rgb(147,147,147);
tt_set_size(_tt_font, 12);
if (tt_string_width(_tt_font, tmp_title) + EXTRA_SPACE > width) {
while (t_l >= 0 && (tt_string_width(_tt_font, tmp_title) + EXTRA_SPACE > width)) {
uint32_t title_color = (decors_active == ACTIVE) ? ACTIVE_COLOR : INACTIVE_COLOR;
tt_set_size(_tt_font, 12 * TOTAL_SCALE);
if (tt_string_width(_tt_font, tmp_title) + EXTRA_SPACE * TOTAL_SCALE > width) {
while (t_l >= 0 && (tt_string_width(_tt_font, tmp_title) + EXTRA_SPACE * TOTAL_SCALE > width)) {
tmp_title[t_l] = '\0';
t_l--;
}
@ -151,27 +213,34 @@ static void render_decorations_fancy(yutani_window_t * window, gfx_context_t * c
if (*tmp_title) {
int title_offset = (width / 2) - (tt_string_width(_tt_font, tmp_title) / 2);
tt_draw_string(ctx, _tt_font, title_offset, TEXT_OFFSET + 14, tmp_title, title_color);
tt_draw_string(ctx, _tt_font, title_offset, (TEXT_OFFSET + 14) * TOTAL_SCALE, tmp_title, title_color);
}
free(tmp_title);
/* Buttons */
draw_sprite(ctx, sprites[decors_active + 8], width - 28 + BUTTON_OFFSET, 16 - BUTTON_OFFSET);
draw_sprite_alpha_paint(ctx, sprites[BUTTON_CLOSE],
width + (BUTTON_OFFSET - 28) * TOTAL_SCALE,
(16 - BUTTON_OFFSET) * TOTAL_SCALE, 1.0, title_color);
if (!(window->decorator_flags & DECOR_FLAG_NO_MAXIMIZE)) {
draw_sprite(ctx, sprites[decors_active + 9], width - 50 + BUTTON_OFFSET, 16 - BUTTON_OFFSET);
draw_sprite_alpha_paint(ctx, sprites[BUTTON_MAXIMIZE],
width + (BUTTON_OFFSET - 50) * TOTAL_SCALE,
(16 - BUTTON_OFFSET) * TOTAL_SCALE, 1.0, title_color);
}
}
static int check_button_press_fancy(yutani_window_t * window, int x, int y) {
if (x >= (int)window->width - 28 + BUTTON_OFFSET && x <= (int)window->width - 18 + BUTTON_OFFSET &&
y >= 16 && y <= 26) {
if (x >= (int)window->width + (BUTTON_OFFSET - 28) * TOTAL_SCALE &&
x <= (int)window->width + (BUTTON_OFFSET - 18) * TOTAL_SCALE &&
y >= 16 * TOTAL_SCALE && y <= 26 * TOTAL_SCALE ) {
return DECOR_CLOSE;
}
if (!(window->decorator_flags & DECOR_FLAG_NO_MAXIMIZE)) {
if (x >= (int)window->width - 50 + BUTTON_OFFSET && x <= (int)window->width - 40 + BUTTON_OFFSET &&
y >= 16 && y <= 26) {
if (x >= (int)window->width + (BUTTON_OFFSET - 50) * TOTAL_SCALE &&
x <= (int)window->width + (BUTTON_OFFSET - 40) * TOTAL_SCALE &&
y >= 16 * TOTAL_SCALE && y <= 26 * TOTAL_SCALE) {
return DECOR_MAXIMIZE;
}
}
@ -180,27 +249,11 @@ static int check_button_press_fancy(yutani_window_t * window, int x, int y) {
}
void decor_init() {
init_sprite(0, TTK_FANCY_PATH "active/ul.png");
init_sprite(1, TTK_FANCY_PATH "active/um.png");
init_sprite(2, TTK_FANCY_PATH "active/ur.png");
init_sprite(3, TTK_FANCY_PATH "active/ml.png");
init_sprite(4, TTK_FANCY_PATH "active/mr.png");
init_sprite(5, TTK_FANCY_PATH "active/ll.png");
init_sprite(6, TTK_FANCY_PATH "active/lm.png");
init_sprite(7, TTK_FANCY_PATH "active/lr.png");
init_sprite(8, TTK_FANCY_PATH "active/button-close.png");
init_sprite(9, TTK_FANCY_PATH "active/button-maximize.png");
init_sprite(BUTTON_CLOSE, TTK_FANCY_PATH "button-close.png");
init_sprite(BUTTON_MAXIMIZE, TTK_FANCY_PATH "button-maximize.png");
init_sprite(INACTIVE + 0, TTK_FANCY_PATH "inactive/ul.png");
init_sprite(INACTIVE + 1, TTK_FANCY_PATH "inactive/um.png");
init_sprite(INACTIVE + 2, TTK_FANCY_PATH "inactive/ur.png");
init_sprite(INACTIVE + 3, TTK_FANCY_PATH "inactive/ml.png");
init_sprite(INACTIVE + 4, TTK_FANCY_PATH "inactive/mr.png");
init_sprite(INACTIVE + 5, TTK_FANCY_PATH "inactive/ll.png");
init_sprite(INACTIVE + 6, TTK_FANCY_PATH "inactive/lm.png");
init_sprite(INACTIVE + 7, TTK_FANCY_PATH "inactive/lr.png");
init_sprite(INACTIVE + 8, TTK_FANCY_PATH "inactive/button-close.png");
init_sprite(INACTIVE + 9, TTK_FANCY_PATH "inactive/button-maximize.png");
create_borders_from_spritesheet(ACTIVE, TTK_FANCY_PATH "borders-active.png");
create_borders_from_spritesheet(INACTIVE, TTK_FANCY_PATH "borders-inactive.png");
decor_render_decorations = render_decorations_fancy;
decor_check_button_press = check_button_press_fancy;