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;