added scrollbar

This commit is contained in:
vurtun 2015-03-04 14:54:48 +01:00
parent c046e0eab4
commit a40e9bd2e2
3 changed files with 159 additions and 79 deletions

171
gui.c
View File

@ -26,7 +26,7 @@
#define ASSERT(predicate) ASSERT_LINE(predicate,__LINE__,__FILE__)
#define vec2_load(v,a,b) (v).x = (a), (v).y = (b)
#define vec2_cpy(to,from) (to).x = (from).x, (to).y = (from).y
#define vec2_mov(to,from) (to).x = (from).x, (to).y = (from).y
#define vec2_len(v) ((float)fsqrt((v).x*(v).x+(v).y*(v).y))
#define vec2_sub(r,a,b) do {(r).x=(a).x-(b).x; (r).y=(a).y-(b).y;} while(0)
#define vec2_add(r,a,b) do {(r).x=(a).x+(b).x; (r).y=(a).y+(b).y;} while(0)
@ -129,7 +129,7 @@ gui_input_begin(struct gui_input *in)
if (!in) return;
in->mouse_clicked = 0;
in->glyph_count = 0;
vec2_cpy(in->mouse_prev, in->mouse_pos);
vec2_mov(in->mouse_prev, in->mouse_pos);
}
void
@ -378,11 +378,22 @@ gui_slider(struct gui_draw_list *list, const struct gui_input *in,
gui_int mouse_x, mouse_y;
gui_int clicked_x, clicked_y;
/* TODO(micha): make this safe */
const gui_float cursor_w = (w - 2 * pad) / (((max - min) + 1) / step);
const gui_int cursor_h = h - 2 * pad;
gui_int cursor_x = x + pad + (cursor_w * (value - min));
gui_int cursor_y = y + pad;
gui_float cursor_w;
gui_int cursor_x;
gui_int cursor_y;
gui_int cursor_h;
if (step == 0.0f) return value;
w = MAX(w, 2 * pad);
h = MAX(h, 2 * pad);
max = MAX(min, max);
min = MIN(min, max);
value = CLAMP(min, value, max);
cursor_w = (w - 2 * pad) / (((max - min) + step) / step);
cursor_h = h - 2 * pad;
cursor_x = x + pad + (cursor_w * (value - min));
cursor_y = y + pad;
if (!list || !in) return 0;
mouse_x = in->mouse_pos.x;
@ -396,7 +407,6 @@ gui_slider(struct gui_draw_list *list, const struct gui_input *in,
{
gui_float cursor_next_x;
const gui_float tmp = mouse_x - cursor_x + (cursor_w / 2);
/* TODO(micha): make this safe */
gui_float next_value = value + step * ((tmp < 0) ? -1.0f : 1.0f);
next_value = CLAMP(min, next_value, max);
cursor_next_x = x + pad + (cursor_w * (next_value - min));
@ -416,32 +426,38 @@ gui_int
gui_progress(struct gui_draw_list *list, const struct gui_input *in,
struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad,
gui_float cur, gui_float max, gui_bool modifyable)
gui_size value, gui_size max, gui_bool modifyable)
{
gui_int mx;
gui_int my;
gui_int mouse_x, mouse_y;
gui_float scale;
gui_int cx, cy, cw, ch;
gui_int cursor_x;
gui_int cursor_y;
gui_int cursor_w;
gui_int cursor_h;
if (!list || !in) return 0;
mx = in->mouse_pos.x;
my = in->mouse_pos.y;
mouse_x = in->mouse_pos.x;
mouse_y = in->mouse_pos.y;
/* TODO(micha): make this safe */
if (modifyable && in->mouse_down && INBOX(mx, my, x, y, x + w, y + h))
cur = max * (((gui_float)mx - (gui_float)x) / (gui_float)w);
w = MAX(w, 2 * pad + 1);
h = MAX(h, 2 * pad + 1);
value = MIN(value, max);
if (!max) return cur;
/* TODO(micha): make this safe */
cur = CLAMP(0, cur, max);
scale = (cur/max);
ch = h - 2 * pad;
cw = (w - 2 * pad) * scale;
cx = x + pad;
cy = y + pad;
if (modifyable && in->mouse_down && INBOX(mouse_x, mouse_y, x, y, x+w, y+h)) {
gui_float ratio = (gui_float)(mouse_x - x) / (gui_float)w;
value = (gui_size)((gui_float)max * ratio);
}
if (!max) return value;
value = MIN(value, max);
scale = (gui_float)value / (gui_float)max;
cursor_h = h - 2 * pad;
cursor_w = (w - 2 * pad) * scale;
cursor_x = x + pad;
cursor_y = y + pad;
gui_rectf(list, x, y, w, h, bg);
gui_rectf(list, cx, cy, cw, ch, fg);
return cur;
gui_rectf(list, cursor_x, cursor_y, cursor_w, cursor_h, fg);
return value;
}
gui_int
@ -450,42 +466,91 @@ gui_scroll(struct gui_draw_list *list, const struct gui_input *in,
gui_int x, gui_int y, gui_int w, gui_int h,
gui_int offset, gui_int dst)
{
gui_bool up, down;
/* TODO(micha): make this safe */
const gui_int p = w / 4;
const gui_int bs = w;
const gui_int bh = bs / 2;
const gui_int by = y + h - bs;
const gui_int barh = h - 2 * bs;
const gui_int bary = y + bs;
gui_int mouse_x;
gui_int mouse_y;
gui_int prev_x;
gui_int prev_y;
/* TODO(micha): make this safe */
const gui_float ratio = (gui_float)barh/(gui_float)dst;
gui_float off = (gui_float)offset/(gui_float)dst;
const gui_int ch = (gui_int)(ratio * (gui_float)barh);
gui_int cy = bary + (gui_int)(off * barh);
const gui_int cw = w;
const gui_int cx = x;
gui_bool up, down;
gui_int button_size;
gui_int button_half;
gui_int button_y;
gui_int bar_h;
gui_int bar_y;
gui_float ratio;
gui_float off;
gui_int cursor_x;
gui_int cursor_y;
gui_int cursor_w;
gui_int cursor_h;
gui_int cursor_px;
gui_int cursor_py;
gui_bool inscroll;
gui_bool incursor;
gui_int pad;
gui_int xoff, yoff, boff;
gui_int xpad, ypad;
gui_int xmid;
if (!list || !in) return 0;
gui_rectf(list, x, y, w, h, bg);
if (dst <= h) return 0;
/* TODO(micha): make this safe */
up = gui_button(list, in, fg, bg, x, y, bs, bs, 0, "", 0);
down = gui_button(list, in, fg, bg, x, by, bs, bs, 0, "", 0);
gui_trianglef(list, x + bh, y+p, x+(bs-p), y+(bs-p), x+p, y+(bs-p), bg);
gui_trianglef(list, x+p, by + p, x + bs - p, by+p, x + bh, by + bs-p, bg);
mouse_x = in->mouse_pos.x;
mouse_y = in->mouse_pos.y;
prev_x = in->mouse_prev.x;
prev_y = in->mouse_prev.y;
if (up || down) {
const gui_int h2 = h/2;
offset = (down) ? MIN(offset+h2, dst-barh) : MAX(0, offset - h2);
w = MAX(w, 0);
h = MAX(h, 2 * w);
pad = w / 4;
button_size = w;
button_half = button_size / 2;
button_y = y + h - button_size;
bar_h = h - 2 * button_size;
bar_y = y + button_size;
ratio = (gui_float)bar_h/(gui_float)dst;
off = (gui_float)offset/(gui_float)dst;
cy = bary + (gui_int)(off * barh);
cursor_h = (gui_int)(ratio * (gui_float)bar_h);
cursor_y = bar_y + (gui_int)(off * bar_h);
cursor_w = w;
cursor_x = x;
xpad = x + pad;
ypad = button_y + pad;
xmid = x + button_half;
xoff = x + (button_size - pad);
yoff = y + (button_size - pad);
boff = button_y + (button_size - pad);
up = gui_button(list, in, fg, bg, x, y, button_size, button_size, 0, "", 0);
down = gui_button(list,in,fg,bg,x,button_y,button_size,button_size,0,"", 0);
gui_trianglef(list, xmid, y + pad, xoff, yoff, xpad, yoff, bg);
gui_trianglef(list, xpad, ypad, xoff, ypad, xmid, boff, bg);
cursor_px = cursor_x + cursor_w;
cursor_py = cursor_y + cursor_h;
inscroll = INBOX(mouse_x, mouse_y, x, y, x + w, y + h);
incursor = INBOX(prev_x, prev_y, cursor_x, cursor_y, cursor_px, cursor_py);
if (in->mouse_down && inscroll && incursor)
{
const gui_float pixel = in->mouse_delta.y;
const gui_float delta = (pixel/(gui_float)bar_h) * (gui_float)dst;
offset = CLAMP(0, offset + delta, dst - bar_h);
cursor_y += pixel;
} else if (up || down) {
const gui_int h2 = h/2;
offset = (down) ? MIN(offset + h2, dst - bar_h) : MAX(0, offset - h2);
off = (gui_float)offset/(gui_float)dst;
cursor_y = bar_y + (gui_int)(off * bar_h);
}
gui_rectf(list, cx, cy, cw, ch, fg);
gui_rect(list, cx, cy, cw, ch, bg);
gui_rectf(list, cursor_x, cursor_y, cursor_w, cursor_h, fg);
gui_rect(list, cursor_x, cursor_y, cursor_w, cursor_h, bg);
return offset;
}

20
gui.h
View File

@ -81,11 +81,6 @@ struct gui_font {
struct gui_font_glyph glyphes[GUI_GLYPHES_MAX];
};
void gui_begin(struct gui_draw_list *list, gui_byte *memory, gui_size size);
gui_size gui_end(struct gui_draw_list *list);
const struct gui_draw_command *gui_next(const struct gui_draw_list *list,
const struct gui_draw_command*);
void gui_input_begin(struct gui_input *in);
void gui_input_motion(struct gui_input *in, gui_int x, gui_int y);
void gui_input_key(struct gui_input *in, enum gui_keys key, gui_int down);
@ -93,7 +88,13 @@ void gui_input_button(struct gui_input *in, gui_int x, gui_int y, gui_int down);
void gui_input_char(struct gui_input *in, gui_glyph glyph);
void gui_input_end(struct gui_input *in);
void gui_begin(struct gui_draw_list *list, gui_byte *memory, gui_size size);
gui_size gui_end(struct gui_draw_list *list);
const struct gui_draw_command *gui_next(const struct gui_draw_list *list,
const struct gui_draw_command*);
gui_int gui_button(struct gui_draw_list *list, const struct gui_input *in,
const struct gui_font *font,
struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad,
const char *str, gui_int len);
@ -108,14 +109,15 @@ gui_int gui_slider(struct gui_draw_list *list, const struct gui_input *in,
gui_int gui_progress(struct gui_draw_list *list, const struct gui_input *in,
struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad,
gui_float cur, gui_float max, gui_bool modifyable);
gui_size cur, gui_size max, gui_bool modifyable);
gui_int gui_scroll(struct gui_draw_list *list, const struct gui_input *in,
struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h,
gui_int offset, gui_int dst);
gui_int gui_input(struct gui_draw_list *list,
const struct gui_input *in, gui_char *buffer, gui_int *len,
gui_int gui_input(struct gui_draw_list *list, const struct gui_input *in,
const struct gui_font *font,
struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h, gui_int active);
gui_int x, gui_int y, gui_int w, gui_int h,
gui_char *buffer, gui_int *len, gui_bool active);
#endif

47
x11.c
View File

@ -127,11 +127,16 @@ kpress(struct Console *con, XEvent* e)
struct XWindow *xw = con->win;
KeySym *keysym = XGetKeyboardMapping(xw->dpy, e->xkey.keycode, 1, &ret);
if (*keysym == XK_Escape) xw->running = 0;
else if (*keysym == XK_Shift_L || *keysym == XK_Shift_R) gui_input_key(&con->input, GUI_KEY_SHIFT, gui_true);
else if (*keysym == XK_Control_L || *keysym == XK_Control_L) gui_input_key(&con->input, GUI_KEY_CTRL, gui_true);
else if (*keysym == XK_Delete) gui_input_key(&con->input, GUI_KEY_DEL, gui_true);
else if (*keysym == XK_Return) gui_input_key(&con->input, GUI_KEY_ENTER, gui_true);
else if (*keysym == XK_BackSpace) gui_input_key(&con->input, GUI_KEY_BACKSPACE, gui_true);
else if (*keysym == XK_Shift_L || *keysym == XK_Shift_R)
gui_input_key(&con->input, GUI_KEY_SHIFT, gui_true);
else if (*keysym == XK_Control_L || *keysym == XK_Control_L)
gui_input_key(&con->input, GUI_KEY_CTRL, gui_true);
else if (*keysym == XK_Delete)
gui_input_key(&con->input, GUI_KEY_DEL, gui_true);
else if (*keysym == XK_Return)
gui_input_key(&con->input, GUI_KEY_ENTER, gui_true);
else if (*keysym == XK_BackSpace)
gui_input_key(&con->input, GUI_KEY_BACKSPACE, gui_true);
}
static void
@ -140,11 +145,16 @@ krelease(struct Console *con, XEvent* e)
int ret;
struct XWindow *xw = con->win;
KeySym *keysym = XGetKeyboardMapping(xw->dpy, e->xkey.keycode, 1, &ret);
if (*keysym == XK_Shift_L || *keysym == XK_Shift_R) gui_input_key(&con->input, GUI_KEY_SHIFT, gui_false);
else if (*keysym == XK_Control_L || *keysym == XK_Control_L) gui_input_key(&con->input, GUI_KEY_CTRL, gui_false);
else if (*keysym == XK_Delete) gui_input_key(&con->input, GUI_KEY_DEL, gui_false);
else if (*keysym == XK_Return) gui_input_key(&con->input, GUI_KEY_ENTER, gui_false);
else if (*keysym == XK_BackSpace) gui_input_key(&con->input, GUI_KEY_BACKSPACE, gui_false);
if (*keysym == XK_Shift_L || *keysym == XK_Shift_R)
gui_input_key(&con->input, GUI_KEY_SHIFT, gui_false);
else if (*keysym == XK_Control_L || *keysym == XK_Control_L)
gui_input_key(&con->input, GUI_KEY_CTRL, gui_false);
else if (*keysym == XK_Delete)
gui_input_key(&con->input, GUI_KEY_DEL, gui_false);
else if (*keysym == XK_Return)
gui_input_key(&con->input, GUI_KEY_ENTER, gui_false);
else if (*keysym == XK_BackSpace)
gui_input_key(&con->input, GUI_KEY_BACKSPACE, gui_false);
}
static void
@ -169,8 +179,8 @@ brelease(struct Console *con, XEvent *evt)
static void
bmotion(struct Console *con, XEvent *evt)
{
const float x = evt->xbutton.x;
const float y = evt->xbutton.y;
const gui_int x = evt->xbutton.x;
const gui_int y = evt->xbutton.y;
struct XWindow *xw = con->win;
gui_input_motion(&con->input, x, y);
}
@ -270,7 +280,7 @@ main(int argc, char *argv[])
xw.swa.colormap = xw.cmap;
xw.swa.event_mask =
ExposureMask | KeyPressMask | ButtonPress |
ButtonReleaseMask | ButtonMotionMask |
ButtonReleaseMask | ButtonMotionMask | PointerMotionMask |
Button1MotionMask | Button2MotionMask | Button3MotionMask;
xw.win = XCreateWindow(
xw.dpy, xw.root, 0, 0,WIN_WIDTH,WIN_HEIGHT, 0,
@ -290,7 +300,7 @@ main(int argc, char *argv[])
xw.running = 1;
while (xw.running) {
/* Input */
/*----------------------- Input -----------------------------*/
XEvent ev;
started = timestamp();
gui_input_begin(&con.input);
@ -308,9 +318,12 @@ main(int argc, char *argv[])
gui_begin(&con.gui, buffer, MAX_VERTEX_BUFFER);
if (gui_button(&con.gui, &con.input, colorA, colorC, 50,50,150,30,5,"",0))
fprintf(stdout, "Button pressed!\n");
slider = gui_slider(&con.gui, &con.input, colorA, colorB, 50,100,150,30,2, 0.0f, slider, 10.0f, 1.0f);
prog = gui_progress(&con.gui, &con.input, colorA, colorB, 50,150,150,30,2, prog, 100.0f, gui_true);
offset = gui_scroll(&con.gui, &con.input, colorA, colorB, 250,50,16,332, offset, 600);
slider = gui_slider(&con.gui, &con.input, colorA, colorB,
50,100,150,30,2, 0.0f, slider, 10.0f, 1.0f);
prog = gui_progress(&con.gui, &con.input, colorA, colorB,
50,150,150,30,2, prog, 100.0f, gui_true);
offset = gui_scroll(&con.gui, &con.input, colorA, colorB,
250,50,16,300, offset, 600);
gui_end(&con.gui);
/* ---------------------------------------------------------*/