imtk
changeset 20:c7a7ddbe7714
half-arsed automatic layout
author | John Tsiombikas <nuclear@siggraph.org> |
---|---|
date | Sat, 30 Apr 2011 05:23:59 +0300 |
parents | 11da537aeba6 |
children | 3138c38433e2 |
files | Makefile src/button.c src/checkbox.c src/imtk.c src/imtk.h src/listbox.c src/progress.c src/slider.c src/textbox.c test.c |
diffstat | 10 files changed, 170 insertions(+), 42 deletions(-) [+] |
line diff
1.1 --- a/Makefile Tue Apr 26 22:53:21 2011 +0300 1.2 +++ b/Makefile Sat Apr 30 05:23:59 2011 +0300 1.3 @@ -1,9 +1,13 @@ 1.4 -src = $(wildcard *.c src/*.c) 1.5 +src = $(wildcard src/*.c) 1.6 obj = $(src:.c=.o) 1.7 depfiles = $(obj:.o=.d) 1.8 +lib_a = libimtk.a 1.9 bin = test 1.10 1.11 +PREFIX = /usr/local 1.12 + 1.13 CC = gcc 1.14 +AR = ar 1.15 CFLAGS = -pedantic -Wall -g -Isrc 1.16 LDFLAGS = $(libgl) -lm 1.17 1.18 @@ -13,8 +17,11 @@ 1.19 libgl = -lGL -lGLU -lglut 1.20 endif 1.21 1.22 -$(bin): $(obj) 1.23 - $(CC) -o $@ $(obj) $(LDFLAGS) 1.24 +$(bin): $(lib_a) test.o 1.25 + $(CC) -o $@ test.o $(lib_a) $(LDFLAGS) 1.26 + 1.27 +$(lib_a): $(obj) 1.28 + $(AR) rcs $@ $(obj) 1.29 1.30 -include $(depfiles) 1.31 1.32 @@ -23,8 +30,19 @@ 1.33 1.34 .PHONY: clean 1.35 clean: 1.36 - rm -f $(obj) $(bin) 1.37 + rm -f $(obj) $(bin) $(lib_a) test.o 1.38 1.39 .PHONY: cleandep 1.40 cleandep: 1.41 rm -f $(depfiles) 1.42 + 1.43 +.PHONY: install 1.44 +install: $(lib_a) 1.45 + mkdir -p $(PREFIX)/include $(PREFIX)/lib 1.46 + cp $(lib_a) $(PREFIX)/lib/$(lib_a) 1.47 + cp src/imtk.h $(PREFIX)/include/imtk.h 1.48 + 1.49 +.PHONY: uninstall 1.50 +uninstall: 1.51 + rm -f $(PREFIX)/lib/$(lib_a) 1.52 + rm -f $(PREFIX)/include/imtk.h
2.1 --- a/src/button.c Tue Apr 26 22:53:21 2011 +0300 2.2 +++ b/src/button.c Sat Apr 30 05:23:59 2011 +0300 2.3 @@ -14,6 +14,10 @@ 2.4 2.5 assert(id >= 0); 2.6 2.7 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 2.8 + imtk_layout_get_pos(&x, &y); 2.9 + } 2.10 + 2.11 calc_button_size(label, &w, &h); 2.12 2.13 if(imtk_hit_test(x, y, w, h)) { 2.14 @@ -35,6 +39,7 @@ 2.15 } 2.16 2.17 draw_button(id, label, x, y, over); 2.18 + imtk_layout_advance(w, h); 2.19 return res; 2.20 } 2.21
3.1 --- a/src/checkbox.c Tue Apr 26 22:53:21 2011 +0300 3.2 +++ b/src/checkbox.c Sat Apr 30 05:23:59 2011 +0300 3.3 @@ -13,11 +13,16 @@ 3.4 int imtk_checkbox(int id, const char *label, int x, int y, int state) 3.5 { 3.6 int sz = CHECKBOX_SIZE; 3.7 - int over = 0; 3.8 + int full_size, over = 0; 3.9 3.10 assert(id >= 0); 3.11 3.12 - if(imtk_hit_test(x, y, sz + imtk_string_size(label) + 5, sz)) { 3.13 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 3.14 + imtk_layout_get_pos(&x, &y); 3.15 + } 3.16 + 3.17 + full_size = sz + imtk_string_size(label) + 5; 3.18 + if(imtk_hit_test(x, y, full_size, sz)) { 3.19 imtk_set_hot(id); 3.20 over = 1; 3.21 } 3.22 @@ -36,6 +41,7 @@ 3.23 } 3.24 3.25 draw_checkbox(id, label, x, y, state, over); 3.26 + imtk_layout_advance(full_size, sz); 3.27 return state; 3.28 } 3.29
4.1 --- a/src/imtk.c Tue Apr 26 22:53:21 2011 +0300 4.2 +++ b/src/imtk.c Sat Apr 30 05:23:59 2011 +0300 4.3 @@ -22,6 +22,20 @@ 4.4 { 4.5 int width, height; 4.6 4.7 + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); 4.8 + 4.9 + glDisable(GL_DEPTH_TEST); 4.10 + glDisable(GL_STENCIL_TEST); 4.11 + glDisable(GL_ALPHA_TEST); 4.12 + glDisable(GL_TEXTURE_1D); 4.13 + glDisable(GL_TEXTURE_2D); 4.14 + glDisable(GL_CULL_FACE); 4.15 + glDisable(GL_SCISSOR_TEST); 4.16 + glDisable(GL_LIGHTING); 4.17 + glEnable(GL_BLEND); 4.18 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 4.19 + 4.20 + 4.21 imtk_get_viewport(&width, &height); 4.22 4.23 glMatrixMode(GL_PROJECTION); 4.24 @@ -33,42 +47,88 @@ 4.25 glMatrixMode(GL_MODELVIEW); 4.26 glPushMatrix(); 4.27 glLoadIdentity(); 4.28 - 4.29 - glPushAttrib(GL_ENABLE_BIT); 4.30 - glDisable(GL_DEPTH_TEST); 4.31 - glDisable(GL_CULL_FACE); 4.32 - glDisable(GL_LIGHTING); 4.33 - glEnable(GL_BLEND); 4.34 - 4.35 - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 4.36 } 4.37 4.38 void imtk_end(void) 4.39 { 4.40 - glPopAttrib(); 4.41 - 4.42 glMatrixMode(GL_PROJECTION); 4.43 glPopMatrix(); 4.44 glMatrixMode(GL_MODELVIEW); 4.45 glPopMatrix(); 4.46 + 4.47 + glPopAttrib(); 4.48 } 4.49 4.50 void imtk_label(const char *str, int x, int y) 4.51 { 4.52 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 4.53 + imtk_layout_get_pos(&x, &y); 4.54 + } 4.55 + 4.56 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR)); 4.57 - imtk_draw_string(x, y, str); 4.58 + imtk_draw_string(x, y + 15, str); 4.59 + imtk_layout_advance(imtk_string_size(str), 12); 4.60 } 4.61 4.62 4.63 -/* 4.64 -int imtk_combobox(int id, char *textbuf, size_t buf_sz, const char *list, int sel, int x, int y) 4.65 +static int box[4], span[4]; 4.66 +static int spacing; 4.67 +static int layout; 4.68 + 4.69 +void imtk_layout_start(int x, int y, int sp, int dir) 4.70 { 4.71 - imtk_textbox(id + 1, textbuf, buf_sz, x, y); 4.72 - imtk_button(id + 3, "V", x + TEXTBOX_SIZE, y); 4.73 + box[0] = span[0] = x; 4.74 + box[1] = span[1] = y; 4.75 + box[2] = box[3] = span[2] = span[3] = 0; 4.76 + spacing = sp; 4.77 + layout = dir; 4.78 +} 4.79 4.80 - if(prev_active == id + 3) { 4.81 - sel = imtk_listbox(id + 5, list, sel, x, y + 20); 4.82 +void imtk_layout_dir(int dir) 4.83 +{ 4.84 + layout = dir; 4.85 + if(dir == IMTK_VERTICAL) { 4.86 + imtk_layout_newline(); 4.87 } 4.88 - return sel; 4.89 } 4.90 -*/ 4.91 + 4.92 +void imtk_layout_advance(int width, int height) 4.93 +{ 4.94 + int max_span_y, max_box_y; 4.95 + 4.96 + box[2] += width + spacing; 4.97 + span[2] += width + spacing; 4.98 + 4.99 + if(height > span[3]) { 4.100 + span[3] = height; 4.101 + } 4.102 + 4.103 + max_span_y = span[1] + span[3]; 4.104 + max_box_y = box[1] + box[3]; 4.105 + 4.106 + if(max_span_y > max_box_y) { 4.107 + box[3] = max_span_y - box[1]; 4.108 + } 4.109 + 4.110 + if(layout == IMTK_VERTICAL) { 4.111 + imtk_layout_newline(); 4.112 + } 4.113 +} 4.114 + 4.115 +void imtk_layout_newline(void) 4.116 +{ 4.117 + span[0] = box[0]; 4.118 + span[1] = box[1] + box[3] + spacing; 4.119 + span[2] = span[3] = 0; 4.120 +} 4.121 + 4.122 +void imtk_layout_get_pos(int *x, int *y) 4.123 +{ 4.124 + *x = span[0] + span[2]; 4.125 + *y = span[1]; 4.126 +} 4.127 + 4.128 +void imtk_layout_get_bounds(int *bbox) 4.129 +{ 4.130 + memcpy(bbox, box, sizeof box); 4.131 +}
5.1 --- a/src/imtk.h Tue Apr 26 22:53:21 2011 +0300 5.2 +++ b/src/imtk.h Sat Apr 30 05:23:59 2011 +0300 5.3 @@ -2,7 +2,7 @@ 5.4 #define IMTK_H_ 5.5 5.6 #include <stdlib.h> 5.7 - 5.8 +#include <limits.h> 5.9 5.10 #define IMUID (__LINE__ << 10) 5.11 #define IMUID_IDX(i) ((__LINE__ << 10) + ((i) << 1)) 5.12 @@ -31,10 +31,16 @@ 5.13 IMTK_CHECK_COLOR 5.14 }; 5.15 5.16 +enum { 5.17 + IMTK_HORIZONTAL, 5.18 + IMTK_VERTICAL 5.19 +}; 5.20 + 5.21 #define IMTK_FOCUS_BIT 0x100 5.22 #define IMTK_PRESS_BIT 0x200 5.23 #define IMTK_SEL_BIT 0x400 5.24 5.25 +#define IMTK_AUTO INT_MIN 5.26 5.27 #ifdef __cplusplus 5.28 extern "C" { 5.29 @@ -62,10 +68,18 @@ 5.30 int imtk_listbox(int id, const char *list, int sel, int x, int y); 5.31 int imtk_radiogroup(int id, const char *list, int sel, int x, int y); 5.32 5.33 -/* helper functions to create and destroy item lists for listboxes and comboboxes */ 5.34 +/* helper functions to create and destroy item lists for listboxes */ 5.35 char *imtk_create_list(const char *first, ...); 5.36 void imtk_free_list(char *list); 5.37 5.38 +/* automatic layout */ 5.39 +void imtk_layout_start(int x, int y, int spacing, int dir); 5.40 +void imtk_layout_dir(int dir); 5.41 +void imtk_layout_advance(int width, int height); 5.42 +void imtk_layout_newline(void); 5.43 +void imtk_layout_get_pos(int *x, int *y); 5.44 +void imtk_layout_get_bounds(int *bbox); 5.45 + 5.46 /* defined in draw.c */ 5.47 void imtk_set_color(unsigned int col, float r, float g, float b, float a); 5.48 float *imtk_get_color(unsigned int col);
6.1 --- a/src/listbox.c Tue Apr 26 22:53:21 2011 +0300 6.2 +++ b/src/listbox.c Sat Apr 30 05:23:59 2011 +0300 6.3 @@ -29,6 +29,10 @@ 6.4 6.5 assert(id >= 0); 6.6 6.7 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 6.8 + imtk_layout_get_pos(&x, &y); 6.9 + } 6.10 + 6.11 max_width = 0; 6.12 over = 0; 6.13 6.14 @@ -61,6 +65,7 @@ 6.15 } 6.16 6.17 draw(id, list, sel, x, y, max_width, nitems, over); 6.18 + imtk_layout_advance(max_width, ITEM_HEIGHT * nitems); 6.19 return sel; 6.20 } 6.21
7.1 --- a/src/progress.c Tue Apr 26 22:53:21 2011 +0300 7.2 +++ b/src/progress.c Sat Apr 30 05:23:59 2011 +0300 7.3 @@ -9,7 +9,12 @@ 7.4 7.5 void imtk_progress(int id, float pos, int x, int y) 7.6 { 7.7 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 7.8 + imtk_layout_get_pos(&x, &y); 7.9 + } 7.10 + 7.11 draw_progress(id, pos, x, y); 7.12 + imtk_layout_advance(PROGR_SIZE, PROGR_HEIGHT); 7.13 } 7.14 7.15 static void draw_progress(int id, float pos, int x, int y)
8.1 --- a/src/slider.c Tue Apr 26 22:53:21 2011 +0300 8.2 +++ b/src/slider.c Sat Apr 30 05:23:59 2011 +0300 8.3 @@ -18,6 +18,11 @@ 8.4 8.5 assert(id >= 0); 8.6 8.7 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 8.8 + imtk_layout_get_pos(&x, &y); 8.9 + } 8.10 + y += THUMB_HEIGHT / 2; 8.11 + 8.12 imtk_get_mouse(&mousex, &mousey); 8.13 8.14 pos = (pos - min) / range; 8.15 @@ -60,6 +65,7 @@ 8.16 } 8.17 8.18 draw_slider(id, pos, min, max, x, y, over); 8.19 + imtk_layout_advance(SLIDER_SIZE + THUMB_WIDTH, THUMB_HEIGHT); 8.20 return pos * range + min; 8.21 } 8.22
9.1 --- a/src/textbox.c Tue Apr 26 22:53:21 2011 +0300 9.2 +++ b/src/textbox.c Sat Apr 30 05:23:59 2011 +0300 9.3 @@ -6,6 +6,7 @@ 9.4 #include "draw.h" 9.5 9.6 #define TEXTBOX_SIZE 100 9.7 +#define TEXTBOX_HEIGHT 20 9.8 9.9 static void draw_textbox(int id, char *text, int cursor, int x, int y, int over); 9.10 9.11 @@ -16,6 +17,10 @@ 9.12 9.13 assert(id >= 0); 9.14 9.15 + if(x == IMTK_AUTO || y == IMTK_AUTO) { 9.16 + imtk_layout_get_pos(&x, &y); 9.17 + } 9.18 + 9.19 len = strlen(textbuf); 9.20 9.21 /* HACK! using last element of textbuf for saving cursor position */ 9.22 @@ -23,7 +28,7 @@ 9.23 cursor = len; 9.24 } 9.25 9.26 - if(imtk_hit_test(x, y, TEXTBOX_SIZE, 20)) { 9.27 + if(imtk_hit_test(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT)) { 9.28 imtk_set_hot(id); 9.29 over = 1; 9.30 } 9.31 @@ -106,6 +111,7 @@ 9.32 9.33 textbuf[buf_sz - 1] = cursor; 9.34 draw_textbox(id, textbuf, cursor, x, y, over); 9.35 + imtk_layout_advance(TEXTBOX_SIZE, TEXTBOX_HEIGHT); 9.36 } 9.37 9.38 9.39 @@ -120,7 +126,7 @@ 9.40 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol); 9.41 memcpy(bcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof bcol); 9.42 9.43 - imtk_draw_rect(x, y, TEXTBOX_SIZE, 20, tcol, bcol); 9.44 + imtk_draw_rect(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, tcol, bcol); 9.45 9.46 if(imtk_has_focus(id)) { 9.47 int strsz; 9.48 @@ -143,6 +149,6 @@ 9.49 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR)); 9.50 imtk_draw_string(x + 2, y + 15, text); 9.51 9.52 - imtk_draw_frame(x, y, TEXTBOX_SIZE, 20, FRAME_INSET); 9.53 + imtk_draw_frame(x, y, TEXTBOX_SIZE, TEXTBOX_HEIGHT, FRAME_INSET); 9.54 } 9.55
10.1 --- a/test.c Tue Apr 26 22:53:21 2011 +0300 10.2 +++ b/test.c Sat Apr 30 05:23:59 2011 +0300 10.3 @@ -125,6 +125,7 @@ 10.4 char *itemlist; 10.5 10.6 imtk_begin(); 10.7 + imtk_layout_start(30, 50, 10, IMTK_VERTICAL); 10.8 10.9 /*glBegin(GL_QUADS); 10.10 glColor3f(0.6, 0.6, 0.6); 10.11 @@ -134,47 +135,49 @@ 10.12 glVertex2f(0, glutGet(GLUT_WINDOW_HEIGHT)); 10.13 glEnd();*/ 10.14 10.15 - if(imtk_button(IMUID, "red", 30, 50)) { 10.16 + if(imtk_button(IMUID, "red", IMTK_AUTO, IMTK_AUTO)) { 10.17 float color[] = {1, 0.4, 0.3, 1}; 10.18 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 10.19 glutPostRedisplay(); 10.20 } 10.21 - if(imtk_button(IMUID, "blue", 30, 80)) { 10.22 + if(imtk_button(IMUID, "blue", IMTK_AUTO, IMTK_AUTO)) { 10.23 float color[] = {0.3, 0.4, 1, 1}; 10.24 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 10.25 glutPostRedisplay(); 10.26 } 10.27 10.28 itemlist = imtk_create_list("teapot", "torus", "sphere", NULL); 10.29 - if((objsel = imtk_radiogroup(IMUID, itemlist, prev_sel, 30, 120)) != prev_sel) { 10.30 + if((objsel = imtk_radiogroup(IMUID, itemlist, prev_sel, IMTK_AUTO, IMTK_AUTO)) != prev_sel) { 10.31 prev_sel = objsel; 10.32 glutPostRedisplay(); 10.33 } 10.34 imtk_free_list(itemlist); 10.35 10.36 - imtk_textbox(IMUID, textbuf, sizeof textbuf, 30, 200); 10.37 - imtk_textbox(IMUID, textbuf2, sizeof textbuf2, 30, 250); 10.38 + imtk_textbox(IMUID, textbuf, sizeof textbuf, IMTK_AUTO, IMTK_AUTO); 10.39 + imtk_textbox(IMUID, textbuf2, sizeof textbuf2, IMTK_AUTO, IMTK_AUTO); 10.40 10.41 - if((bnshow = imtk_checkbox(IMUID, "show hidden button", 30, 300, bnshow))) { 10.42 - if(imtk_button(IMUID, "yellow", 50, 340)) { 10.43 + if((bnshow = imtk_checkbox(IMUID, "show hidden button", IMTK_AUTO, IMTK_AUTO, bnshow))) { 10.44 + if(imtk_button(IMUID, "yellow", IMTK_AUTO, IMTK_AUTO)) { 10.45 float color[] = {0.8, 0.75, 0.3, 1}; 10.46 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 10.47 glutPostRedisplay(); 10.48 } 10.49 } 10.50 10.51 - val = imtk_slider(IMUID, angle, 0.0, 360.0, 30, 390); 10.52 + val = imtk_slider(IMUID, angle, 0.0, 360.0, IMTK_AUTO, IMTK_AUTO); 10.53 if(val != angle) { 10.54 angle = val; 10.55 glutPostRedisplay(); 10.56 } 10.57 10.58 - imtk_progress(IMUID, val / 360.0, 30, 420); 10.59 + imtk_progress(IMUID, val / 360.0, IMTK_AUTO, IMTK_AUTO); 10.60 10.61 - imtk_label("alpha:", 24, 473); 10.62 - imtk_set_alpha(imtk_slider(IMUID, imtk_get_alpha(), 0.0, 1.0, 60, 470)); 10.63 + imtk_layout_dir(IMTK_HORIZONTAL); 10.64 + imtk_label("alpha:", IMTK_AUTO, IMTK_AUTO); 10.65 + imtk_set_alpha(imtk_slider(IMUID, imtk_get_alpha(), 0.0, 1.0, IMTK_AUTO, IMTK_AUTO)); 10.66 + imtk_layout_dir(IMTK_VERTICAL); 10.67 10.68 - if(imtk_button(IMUID, "Quit", 30, 500)) { 10.69 + if(imtk_button(IMUID, "Quit", IMTK_AUTO, IMTK_AUTO)) { 10.70 exit(0); 10.71 } 10.72