Merge pull request #4497 from orestisfl/icons-title-align

Make window icons follow title alignment
This commit is contained in:
Orestis Floros 2021-09-09 09:27:30 +02:00 committed by GitHub
commit ce2c21885d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

81
src/x.c
View File

@ -614,33 +614,11 @@ void x_draw_decoration(Con *con) {
/* 6: draw the icon and title */
int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
int text_offset_x = 0;
struct Window *win = con->window;
const int title_padding = logical_px(2);
const int deco_width = (int)con->deco_rect.width;
/* Draw the icon */
if (con->window_icon_padding > -1 && win && win->icon) {
/* icon_padding is applied horizontally only,
* the icon will always use all available vertical space. */
const int icon_padding = logical_px(1 + con->window_icon_padding);
const uint16_t icon_size = con->deco_rect.height - 2 * logical_px(1);
const int icon_offset_y = logical_px(1);
text_offset_x += icon_size + 2 * icon_padding;
draw_util_image(
win->icon,
&(parent->frame_buffer),
con->deco_rect.x + icon_padding,
con->deco_rect.y + icon_offset_y,
icon_size,
icon_size);
}
const int title_padding = logical_px(2);
int mark_width = 0;
if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) {
@ -699,33 +677,62 @@ void x_draw_decoration(Con *con) {
goto copy_pixmaps;
}
/* icon_padding is applied horizontally only, the icon will always use all
* available vertical space. */
int icon_size = max(0, con->deco_rect.height - logical_px(2));
int icon_padding = logical_px(max(1, con->window_icon_padding));
int total_icon_space = icon_size + 2 * icon_padding;
const bool has_icon = (con->window_icon_padding > -1) && win && win->icon && (total_icon_space < deco_width);
if (!has_icon) {
icon_size = icon_padding = total_icon_space = 0;
}
/* Determine x offsets according to title alignment */
int icon_offset_x;
int title_offset_x;
switch (config.title_align) {
case ALIGN_LEFT:
/* (pad)[text ](pad)[mark + its pad) */
title_offset_x = title_padding;
/* (pad)[(pad)(icon)(pad)][text ](pad)[mark + its pad)
* ^ ^--- title_offset_x
* ^--- icon_offset_x */
icon_offset_x = icon_padding;
title_offset_x = title_padding + total_icon_space;
break;
case ALIGN_CENTER:
/* (pad)[ text ](pad)[mark + its pad)
* To center the text inside its allocated space, the surface
* between the brackets, we use the formula
* (surface_width - predict_text_width) / 2
* where surface_width = deco_width - 2 * pad - mark_width
* so, offset = pad + (surface_width - predict_text_width) / 2 =
* = = (deco_width - mark_width - predict_text_width) / 2 */
title_offset_x = max(title_padding, (deco_width - mark_width - predict_text_width(title)) / 2);
/* (pad)[ ][(pad)(icon)(pad)][text ](pad)[mark + its pad)
* ^ ^--- title_offset_x
* ^--- icon_offset_x
* Text should come right after the icon (+padding). We calculate
* the offset for the icon (white space in the title) by dividing
* by two the total available area. That's the decoration width
* minus the elements that come after icon_offset_x (icon, its
* padding, text, marks). */
icon_offset_x = max(icon_padding, (deco_width - icon_padding - icon_size - predict_text_width(title) - title_padding - mark_width) / 2);
title_offset_x = max(title_padding, icon_offset_x + icon_padding + icon_size);
break;
case ALIGN_RIGHT:
/* [mark + its pad](pad)[ text](pad) */
title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title));
/* [mark + its pad](pad)[ text][(pad)(icon)(pad)](pad)
* ^ ^--- icon_offset_x
* ^--- title_offset_x */
title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title) - total_icon_space);
/* Make sure the icon does not escape title boundaries */
icon_offset_x = min(deco_width - icon_size - icon_padding - title_padding, title_offset_x + predict_text_width(title) + icon_padding);
break;
}
draw_util_text(title, &(parent->frame_buffer),
p->color->text, p->color->background,
con->deco_rect.x + text_offset_x + title_offset_x,
con->deco_rect.x + title_offset_x,
con->deco_rect.y + text_offset_y,
deco_width - text_offset_x - mark_width - 2 * title_padding);
deco_width - mark_width - 2 * title_padding - total_icon_space);
if (has_icon) {
draw_util_image(
win->icon,
&(parent->frame_buffer),
con->deco_rect.x + icon_offset_x,
con->deco_rect.y + logical_px(1),
icon_size,
icon_size);
}
if (win == NULL || con->title_format != NULL) {
I3STRING_FREE(title);