Compare commits
No commits in common. "dc83e09f43c3793603220681520e0c8f90a17878" and "996d6fb5201c104f75dc55d5c79bb99ad73859d2" have entirely different histories.
dc83e09f43
...
996d6fb520
6 changed files with 21 additions and 58 deletions
2
Makefile
2
Makefile
|
@ -13,7 +13,7 @@ OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
||||||
DEPS=$(OBJS:%.o=%.d)
|
DEPS=$(OBJS:%.o=%.d)
|
||||||
|
|
||||||
|
|
||||||
all: CFLAGS+=-Og -ggdb -DNDEBUG
|
all: CFLAGS+=-fsanitize=address -Og -ggdb
|
||||||
all: $(BUILD) $(BIN)
|
all: $(BUILD) $(BIN)
|
||||||
|
|
||||||
release: CFLAGS+=-O2 -flto=auto -DNDEBUG
|
release: CFLAGS+=-O2 -flto=auto -DNDEBUG
|
||||||
|
|
|
@ -130,15 +130,13 @@ int app_handle(struct UINode *node, void *data, int event_type, size_t d, void *
|
||||||
|
|
||||||
box_layout_new(buttons, UI_DIRECTION_VERTICAL);
|
box_layout_new(buttons, UI_DIRECTION_VERTICAL);
|
||||||
|
|
||||||
for (int i = 0; i < 10000; i++) {
|
for (int i = 0; i < 100; 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;
|
||||||
|
|
36
src/node.c
36
src/node.c
|
@ -28,25 +28,14 @@ int node_dispatch(UINode *node, enum UIEvent ev, size_t d, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = 0;
|
|
||||||
int component_index = UI_NODE_LAST_COMPONENT_INDEX_NONE;
|
|
||||||
for (int i = 0; i < node->nodes_count; i++) {
|
for (int i = 0; i < node->nodes_count; i++) {
|
||||||
if (node->last_component_index == UI_NODE_LAST_COMPONENT_INDEX_NONE || (node->last_component_index >= 0 && i > node->last_component_index)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (node->nodes[i]->flags & UI_NODE_COMPONENT) {
|
if (node->nodes[i]->flags & UI_NODE_COMPONENT) {
|
||||||
component_index = i;
|
int result = node_dispatch(node->nodes[i], ev, d, p);
|
||||||
result = node_dispatch(node->nodes[i], ev, d, p);
|
|
||||||
if (result) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (node->last_component_index < 0) {
|
|
||||||
node->last_component_index = component_index;
|
|
||||||
}
|
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (node->handle) {
|
if (node->handle) {
|
||||||
result = (node->handle)(node, ev, d, p);
|
int result = (node->handle)(node, ev, d, p);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
}
|
}
|
||||||
if (node->handle_proto) {
|
if (node->handle_proto) {
|
||||||
|
@ -82,20 +71,12 @@ void node_init(UINode *node)
|
||||||
node->height_policy = UI_SIZE_POLICY_DYNAMIC;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void node_free(UINode *node)
|
void node_free(UINode *node)
|
||||||
{
|
{
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|
||||||
// TODO: properly handle removing this node from its parent
|
|
||||||
|
|
||||||
// Invalidate component index cache
|
|
||||||
if ((node->flags & UI_NODE_COMPONENT) && node->parent) {
|
|
||||||
node->parent->last_component_index = UI_NODE_LAST_COMPONENT_INDEX_INVALIDATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
node_dispatch(node, UI_EVENT_DESTROY, 0, NULL);
|
node_dispatch(node, UI_EVENT_DESTROY, 0, NULL);
|
||||||
|
|
||||||
for (int i = 0; i < node->nodes_count; i++) {
|
for (int i = 0; i < node->nodes_count; i++) {
|
||||||
|
@ -154,14 +135,7 @@ UINode *node_attach(UINode *parent, UINode *node)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int index = parent->nodes_count++;
|
parent->nodes[parent->nodes_count++] = node;
|
||||||
parent->nodes[index] = node;
|
|
||||||
|
|
||||||
// Let's save the index of the last component so that we can exit the loop early
|
|
||||||
// if there's no components left when we're in node_dispatch()
|
|
||||||
if ((node->flags & UI_NODE_COMPONENT) && index > parent->last_component_index) {
|
|
||||||
parent->last_component_index = index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -41,8 +41,6 @@ enum UIDirection {
|
||||||
#define UI_NODE_RETAINS_PRESS (1 << 1)
|
#define UI_NODE_RETAINS_PRESS (1 << 1)
|
||||||
#define UI_NODE_DISABLED (1 << 2)
|
#define UI_NODE_DISABLED (1 << 2)
|
||||||
|
|
||||||
#define UI_NODE_LAST_COMPONENT_INDEX_INVALIDATED (-1)
|
|
||||||
#define UI_NODE_LAST_COMPONENT_INDEX_NONE (-2)
|
|
||||||
typedef struct UINode {
|
typedef struct UINode {
|
||||||
const char *text;
|
const char *text;
|
||||||
UIRect rect;
|
UIRect rect;
|
||||||
|
@ -55,7 +53,6 @@ typedef struct UINode {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
enum UISizePolicy width_policy;
|
enum UISizePolicy width_policy;
|
||||||
enum UISizePolicy height_policy;
|
enum UISizePolicy height_policy;
|
||||||
int last_component_index;
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -17,9 +17,6 @@ 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);
|
||||||
|
@ -50,7 +47,6 @@ 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;
|
||||||
}
|
}
|
||||||
n->computed_dimensions_invalid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ev) {
|
switch (ev) {
|
||||||
|
@ -63,23 +59,24 @@ 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_WIDTH: /* through */
|
case UI_EVENT_GET_WIDTH: {
|
||||||
case UI_EVENT_GET_HEIGHT: {
|
if (!n->layout) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (ev == UI_EVENT_GET_WIDTH) {
|
|
||||||
*(double*)p = n->computed_text_width;
|
|
||||||
}
|
|
||||||
if (ev == UI_EVENT_GET_HEIGHT) {
|
|
||||||
*(double*)p = n->computed_text_height;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
int w;
|
||||||
|
pango_layout_get_size(n->layout, &w, NULL);
|
||||||
|
*(double*)p = pango_units_to_double(w);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case UI_EVENT_GET_HEIGHT: {
|
||||||
|
if (!n->layout) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int h;
|
||||||
|
pango_layout_get_size(n->layout, NULL, &h);
|
||||||
|
*(double*)p = pango_units_to_double(h);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
case UI_EVENT_RELAYOUT: {
|
case UI_EVENT_RELAYOUT: {
|
||||||
if (!n->layout) {
|
if (!n->layout) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -15,9 +15,6 @@ 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);
|
||||||
|
|
Loading…
Reference in a new issue