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