added dragging widget

This commit is contained in:
vurtun 2015-11-10 15:07:43 +01:00
parent ef978385ba
commit 65a865c570
3 changed files with 215 additions and 26 deletions

View File

@ -569,6 +569,8 @@ show_test_window(struct zr_window *window, struct zr_style *config, enum theme *
static zr_size prog_value = 40;
static zr_float float_spinner = 2.5f;
static zr_int int_spinner = 20;
static zr_float drag_float = 2;
static zr_int drag_int = 10;
static zr_state spinneri_active, spinnerf_active;
static const zr_float ratio[] = {100, 150};
const struct zr_input *in = zr_input(&layout);
@ -589,12 +591,17 @@ show_test_window(struct zr_window *window, struct zr_style *config, enum theme *
zr_tooltip(&layout, "This is a tooltip");
zr_layout_row(&layout, ZR_STATIC, 30, 2, ratio);
zr_labelf(&layout, ZR_TEXT_LEFT, "Slider(%d):", int_slider);
zr_labelf(&layout, ZR_TEXT_LEFT, "Slider int: %d", int_slider);
zr_slider_int(&layout, 0, &int_slider, 10, 1);
zr_labelf(&layout, ZR_TEXT_LEFT, "Slider(%.2f):", float_slider);
zr_labelf(&layout, ZR_TEXT_LEFT, "Slider float: %.2f", float_slider);
zr_slider_float(&layout, 0, &float_slider, 5.0, 0.5f);
zr_labelf(&layout, ZR_TEXT_LEFT, "Progressbar: %lu:" , prog_value);
zr_progress(&layout, &prog_value, 100, ZR_MODIFYABLE);
zr_label(&layout, "Drag float:", ZR_TEXT_LEFT);
zr_drag_float(&layout, 0, &drag_float, 64.0f, 0.1f);
zr_label(&layout, "Drag int:", ZR_TEXT_LEFT);
zr_drag_int(&layout, 0, &drag_int, 100, 1);
zr_label(&layout, "Spinner int:", ZR_TEXT_LEFT);
zr_spinner_int(&layout, 0, &int_spinner, 50.0, 1, &spinneri_active);
zr_label(&layout, "Spinner float:", ZR_TEXT_LEFT);
@ -1117,6 +1124,9 @@ init_demo(struct demo *gui)
gui->config_white.colors[ZR_COLOR_PROGRESS_CURSOR] = zr_rgba(80, 80, 80, 255);
gui->config_white.colors[ZR_COLOR_PROGRESS_CURSOR_HOVER] = zr_rgba(70, 70, 70, 255);
gui->config_white.colors[ZR_COLOR_PROGRESS_CURSOR_ACTIVE] = zr_rgba(60, 60, 60, 255);
gui->config_white.colors[ZR_COLOR_DRAG] = zr_rgba(150, 150, 150, 255);
gui->config_white.colors[ZR_COLOR_DRAG_HOVER] = zr_rgba(160, 160, 160, 255);
gui->config_white.colors[ZR_COLOR_DRAG_ACTIVE] = zr_rgba(165, 165, 165, 255);
gui->config_white.colors[ZR_COLOR_INPUT] = zr_rgba(150, 150, 150, 255);
gui->config_white.colors[ZR_COLOR_INPUT_CURSOR] = zr_rgba(0, 0, 0, 255);
gui->config_white.colors[ZR_COLOR_INPUT_TEXT] = zr_rgba(0, 0, 0, 255);

158
zahnrad.c
View File

@ -789,6 +789,27 @@ zr_triangle_from_direction(struct zr_vec2 *result, struct zr_rect r,
result[2] = zr_vec2(r.x + r.w, r.y + r.h);
}
}
static zr_size
zr_string_float_limit(char *string, zr_int prec)
{
zr_int dot = 0;
char *c = string;
while (*c) {
if (*c == '.') {
dot = 1;
c++;
continue;
}
if (dot == (prec+1)) {
*c = 0;
break;
}
if (dot > 0) dot++;
c++;
}
return (zr_size)(c - string);
}
/*
* ==============================================================
*
@ -4489,6 +4510,78 @@ zr_widget_slider(struct zr_command_buffer *out, struct zr_rect slider,
return slider_value;
}
zr_float
zr_widget_drag(struct zr_command_buffer *out, struct zr_rect drag,
zr_float min, zr_float val, zr_float max,
zr_float inc_per_pixel, const struct zr_drag *d,
const struct zr_input *in, const struct zr_user_font *f)
{
struct zr_text t;
struct zr_color col;
struct zr_color background;
zr_float drag_range;
zr_float drag_min, drag_max;
zr_float drag_value, drag_steps;
zr_float cursor_offset;
char string[ZR_MAX_NUMBER_BUFFER];
zr_size len;
zr_bool left_mouse_down;
zr_bool left_mouse_click_in_cursor;
ZR_ASSERT(d);
ZR_ASSERT(out);
ZR_ASSERT(f);
if (!out || !d)
return 0;
/* make sure the provided values are correct */
drag.x = drag.x + d->padding.x;
drag.y = drag.y + d->padding.y;
drag.h = MAX(drag.h, 2 * d->padding.y);
drag.w = MAX(drag.w, 1 + drag.h + 2 * d->padding.x);
drag.h -= 2 * d->padding.y;
drag.w -= 2 * d->padding.y;
drag_max = MAX(min, max);
drag_min = MIN(min, max);
drag_value = CLAMP(drag_min, val, drag_max);
/* update value user input */
left_mouse_down = in && in->mouse.buttons[ZR_BUTTON_LEFT].down;
left_mouse_click_in_cursor = in && zr_input_has_mouse_click_down_in_rect(in,
ZR_BUTTON_LEFT, drag, zr_true);
t.text = d->text;
background = d->normal;
if (zr_input_is_mouse_hovering_rect(in, drag))
background = d->hover;
if (left_mouse_down && left_mouse_click_in_cursor) {
zr_float delta, pixels;
background = d->active;
t.text = d->text_active;
pixels = in->mouse.delta.x;
delta = pixels * inc_per_pixel;
drag_value += delta;
drag_value = CLAMP(drag_min, drag_value, drag_max);
}
/* draw border + background */
zr_command_buffer_push_rect(out, drag, d->rounding, d->border);
drag = zr_shrink_rect(drag, d->border_width);
zr_command_buffer_push_rect(out, drag, d->rounding, background);
/* draw value as text */
t.background = background;
t.padding = zr_vec2(0,0);
len = zr_dtos(string, drag_value);
len = zr_string_float_limit(string, ZR_MAX_FLOAT_PRECISION);
zr_widget_text(out, drag, string, len, &t, ZR_TEXT_CENTERED, f);
return drag_value;
}
zr_size
zr_widget_progress(struct zr_command_buffer *out, struct zr_rect r,
zr_size value, zr_size max, zr_bool modifyable,
@ -5034,7 +5127,6 @@ zr_widget_spinner_base(struct zr_command_buffer *out, struct zr_rect r,
return ret;
}
zr_int
zr_widget_spinner_int(struct zr_command_buffer *out, struct zr_rect r,
const struct zr_spinner *s, zr_int min, zr_int value,
@ -5069,27 +5161,6 @@ zr_widget_spinner_int(struct zr_command_buffer *out, struct zr_rect r,
return value;
}
static zr_size
zr_string_float_limit(char *string, zr_int prec)
{
zr_int dot = 0;
char *c = string;
while (*c) {
if (*c == '.') {
dot = 1;
c++;
continue;
}
if (dot == (prec+1)) {
*c = 0;
break;
}
if (dot > 0) dot++;
c++;
}
return (zr_size)(c - string);
}
zr_float
zr_widget_spinner_float(struct zr_command_buffer *out, struct zr_rect r,
const struct zr_spinner *s, zr_float min, zr_float value, zr_float max,
@ -5177,6 +5248,9 @@ zr_widget_spinner_float(struct zr_command_buffer *out, struct zr_rect r,
COLOR(PROGRESS_CURSOR, 100, 100, 100, 255)\
COLOR(PROGRESS_CURSOR_HOVER, 120, 120, 120, 255)\
COLOR(PROGRESS_CURSOR_ACTIVE, 150, 150, 150, 255)\
COLOR(DRAG, 38, 38, 38, 255)\
COLOR(DRAG_HOVER, 50, 50, 50, 255)\
COLOR(DRAG_ACTIVE, 60, 60, 60, 255)\
COLOR(INPUT, 45, 45, 45, 255)\
COLOR(INPUT_CURSOR, 100, 100, 100, 255)\
COLOR(INPUT_TEXT, 135, 135, 135, 255)\
@ -7286,6 +7360,46 @@ zr_slider_int(struct zr_context *layout, zr_int min_value, zr_int *value,
*value = (zr_int)val;
}
void
zr_drag_float(struct zr_context *layout, zr_float min, zr_float *val,
zr_float max, zr_float inc_per_pixel)
{
struct zr_rect bounds;
struct zr_drag drag;
const struct zr_style *config;
struct zr_vec2 item_padding;
const struct zr_input *i;
enum zr_widget_state state;
state = zr_widget(&bounds, layout);
if (!state) return;
i = (state == ZR_WIDGET_ROM || layout->flags & ZR_WINDOW_ROM) ? 0 : layout->input;
config = layout->style;
item_padding = zr_style_property(config, ZR_PROPERTY_ITEM_PADDING);
drag.padding.x = item_padding.x;
drag.padding.y = item_padding.y;
drag.border = config->colors[ZR_COLOR_BORDER];
drag.normal = config->colors[ZR_COLOR_DRAG];
drag.hover = config->colors[ZR_COLOR_DRAG_HOVER];
drag.active = config->colors[ZR_COLOR_DRAG_ACTIVE];
drag.text = config->colors[ZR_COLOR_TEXT];
drag.text_active = config->colors[ZR_COLOR_TEXT_ACTIVE];
drag.rounding = config->rounding[ZR_ROUNDING_SLIDER];
*val = zr_widget_drag(layout->buffer, bounds, min, *val, max,
inc_per_pixel, &drag, i, &config->font);
}
void zr_drag_int(struct zr_context *layout, zr_int min, zr_int *val,
zr_int max, zr_int inc_per_pixel)
{
zr_float value = (zr_float)*val;
zr_drag_float(layout, (zr_float)min, &value,
(zr_float)max, (zr_float)inc_per_pixel);
*val = (zr_int)value;
}
void
zr_progress(struct zr_context *layout, zr_size *cur_value, zr_size max_value,
zr_bool is_modifyable)

View File

@ -1800,8 +1800,6 @@ zr_size zr_edit_box_len(struct zr_edit_box*);
zr_widget_edit_filtered -- Editbox with utf8 gylph filter capabilities
zr_widget_spinner_int -- integer spinner widget
zr_widget_spinner_float -- float spinner widget
zr_widget_drag_int -- integer dragging widget
zr_widget_drag_float -- float dragging widget
zr_widget_scrollbarv -- vertical scrollbar widget imeplementation
zr_widget_scrollbarh -- horizontal scrollbar widget imeplementation
*/
@ -1950,6 +1948,27 @@ struct zr_slider {
/* slider rounding */
};
struct zr_drag {
struct zr_vec2 padding;
/* padding between bounds and content */
struct zr_color border;
/* dragging widget cursor border color */
struct zr_color normal;
/* dragging widget cursor color */
struct zr_color hover;
/* dragging widget cursor color */
struct zr_color active;
/* dragging widget cursor color */
struct zr_color text;
/* dragging widget text color */
struct zr_color text_active;
/* dragging widget active widget text color */
zr_float rounding;
/* dragging widget rounding */
zr_float border_width;
/* dragging widget border width */
};
struct zr_scrollbar {
zr_float rounding;
/* scrollbar rectangle rounding */
@ -2170,6 +2189,23 @@ zr_float zr_widget_slider(struct zr_command_buffer*, struct zr_rect,
Output:
- returns the from the user input updated value
*/
zr_float zr_widget_drag(struct zr_command_buffer*, struct zr_rect,
zr_float min, zr_float val, zr_float max,
zr_float inc_per_pixel, const struct zr_drag*,
const struct zr_input*, const struct zr_user_font*);
/* this function executes a dragging widget
Input:
- output command buffer for drawing
- bounds of the slider
- minimal draging value that will not be underflown
- dragging value to be updated by the user
- maximal draggin value that will not be overflown
- incrementing value per dragged pixel
- visual style structure describing the dragging widget
- input structure to update the dragging widget with
Output:
- returns the from the user input updated value
*/
zr_size zr_widget_progress(struct zr_command_buffer*, struct zr_rect,
zr_size value, zr_size max, zr_bool modifyable,
const struct zr_progress*, const struct zr_input*);
@ -2374,6 +2410,9 @@ enum zr_style_colors {
ZR_COLOR_PROGRESS_CURSOR,
ZR_COLOR_PROGRESS_CURSOR_HOVER,
ZR_COLOR_PROGRESS_CURSOR_ACTIVE,
ZR_COLOR_DRAG,
ZR_COLOR_DRAG_HOVER,
ZR_COLOR_DRAG_ACTIVE,
ZR_COLOR_INPUT,
ZR_COLOR_INPUT_CURSOR,
ZR_COLOR_INPUT_TEXT,
@ -2404,6 +2443,7 @@ enum zr_style_rounding {
ZR_ROUNDING_BUTTON,
ZR_ROUNDING_SLIDER,
ZR_ROUNDING_PROGRESS,
ZR_ROUNDING_DRAG,
ZR_ROUNDING_CHECK,
ZR_ROUNDING_INPUT,
ZR_ROUNDING_GRAPH,
@ -3379,6 +3419,31 @@ void zr_slider_int(struct zr_context*, zr_int min, zr_int *val, zr_int max,
Output:
- the from user input updated slider value
*/
void zr_drag_float(struct zr_context*, zr_float min, zr_float *val,
zr_float max, zr_float inc_per_pixel);
/* this function executes a dragable float widget
Input:
- minimal dragging value that will not be underflown
- slider dragging which shall be updated
- maximal dragging value that will not be overflown
- value increment per dragged pixel delta
- dragging axis with either ZR_AXIS_X or ZR_AXIS_Y
Output:
- returns the from the user input updated value
*/
void zr_drag_int(struct zr_context*, zr_int min, zr_int *val,
zr_int max, zr_int inc_per_pixel);
/* this function executes a dragable int value widget
Input:
- minimal dragging value that will not be underflown
- slider dragging which shall be updated
- maximal dragging value that will not be overflown
- value increment per dragged pixel delta
- dragging axis with either ZR_AXIS_X or ZR_AXIS_Y
Output:
- returns the from the user input updated value
*/
void zr_progress(struct zr_context*, zr_size *cur, zr_size max, zr_bool modifyable);
/* this function creates an either user or program controlled progressbar
Input: