added panel scaling

This commit is contained in:
vurtun 2015-03-25 14:15:42 +01:00
parent 1085f843aa
commit 760767d789
3 changed files with 57 additions and 15 deletions

62
gui.c
View File

@ -22,10 +22,6 @@
#define OFFSETOF(st,m) ((gui_size)(&((st*)0)->m))
#define CONTAINER_OF(p, t, m) ((t*)(void*)((char*)p - OFFSETOF(t,m)))
#define ASSERT_LINE(p, l, f) \
typedef char PASTE(assertion_failed_##f##_,l)[2*!!(p)-1];
#define ASSERT(predicate) ASSERT_LINE(predicate,__LINE__,__FILE__)
#define col_load(c,j,k,l,m) (c).r = (j), (c).g = (k), (c).b = (l), (c).a = (m)
#define vec2_load(v,a,b) (v).x = (a), (v).y = (b)
#define vec2_mov(to,from) (to).x = (from).x, (to).y = (from).y
@ -34,9 +30,8 @@
#define vec2_muls(r, v, s) do {(r).x=(v).x*(s); (r).y=(v).y*(s);} while(0)
struct gui_context_panel {
gui_float x, y;
gui_float w, h;
struct gui_panel panel;
gui_float x, y, w, h;
struct gui_draw_call_list list;
struct gui_context_panel *next;
};
@ -55,7 +50,7 @@ struct gui_context {
};
static const gui_texture null_tex;
static const struct gui_rect null_rect = {0, 0, 9999, 9999};
static const struct gui_rect null_rect = {0.0f, 0.0f, 9999.0f, 9999.0f};
static const gui_char utfbyte[GUI_UTF_SIZE+1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
static const gui_char utfmask[GUI_UTF_SIZE+1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const long utfmin[GUI_UTF_SIZE+1] = {0, 0, 0x80, 0x800, 0x100000};
@ -65,9 +60,9 @@ static gui_float
fsqrt(float x)
{
float xhalf = 0.5f*x;
union {float f; int i;} val;
ASSERT(sizeof(int) == sizeof(float));
val.f = x;
union {float f; long i;} val;
val.i = 0;
val.f = ABS(x);
val.i = 0x5f375a86 - (val.i >> 1);
val.f = val.f * (1.5f - xhalf * val.f * val.f);
return 1.0f/val.f;
@ -1394,6 +1389,7 @@ gui_default_config(struct gui_config *config)
vec2_load(config->panel_min_size, 64.0f, 64.0f);
vec2_load(config->item_spacing, 8.0f, 8.0f);
vec2_load(config->item_padding, 4.0f, 4.0f);
vec2_load(config->scaler_size, 16.0f, 16.0f);
col_load(config->colors[GUI_COLOR_TEXT], 100, 100, 100, 255);
col_load(config->colors[GUI_COLOR_PANEL], 45, 45, 45, 255);
col_load(config->colors[GUI_COLOR_BORDER], 100, 100, 100, 255);
@ -2416,6 +2412,33 @@ gui_panel_del(struct gui_context *ctx, struct gui_panel *panel)
gui_free_panel(ctx, cpanel);
}
void
gui_panel_geometry(struct gui_panel *panel, struct gui_rect *geometry)
{
const struct gui_context_panel *cpanel;
cpanel = CONTAINER_OF(panel, const struct gui_context_panel, panel);
geometry->x = cpanel->x;
geometry->y = cpanel->y;
geometry->w = cpanel->w;
geometry->h = cpanel->h;
}
gui_flags
gui_panel_get_flags(struct gui_panel *panel)
{
const struct gui_context_panel *cpanel;
cpanel = CONTAINER_OF(panel, const struct gui_context_panel, panel);
return cpanel->panel.flags;
}
void
gui_panel_set_flags(struct gui_panel *panel, gui_flags flags)
{
struct gui_context_panel *cpanel;
cpanel = CONTAINER_OF(panel, struct gui_context_panel, panel);
cpanel->panel.flags = flags;
}
void
gui_begin(struct gui_context *ctx, gui_float w, gui_float h)
{
@ -2443,11 +2466,10 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
gui_size n = 0;
struct gui_context_panel *p = NULL;
while (n < ctx->panel_size && ctx->panel_lists[n++] != &cpanel->list);
while (n < ctx->panel_size) {
for (n; n < ctx->panel_size; n++) {
p = CONTAINER_OF(ctx->panel_lists[n], struct gui_context_panel, list);
if (INBOX(in->mouse_prev.x, in->mouse_prev.y, p->x, p->y, p->w, p->h))
break;
n++;
}
if (n >= ctx->panel_size) {
gui_rm_draw_list(ctx, &cpanel->list);
@ -2470,6 +2492,22 @@ gui_begin_panel(struct gui_context *ctx, struct gui_panel *panel,
}
}
if (ctx->active == cpanel && (flags & GUI_PANEL_SCALEABLE) && (flags & GUI_PANEL_SCROLLBAR)) {
const struct gui_config *config = cpanel->panel.config;
gui_bool inscroll, incursor;
const gui_float scaler_x = cpanel->x;
const gui_float scaler_y = (cpanel->y + cpanel->h) - config->scaler_size.y;
const gui_float scaler_w = config->scaler_size.x;
const gui_float scaler_h = config->scaler_size.y;
inscroll = INBOX(in->mouse_pos.x,in->mouse_pos.y,scaler_x, scaler_y, scaler_w, scaler_h);
incursor = INBOX(in->mouse_prev.x,in->mouse_prev.y,scaler_x, scaler_y, scaler_w, scaler_h);
if (in->mouse_down && inscroll && incursor) {
cpanel->x = CLAMP(0, cpanel->x + in->mouse_delta.x, ctx->width - cpanel->w);
cpanel->w = CLAMP(0, cpanel->w - in->mouse_delta.x, ctx->width - cpanel->x);
cpanel->h = CLAMP(0, cpanel->h + in->mouse_delta.y, ctx->height - cpanel->y);
}
}
global = &ctx->global_buffer;
out = &ctx->buffer;
out->vertex_size = 0;

8
gui.h
View File

@ -319,6 +319,7 @@ struct gui_config {
struct gui_vec2 panel_min_size;
struct gui_vec2 item_spacing;
struct gui_vec2 item_padding;
struct gui_vec2 scaler_size;
gui_float scrollbar_width;
struct gui_color colors[GUI_COLOR_COUNT];
};
@ -331,8 +332,8 @@ enum gui_panel_flags {
GUI_PANEL_CLOSEABLE = 0x10,
GUI_PANEL_SCROLLBAR = 0x20,
GUI_PANEL_HIDDEN = 0x40,
GUI_PANEL_SCALEABLE = 0x80,
GUI_PANEL_MOVEABLE = 0x100
GUI_PANEL_MOVEABLE = 0x80,
GUI_PANEL_SCALEABLE = 0x100
};
struct gui_panel {
@ -451,6 +452,9 @@ void gui_begin(struct gui_context*, gui_float width, gui_float height);
void gui_end(struct gui_context*, struct gui_output*, struct gui_memory_status*);
struct gui_panel *gui_panel_new(struct gui_context*, gui_float x, gui_float y, gui_float w,
gui_float h, const struct gui_config* , const struct gui_font*);
void gui_panel_geometry(struct gui_panel*, struct gui_rect*);
gui_flags gui_panel_get_flags(struct gui_panel*);
void gui_panel_set_flags(struct gui_panel*, gui_flags flags);
void gui_panel_del(struct gui_context*, struct gui_panel*);
gui_bool gui_begin_panel(struct gui_context*, struct gui_panel*, const char *title, gui_flags flags);
void gui_end_panel(struct gui_context*, struct gui_panel*, struct gui_memory_status*);

View File

@ -402,7 +402,7 @@ main(int argc, char *argv[])
gui_begin(ctx, (gui_float)width, (gui_float)height);
running = gui_begin_panel(ctx, panel, "Demo",
GUI_PANEL_HEADER|GUI_PANEL_CLOSEABLE|GUI_PANEL_MINIMIZABLE|
GUI_PANEL_MOVEABLE|GUI_PANEL_SCROLLBAR);
GUI_PANEL_MOVEABLE|GUI_PANEL_SCROLLBAR|GUI_PANEL_SCALEABLE);
gui_panel_layout(panel, 30, 1);
if (gui_panel_button_text(panel, "button", 6, GUI_BUTTON_SWITCH))
fprintf(stdout, "button pressed!\n");