Compare commits
No commits in common. "1e2e11cd2b0abca503dffc31a5ca084278410207" and "dc83e09f43c3793603220681520e0c8f90a17878" have entirely different histories.
1e2e11cd2b
...
dc83e09f43
9 changed files with 85 additions and 80 deletions
4
Makefile
4
Makefile
|
@ -13,10 +13,10 @@ OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
||||||
DEPS=$(OBJS:%.o=%.d)
|
DEPS=$(OBJS:%.o=%.d)
|
||||||
|
|
||||||
|
|
||||||
all: CFLAGS+=-fsanitize=address -Og -ggdb
|
all: CFLAGS+=-Og -ggdb -DNDEBUG
|
||||||
all: $(BUILD) $(BIN)
|
all: $(BUILD) $(BIN)
|
||||||
|
|
||||||
release: CFLAGS+=-O2 -flto=auto -DNDEBUG -ggdb
|
release: CFLAGS+=-O2 -flto=auto -DNDEBUG
|
||||||
release: clean $(BUILD) $(BIN)
|
release: clean $(BUILD) $(BIN)
|
||||||
|
|
||||||
$(BIN): $(OBJS)
|
$(BIN): $(OBJS)
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "box-layout-node.h"
|
#include "box-layout-node.h"
|
||||||
#include "node.h"
|
|
||||||
#include "rect.h"
|
|
||||||
|
|
||||||
int box_layout_handle(UINode *component, enum UIEvent ev, size_t d, void *p)
|
int box_layout_handle(UINode *component, enum UIEvent ev, size_t d, void *p)
|
||||||
{
|
{
|
||||||
|
@ -29,33 +27,38 @@ int box_layout_handle(UINode *component, enum UIEvent ev, size_t d, void *p)
|
||||||
int growing_widgets = 0;
|
int growing_widgets = 0;
|
||||||
int current_index = 0;
|
int current_index = 0;
|
||||||
|
|
||||||
if (ev == UI_EVENT_RELAYOUT || ev == UI_EVENT_GET_EXTENTS) {
|
if (ev == UI_EVENT_RELAYOUT || ev == UI_EVENT_GET_HEIGHT || ev == UI_EVENT_GET_WIDTH) {
|
||||||
for (int i = 0; i < node->nodes_count; i++) {
|
for (int i = 0; i < node->nodes_count; i++) {
|
||||||
UINode *current = node->nodes[i];
|
UINode *current = node->nodes[i];
|
||||||
if (current->flags & UI_NODE_COMPONENT) continue;
|
if (current->flags & UI_NODE_COMPONENT) continue;
|
||||||
|
|
||||||
UIRect current_rect = node_get_computed_rect(current);
|
double w = current->rect.w;
|
||||||
|
double h = current->rect.h;
|
||||||
current->rect.w = current_rect.w;
|
if (current->width_policy == UI_SIZE_POLICY_DYNAMIC) {
|
||||||
current->rect.h = current_rect.h;
|
node_dispatch(current, UI_EVENT_GET_WIDTH, 0, &w);
|
||||||
|
current->rect.w = w;
|
||||||
|
}
|
||||||
|
if (current->height_policy == UI_SIZE_POLICY_DYNAMIC) {
|
||||||
|
node_dispatch(current, UI_EVENT_GET_HEIGHT, 0, &h);
|
||||||
|
current->rect.h = h;
|
||||||
|
}
|
||||||
if (is_horizontal) {
|
if (is_horizontal) {
|
||||||
if (current_rect.h > maximum_secondary_position) {
|
if (h > maximum_secondary_position) {
|
||||||
maximum_secondary_position = current_rect.h;
|
maximum_secondary_position = h;
|
||||||
}
|
}
|
||||||
if (current->width_policy == UI_SIZE_POLICY_GROW) {
|
if (current->width_policy == UI_SIZE_POLICY_GROW) {
|
||||||
growing_widgets++;
|
growing_widgets++;
|
||||||
} else {
|
} else {
|
||||||
size += current_rect.w;
|
size += w;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (current_rect.w > maximum_secondary_position) {
|
if (w > maximum_secondary_position) {
|
||||||
maximum_secondary_position = current_rect.w;
|
maximum_secondary_position = w;
|
||||||
}
|
}
|
||||||
if (current->height_policy == UI_SIZE_POLICY_GROW) {
|
if (current->height_policy == UI_SIZE_POLICY_GROW) {
|
||||||
growing_widgets++;
|
growing_widgets++;
|
||||||
} else {
|
} else {
|
||||||
size += current_rect.h;
|
size += h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current_index) {
|
if (current_index) {
|
||||||
|
@ -67,14 +70,18 @@ int box_layout_handle(UINode *component, enum UIEvent ev, size_t d, void *p)
|
||||||
maximum_secondary_position += is_horizontal ? margin_top + margin_bottom : margin_left + margin_right;
|
maximum_secondary_position += is_horizontal ? margin_top + margin_bottom : margin_left + margin_right;
|
||||||
size += is_vertical ? margin_top + margin_bottom : margin_left + margin_right;
|
size += is_vertical ? margin_top + margin_bottom : margin_left + margin_right;
|
||||||
|
|
||||||
if (ev == UI_EVENT_GET_EXTENTS) {
|
if (ev == UI_EVENT_GET_WIDTH) {
|
||||||
((UIRect*)p)->w = is_horizontal ? size : maximum_secondary_position;
|
*(double*)p = is_horizontal ? size : maximum_secondary_position;
|
||||||
((UIRect*)p)->h = is_vertical ? size : maximum_secondary_position;
|
return 1;
|
||||||
return UI_NODE_COMPUTED_EXTENTS_OK;
|
}
|
||||||
|
if (ev == UI_EVENT_GET_HEIGHT) {
|
||||||
|
*(double*)p = is_vertical ? size : maximum_secondary_position;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// we can distribute growing layout children only if we have a fixed sized policy in the layout primary direction
|
// we can distribute growing layout children only if we have a fixed sized policy in the layout primary direction
|
||||||
bool is_fixed_for_primary_direction = (is_horizontal && node->width_policy != UI_SIZE_POLICY_COMPUTED) || (is_vertical && node->height_policy != UI_SIZE_POLICY_COMPUTED);
|
bool is_fixed_for_primary_direction = (is_horizontal && node->width_policy != UI_SIZE_POLICY_DYNAMIC) || (is_vertical && node->height_policy != UI_SIZE_POLICY_DYNAMIC);
|
||||||
double primary_direction = is_horizontal ? node->rect.w - margin_left - margin_right : node->rect.h - margin_top - margin_bottom;
|
double primary_direction = is_horizontal ? node->rect.w - margin_left - margin_right : node->rect.h - margin_top - margin_bottom;
|
||||||
bool distributes_growing_widgets = growing_widgets && is_fixed_for_primary_direction;
|
bool distributes_growing_widgets = growing_widgets && is_fixed_for_primary_direction;
|
||||||
double size_per_growing_widget = 0;
|
double size_per_growing_widget = 0;
|
||||||
|
@ -88,7 +95,7 @@ int box_layout_handle(UINode *component, enum UIEvent ev, size_t d, void *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_fixed_for_secondary_direction = (is_horizontal && node->height_policy != UI_SIZE_POLICY_COMPUTED) || (is_vertical && node->width_policy != UI_SIZE_POLICY_COMPUTED);
|
bool is_fixed_for_secondary_direction = (is_horizontal && node->height_policy != UI_SIZE_POLICY_DYNAMIC) || (is_vertical && node->width_policy != UI_SIZE_POLICY_DYNAMIC);
|
||||||
double secondary_direction = is_horizontal ? node->rect.h - margin_top - margin_bottom : node->rect.w - margin_left - margin_right;
|
double secondary_direction = is_horizontal ? node->rect.h - margin_top - margin_bottom : node->rect.w - margin_left - margin_right;
|
||||||
// if our layout secondary direction is fixed, we set the maximum known secondary position to it
|
// if our layout secondary direction is fixed, we set the maximum known secondary position to it
|
||||||
if (is_fixed_for_secondary_direction) {
|
if (is_fixed_for_secondary_direction) {
|
||||||
|
|
|
@ -125,18 +125,20 @@ int app_handle(struct UINode *node, void *data, int event_type, size_t d, void *
|
||||||
UIScrollableNode *scroll = scrollable_new(scroll_container, NULL);
|
UIScrollableNode *scroll = scrollable_new(scroll_container, NULL);
|
||||||
UINode *buttons = node_new(scroll_container, "buttons");
|
UINode *buttons = node_new(scroll_container, "buttons");
|
||||||
buttons->width_policy = UI_SIZE_POLICY_GROW;
|
buttons->width_policy = UI_SIZE_POLICY_GROW;
|
||||||
buttons->height_policy = UI_SIZE_POLICY_COMPUTED;
|
buttons->height_policy = UI_SIZE_POLICY_DYNAMIC;
|
||||||
scroll->target = buttons;
|
scroll->target = buttons;
|
||||||
|
|
||||||
box_layout_new(buttons, UI_DIRECTION_VERTICAL);
|
box_layout_new(buttons, UI_DIRECTION_VERTICAL);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 10000; i++) {
|
||||||
UINode *button = node_new(buttons, "button");
|
UINode *button = node_new(buttons, "button");
|
||||||
state_background_node_new(button, UIPurple600, UIPurple700, UIPurple800, 6.0);
|
state_background_node_new(button, UIPurple600, UIPurple700, UIPurple800, 6.0);
|
||||||
text_node_new(button, state->font, UINeutral50, "button");
|
text_node_new(button, state->font, UINeutral50, "button");
|
||||||
dispatcher_new(button, UI_EVENT_UNPRESSED, INCREMENT_COUNT, state, app_handle);
|
dispatcher_new(button, UI_EVENT_UNPRESSED, INCREMENT_COUNT, state, app_handle);
|
||||||
button->width_policy = UI_SIZE_POLICY_GROW;
|
button->width_policy = UI_SIZE_POLICY_GROW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("%d\n", buttons->last_component_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
25
src/node.c
25
src/node.c
|
@ -6,24 +6,6 @@
|
||||||
typedef struct UIWindow UIWindow;
|
typedef struct UIWindow UIWindow;
|
||||||
int window_invalidate_node(UIWindow *window, UINode *node);
|
int window_invalidate_node(UIWindow *window, UINode *node);
|
||||||
|
|
||||||
UIRect node_get_computed_rect(UINode *node) {
|
|
||||||
UIRect rect = node->rect;
|
|
||||||
UIRect extents = node->rect;
|
|
||||||
|
|
||||||
if (!node->cached_computed_extents && (node->width_policy == UI_SIZE_POLICY_COMPUTED || node->height_policy == UI_SIZE_POLICY_COMPUTED)) {
|
|
||||||
if (node_dispatch(node, UI_EVENT_GET_EXTENTS, 0, &extents) == UI_NODE_COMPUTED_EXTENTS_CACHED) {
|
|
||||||
// Whoever returned UI_NODE_COMPUTED_EXTENTS_CACHED has the responsibility to set
|
|
||||||
// cached_computed_extents back to false when the cache is no longer valid.
|
|
||||||
node->cached_computed_extents = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rect.w = node->width_policy == UI_SIZE_POLICY_COMPUTED ? extents.w : rect.w;
|
|
||||||
rect.h = node->height_policy == UI_SIZE_POLICY_COMPUTED ? extents.h : rect.h;
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
int node_send(UINode *node, enum UIEvent ev, size_t d, void *p)
|
int node_send(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
{
|
{
|
||||||
if (node->flags & UI_NODE_DISABLED) {
|
if (node->flags & UI_NODE_DISABLED) {
|
||||||
|
@ -54,7 +36,7 @@ int node_dispatch(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
}
|
}
|
||||||
if (node->nodes[i]->flags & UI_NODE_COMPONENT) {
|
if (node->nodes[i]->flags & UI_NODE_COMPONENT) {
|
||||||
component_index = i;
|
component_index = i;
|
||||||
result = node_send(node->nodes[i], ev, d, p);
|
result = node_dispatch(node->nodes[i], ev, d, p);
|
||||||
if (result) break;
|
if (result) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,12 +78,11 @@ void node_init(UINode *node)
|
||||||
node->nodes_count = 0;
|
node->nodes_count = 0;
|
||||||
node->nodes_capacity = 0;
|
node->nodes_capacity = 0;
|
||||||
node->flags = 0;
|
node->flags = 0;
|
||||||
node->width_policy = UI_SIZE_POLICY_COMPUTED;
|
node->width_policy = UI_SIZE_POLICY_DYNAMIC;
|
||||||
node->height_policy = UI_SIZE_POLICY_COMPUTED;
|
node->height_policy = UI_SIZE_POLICY_DYNAMIC;
|
||||||
node->handle = NULL;
|
node->handle = NULL;
|
||||||
node->handle_proto = NULL;
|
node->handle_proto = NULL;
|
||||||
node->last_component_index = UI_NODE_LAST_COMPONENT_INDEX_NONE;
|
node->last_component_index = UI_NODE_LAST_COMPONENT_INDEX_NONE;
|
||||||
node->cached_computed_extents = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void node_free(UINode *node)
|
void node_free(UINode *node)
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
#include "rect.h"
|
#include "rect.h"
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
|
|
||||||
#define UI_NODE_COMPUTED_EXTENTS_OK (1)
|
|
||||||
#define UI_NODE_COMPUTED_EXTENTS_CACHED (2)
|
|
||||||
enum UIEvent {
|
enum UIEvent {
|
||||||
UI_EVENT_REPAINT,
|
UI_EVENT_REPAINT,
|
||||||
UI_EVENT_RELAYOUT,
|
UI_EVENT_RELAYOUT,
|
||||||
UI_EVENT_GET_EXTENTS,
|
UI_EVENT_GET_WIDTH,
|
||||||
|
UI_EVENT_GET_HEIGHT,
|
||||||
UI_EVENT_HOVERED,
|
UI_EVENT_HOVERED,
|
||||||
UI_EVENT_UNHOVERED,
|
UI_EVENT_UNHOVERED,
|
||||||
UI_EVENT_PRESSED,
|
UI_EVENT_PRESSED,
|
||||||
|
@ -27,7 +26,7 @@ enum UIEvent {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UISizePolicy {
|
enum UISizePolicy {
|
||||||
UI_SIZE_POLICY_COMPUTED,
|
UI_SIZE_POLICY_DYNAMIC,
|
||||||
UI_SIZE_POLICY_GROW,
|
UI_SIZE_POLICY_GROW,
|
||||||
UI_SIZE_POLICY_FIXED,
|
UI_SIZE_POLICY_FIXED,
|
||||||
UI_SIZE_POLICY_STATIC
|
UI_SIZE_POLICY_STATIC
|
||||||
|
@ -57,13 +56,11 @@ typedef struct UINode {
|
||||||
enum UISizePolicy width_policy;
|
enum UISizePolicy width_policy;
|
||||||
enum UISizePolicy height_policy;
|
enum UISizePolicy height_policy;
|
||||||
int last_component_index;
|
int last_component_index;
|
||||||
bool cached_computed_extents;
|
|
||||||
|
|
||||||
int (*handle)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
int (*handle)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||||
int (*handle_proto)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
int (*handle_proto)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||||
} UINode;
|
} UINode;
|
||||||
|
|
||||||
UIRect node_get_computed_rect(UINode *node);
|
|
||||||
int node_send(UINode *node, enum UIEvent ev, size_t d, void *p);
|
int node_send(UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||||
int node_dispatch(UINode *node, enum UIEvent ev, size_t d, void *p);
|
int node_dispatch(UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||||
UINode *node_by_point(UINode *root, double x, double y);
|
UINode *node_by_point(UINode *root, double x, double y);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "scrollable-node.h"
|
#include "scrollable-node.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "rect.h"
|
|
||||||
#include "window.h"
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -44,16 +42,26 @@ int scrollable_handle(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
if (n->y_scroll > scroll_end) {
|
if (n->y_scroll > scroll_end) {
|
||||||
n->y_scroll = scroll_end;
|
n->y_scroll = scroll_end;
|
||||||
}
|
}
|
||||||
target->rect.x = n->x_scroll ? -n->x_scroll : 0;
|
node_request_relayout(n->node.parent);
|
||||||
target->rect.y = n->y_scroll ? -n->y_scroll : 0;
|
|
||||||
window_invalidate_node(node->window, node);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UI_EVENT_RELAYOUT: {
|
case UI_EVENT_RELAYOUT: {
|
||||||
UIRect rect = {0};
|
double w = target->rect.w;
|
||||||
node_dispatch(target, UI_EVENT_GET_EXTENTS, 0, &rect);
|
double h = target->rect.h;
|
||||||
target->rect.w = target->width_policy == UI_SIZE_POLICY_GROW ? node->parent->rect.w : rect.w;
|
if (target->width_policy == UI_SIZE_POLICY_DYNAMIC) {
|
||||||
target->rect.h = target->height_policy == UI_SIZE_POLICY_GROW ? node->parent->rect.h : rect.h;
|
node_dispatch(target, UI_EVENT_GET_WIDTH, 0, &w);
|
||||||
|
target->rect.w = w;
|
||||||
|
} else if (target->width_policy == UI_SIZE_POLICY_GROW) {
|
||||||
|
target->rect.w = node->parent->rect.w;
|
||||||
|
}
|
||||||
|
if (target->height_policy == UI_SIZE_POLICY_DYNAMIC) {
|
||||||
|
node_dispatch(target, UI_EVENT_GET_HEIGHT, 0, &h);
|
||||||
|
target->rect.h = h;
|
||||||
|
} else if (target->height_policy == UI_SIZE_POLICY_GROW) {
|
||||||
|
target->rect.h = node->parent->rect.h;
|
||||||
|
}
|
||||||
|
target->rect.x = n->x_scroll ? -n->x_scroll : 0;
|
||||||
|
target->rect.y = n->y_scroll ? -n->y_scroll : 0;
|
||||||
node_dispatch(target, UI_EVENT_RELAYOUT, 0, NULL);
|
node_dispatch(target, UI_EVENT_RELAYOUT, 0, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "pango/pango-layout.h"
|
#include "pango/pango-layout.h"
|
||||||
#include "pango/pango-types.h"
|
#include "pango/pango-types.h"
|
||||||
#include "rect.h"
|
|
||||||
#include "text-node.h"
|
#include "text-node.h"
|
||||||
|
|
||||||
UITextNode *text_node_new(UINode *parent, PangoFontDescription *desc, UIRGBA color, char *text)
|
UITextNode *text_node_new(UINode *parent, PangoFontDescription *desc, UIRGBA color, char *text)
|
||||||
|
@ -18,6 +17,9 @@ UITextNode *text_node_new(UINode *parent, PangoFontDescription *desc, UIRGBA col
|
||||||
n->color = color;
|
n->color = color;
|
||||||
n->caret_index = -1;
|
n->caret_index = -1;
|
||||||
n->caret_node = NULL;
|
n->caret_node = NULL;
|
||||||
|
n->computed_dimensions_invalid = true;
|
||||||
|
n->computed_text_width = 0;
|
||||||
|
n->computed_text_height = 0;
|
||||||
n->node.text = "text";
|
n->node.text = "text";
|
||||||
n->node.handle_proto = text_node_handle;
|
n->node.handle_proto = text_node_handle;
|
||||||
node_attach(parent, (UINode*)n);
|
node_attach(parent, (UINode*)n);
|
||||||
|
@ -48,7 +50,7 @@ int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
n->layout = layout;
|
n->layout = layout;
|
||||||
n->pending_text = NULL;
|
n->pending_text = NULL;
|
||||||
}
|
}
|
||||||
node->parent->cached_computed_extents = false;
|
n->computed_dimensions_invalid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
|
@ -61,21 +63,28 @@ int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
cairo_fill(n->node.drw);
|
cairo_fill(n->node.drw);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UI_EVENT_GET_EXTENTS: {
|
case UI_EVENT_GET_WIDTH: /* through */
|
||||||
if (!n->layout) {
|
case UI_EVENT_GET_HEIGHT: {
|
||||||
break;
|
if (n->computed_dimensions_invalid) {
|
||||||
|
int w, h = 0;
|
||||||
|
pango_layout_get_size(n->layout, &w, &h);
|
||||||
|
n->computed_text_width = pango_units_to_double(w);
|
||||||
|
n->computed_text_height = pango_units_to_double(h);
|
||||||
|
n->computed_dimensions_invalid = false;
|
||||||
}
|
}
|
||||||
int w, h = 0;
|
if (ev == UI_EVENT_GET_WIDTH) {
|
||||||
pango_layout_get_size(n->layout, &w, &h);
|
*(double*)p = n->computed_text_width;
|
||||||
|
}
|
||||||
((UIRect*)p)->w = pango_units_to_double(w);
|
if (ev == UI_EVENT_GET_HEIGHT) {
|
||||||
((UIRect*)p)->h = pango_units_to_double(h);
|
*(double*)p = n->computed_text_height;
|
||||||
return UI_NODE_COMPUTED_EXTENTS_CACHED;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case UI_EVENT_RELAYOUT: {
|
case UI_EVENT_RELAYOUT: {
|
||||||
if (!n->layout) {
|
if (!n->layout) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
pango_cairo_update_layout(n->node.drw, n->layout);
|
||||||
if (n->caret_index >= 0) {
|
if (n->caret_index >= 0) {
|
||||||
if (!n->caret_node) {
|
if (!n->caret_node) {
|
||||||
n->caret_node = node_new(&n->node, "caret");
|
n->caret_node = node_new(&n->node, "caret");
|
||||||
|
|
|
@ -15,6 +15,9 @@ typedef struct UITextNode {
|
||||||
UIRGBA color;
|
UIRGBA color;
|
||||||
ssize_t caret_index;
|
ssize_t caret_index;
|
||||||
UINode *caret_node;
|
UINode *caret_node;
|
||||||
|
double computed_text_width;
|
||||||
|
double computed_text_height;
|
||||||
|
bool computed_dimensions_invalid;
|
||||||
} UITextNode;
|
} UITextNode;
|
||||||
|
|
||||||
int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p);
|
int text_node_handle(UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||||
|
|
14
src/window.c
14
src/window.c
|
@ -428,7 +428,7 @@ static void window_process_xcb_event(UIWindow *window, xcb_generic_event_t *even
|
||||||
node_dispatch(window->root, UI_EVENT_RELAYOUT, 0, NULL);
|
node_dispatch(window->root, UI_EVENT_RELAYOUT, 0, NULL);
|
||||||
window_invalidate_node(window, window->root);
|
window_invalidate_node(window, window->root);
|
||||||
#ifdef _UI_DEBUG
|
#ifdef _UI_DEBUG
|
||||||
//node_dump(window->root, 0);
|
node_dump(window->root, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
end_clock();
|
end_clock();
|
||||||
|
@ -497,14 +497,12 @@ static void window_process_xcb_event(UIWindow *window, xcb_generic_event_t *even
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ui_event == UI_EVENT_SCROLL && !state)) {
|
UINode *n = node;
|
||||||
UINode *n = node;
|
while (n) {
|
||||||
while (n) {
|
if (node_dispatch(n, ui_event, state, &delta) > 0) {
|
||||||
if (node_dispatch(n, ui_event, state, &delta) > 0) {
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
n = n->parent;
|
|
||||||
}
|
}
|
||||||
|
n = n->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui_event == UI_EVENT_BUTTON_LEFT_UPDATE) {
|
if (ui_event == UI_EVENT_BUTTON_LEFT_UPDATE) {
|
||||||
|
|
Loading…
Reference in a new issue