aboutsummaryrefslogtreecommitdiff
path: root/src/layout.c
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2024-11-12 00:36:47 +0100
committerFederico Angelilli <code@fedang.net>2024-11-12 00:36:47 +0100
commit686802c2a472746a1b40fab30cbb0351e536c9ba (patch)
tree9a4fe3fa654fbe7b9bb35893a2da71c9754745b4 /src/layout.c
parent3f2af32442b9384d316651d42ad35945533dc39e (diff)
Modify block struct
Diffstat (limited to 'src/layout.c')
-rw-r--r--src/layout.c138
1 files changed, 90 insertions, 48 deletions
diff --git a/src/layout.c b/src/layout.c
index 92e6469..db707c5 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -5,6 +5,7 @@
#include "any_log.h"
#include "layout.h"
+#include "block.h"
void layout_init(layout_t *layout, block_t *block, layout_info_t info)
{
@@ -19,49 +20,68 @@ void layout_init(layout_t *layout, block_t *block, layout_info_t info)
layout->y_padding = block->y_padding;
layout->height = info.height;
- if (block->type == BLOCK_GROUP) {
- int x_offset = info.x_offset;
- layout->children = calloc(block->group.n_children, sizeof(layout_t));
+ switch (block->type) {
+ case BLOCK_TEXT: {
+ block_text_t *text = (block_text_t *)block;
+ layout->pl = pango_layout_new(info.context);
- for (int i = 0; i < block->group.n_children; i++) {
- if (block->group.children[i]->hidden)
- continue;
+ pango_layout_set_font_description(layout->pl, info.fontdesc);
+ pango_layout_set_alignment(layout->pl, text->text_align);
+ pango_layout_set_height(layout->pl, 0);
+ pango_layout_set_text(layout->pl, text->text, -1);
+ pango_layout_get_pixel_size(layout->pl, &layout->text_width, &layout->text_height);
- layout_init(&layout->children[layout->n_children], block->group.children[i], info);
- info.x_offset += layout->children[layout->n_children].width + block->group.spacing;
- layout->n_children++;
+ size_t length = strlen(text->text);
+ layout->width = info.height + (length != 1) * layout->text_width;
+ break;
}
- if (block->group.collapse && layout->n_children == 1) {
- layout_t *children = layout->children;
- memcpy(layout, children, sizeof(layout_t));
- free(children);
+ case BLOCK_GROUP: {
+ block_group_t *group = (block_group_t *)block;
+ int x_offset = info.x_offset;
+ layout->children = calloc(group->n_children, sizeof(layout_t));
- } else if (layout->n_children > 0) {
- layout_t *last = &layout->children[layout->n_children - 1];
- layout->width = last->x + last->width - x_offset;
+ for (size_t i = 0; i < group->n_children; i++) {
+ if (group->children[i]->hidden)
+ continue;
- // NOTE: Temporary solution to make blocks not overlapping correctly
- // less noticeable
- if (layout->children[0].x_padding == 0) {
- layout->x += 1;
- layout->width -= 1;
+ layout_init(&layout->children[layout->n_children], group->children[i], info);
+ info.x_offset += layout->children[layout->n_children].width + group->spacing;
+ layout->n_children++;
}
- if (last->x_padding == 0)
- layout->width -= 1;
+ if (group->collapse && layout->n_children == 1) {
+ layout_t *children = layout->children;
+ memcpy(layout, children, sizeof(layout_t));
+ free(children);
+
+ } else if (layout->n_children > 0) {
+ layout_t *last = &layout->children[layout->n_children - 1];
+ layout->width = last->x + last->width - x_offset;
+
+ // NOTE: Temporary solution to make blocks not overlapping correctly
+ // less noticeable
+ if (layout->children[0].x_padding == 0) {
+ layout->x += 1;
+ layout->width -= 1;
+ }
+
+ if (last->x_padding == 0)
+ layout->width -= 1;
+ }
+ break;
}
- } else if (block->type == BLOCK_TEXT) {
- layout->pl = pango_layout_new(info.context);
- pango_layout_set_font_description(layout->pl, info.fontdesc);
- pango_layout_set_alignment(layout->pl, block->text.text_align);
- pango_layout_set_height(layout->pl, 0);
- pango_layout_set_text(layout->pl, block->text.text, -1);
- pango_layout_get_pixel_size(layout->pl, &layout->text_width, &layout->text_height);
+ case BLOCK_SPEC: {
+ block_spec_t *spec = (block_spec_t *)block;
+ // You are on your own
+ // TODO: Maybe check for layout correctness
+ spec->layout_fn(block, layout, info);
+ break;
+ }
- int length = strlen(block->text.text);
- layout->width = info.height + (length != 1) * layout->text_width;
+ default:
+ unreachable();
}
if (layout->block->max_width > 0 && layout->width > layout->block->max_width)
@@ -98,24 +118,46 @@ void layout_render(layout_t *layout, cairo_t *cr)
cairo_close_path(cr);
cairo_stroke(cr);
- if (layout->block->type == BLOCK_GROUP) {
- for (int i = 0; i < layout->n_children; i++) {
- cairo_push_group(cr);
- layout_render(&layout->children[i], cr);
- cairo_pop_group_to_source(cr);
- cairo_paint(cr);
+ switch (layout->block->type) {
+ case BLOCK_TEXT: {
+ block_text_t *text = (block_text_t *)layout->block;
+ assert(layout->n_children == 0);
+
+ int text_x = layout->x + (layout->width - layout->text_width) / 2;
+ int text_y = layout->y + (layout->height - layout->text_height) / 2;
+
+ color = text->text_color;
+ cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
+ cairo_move_to(cr, text_x, text_y);
+
+ pango_layout_set_text(layout->pl, text->text, -1);
+ pango_cairo_update_layout(cr, layout->pl);
+ pango_cairo_show_layout(cr, layout->pl);
+ break;
+ }
+
+ case BLOCK_GROUP: {
+ for (size_t i = 0; i < layout->n_children; i++) {
+ cairo_push_group(cr);
+ layout_render(&layout->children[i], cr);
+ cairo_pop_group_to_source(cr);
+ cairo_paint(cr);
+ }
+ break;
}
- } else if (layout->block->type == BLOCK_TEXT) {
- int text_x = layout->x + (layout->width - layout->text_width) / 2;
- int text_y = layout->y + (layout->height - layout->text_height) / 2;
- color = layout->block->text.text_color;
- cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
- cairo_move_to(cr, text_x, text_y);
+ case BLOCK_SPEC: {
+ // NOTE: What if a special block adds children to the layout?
+ // For now do nothing and let them handle it, however
+ // this is a strange behavior in my opinion...
+ //
+ block_spec_t *spec = (block_spec_t *)layout->block;
+ spec->render_fn(layout, cr);
+ break;
+ }
- pango_layout_set_text(layout->pl, layout->block->text.text, -1);
- pango_cairo_update_layout(cr, layout->pl);
- pango_cairo_show_layout(cr, layout->pl);
+ default:
+ unreachable();
}
}
@@ -124,7 +166,7 @@ void layout_free(layout_t *layout)
if (layout->pl != NULL)
g_object_unref(layout->pl);
- for (int i = 0; i < layout->n_children; i++)
+ for (size_t i = 0; i < layout->n_children; i++)
layout_free(&layout->children[i]);
free(layout->children);