modularize core bar logic

This commit is contained in:
Felix Kratz 2021-11-11 01:34:29 +01:00
parent 766e3f6984
commit 28729302e3
9 changed files with 96 additions and 87 deletions

View file

@ -3,8 +3,10 @@
void background_init(struct background* background) {
background->enabled = false;
background->overrides_height = false;
background->height = 0;
background->width = 0;
background->border_width = 0;
background->padding_left = 0;
background->padding_right = 0;
@ -44,6 +46,7 @@ bool background_set_enabled(struct background* background, bool enabled) {
bool background_set_height(struct background* background, uint32_t height) {
if (background->height == height) return false;
background->height = height;
background->overrides_height = height != 0;
return true;
}
@ -71,6 +74,12 @@ bool background_set_padding_right(struct background* background, uint32_t pad) {
return true;
}
void background_draw(struct background* background, CGPoint origin, CGContextRef context) {
if (!background->enabled) return;
CGRect draw_region = {{origin.x, origin.y}, {background->width, background->height}};
draw_rect(context, draw_region, &background->color, background->corner_radius, background->border_width, &background->border_color, false);
}
static bool background_parse_sub_domain(struct background* background, FILE* rsp, struct token property, char* message) {
if (token_equals(property, PROPERTY_DRAWING))
return background_set_enabled(background, evaluate_boolean_state(get_token(&message), background->enabled));

View file

@ -1,9 +1,12 @@
#ifndef BACKGROUND_H
#define BACKGROUND_H
#include <stdint.h>
struct background {
bool enabled;
bool overrides_height;
uint32_t height;
uint32_t width;
uint32_t corner_radius;
uint32_t border_width;
int padding_left;
@ -22,6 +25,8 @@ bool background_set_corner_radius(struct background* background, uint32_t corner
bool background_set_padding_left(struct background* background, uint32_t pad);
bool background_set_padding_right(struct background* background, uint32_t pad);
void background_draw(struct background* background, CGPoint origin, CGContextRef context);
static bool background_parse_sub_domain(struct background* background, FILE* rsp, struct token property, char* message);
#endif // !BACKGROUND_H

119
src/bar.c
View file

@ -2,7 +2,9 @@
#include "alias.h"
#include "bar_item.h"
#include "display.h"
#include "graph.h"
#include "misc/helpers.h"
#include "text.h"
#include <_types/_uint32_t.h>
#include <stdint.h>
@ -34,12 +36,6 @@ static CGPoint bar_align_line(struct bar *bar, struct text_line* line, int align
return (CGPoint) { x, y };
}
static void bar_draw_line(struct bar *bar, struct text_line* line, float x, float y) {
CGContextSetRGBFillColor(bar->context, line->color.r, line->color.g, line->color.b, line->color.a);
CGContextSetTextPosition(bar->context, x, y);
CTLineDraw(line->line, bar->context);
}
void bar_draw_graph_line(struct bar *bar, struct graph* graph, uint32_t x, uint32_t y, uint32_t height, bool right_to_left) {
y-= height / 2;
uint32_t sample_width = 1;
@ -121,30 +117,11 @@ bool bar_draws_item(struct bar* bar, struct bar_item* bar_item) {
}
void bar_draw_bar_items(struct bar* bar) {
bool atomic_redraw = true;
SLSDisableUpdate(g_connection);
SLSOrderWindow(g_connection, bar->id, -1, 0);
SLSRemoveAllTrackingAreas(g_connection, bar->id);
if (g_bar_manager.picky_redraw) {
for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
struct bar_item* bar_item = g_bar_manager.bar_items[i];
if (!bar_item->queued_for_redraw || !bar_draws_item(bar, bar_item)) continue;
if (atomic_redraw && bar_item->num_rects >= bar->adid && bar_item->bounding_rects[bar->adid - 1]) {
CGRect draw_region = {{bar_item->bounding_rects[bar->adid - 1]->origin.x - bar->origin.x, 0},
{bar_item->bounding_rects[bar->adid - 1]->size.width, bar->frame.size.height}};
draw_rect(bar->context, CGRectInset(draw_region, g_bar_manager.background.border_width, 0), &g_bar_manager.background.color, 0, 0, &g_bar_manager.background.border_color, true);
}
atomic_redraw &= bar_item->redraw_in_place;
}
} else
atomic_redraw = false;
if (!bar->background_exists || !atomic_redraw) {
draw_rect(bar->context, bar->frame, &g_bar_manager.background.color, g_bar_manager.background.corner_radius, g_bar_manager.background.border_width, &g_bar_manager.background.border_color, true);
bar->background_exists = true;
}
draw_rect(bar->context, bar->frame, &g_bar_manager.background.color, g_bar_manager.background.corner_radius, g_bar_manager.background.border_width, &g_bar_manager.background.border_color, true);
for (int i = 0; i < g_bar_manager.bar_item_count; i++) {
struct bar_item* bar_item = g_bar_manager.bar_items[i];
@ -153,20 +130,18 @@ void bar_draw_bar_items(struct bar* bar) {
if (!bar_draws_item(bar, bar_item)) continue;
bar_item_append_associated_bar(bar_item, bar->adid);
if (!bar_item->queued_for_redraw && atomic_redraw) continue;
if (bar_item->update_mask & UPDATE_MOUSE_ENTERED || bar_item->update_mask & UPDATE_MOUSE_EXITED)
SLSAddTrackingRect(g_connection, bar->id, CGRectInset(bar_item_construct_bounding_rect(bar_item), 1, 1));
struct text_line* label = &bar_item->label.line;
struct text_line* icon = &bar_item->icon.line;
bar_item_set_bounding_rect_for_display(bar_item, bar->adid, bar->origin);
bar_draw_group(bar, bar_item, bar->adid);
bar_draw_item_background(bar, bar_item, bar->adid);
bar_draw_line(bar, icon, icon->bounds.origin.x, icon->bounds.origin.y + bar_item->y_offset);
bar_draw_line(bar, label, label->bounds.origin.x, label->bounds.origin.y + bar_item->y_offset);
text_draw(&bar_item->icon, bar_item->icon.line.bounds.origin, bar->context);
text_draw(&bar_item->label, bar_item->label.line.bounds.origin, bar->context);
bar_draw_alias(bar, bar_item, bar_item->sandwich_position);
bar_draw_graph(bar, bar_item, bar_item->sandwich_position, bar_item->graph.rtl);
}
@ -191,93 +166,83 @@ void bar_redraw(struct bar* bar) {
struct text_line* label = &bar_item->label.line;
struct text_line* icon = &bar_item->icon.line;
CGPoint icon_position = bar_align_line(bar, icon, ALIGN_CENTER, ALIGN_CENTER);
icon_position.y += bar_item->y_offset;
CGPoint label_position = bar_align_line(bar, label, ALIGN_CENTER, ALIGN_CENTER);
label_position.y += bar_item->y_offset;
uint32_t sandwich_position = 0;
bool graph_rtl = false;
bool rtl = false;
if (bar_item->position == POSITION_LEFT) {
icon_position.x = bar_left_final_item_x + bar_item->icon.padding_left + bar_item->background.padding_left + 1;
label_position.x = icon_position.x + icon->bounds.size.width + bar_item->icon.padding_right + bar_item->label.padding_left;
icon_position.x = bar_left_final_item_x + bar_item->background.padding_left + 1;
label_position.x = icon_position.x + text_get_length(&bar_item->icon);
if (!bar_item->has_const_width)
bar_left_final_item_x = label_position.x + label->bounds.size.width + bar_item->label.padding_right + bar_item->background.padding_right;
bar_left_final_item_x = label_position.x + text_get_length(&bar_item->label) + bar_item->background.padding_right;
else
bar_left_final_item_x += bar_item->custom_width;
sandwich_position = label_position.x;
if (bar_item->has_graph) {
if (!bar_item->has_const_width)
bar_left_final_item_x += bar_item->graph.width;
sandwich_position = label_position.x - bar_item->label.padding_left;
label_position.x += bar_item->graph.width;
bar_left_final_item_x += graph_get_length(&bar_item->graph);
label_position.x += graph_get_length(&bar_item->graph);
} else if (bar_item->has_alias) {
if (!bar_item->has_const_width)
bar_left_final_item_x += bar_item->alias.bounds.size.width;
sandwich_position = label_position.x - bar_item->label.padding_left;
label_position.x += bar_item->alias.bounds.size.width;
bar_left_final_item_x += alias_get_length(&bar_item->alias);
label_position.x += alias_get_length(&bar_item->alias);
}
}
else if (bar_item->position == POSITION_RIGHT) {
label_position.x = bar_right_first_item_x - label->bounds.size.width - bar_item->label.padding_right - bar_item->background.padding_right;
icon_position.x = label_position.x - icon->bounds.size.width - bar_item->icon.padding_right - bar_item->label.padding_left - 1;
rtl = true;
label_position.x = bar_right_first_item_x - text_get_length(&bar_item->label) - bar_item->background.padding_right;
icon_position.x = label_position.x - text_get_length(&bar_item->icon) - 1;
if (!bar_item->has_const_width)
bar_right_first_item_x = icon_position.x - bar_item->icon.padding_left - bar_item->background.padding_left;
bar_right_first_item_x = icon_position.x - bar_item->background.padding_left;
else
bar_right_first_item_x -= bar_item->custom_width;
if (bar_item->has_graph) {
graph_rtl = true;
if (!bar_item->has_const_width)
bar_right_first_item_x -= bar_item->graph.width;
sandwich_position = icon_position.x + bar_item->icon.padding_right + icon->bounds.size.width;
icon_position.x -= bar_item->graph.width;
bar_right_first_item_x -= graph_get_length(&bar_item->graph);
sandwich_position = icon_position.x + text_get_length(&bar_item->icon);
icon_position.x -= graph_get_length(&bar_item->graph);
} else if (bar_item->has_alias) {
if (!bar_item->has_const_width)
icon_position.x -= bar_item->alias.bounds.size.width;
sandwich_position = icon_position.x + bar_item->icon.padding_right + icon->bounds.size.width;
bar_right_first_item_x -= bar_item->alias.bounds.size.width;
icon_position.x -= alias_get_length(&bar_item->alias);
bar_right_first_item_x -= alias_get_length(&bar_item->alias);
sandwich_position = icon_position.x + text_get_length(&bar_item->icon);
}
}
else if (bar_item->position == POSITION_CENTER) {
icon_position.x = bar_center_first_item_x + bar_item->icon.padding_left + bar_item->background.padding_left + 1;
label_position.x = icon_position.x + icon->bounds.size.width + bar_item->icon.padding_right + bar_item->label.padding_left;
icon_position.x = bar_center_first_item_x + bar_item->background.padding_left + 1;
label_position.x = icon_position.x + text_get_length(&bar_item->icon);
if (!bar_item->has_const_width)
bar_center_first_item_x = label_position.x + label->bounds.size.width + bar_item->label.padding_right + bar_item->background.padding_right;
bar_center_first_item_x = label_position.x + text_get_length(&bar_item->label) + bar_item->background.padding_right;
else
bar_center_first_item_x += bar_item->custom_width;
sandwich_position = label_position.x;
if (bar_item->has_graph) {
if (!bar_item->has_const_width)
bar_center_first_item_x += bar_item->graph.width;
sandwich_position = label_position.x - bar_item->label.padding_left;
label_position.x += bar_item->graph.width;
bar_center_first_item_x += graph_get_length(&bar_item->graph);
label_position.x += graph_get_length(&bar_item->graph);
} else if (bar_item->has_alias) {
if (!bar_item->has_const_width)
bar_center_first_item_x += bar_item->alias.bounds.size.width;
sandwich_position = label_position.x - bar_item->label.padding_left;
label_position.x += bar_item->alias.bounds.size.width;
bar_center_first_item_x += alias_get_length(&bar_item->alias);
label_position.x += alias_get_length(&bar_item->alias);
}
}
bar_item->queued_for_redraw = true;
bar_item->redraw_in_place = false;
if (g_bar_manager.picky_redraw) {
if (bar_item->num_rects >= bar->adid && bar_item->bounding_rects[bar->adid - 1]) {
if ((bar_item->bounding_rects[bar->adid - 1]->origin.x == icon_position.x - bar_item->icon.padding_left + bar->origin.x) && !bar_item->needs_update) {
bar_item->queued_for_redraw = false;
}
else if (bar_item->bounding_rects[bar->adid - 1]->origin.x == icon_position.x - bar_item->icon.padding_left + bar->origin.x
&& bar_item->needs_update
&& bar_item->bounding_rects[bar->adid - 1]->size.width >= bar_item_construct_bounding_rect(bar_item).size.width)
bar_item->redraw_in_place = true;
}
}
bar_item->icon.line.bounds.origin = icon_position;
bar_item->label.line.bounds.origin = label_position;
label->bounds.origin = label_position;
icon->bounds.origin = icon_position;
bar_item->graph.rtl = graph_rtl;
bar_item->graph.rtl = rtl;
bar_item->sandwich_position = sandwich_position;
}

View file

@ -37,7 +37,6 @@ extern CGError SLSWindowSetShadowProperties(uint32_t wid, CFDictionaryRef proper
struct bar {
bool hidden;
bool background_exists;
uint32_t id;
uint32_t did;
uint32_t sid;

View file

@ -295,7 +295,6 @@ void bar_item_remove_bounding_rect_for_display(struct bar_item* bar_item, uint32
CGRect bar_item_construct_bounding_rect(struct bar_item* bar_item) {
CGRect bounding_rect;
bounding_rect.origin = bar_item->icon.line.bounds.origin;
bounding_rect.origin.x -= bar_item->icon.padding_left;
bounding_rect.origin.y = bar_item->icon.line.bounds.origin.y < bar_item->label.line.bounds.origin.y ? bar_item->icon.line.bounds.origin.y : bar_item->label.line.bounds.origin.y + bar_item->y_offset;
bounding_rect.size.width = bar_item_get_length(bar_item);
bounding_rect.size.height = bar_item_get_height(bar_item);

View file

@ -20,8 +20,6 @@ struct bar_item {
bool drawing;
bool has_const_width;
uint32_t custom_width;
bool queued_for_redraw;
bool redraw_in_place;
// These are 32bit masks where the ith bit represents the ith screen/display/bar association
uint32_t associated_bar;

View file

@ -5,7 +5,7 @@
#include <stdint.h>
#define array_count(a) (sizeof((a)) / sizeof(*(a)))
#define MAXLEN 512
#define FORK_TIMEOUT 10
#define FORK_TIMEOUT 60
#include <string.h>
extern CFArrayRef SLSCopyManagedDisplaySpaces(int cid);

View file

@ -26,9 +26,13 @@ static CTFontRef text_create_font(char *cstring) {
}
void text_init(struct text* text) {
text->drawing = true;
text->highlight = false;
text->has_const_width = false;
text->custom_width = 0;
text->padding_left = 0;
text->padding_right = 0;
text->y_offset = 0;
text->color = rgba_color_from_hex(0xffffffff);
@ -105,6 +109,8 @@ void text_clear_pointers(struct text* text) {
}
uint32_t text_get_length(struct text* text) {
if (!text->drawing) return 0;
if (text->has_const_width) return text->custom_width;
return (text->line.bounds.size.width + text->padding_left + text->padding_right) > 0 ? (text->line.bounds.size.width + text->padding_left + text->padding_right) : 0;
}
@ -125,25 +131,45 @@ void text_destroy(struct text* text) {
text_clear_pointers(text);
}
void text_draw(struct text* text, CGPoint origin, CGContextRef context) {
if (!text->drawing) return;
CGContextSetRGBFillColor(context, text->line.color.r, text->line.color.g, text->line.color.b, text->line.color.a);
CGContextSetTextPosition(context, origin.x + text->padding_left, origin.y + text->y_offset);
CTLineDraw(text->line.line, context);
}
static bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property, char* message) {
if (token_equals(property, PROPERTY_COLOR))
return text_set_color(text, token_to_uint32t(get_token(&message)));
else if (token_equals(property, PROPERTY_HIGHLIGHT)) {
text->highlight = evaluate_boolean_state(get_token(&message), text->highlight);
return text_update_color(text);
}
else if (token_equals(property, PROPERTY_FONT))
} else if (token_equals(property, PROPERTY_FONT))
return text_set_font(text, string_copy(message), false);
else if (token_equals(property, PROPERTY_HIGHLIGHT_COLOR)) {
text->highlight_color = rgba_color_from_hex(token_to_uint32t(get_token(&message)));
return text_update_color(text);
}
else if (token_equals(property, PROPERTY_PADDING_LEFT)) {
} else if (token_equals(property, PROPERTY_PADDING_LEFT)) {
text->padding_left = token_to_int(get_token(&message));
return true;
} else if (token_equals(property, PROPERTY_PADDING_RIGHT)) {
text->padding_right = token_to_int(get_token(&message));
return true;
} else if (token_equals(property, PROPERTY_YOFFSET)) {
text->y_offset = token_to_int(get_token(&message));
return true;
} else if (token_equals(property, PROPERTY_WIDTH)) {
struct token token = get_token(&message);
if (token_equals(token, "dynamic"))
text->has_const_width = false;
else {
text->has_const_width = true;
text->custom_width = token_to_uint32t(token);
}
return true;
} else if (token_equals(property, PROPERTY_DRAWING)) {
text->drawing = evaluate_boolean_state(get_token(&message), text->drawing);
return true;
}
else {
fprintf(rsp, "Unknown property: %s \n", property.text);

View file

@ -10,15 +10,21 @@ struct text_line {
};
struct text {
int y_offset;
bool highlight;
struct text_line line;
bool drawing;
bool has_const_width;
uint32_t custom_width;
char* string;
char* font_name;
CTFontRef font;
int padding_left;
int padding_right;
struct text_line line;
struct rgba_color color;
struct rgba_color highlight_color;
struct background background;
};
void text_init(struct text* text);
@ -32,6 +38,8 @@ uint32_t text_get_length(struct text* text);
uint32_t text_get_height(struct text* text);
bool text_update_color(struct text* text);
void text_draw(struct text* text, CGPoint origin, CGContextRef context);
static bool text_parse_sub_domain(struct text* text, FILE* rsp, struct token property, char* message);
#endif // !TEXT_H_