swk

static widget kit
git clone git://git.suckless.org/swk
Log | Files | Refs | README | LICENSE

commit aa3d8ecb8e9c3aa770a8474bcfaef03f43a336f1
parent de43db41e02a8de24fc6060855a50e9d3a9842f7
Author: pancake <pancake@nopcode.org>
Date:   Wed, 21 Apr 2010 23:08:01 +0200

added swk_focus_first()
hook ^[hjkl] and Esc keys
do not append nonprintable chars in swk_entry
align text widgets to their borders
Diffstat:
gi_sdl.c | 30+++++++++++++++---------------
swk.c | 58+++++++++++++++++++++++++++++++++++++++++++++++-----------
swk.h | 1+
test.c | 8+++-----
4 files changed, 66 insertions(+), 31 deletions(-)

diff --git a/gi_sdl.c b/gi_sdl.c @@ -1,3 +1,4 @@ +/* See LICENSE file for copyright and license details. */ #include <SDL/SDL.h> #include <SDL/SDL_ttf.h> #include "swk.h" @@ -10,6 +11,7 @@ #define FONTSIZE 14 #define FS FONTSIZE #define BPP 32 +#define SDLFLAGS SDL_DOUBLEBUF|SDL_RESIZABLE /* --- */ static Uint32 pal[ColorLast]; @@ -42,15 +44,15 @@ static void putpixel(int x, int y, Uint32 pixel) { int swk_gi_init(SwkWindow *w) { - if (SDL_Init(SDL_INIT_VIDEO)) { + if(SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "Cannot initialize SDL\n"); return 0; } - if (TTF_Init()==-1) { + if(TTF_Init()==-1) { fprintf(stderr, "Cannot initialize TTF: %s\n", TTF_GetError()); return 0; } - SDL_SetVideoMode(w->r.w, w->r.h, BPP, SDL_DOUBLEBUF|SDL_RESIZABLE); + SDL_SetVideoMode(w->r.w, w->r.h, BPP, SDLFLAGS); SDL_WM_SetCaption(w->title, NULL); screen = SDL_GetVideoSurface(); SDL_EnableUNICODE(1); @@ -59,7 +61,7 @@ swk_gi_init(SwkWindow *w) { pal[ColorBG] = SDL_MapRGB(screen->format, BGCOLOR); pal[ColorHI] = SDL_MapRGB(screen->format, HICOLOR); font = TTF_OpenFont(FONTNAME, FONTSIZE); - if (font == NULL) { + if(font == NULL) { fprintf(stderr, "Cannot open font '%s'\n", FONTNAME); return 0; } else TTF_SetFontStyle(font, TTF_STYLE_BOLD); @@ -68,7 +70,6 @@ swk_gi_init(SwkWindow *w) { int swk_gi_update(SwkWindow *w) { - SDL_SetVideoMode(screen->w, screen->h, BPP, SDL_DOUBLEBUF|SDL_RESIZABLE); screen = SDL_GetVideoSurface(); w->r.w = screen->w / FS; w->r.h = screen->h / FS; @@ -86,7 +87,7 @@ static SDL_Event lastev = {.type=-1}; int swk_gi_has_event(SwkWindow *w) { - if (!has_event) + if(!has_event) has_event = SDL_PollEvent(&lastev); return has_event; } @@ -99,13 +100,12 @@ swk_gi_event(SwkWindow *w, int dowait) { if(has_event) event = lastev; else has_event = SDL_WaitEvent(&event); - if (has_event); + if(has_event); switch(event.type) { default: ret = NULL; break; case SDL_VIDEORESIZE: fprintf(stderr, "resize %d %d\n", event.resize.w, event.resize.h); - SDL_SetVideoMode(event.resize.w, event.resize.h, - 32, SDL_DOUBLEBUF|SDL_RESIZABLE); + SDL_SetVideoMode(event.resize.w, event.resize.h, BPP, SDLFLAGS); case SDL_VIDEOEXPOSE: ret->type = EExpose; ret->data.expose.x = ret->data.expose.y = \ @@ -126,7 +126,7 @@ swk_gi_event(SwkWindow *w, int dowait) { fprintf(stderr, "event: click %d\n", event.button.button); break; case SDL_KEYDOWN: - if (ret->data.key.keycode != 0 && event.key.keysym.unicode != 0) { + if(ret->data.key.keycode != 0 && event.key.keysym.unicode != 0) { ret->type = EKey; ret->data.key.keycode = event.key.keysym.unicode; ret->data.key.modmask = 0; @@ -170,9 +170,9 @@ swk_gi_line(int x1, int y1, int x2, int y2, int color) { x1 *= FS; y1 *= FS; x2 *= FS; y2 *= FS; - if (x2==0) for(i=0;i<y2;i++) putpixel(x1, y1+i, pal[color]); + if(x2==0) for(i=0;i<y2;i++) putpixel(x1, y1+i, pal[color]); else - if (y2==0) for(i=0;i<x2;i++) putpixel(x1+i, y1, pal[color]); + if(y2==0) for(i=0;i<x2;i++) putpixel(x1+i, y1, pal[color]); } void @@ -191,10 +191,10 @@ swk_gi_rect(Rect r, int color) { void swk_gi_text(Rect r, const char *text) { - if (*text) { + if(*text) { SDL_Surface *ts = TTF_RenderText_Solid(font, text, fontcolor); - if (ts) { - SDL_Rect to = { (r.x+1)*FS, r.y*FS, ts->w, ts->h }; + if(ts) { + SDL_Rect to = { (r.x)*FS, r.y*FS, ts->w, ts->h }; SDL_BlitSurface(ts, NULL, screen, &to); SDL_FreeSurface(ts); } else fprintf(stderr, "Cannot render string (%s)\n", text); diff --git a/swk.c b/swk.c @@ -4,12 +4,13 @@ #include <stdlib.h> #include "swk.h" +// move into SwkWindow* ? static int running = 0; int swk_init(SwkWindow *w) { w->_e.win = w; - w->box = w->boxes; + swk_focus_first(w); if(w->r.w == 0 || w->r.h == 0) { w->r.w = 640; w->r.h = 480; @@ -47,7 +48,7 @@ swk_loop(SwkWindow *w) { do { if((e = swk_next_event(w))) swk_handle_event(e); - } while (!e || e->type != EQuit); + } while(!e || e->type != EQuit); } static void swk_fit_row(SwkWindow *w, SwkBox *a, SwkBox *b, int y) { @@ -101,7 +102,24 @@ swk_handle_event(SwkEvent *e) { SwkBox *b; switch(e->type) { case EKey: - // TODO: handle ^Y and ^P to copypasta box->text + // TODO: ^F ullscreen? handle ^Y and ^P to copypasta box->text + // ^A focus first widget, ^E focus last widget ? + if(e->data.key.modmask == 2) { + switch(e->data.key.keycode) { + case 8: + swk_focus_first(e->win); + break; + case 10: + swk_focus_next(e->win); + break; + case 11: + swk_focus_prev(e->win); + break; + case 12: + e->type = EClick; + break; + } + } else if(e->data.key.keycode == 9) { // TAB if(e->data.key.modmask) swk_focus_prev(e->win); @@ -111,6 +129,11 @@ swk_handle_event(SwkEvent *e) { if(e->data.key.keycode == 13) { // ENTER e->box = e->win->box; e->type = EClick; + } else + if(e->data.key.keycode == 27) { // ESC + e->box = e->win->box; + e->type = EQuit; + swk_exit(); } // send key to focused box e->box = e->win->box; @@ -149,6 +172,15 @@ swk_handle_event(SwkEvent *e) { } void +swk_focus_first(SwkWindow *w) { + w->box = w->boxes; + while(w->box->cb == swk_filler) + w->box++; + if(w->box->cb == NULL) + w->box = w->boxes; +} + +void swk_focus_next(SwkWindow *w) { w->box++; if(w->box->cb == NULL) @@ -156,7 +188,7 @@ swk_focus_next(SwkWindow *w) { while(w->box->cb == swk_filler) w->box++; if(w->box->cb == NULL) - w->box = w->boxes; + swk_focus_first(w); } void @@ -167,7 +199,7 @@ swk_focus_prev(SwkWindow *w) { w->box--; } else { w->box--; - while (w->box->cb == swk_filler) { + while(w->box->cb == swk_filler) { w->box--; if(w->box < w->boxes) { w->box = w->boxes; @@ -202,18 +234,21 @@ swk_entry(SwkEvent *e) { case EKey: key = e->data.key.keycode; if(key == 8) { - ptr = strdup (e->box->text); + ptr = (char*)malloc(strlen(e->box->text)+2); + strcpy(ptr, e->box->text); if(e->box->data) free(e->box->text); if((len = strlen (ptr))>0) ptr[len-1] = '\0'; e->box->text = e->box->data = ptr; } else { - ptr = (char*)malloc(strlen(e->box->text)+2); - sprintf(ptr, "%s%c", e->box->text, e->data.key.keycode); - if(e->box->data) - free(e->box->text); - e->box->text = e->box->data = ptr; + if(key>=' '&&key<='~') { + ptr = (char*)malloc(strlen(e->box->text)+2); + sprintf(ptr, "%s%c", e->box->text, e->data.key.keycode); + if(e->box->data) + free(e->box->text); + e->box->text = e->box->data = ptr; + } } break; default: @@ -231,6 +266,7 @@ swk_button(SwkEvent *e) { if(e->win->box == e->box) swk_gi_rect(r, ColorHI); else swk_gi_rect(r, ColorFG); + r.x++; swk_gi_text(r, e->box->text); break; default: diff --git a/swk.h b/swk.h @@ -73,6 +73,7 @@ SwkEvent *swk_next_event(SwkWindow *w); int swk_has_event(SwkWindow *w); void swk_handle_event(SwkEvent *e); +void swk_focus_first(SwkWindow *w); void swk_focus_next(SwkWindow *w); void swk_focus_prev(SwkWindow *w); diff --git a/test.c b/test.c @@ -8,16 +8,14 @@ static SwkBox helloworld[]; static void mybutton(SwkEvent *e) { if (e->type == EClick) { sprintf(text, "Do it again %d times\n", count); - helloworld[1].text = text; - if (count-- == 0) + helloworld[0].text = text; + if(count-- == 0) swk_exit(); } swk_button(e); } - static SwkBox helloworld[] = { - SWK_BOX_NEWLINE(1), { .cb=swk_label, .text="Press a button", }, SWK_BOX_NEWLINE(2), { .cb=swk_label, .text="Username:", }, @@ -42,7 +40,7 @@ main() { .title="Hello World", .boxes=helloworld }; - if (!swk_init(&w)) + if(!swk_init(&w)) return 1; swk_loop(&w); return 0;