added tree widget to panel API
This commit is contained in:
parent
fb1b02b177
commit
e4fa5fad12
126
demo/demo.c
126
demo/demo.c
@ -3,6 +3,20 @@
|
||||
#define WINDOW_WIDTH 800
|
||||
#define WINDOW_HEIGHT 600
|
||||
|
||||
struct tree_node {
|
||||
enum gui_tree_node_state state;
|
||||
const char *name;
|
||||
struct tree_node *parent;
|
||||
struct tree_node *children[4];
|
||||
int count;
|
||||
};
|
||||
|
||||
struct test_tree {
|
||||
struct tree_node root;
|
||||
struct tree_node *clipboard[16];
|
||||
int count;
|
||||
};
|
||||
|
||||
struct show_window {
|
||||
struct gui_panel hook;
|
||||
/* input buffer */
|
||||
@ -30,6 +44,9 @@ struct show_window {
|
||||
gui_float table_scrollbar;
|
||||
gui_float time_scrollbar;
|
||||
/* tree */
|
||||
struct test_tree tree;
|
||||
struct tree_node nodes[8];
|
||||
gui_float tree_offset;
|
||||
};
|
||||
|
||||
struct control_window {
|
||||
@ -89,13 +106,12 @@ widget_panel(struct gui_panel_layout *panel, struct show_window *demo)
|
||||
fprintf(stdout, "right triangle button pressed!\n");
|
||||
if (gui_panel_button_text_triangle(panel,GUI_LEFT,"previous",GUI_TEXT_RIGHT,GUI_BUTTON_DEFAULT))
|
||||
fprintf(stdout, "left triangle button pressed!\n");
|
||||
|
||||
demo->toggle = gui_panel_button_toggle(panel, "toggle", demo->toggle);
|
||||
demo->checkbox = gui_panel_check(panel, "checkbox", demo->checkbox);
|
||||
|
||||
gui_panel_row(panel, 30, 2);
|
||||
if (gui_panel_option(panel, "option 0", demo->option == 0)) demo->option = 0;
|
||||
if (gui_panel_option(panel, "option 1", demo->option == 1)) demo->option = 1;
|
||||
|
||||
{
|
||||
char buffer[MAX_BUFFER];
|
||||
const gui_float ratio[] = {0.8f, 0.2f};
|
||||
@ -112,7 +128,7 @@ widget_panel(struct gui_panel_layout *panel, struct show_window *demo)
|
||||
demo->item_current = gui_panel_selector(panel, items, LEN(items), demo->item_current);
|
||||
demo->spinner = gui_panel_spinner(panel, 0, demo->spinner, 250, 10, &demo->spinner_active);
|
||||
|
||||
gui_panel_row_begin(panel, 30);
|
||||
gui_panel_row_begin(panel, 30, 2);
|
||||
gui_panel_row_push_widget(panel, 0.7f);
|
||||
gui_panel_editbox(panel, &demo->input);
|
||||
gui_panel_row_push_widget(panel, 0.3f);
|
||||
@ -121,7 +137,6 @@ widget_panel(struct gui_panel_layout *panel, struct show_window *demo)
|
||||
fprintf(stdout, "command executed!\n");
|
||||
}
|
||||
gui_panel_row_end(panel);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -137,20 +152,6 @@ graph_panel(struct gui_panel_layout *panel, gui_size current)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
time_panel(struct gui_panel_layout *panel, unsigned int ms)
|
||||
{
|
||||
char buffer[MAX_BUFFER];
|
||||
ms = MAX(1, ms);
|
||||
gui_panel_row(panel, 20, 2);
|
||||
gui_panel_label(panel, "FPS:", GUI_TEXT_LEFT);
|
||||
sprintf(buffer, "%.2f", 1.0f/((float)ms/1000.0f));
|
||||
gui_panel_label(panel, buffer, GUI_TEXT_CENTERED);
|
||||
gui_panel_label(panel, "MS:", GUI_TEXT_LEFT);
|
||||
sprintf(buffer, "%d", ms);
|
||||
gui_panel_label(panel, buffer, GUI_TEXT_CENTERED);
|
||||
}
|
||||
|
||||
static void
|
||||
table_panel(struct gui_panel_layout *panel)
|
||||
{
|
||||
@ -180,16 +181,84 @@ init_show(struct show_window *win, struct gui_config *config,
|
||||
gui_stack_push(stack, &win->hook);
|
||||
gui_edit_box_init_fixed(&win->input, win->input_buffer, MAX_BUFFER, NULL, NULL);
|
||||
|
||||
win->widget_tab = GUI_MAXIMIZED;
|
||||
win->widget_tab = GUI_MINIMIZED;
|
||||
win->combobox_tab = GUI_MINIMIZED;
|
||||
win->slider = 10.0f;
|
||||
win->progressbar = 50;
|
||||
win->spinner = 100;
|
||||
|
||||
{
|
||||
struct test_tree *tree = &win->tree;
|
||||
tree->root.state = GUI_NODE_ACTIVE;
|
||||
tree->root.name = "Primitives";
|
||||
tree->root.parent = NULL;
|
||||
tree->root.count = 2;
|
||||
tree->root.children[0] = &win->nodes[0];
|
||||
tree->root.children[1] = &win->nodes[4];
|
||||
|
||||
win->nodes[0].state = 0;
|
||||
win->nodes[0].name = "Boxes";
|
||||
win->nodes[0].parent = &tree->root;
|
||||
win->nodes[0].count = 3;
|
||||
win->nodes[0].children[0] = &win->nodes[1];
|
||||
win->nodes[0].children[1] = &win->nodes[2];
|
||||
win->nodes[0].children[2] = &win->nodes[3];
|
||||
|
||||
win->nodes[1].state = 0;
|
||||
win->nodes[1].name = "Box0";
|
||||
win->nodes[1].parent = &win->nodes[1];
|
||||
win->nodes[1].count = 0;
|
||||
|
||||
win->nodes[2].state = 0;
|
||||
win->nodes[2].name = "Box1";
|
||||
win->nodes[2].parent = &win->nodes[1];
|
||||
win->nodes[2].count = 0;
|
||||
|
||||
win->nodes[3].state = 0;
|
||||
win->nodes[3].name = "Box2";
|
||||
win->nodes[3].parent = &win->nodes[1];
|
||||
win->nodes[3].count = 0;
|
||||
|
||||
win->nodes[4].state = GUI_NODE_ACTIVE;
|
||||
win->nodes[4].name = "Cylinders";
|
||||
win->nodes[4].parent = &tree->root;
|
||||
win->nodes[4].count = 3;
|
||||
win->nodes[4].children[0] = &win->nodes[5];
|
||||
win->nodes[4].children[1] = &win->nodes[6];
|
||||
win->nodes[4].children[2] = &win->nodes[7];
|
||||
|
||||
win->nodes[5].state = 0;
|
||||
win->nodes[5].name = "Cylinder0";
|
||||
win->nodes[5].parent = &win->nodes[4];
|
||||
win->nodes[5].count = 0;
|
||||
|
||||
win->nodes[6].state = 0;
|
||||
win->nodes[6].name = "Cylinder1";
|
||||
win->nodes[6].parent = &win->nodes[4];
|
||||
win->nodes[6].count = 0;
|
||||
|
||||
win->nodes[7].state = 0;
|
||||
win->nodes[7].name = "Cylinder2";
|
||||
win->nodes[7].parent = &win->nodes[4];
|
||||
win->nodes[7].count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_show(struct show_window *show, struct gui_stack *stack, struct gui_input *in,
|
||||
unsigned int ms)
|
||||
upload_tree(struct gui_tree *tree, struct tree_node *node)
|
||||
{
|
||||
int i = 0;
|
||||
if (node->count) {
|
||||
gui_panel_tree_begin_node(tree, node->name, &node->state);
|
||||
for (i = 0; i < node->count; ++i)
|
||||
upload_tree(tree, node->children[i]);
|
||||
gui_panel_tree_end_node(tree);
|
||||
}
|
||||
else gui_panel_tree_leaf(tree, node->name, &node->state);
|
||||
}
|
||||
|
||||
static void
|
||||
update_show(struct show_window *show, struct gui_stack *stack, struct gui_input *in)
|
||||
{
|
||||
struct gui_panel_layout tab;
|
||||
struct gui_panel_layout layout;
|
||||
@ -204,11 +273,6 @@ update_show(struct show_window *show, struct gui_stack *stack, struct gui_input
|
||||
widget_panel(&tab, show);
|
||||
gui_panel_tab_end(&layout, &tab);
|
||||
|
||||
gui_panel_row(&layout, 110, 1);
|
||||
gui_panel_group_begin(&layout, &tab, "Time", show->time_scrollbar);
|
||||
time_panel(&tab, ms);
|
||||
show->time_scrollbar = gui_panel_group_end(&layout, &tab);
|
||||
|
||||
gui_panel_row(&layout, 180, 1);
|
||||
show->shelf_selection = gui_panel_shelf_begin(&layout, &tab, shelfs,
|
||||
LEN(shelfs), show->shelf_selection, show->shelf_scrollbar);
|
||||
@ -219,6 +283,14 @@ update_show(struct show_window *show, struct gui_stack *stack, struct gui_input
|
||||
gui_panel_group_begin(&layout, &tab, "Table", show->table_scrollbar);
|
||||
table_panel(&tab);
|
||||
show->table_scrollbar = gui_panel_group_end(&layout, &tab);
|
||||
|
||||
{
|
||||
struct gui_tree tree;
|
||||
gui_panel_row(&layout, 250, 1);
|
||||
gui_panel_tree_begin(&layout, &tree, "Models", 20, show->tree_offset);
|
||||
upload_tree(&tree, &show->tree.root);
|
||||
show->tree_offset = gui_panel_tree_end(&layout, &tree);
|
||||
}
|
||||
gui_panel_end(&layout, &show->hook);
|
||||
}
|
||||
|
||||
@ -413,7 +485,7 @@ run_demo(struct demo_gui *gui, struct gui_input *input)
|
||||
if (show->hook.flags & GUI_PANEL_ACTIVE)
|
||||
show->hook.flags = control->show_flags|GUI_PANEL_ACTIVE;
|
||||
else show->hook.flags = control->show_flags;
|
||||
update_show(show, &gui->stack, input, gui->ms);
|
||||
update_show(show, &gui->stack, input);
|
||||
if (show->hook.flags & GUI_PANEL_HIDDEN)
|
||||
control->show_flags |= GUI_PANEL_HIDDEN;
|
||||
}
|
||||
|
211
gui.c
211
gui.c
@ -45,6 +45,7 @@ template<typename T> struct gui_alignof{struct Big {T x; char c;}; enum {
|
||||
#define GUI_ALIGN(x, mask) ((x) + (mask-1)) & ~(mask-1)
|
||||
#define GUI_OFFSETOF(st, m) ((gui_size)(&((st *)0)->m))
|
||||
|
||||
enum gui_tree_node_symbol {GUI_TREE_NODE_BULLET, GUI_TREE_NODE_TRIANGLE};
|
||||
static const struct gui_rect gui_null_rect = {-9999.0f, -9999.0f, 2*9999.0f, 2*9999.0f};
|
||||
static const gui_byte gui_utfbyte[GUI_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||
static const gui_byte gui_utfmask[GUI_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||
@ -470,6 +471,28 @@ gui_input_end(struct gui_input *in)
|
||||
gui_vec2_sub(in->mouse_delta, in->mouse_pos, in->mouse_prev);
|
||||
}
|
||||
|
||||
static gui_bool
|
||||
gui_input_clicked(const struct gui_input *i, struct gui_rect *b)
|
||||
{
|
||||
if (!i) return gui_false;
|
||||
if (!GUI_INBOX(i->mouse_pos.x, i->mouse_pos.y, b->x, b->y, b->w, b->h))
|
||||
return gui_false;
|
||||
if (!GUI_INBOX(i->mouse_clicked_pos.x,i->mouse_clicked_pos.y,b->x,b->y,b->w,b->h))
|
||||
return gui_false;
|
||||
return (i->mouse_down && i->mouse_clicked) ? gui_true : gui_false;
|
||||
}
|
||||
|
||||
static gui_bool
|
||||
gui_input_pressed(const struct gui_input *i, enum gui_keys key)
|
||||
{
|
||||
const struct gui_key *k;
|
||||
if (!i) return gui_false;
|
||||
k = &i->keys[key];
|
||||
if (k->down && k->clicked)
|
||||
return gui_true;
|
||||
return gui_false;
|
||||
}
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
@ -1597,29 +1620,20 @@ gui_editbox(struct gui_command_buffer *out, gui_float x, gui_float y, gui_float
|
||||
len = gui_edit_box_len(box);
|
||||
buffer = gui_edit_box_get(box);
|
||||
if (box->active && in) {
|
||||
const struct gui_key *bs = &in->keys[GUI_KEY_BACKSPACE];
|
||||
const struct gui_key *del = &in->keys[GUI_KEY_DEL];
|
||||
const struct gui_key *enter = &in->keys[GUI_KEY_ENTER];
|
||||
const struct gui_key *space = &in->keys[GUI_KEY_SPACE];
|
||||
const struct gui_key *copy = &in->keys[GUI_KEY_COPY];
|
||||
const struct gui_key *paste = &in->keys[GUI_KEY_PASTE];
|
||||
const struct gui_key *left = &in->keys[GUI_KEY_LEFT];
|
||||
const struct gui_key *right = &in->keys[GUI_KEY_RIGHT];
|
||||
|
||||
/* update input buffer by user input */
|
||||
if ((del->down && del->clicked) || (bs->down && bs->clicked))
|
||||
if (gui_input_pressed(in,GUI_KEY_DEL)||gui_input_pressed(in,GUI_KEY_BACKSPACE))
|
||||
gui_edit_box_remove(box);
|
||||
if (enter->down && enter->clicked)
|
||||
if (gui_input_pressed(in, GUI_KEY_ENTER))
|
||||
box->active = gui_false;
|
||||
if (copy->down && copy->clicked && box->clip.copy)
|
||||
if (gui_input_pressed(in, GUI_KEY_COPY) && box->clip.copy)
|
||||
box->clip.copy(box->clip.userdata, buffer, len);
|
||||
if (paste->down && paste->clicked && box->clip.paste)
|
||||
if (gui_input_pressed(in, GUI_KEY_PASTE) && box->clip.paste)
|
||||
box->buffer.allocated = box->clip.paste(box->clip.userdata, buffer, max);
|
||||
if (space->down && space->clicked)
|
||||
if (gui_input_pressed(in, GUI_KEY_SPACE))
|
||||
gui_edit_box_add(box, " ", 1);
|
||||
if (left->down && left->clicked)
|
||||
if (gui_input_pressed(in, GUI_KEY_LEFT))
|
||||
box->cursor = (gui_size)MAX(0, (gui_int)box->cursor-1);
|
||||
if (right->down && right->clicked)
|
||||
if (gui_input_pressed(in, GUI_KEY_RIGHT))
|
||||
box->cursor = MIN((!box->glyphes) ? 0 : box->glyphes, box->cursor+1);
|
||||
if (in->text_len)
|
||||
gui_edit_box_buffer_input(box, in);
|
||||
@ -2683,8 +2697,9 @@ gui_panel_begin_tiled(struct gui_panel_layout *tile, struct gui_panel *panel,
|
||||
rx = 1.0f - ((bounds.w / (gui_float)layout->width) +
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x);
|
||||
layout->slots[GUI_SLOT_RIGHT].ratio.x = rx;
|
||||
layout->slots[GUI_SLOT_RIGHT].offset.x = layout->slots[GUI_SLOT_CENTER].offset.x+
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x;
|
||||
layout->slots[GUI_SLOT_RIGHT].offset.x =
|
||||
layout->slots[GUI_SLOT_CENTER].offset.x +
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x;
|
||||
}
|
||||
bounds.w -= config->scaler_width;
|
||||
break;
|
||||
@ -2714,8 +2729,9 @@ gui_panel_begin_tiled(struct gui_panel_layout *tile, struct gui_panel *panel,
|
||||
lx = 1.0f - ((bounds.w / (gui_float)layout->width) +
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x);
|
||||
layout->slots[GUI_SLOT_LEFT].ratio.x = lx;
|
||||
layout->slots[GUI_SLOT_RIGHT].offset.x = layout->slots[GUI_SLOT_CENTER].offset.x+
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x;
|
||||
layout->slots[GUI_SLOT_RIGHT].offset.x =
|
||||
layout->slots[GUI_SLOT_CENTER].offset.x +
|
||||
layout->slots[GUI_SLOT_CENTER].ratio.x;
|
||||
}
|
||||
|
||||
bounds.x += config->scaler_width;
|
||||
@ -3247,7 +3263,7 @@ gui_panel_button_text_triangle(struct gui_panel_layout *layout, enum gui_heading
|
||||
button.highlight = config->colors[GUI_COLOR_BUTTON_HOVER];
|
||||
button.highlight_content = config->colors[GUI_COLOR_BUTTON_HOVER_FONT];
|
||||
return gui_button_text_triangle(layout->buffer, bounds.x, bounds.y, bounds.w,
|
||||
bounds.h, heading, text, align, behavior, &button, &config->font, layout->input);
|
||||
bounds.h, heading,text,align,behavior,&button,&config->font,layout->input);
|
||||
}
|
||||
|
||||
gui_bool
|
||||
@ -3569,7 +3585,7 @@ gui_panel_graph_push_line(struct gui_panel_layout *l,
|
||||
/* special case for the first data point since it does not have a connection */
|
||||
g->last.x = g->x;
|
||||
g->last.y = (g->y + g->h) - ratio * (gui_float)g->h;
|
||||
if (i && GUI_INBOX(i->mouse_pos.x, i->mouse_pos.y, g->last.x-3, g->last.y-3, 6, 6)){
|
||||
if (i && GUI_INBOX(i->mouse_pos.x,i->mouse_pos.y,g->last.x-3,g->last.y-3,6,6)){
|
||||
selected = (i->mouse_down && i->mouse_clicked) ? gui_true: gui_false;
|
||||
color = config->colors[GUI_COLOR_PLOT_HIGHLIGHT];
|
||||
}
|
||||
@ -3632,7 +3648,7 @@ gui_panel_graph_push_column(struct gui_panel_layout *layout,
|
||||
item_x = item_x + ((gui_float)graph->index * item_padding.x);
|
||||
|
||||
/* user graph bar selection */
|
||||
if (in && GUI_INBOX(in->mouse_pos.x, in->mouse_pos.y, item_x, item_y, item_w, item_h)) {
|
||||
if (in && GUI_INBOX(in->mouse_pos.x,in->mouse_pos.y,item_x,item_y,item_w,item_h)) {
|
||||
selected = (in->mouse_down && in->mouse_clicked) ? (gui_int)graph->index: selected;
|
||||
color = config->colors[GUI_COLOR_HISTO_HIGHLIGHT];
|
||||
}
|
||||
@ -3890,7 +3906,7 @@ gui_panel_tab_end(struct gui_panel_layout *p, struct gui_panel_layout *t)
|
||||
panel.flags = GUI_PANEL_BORDER|GUI_PANEL_MINIMIZABLE|GUI_PANEL_TAB;
|
||||
gui_panel_end(t, &panel);
|
||||
|
||||
/* calculate the from the tab occupied space and allocate the space in the parent panel */
|
||||
/*calculate the from the tab occupied space and allocate it in the parent panel */
|
||||
item_spacing = gui_config_property(p->config, GUI_PROPERTY_ITEM_SPACING);
|
||||
panel_padding = gui_config_property(p->config, GUI_PROPERTY_PADDING);
|
||||
if (t->valid)
|
||||
@ -4117,6 +4133,153 @@ gui_panel_shelf_end(struct gui_panel_layout *p, struct gui_panel_layout *s)
|
||||
return pan.offset;
|
||||
}
|
||||
|
||||
void
|
||||
gui_panel_tree_begin(struct gui_panel_layout *p, struct gui_tree *tree,
|
||||
const char *title, gui_float height, gui_float offset)
|
||||
{
|
||||
struct gui_vec2 padding;
|
||||
const struct gui_config *config;
|
||||
gui_panel_group_begin(p, &tree->group, title, offset);
|
||||
gui_panel_row(&tree->group, height, 1);
|
||||
|
||||
config = tree->group.config;
|
||||
padding = gui_config_property(config, GUI_PROPERTY_ITEM_PADDING);
|
||||
|
||||
tree->at_x = 0;
|
||||
tree->skip = -1;
|
||||
tree->depth = 0;
|
||||
tree->x_off = tree->group.config->font.height + 2 * padding.x;
|
||||
}
|
||||
|
||||
static enum gui_tree_node_operation
|
||||
gui_panel_tree_node(struct gui_tree *tree, enum gui_tree_node_symbol symbol,
|
||||
const char *title, enum gui_tree_node_state *state)
|
||||
{
|
||||
struct gui_rect bounds;
|
||||
struct gui_rect sym, label;
|
||||
struct gui_text text;
|
||||
|
||||
const struct gui_input *i;
|
||||
const struct gui_config *config;
|
||||
struct gui_vec2 item_padding;
|
||||
struct gui_color col;
|
||||
|
||||
enum gui_tree_node_operation op = GUI_NODE_NOP;
|
||||
struct gui_panel_layout *layout = &tree->group;
|
||||
|
||||
if (tree->skip >= 0 || !gui_panel_widget(&bounds, layout)) {
|
||||
if (!tree->depth) tree->at_x = bounds.x;
|
||||
return op;
|
||||
}
|
||||
if (!tree->depth){
|
||||
tree->at_x = bounds.x;
|
||||
} else {
|
||||
bounds.w = (bounds.x + bounds.w) - tree->at_x;
|
||||
bounds.x = tree->at_x;
|
||||
}
|
||||
|
||||
/* fetch some configuration constants */
|
||||
i = layout->input;
|
||||
config = layout->config;
|
||||
item_padding = gui_config_property(config, GUI_PROPERTY_ITEM_PADDING);
|
||||
col = gui_config_color(config, GUI_COLOR_TEXT);
|
||||
|
||||
/* calculate symbol bounds */
|
||||
sym.x = bounds.x;
|
||||
sym.y = bounds.y + (bounds.h/2) - (config->font.height/2);
|
||||
sym.w = config->font.height;
|
||||
sym.h = config->font.height;
|
||||
|
||||
/* calculate text bounds */
|
||||
label.y = bounds.y;
|
||||
label.h = bounds.h;
|
||||
label.x = sym.x + sym.w + item_padding.x;
|
||||
label.w = bounds.w - (sym.w + 2 * item_padding.x);
|
||||
|
||||
/* output symbol */
|
||||
if (symbol == GUI_TREE_NODE_TRIANGLE) {
|
||||
/* parent node */
|
||||
struct gui_vec2 points[3];
|
||||
enum gui_heading heading;
|
||||
if (gui_input_clicked(i, &sym)) {
|
||||
if (*state & GUI_NODE_ACTIVE)
|
||||
*state &= ~(gui_flags)GUI_NODE_ACTIVE;
|
||||
else *state |= GUI_NODE_ACTIVE;
|
||||
}
|
||||
heading = (*state & GUI_NODE_ACTIVE) ? GUI_DOWN : GUI_RIGHT;
|
||||
gui_triangle_from_direction(points, sym.x, sym.y, sym.w, sym.h, 0, 0, heading);
|
||||
gui_command_buffer_push_triangle(layout->buffer, points[0].x, points[0].y,
|
||||
points[1].x, points[1].y, points[2].x, points[2].y, col);
|
||||
} else {
|
||||
/* leaf node */
|
||||
gui_command_buffer_push_circle(layout->buffer, sym.x, sym.y, sym.w, sym.h, col);
|
||||
}
|
||||
|
||||
/* selection */
|
||||
if (gui_input_clicked(i, &label)) {
|
||||
if (*state & GUI_NODE_SELECTED)
|
||||
*state &= ~(gui_flags)GUI_NODE_SELECTED;
|
||||
else *state |= GUI_NODE_SELECTED;
|
||||
}
|
||||
|
||||
{
|
||||
/* tree node opderations */
|
||||
if (gui_input_pressed(i, GUI_KEY_DEL) && (*state & GUI_NODE_SELECTED))
|
||||
op = GUI_NODE_DELETE;
|
||||
if (gui_input_pressed(i, GUI_KEY_COPY) && (*state & GUI_NODE_SELECTED))
|
||||
op = GUI_NODE_CLONE;
|
||||
if (gui_input_pressed(i, GUI_KEY_CUT) && (*state & GUI_NODE_SELECTED))
|
||||
op = GUI_NODE_CUT;
|
||||
if (gui_input_pressed(i, GUI_KEY_PASTE) && (*state & GUI_NODE_SELECTED))
|
||||
op = GUI_NODE_PASTE;
|
||||
}
|
||||
|
||||
/* output label */
|
||||
text.padding.x = item_padding.x;
|
||||
text.padding.y = item_padding.y;
|
||||
text.foreground = config->colors[GUI_COLOR_TEXT];
|
||||
text.background = (*state & GUI_NODE_SELECTED) ?
|
||||
config->colors[GUI_COLOR_BUTTON_HOVER]:
|
||||
config->colors[GUI_COLOR_PANEL];
|
||||
gui_text(layout->buffer,label.x,label.y,label.w,label.h, title, gui_strsiz(title),
|
||||
&text, GUI_TEXT_LEFT, &config->font);
|
||||
return op;
|
||||
}
|
||||
|
||||
enum gui_tree_node_operation
|
||||
gui_panel_tree_begin_node(struct gui_tree *tree, const char *title,
|
||||
enum gui_tree_node_state *state)
|
||||
{
|
||||
enum gui_tree_node_operation op;
|
||||
op = gui_panel_tree_node(tree, GUI_TREE_NODE_TRIANGLE, title, state);
|
||||
tree->at_x += tree->x_off;
|
||||
if (tree->skip < 0 && !(*state & GUI_NODE_ACTIVE))
|
||||
tree->skip = tree->depth;
|
||||
tree->depth++;
|
||||
return op;
|
||||
}
|
||||
|
||||
enum gui_tree_node_operation
|
||||
gui_panel_tree_leaf(struct gui_tree *tree, const char *title,
|
||||
enum gui_tree_node_state *state)
|
||||
{return gui_panel_tree_node(tree, GUI_TREE_NODE_BULLET, title, state);}
|
||||
|
||||
void
|
||||
gui_panel_tree_end_node(struct gui_tree *tree)
|
||||
{
|
||||
GUI_ASSERT(tree->depth);
|
||||
tree->depth--;
|
||||
tree->at_x -= tree->x_off;
|
||||
if (tree->skip == tree->depth)
|
||||
tree->skip = -1;
|
||||
}
|
||||
|
||||
gui_float
|
||||
gui_panel_tree_end(struct gui_panel_layout *p, struct gui_tree* tree)
|
||||
{
|
||||
return gui_panel_group_end(p, &tree->group);
|
||||
}
|
||||
|
||||
void
|
||||
gui_panel_end(struct gui_panel_layout *layout, struct gui_panel *panel)
|
||||
{
|
||||
|
32
gui.h
32
gui.h
@ -187,6 +187,7 @@ enum gui_keys {
|
||||
GUI_KEY_BACKSPACE,
|
||||
GUI_KEY_SPACE,
|
||||
GUI_KEY_COPY,
|
||||
GUI_KEY_CUT,
|
||||
GUI_KEY_PASTE,
|
||||
GUI_KEY_LEFT,
|
||||
GUI_KEY_RIGHT,
|
||||
@ -1704,6 +1705,28 @@ struct gui_panel_layout {
|
||||
/* command draw call output command buffer */
|
||||
};
|
||||
|
||||
enum gui_tree_node_state {
|
||||
GUI_NODE_ACTIVE = 0x01,
|
||||
GUI_NODE_SELECTED = 0x02,
|
||||
GUI_NODE_DRAGGED = 0x04
|
||||
};
|
||||
|
||||
enum gui_tree_node_operation {
|
||||
GUI_NODE_NOP,
|
||||
GUI_NODE_CUT,
|
||||
GUI_NODE_CLONE,
|
||||
GUI_NODE_PASTE,
|
||||
GUI_NODE_DELETE
|
||||
};
|
||||
|
||||
struct gui_tree {
|
||||
struct gui_panel_layout group;
|
||||
gui_float x_off;
|
||||
gui_float at_x;
|
||||
gui_int skip;
|
||||
gui_int depth;
|
||||
};
|
||||
|
||||
struct gui_layout;
|
||||
void gui_panel_init(struct gui_panel*, gui_float x, gui_float y, gui_float w,
|
||||
gui_float h, gui_flags, struct gui_command_buffer*,
|
||||
@ -2140,6 +2163,14 @@ gui_float gui_panel_shelf_end(struct gui_panel_layout*, struct gui_panel_layout*
|
||||
Output:
|
||||
- The from user input updated shelf scrollbar pixel offset
|
||||
*/
|
||||
void gui_panel_tree_begin(struct gui_panel_layout*, struct gui_tree*,
|
||||
const char*, gui_float row_height, gui_float offset);
|
||||
enum gui_tree_node_operation gui_panel_tree_begin_node(struct gui_tree*, const char*,
|
||||
enum gui_tree_node_state*);
|
||||
void gui_panel_tree_end_node(struct gui_tree*);
|
||||
enum gui_tree_node_operation gui_panel_tree_leaf(struct gui_tree*, const char*,
|
||||
enum gui_tree_node_state*);
|
||||
gui_float gui_panel_tree_end(struct gui_panel_layout*, struct gui_tree*);
|
||||
void gui_panel_end(struct gui_panel_layout*, struct gui_panel*);
|
||||
/* this function ends the panel layout build up process and updates the panel
|
||||
*/
|
||||
@ -2298,7 +2329,6 @@ void gui_layout_update_state(struct gui_layout*, gui_uint state);
|
||||
Input:
|
||||
- new state of the layout with either active or inactive
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user