commit 3b4b476d19e68b3cec52ea735742481356256e77
parent 175d41a26f55a312f2c90418b97a29b6bf09a915
Author: pancake <pancake@nopcode.org>
Date: Fri, 11 Jun 2010 00:47:22 +0200
add support for a second column
hook Control-{H,L} to move left/right the column
one/two column setup can be changed in runtime
fix string corruption issue swk_gi_text
make SCROLLSPEED configurable
Diffstat:
8 files changed, 135 insertions(+), 87 deletions(-)
diff --git a/TODO b/TODO
@@ -1,6 +1,6 @@
TODO
====
- * add support for column breakers { SWK_NEWCOLUMN() }
+ * add support for negative colpos (align to right)
* allow to set absolute font size
* buttons must be 3 line height
* receive fine-grained x,y in Point? for sketch or imaging stuff is important
diff --git a/config.def.h b/config.def.h
@@ -1,6 +1,8 @@
/* See LICENSE file for copyright and license details. */
/* appearance */
+#define SCROLLSPEED 2
+#define COLSPLIT 20
#define FONTSIZE 18
#define FONTBOLD 0
#define WINWIDTH 640
@@ -20,12 +22,14 @@
static SwkKeyBind keys[] = {
{ Ctrl, 'j', swk_focus_next },
{ Ctrl, 'k', swk_focus_prev },
- { Ctrl, 8 , swk_focus_first },
- { Ctrl, 9 , swk_focus_prev },
+ //{ Ctrl, 8 , swk_focus_first },
+ //{ Ctrl, 9 , swk_focus_prev },
+ { Ctrl, 8 , swk_column_move_left },
+ { Ctrl, 12 , swk_column_move_right },
{ 0 , 9 , swk_focus_next },
{ Ctrl, 10 , swk_focus_next },
{ Ctrl, 11 , swk_focus_prev },
- { Ctrl, 12 , swk_focus_activate },
+// { Ctrl, 12 , swk_focus_activate },
{ 0 , KUp, swk_focus_prev },
{ 0 , KDown, swk_focus_next },
{ 0 , 13 , swk_focus_activate },
diff --git a/gi_sdl.c b/gi_sdl.c
@@ -8,7 +8,7 @@
#include "config.h"
#define FONTNAME "Inconsolata.otf"
-#define FONTFACTOR 2.1
+#define FONTFACTOR 2.1 /* XXX */
#define BPP 32
#define SDLFLAGS SDL_DOUBLEBUF|SDL_RESIZABLE
@@ -263,16 +263,16 @@ swk_gi_rect(Rect r, int color) {
void
swk_gi_text(Rect r, const char *text) {
+ const char *tptr = text;
char *ptr = NULL;
int w = (int)((double)r.w * FONTFACTOR);
if(text && *text) {
int len = text?strlen(text):0;
if(len>w) {
- ptr = strdup(text);
- text = (const char *)ptr;
+ tptr = ptr = strdup(text);
ptr[w]='\0';
}
- SDL_Surface *ts = TTF_RenderText_Shaded(font, text, fontcolor, bgcolor);
+ SDL_Surface *ts = TTF_RenderText_Shaded(font, tptr, fontcolor, bgcolor);
if(ts) {
SDL_Rect to = { (r.x)*fs, r.y*fs, ts->w, ts->h };
SDL_BlitSurface(ts, NULL, screen, &to);
diff --git a/swk.c b/swk.c
@@ -13,6 +13,7 @@ static __thread int rendering = 0;
int
swk_use(SwkWindow *win) {
w = win = win->_e.win = win;
+ w->colpos = COLSPLIT;
if(win->box == NULL)
swk_focus_first(w);
if(w->r.w == 0 || w->r.h == 0) {
@@ -30,38 +31,46 @@ void
swk_update() {
char text[8];
int roy, oy, scroll = 0;
+ int col = (w->boxes[1])?((w->colpos>w->r.w)?w->r.w:w->colpos):w->r.w;
if(rendering)
return;
- //printf("boxy %d/%d\n", w->box->r.y, w->r.h);
// TODO: Handle scrollup by widget focus
- if (w->box->r.y > w->r.h)
+ if(w->box->r.y > w->r.h)
setscrollbox(-2);
rendering = 1;
w->_e.type = EExpose;
if(swk_gi_update(w)) {
- SwkBox *b = w->boxes;
+ int count = 2;
+ int orw = w->r.w;
+ SwkBox *b = w->boxes[0];
swk_fit(w);
swk_gi_clear();
- roy = oy = 0;
- for(;b->cb; b++) {
- w->_e.box = b;
- if(b->r.w==-1 && b->r.h==-1 && ((int)(size_t)b->data)<0)
- roy = oy+1;
- if(b->scroll)
- scroll = b->scroll;
- if(roy && b->r.y < roy) {
- sprintf(text, "(%d)", scroll);
- Rect r = w->r;
- r.x = r.w-1;
- r.y = roy;
- r.w = 3;
- swk_gi_text(r, text);
- swk_gi_line(--r.x, roy, r.w, 0, ColorHI);
+ for(w->r.w=col; ; b = w->boxes[1]) {
+ swk_fit(w);
+ roy = oy = 0;
+ for(;b->cb; b++) {
+ w->_e.box = b;
+ if(IS_SCROLLBOX(b))
+ roy = oy+1;
+ if(b->scroll)
+ scroll = b->scroll;
+ if(roy && b->r.y < roy) {
+ Rect r = w->r;
+ r.x = col-1;
+ r.y = roy;
+ r.w = 3;
+ sprintf(text, "(%d)", scroll);
+ swk_gi_text(r, text);
+ swk_gi_line(--r.x, roy, 2, 0, ColorHI);
+ } else b->cb(&w->_e);
+ oy = b->r.y;
}
- else b->cb(&w->_e);
- oy = b->r.y;
+ if(!w->boxes[1] || !--count)
+ break;
+ col = orw-w->col;
}
swk_gi_flip();
+ w->r.w = orw;
}
rendering = 0;
}
@@ -84,19 +93,33 @@ swk_loop() {
void
swk_fontsize_increase() {
swk_gi_fontsize(1);
+ w->colpos--;
swk_update(w);
}
void
swk_fontsize_decrease() {
swk_gi_fontsize(-1);
+ w->colpos++;
+ swk_update(w);
+}
+
+void
+swk_column_move_left() {
+ w->colpos--;
+ swk_update(w);
+}
+
+void
+swk_column_move_right() {
+ w->colpos++;
swk_update(w);
}
static void
setscrollbox(int delta) {
SwkBox *r = NULL;
- SwkBox *b = w->boxes;
+ SwkBox *b = w->boxes[w->col];
for(; b->cb; b++) {
if(IS_SCROLLBOX(b))
r = b;
@@ -108,23 +131,23 @@ setscrollbox(int delta) {
void
swk_scroll_up() {
- setscrollbox(2);
+ w->box = w->boxes[w->col];
+ setscrollbox(SCROLLSPEED);
}
void
swk_scroll_down() {
- setscrollbox(-2);
+ w->box = w->boxes[w->col];
+ setscrollbox(-SCROLLSPEED);
}
static void
-swk_fit_row(SwkBox *a, SwkBox *b, int y) {
- SwkBox *btmp;
- int count = 0, x = 0;
- for(btmp=a; btmp<b; btmp++)
- count++;
+swk_fit_row(SwkBox *a, SwkBox *b, int col, int y) {
+ int x = (col)?w->colpos:0, count = b-a;
if(count) {
int winc = w->r.w / count;
- for(btmp=a; btmp<b; btmp++) {
+ SwkBox *btmp = a;
+ for(; btmp<b; btmp++) {
btmp->r.x = x;
btmp->r.y = y;
btmp->r.w = winc;
@@ -146,24 +169,27 @@ countrows(SwkBox *b) {
void
swk_fit() {
+ int i, x, y, skip, tskip;
SwkBox *b, *b2;
- int x, y = 0, skip = 0;
- int tskip = 0;
- for(b=b2=w->boxes; b->cb; b++) {
- if(b->r.w==-1 && b->r.h==-1) {
- x = (int)(size_t)b->data;
- swk_fit_row(b2, b, y);
- y += x-skip+tskip;
- // vertical align //
- tskip = 0;
- if(x<0) y += w->r.h-countrows(b2);
- b2 = b+1;
- } else
- if(b->r.h>1)
- tskip = b->r.h;
- y += b->scroll;
+ for(i=0;i<2;i++) {
+ skip = tskip = y = 0;
+ for(b=b2=w->boxes[i]; b->cb; b++) {
+ if(b->r.w==-1 && b->r.h==-1) {
+ x = (int)(size_t)b->data;
+ swk_fit_row(b2, b, i, y);
+ y += x-skip+tskip;
+ // vertical align //
+ tskip = 0;
+ if(x<0) y += w->r.h-countrows(b2);
+ b2 = b+1;
+ } else if(b->r.h>1)
+ tskip = b->r.h;
+ y += b->scroll;
+ }
+ swk_fit_row(b2, b, i, y);
+ if(!w->boxes[1])
+ break;
}
- swk_fit_row(b2, b, y);
}
int
@@ -201,7 +227,7 @@ swk_handle_event(SwkEvent *e) {
break;
}
}
- /* XXX: this must be implemented in app? */
+ /* XXX: this must be implemented in app? .. sure */
if(e->data.key.keycode==27) {
e->box = e->win->box;
e->type = EQuit;
@@ -215,7 +241,8 @@ swk_handle_event(SwkEvent *e) {
swk_update();
break;
case EMotion:
- for(b=e->win->boxes; b->cb; b++) {
+ w->col = (e->data.motion.x > w->colpos)?1:0;
+ for(b=e->win->boxes[w->col]; b->cb; b++) {
if(SWK_HIT(b->r, e->data.motion)) {
e->win->box = e->box = b;
b->cb(e);
@@ -234,7 +261,7 @@ swk_handle_event(SwkEvent *e) {
swk_scroll_down(e->win);
break;
default:
- for(b=e->win->boxes; b->cb; b++) {
+ for(b=e->win->boxes[w->col]; b->cb; b++) {
if(SWK_HIT(b->r, e->data.click.point)) {
e->box = e->win->box = b;
e->box->cb(e);
@@ -256,18 +283,18 @@ swk_handle_event(SwkEvent *e) {
void
swk_focus_first() {
- w->box = w->boxes;
+ w->box = w->boxes[w->col];
while(w->box->cb == swk_filler)
w->box++;
if(w->box->cb == NULL)
- w->box = w->boxes;
+ w->box = w->boxes[w->col];
}
void
swk_focus_next() {
w->box++;
if(w->box->cb == NULL)
- w->box = w->boxes;
+ w->box = w->boxes[w->col];
while(w->box->cb == swk_filler)
w->box++;
if(w->box->cb == NULL)
@@ -276,7 +303,7 @@ swk_focus_next() {
void
swk_focus_prev() {
- if(w->box == w->boxes) {
+ if(w->box == w->boxes[w->col]) {
while(w->box->cb)
w->box++;
w->box--;
@@ -284,8 +311,8 @@ swk_focus_prev() {
w->box--;
while(w->box->cb == swk_filler) {
w->box--;
- if(w->box < w->boxes) {
- w->box = w->boxes;
+ if(w->box < w->boxes[w->col]) {
+ w->box = w->boxes[w->col];
swk_focus_prev(w);
return;
}
diff --git a/swk.h b/swk.h
@@ -70,7 +70,9 @@ struct SwkWindow {
char *title;
SwkEventCallback cb;
Rect r;
- SwkBox *boxes;
+ SwkBox *boxes[2];
+ int col;
+ int colpos;
/* internal use */
SwkBox *box;
SwkEvent _e;
@@ -93,8 +95,11 @@ void swk_scroll_up();
void swk_scroll_down();
void swk_fontsize_increase();
void swk_fontsize_decrease();
+void swk_column_move_left();
+void swk_column_move_right();
void swk_button(SwkEvent *e);
+void swk_bigbutton(SwkEvent *e);
void swk_label(SwkEvent *e);
void swk_entry(SwkEvent *e);
void swk_password(SwkEvent *e);
diff --git a/t/test.c b/t/test.c
@@ -30,7 +30,7 @@ static void myprogressbutton(SwkEvent *e) {
pccount+=6;
if(pccount > 100) {
pccount = 0;
- e->win->boxes = helloworld;
+ e->win->boxes[e->win->col] = helloworld;
swk_update(e->win);
}
sprintf(pctext, "%d%%", pccount);
@@ -65,7 +65,7 @@ static SwkBox about[] = {
static void mybutton_about_ok(SwkEvent *e) {
if(e->type == EClick) {
- e->win->boxes = helloworld;
+ e->win->boxes[e->win->col] = helloworld;
swk_update(e->win);
}
swk_button(e);
@@ -73,7 +73,7 @@ static void mybutton_about_ok(SwkEvent *e) {
static void mybutton_about(SwkEvent *e) {
if(e->type == EClick) {
- e->win->boxes = about;
+ e->win->boxes[e->win->col] = about;
swk_update(e->win);
}
swk_button(e);
@@ -96,7 +96,7 @@ static SwkBox scrollwin[] = {
static void mybutton_numscroll(SwkEvent *e) {
if(e->type == EClick) {
- e->win->boxes = scrollwin;
+ e->win->boxes[e->win->col] = scrollwin;
swk_update(e->win);
}
swk_button(e);
@@ -139,11 +139,18 @@ static SwkBox helloworld[] = {
{ .cb=NULL }
};
+static SwkBox column[] = {
+ { .cb=swk_label, .text="this is a column", },
+ SWK_BOX_NEWLINE(-1),
+ { .cb=swk_label, .text="text in column", },
+ { .cb=NULL }
+};
+
int
main() {
SwkWindow w = {
.title="Hello World",
- .boxes=helloworld,
+ .boxes={ helloworld, column },
.box=helloworld+10,
//.r = { 0, 0, 320, 240 },
/*
diff --git a/t/tlock.c b/t/tlock.c
@@ -60,13 +60,17 @@ static void init_alarm() {
int main() {
SwkWindow w = {
.title="touch lock",
- .boxes=contents,
+ .boxes={contents,NULL},
.box=contents,
+ .r={200, 100, 800, 500} // x,y, w,h
};
if(!swk_use(&w))
return 1;
init_alarm();
swk_fontsize_increase();
+ swk_fontsize_increase();
+ swk_fontsize_increase();
+ swk_fontsize_increase();
swk_loop();
return 0;
}
diff --git a/t/ui.c b/t/ui.c
@@ -24,7 +24,7 @@ SwkBox *b = swk_ui_get(w, "ok");
void
swk_ui_free(SwkWindow *w) {
// leaks in box->text ?
- free(w->boxes);
+ free(w->boxes[1]);
free(w->title);
free(w);
}
@@ -56,7 +56,8 @@ swk_ui(const char *text) {
}
printf("WINDETS=%d\n", sz);
- w->box = w->boxes = (SwkBox*)malloc(128*sizeof(SwkBox)); // Use sz after counting
+ w->box = w->boxes[0] = (SwkBox*)malloc(128*sizeof(SwkBox)); // Use sz after counting
+ w->boxes[1] = NULL;
memset(w->box, 0, 128*sizeof(SwkBox));
while(text && *text) {
@@ -65,8 +66,8 @@ swk_ui(const char *text) {
if ((*text=='\''&&str[stri-1]!='\\') || *text=='\n') {
printf("label(%s)\n", str);
stri = mode = 0;
- w->boxes[count].cb = swk_label;
- w->boxes[count].text = strdup (str);
+ w->boxes[w->col][count].cb = swk_label;
+ w->boxes[w->col][count].text = strdup (str);
count++;
} else {
str[stri++] = *text;
@@ -77,8 +78,8 @@ swk_ui(const char *text) {
if ((*text=='>'&&str[stri-1]!='\\') || *text=='\n') {
printf("image(%s)\n", str);
stri = mode = 0;
- w->boxes[count].cb = swk_image;
- w->boxes[count].text = strdup (str);
+ w->boxes[w->col][count].cb = swk_image;
+ w->boxes[w->col][count].text = strdup (str);
count++;
} else {
str[stri++] = *text;
@@ -87,7 +88,7 @@ swk_ui(const char *text) {
break;
case '*':
if (*text=='\n') {
- w->boxes[count].cb = swk_filler;
+ w->boxes[w->col][count].cb = swk_filler;
count++;
mode = 0;
}
@@ -95,14 +96,14 @@ swk_ui(const char *text) {
case '=':
if (*text=='\n') {
SwkBox b = SWK_BOX_NEWLINE(-1);
- w->boxes[count] = b;
+ w->boxes[w->col][count] = b;
count++;
mode = 0;
}
break;
case '-':
if (*text=='\n') {
- w->boxes[count].cb = swk_separator;
+ w->boxes[w->col][count].cb = swk_separator;
count++;
mode = 0;
}
@@ -111,8 +112,8 @@ swk_ui(const char *text) {
if ((*text==')'&&str[stri-1]!='\\') || *text=='\n') {
printf("option(%s)\n", str);
stri = mode = 0;
- w->boxes[count].cb = swk_option;
- w->boxes[count].text = strdup (str);
+ w->boxes[w->col][count].cb = swk_option;
+ w->boxes[w->col][count].text = strdup (str);
count++;
} else {
str[stri++] = *text;
@@ -124,12 +125,12 @@ swk_ui(const char *text) {
stri = mode = 0;
if (*str=='*') {
printf("pass(%s)\n", str);
- w->boxes[count].cb = swk_password;
- w->boxes[count].text = "";
+ w->boxes[w->col][count].cb = swk_password;
+ w->boxes[w->col][count].text = "";
} else {
printf("entry(%s)\n", str);
- w->boxes[count].cb = swk_entry;
- w->boxes[count].text = strdup (str);
+ w->boxes[w->col][count].cb = swk_entry;
+ w->boxes[w->col][count].text = strdup (str);
}
count++;
} else {
@@ -141,8 +142,8 @@ swk_ui(const char *text) {
if ((*text==']'&&str[stri-1]!='\\') || *text=='\n') {
printf("button(%s)\n", str);
stri = mode = 0;
- w->boxes[count].cb = swk_button;
- w->boxes[count].text = strdup (str);
+ w->boxes[w->col][count].cb = swk_button;
+ w->boxes[w->col][count].text = strdup (str);
count++;
} else {
str[stri++] = *text;
@@ -162,7 +163,7 @@ swk_ui(const char *text) {
default:
if (*text=='\n') {
SwkBox b = SWK_BOX_NEWLINE(1);
- w->boxes[count] = b;
+ w->boxes[w->col][count] = b;
count++;
} else {
mode = *text;