commit 4f51b8003075b192d1e5237cce4b5ce4a9109420
parent ab0626c9a9a78fe128fbbdaa1216227b9990a004
Author: pancake <pancake@nopcode.org>
Date: Tue, 27 Apr 2010 01:42:50 +0200
added FONTBOLD define in config.def.h
use gray instead of white for font color
fix overflow in putpixel function (slow but ok)
use antialiased fonts with SDL_ttf
embed 'running' variable into SwkWindow
swk_gi_fill now supports 'lil' mode (small box)
fix overflow in text rendering
vertical padding now fits better to bottom
swk_exit gets the SwkWindow instance
swk_option supports single or multioption selection mode
Diffstat:
5 files changed, 84 insertions(+), 32 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -2,6 +2,7 @@
/* appearance */
#define FONTSIZE 14
+#define FONTBOLD 1
#define WINWIDTH 640
#define WINHEIGHT 480
// SDL
@@ -10,7 +11,7 @@
//#define SWK_COLOR(r,g,b) r##g##b
#define HICOLOR SWK_COLOR(0,66,ff)
-#define FGCOLOR SWK_COLOR(ff,ff,ff)
+#define FGCOLOR SWK_COLOR(e0,e0,e0)
#define BGCOLOR SWK_COLOR(00,00,00)
#define TFCOLOR SWK_COLOR(cc,cc,cc)
diff --git a/gi_sdl.c b/gi_sdl.c
@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
+#define _BSD_SOURCE // strdup
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "swk.h"
@@ -11,6 +12,7 @@
static Uint32 pal[ColorLast];
static SDL_Color fontcolor = { TFCOLOR };
+static SDL_Color bgcolor = { BGCOLOR };
static SDL_Surface *screen = NULL;
static TTF_Font *font = NULL;
/* FIXME: put ugly statics into void *aux of SwkWindow */
@@ -18,9 +20,13 @@ static int has_event = 0;
static SDL_Event lastev = { .type=-1 };
static void putpixel(int x, int y, Uint32 pixel) {
- int bpp = screen->format->BytesPerPixel;
- Uint8 *p;
- p = (Uint8 *)screen->pixels + y * screen->pitch + x * bpp;
+ int delta, bpp = screen->format->BytesPerPixel;
+ Uint8 *p, *pend;
+ delta = y * screen->pitch + x * bpp;
+ p = (Uint8 *)screen->pixels + delta;
+ pend = (Uint8 *)screen->pixels + ((screen->h*screen->w)*bpp);
+ if ((p<((Uint8 *)screen->pixels)) || (p>=pend))
+ return;
#if BPP == 8
*p = pixel;
#elif BPP == 16
@@ -58,17 +64,21 @@ swk_gi_init(SwkWindow *w) {
pal[ColorFG] = SDL_MapRGB(screen->format, FGCOLOR);
pal[ColorBG] = SDL_MapRGB(screen->format, BGCOLOR);
pal[ColorHI] = SDL_MapRGB(screen->format, HICOLOR);
- font = TTF_OpenFont(FONTNAME, FONTSIZE);
+ font = TTF_OpenFont(FONTNAME, FS);
if(font == NULL) {
fprintf(stderr, "Cannot open font '%s'\n", FONTNAME);
return 0;
- } else TTF_SetFontStyle(font, TTF_STYLE_BOLD);
+ } else
+ if (FONTBOLD)
+ TTF_SetFontStyle(font, TTF_STYLE_BOLD);
return 1;
}
int
swk_gi_update(SwkWindow *w) {
screen = SDL_GetVideoSurface();
+ if (screen == NULL)
+ return 0;
w->r.w = screen->w / FS;
w->r.h = screen->h / FS;
return 1;
@@ -136,6 +146,7 @@ swk_gi_event(SwkWindow *w, int dowait) {
fprintf(stderr, "event: key %d %d\n",
ret->data.key.modmask, ret->data.key.keycode);
} else {
+ // TODO key aliases defined in config.h
switch(event.key.keysym.sym) {
case 273:
ret->data.key.keycode = KUp;
@@ -182,8 +193,15 @@ swk_gi_line(int x1, int y1, int x2, int y2, int color) {
}
void
-swk_gi_fill(Rect r, int color) {
+swk_gi_fill(Rect r, int color, int lil) {
SDL_Rect area = { r.x*FS, r.y*FS, r.w*FS, r.h*FS };
+ if (lil) {
+ const int s = FS/4;
+ area.x += s;
+ area.y += s;
+ area.w -= (s*2);
+ area.h -= (s*2);
+ }
SDL_FillRect(screen, &area, pal[color]);
}
@@ -197,12 +215,21 @@ swk_gi_rect(Rect r, int color) {
void
swk_gi_text(Rect r, const char *text) {
+ char *ptr = NULL;
+ int len = strlen(text);
+ int w = (int)((double)r.w * 1.6); // hacky
+ if (len>w) {
+ ptr = strdup(text);
+ text = (const char *)ptr;
+ ptr[w] = '\0';
+ }
if(*text) {
- SDL_Surface *ts = TTF_RenderText_Solid(font, text, fontcolor);
+ SDL_Surface *ts = TTF_RenderText_Shaded(font, text, fontcolor, bgcolor);
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);
}
+ free(ptr);
}
diff --git a/swk.c b/swk.c
@@ -5,9 +5,6 @@
#include "swk.h"
#include "config.h"
-// move into SwkWindow* ?
-static int running = 0;
-
int
swk_init(SwkWindow *w) {
w->_e.win = w;
@@ -18,10 +15,10 @@ swk_init(SwkWindow *w) {
w->r.h = WINHEIGHT;
}
if(swk_gi_init(w)) {
- running = 1;
+ w->running = 1;
swk_update(w);
}
- return running;
+ return w->running;
}
void
@@ -36,12 +33,12 @@ swk_update(SwkWindow *w) {
b->cb(&w->_e);
}
swk_gi_flip();
- } else running = 0;
+ } else w->running = 0;
}
void
-swk_exit(void) {
- running = 0;
+swk_exit(SwkWindow *w) {
+ w->running = 0;
}
void
@@ -96,7 +93,7 @@ swk_fit(SwkWindow *w) {
} else {
swk_fit_row(w, b2, b, y);
b2 = b+1;
- y += (w->r.h-countrows(b2));
+ y += 1+(w->r.h-countrows(b2));
if (y<0) {
fprintf(stderr, "overflow: must scroll\n");
y=0;
@@ -120,7 +117,7 @@ swk_focus_activate(SwkWindow *w) {
SwkEvent *
swk_next_event(SwkWindow *w) {
- if(running)
+ if(w->running)
return swk_gi_event(w, 1);
w->_e.type = EQuit;
w->_e.win = w;
@@ -144,7 +141,7 @@ swk_handle_event(SwkEvent *e) {
if (e->data.key.keycode==27) {
e->box = e->win->box;
e->type = EQuit;
- swk_exit();
+ swk_exit(e->win);
break;
}
// send key to focused box
@@ -222,16 +219,17 @@ swk_focus_prev(SwkWindow *w) {
}
}
-/* widgets */
+/* -- widgets -- */
+
void
swk_label(SwkEvent *e) {
Rect r;
switch(e->type) {
case EExpose:
r = e->box->r;
+ swk_gi_text(r, e->box->text);
if(e->win->box == e->box)
swk_gi_line(r.x, r.y+1, r.w, 0, ColorHI);
- swk_gi_text(r, e->box->text);
break;
default:
break;
@@ -302,11 +300,12 @@ swk_button(SwkEvent *e) {
switch(e->type) {
case EExpose:
r = e->box->r;
+ r.x++;
+ swk_gi_text(r, e->box->text);
+ r.x--;
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:
break;
@@ -320,19 +319,24 @@ swk_filler(SwkEvent *e) {
void
swk_option(SwkEvent *e) {
- SwkBox **b = (SwkBox**)e->box->data;
Rect r;
+ SwkBox **b = (SwkBox**)e->box->data;
switch(e->type) {
case EClick:
- *b = (e->box==*b)?NULL:e->box;
+ if (b==(void*)0) e->box->data = (void*)1;
+ else if (b==(void*)1) e->box->data = (void*)0;
+ else *b = (e->box==*b)?NULL:e->box;
break;
case EExpose:
r = e->box->r;
if(e->win->box == e->box)
swk_gi_line(r.x, r.y+1, r.w, 0, ColorHI);
r.w = r.h = 1;
- if(e->box==*b) swk_gi_fill(r, ColorFG);
- else swk_gi_rect(r, ColorFG);
+ if (b==(void*)1) swk_gi_fill(r, ColorHI, 1);
+ else if (b==(void*)0) swk_gi_fill(r, ColorFG, 1);
+ else if (e->box==*b) swk_gi_fill(r, ColorHI, 1);
+ else swk_gi_fill(r, ColorFG, 1);
+ r = e->box->r;
r.x += 2;
swk_gi_text(r, e->box->text);
break;
@@ -340,3 +344,18 @@ swk_option(SwkEvent *e) {
break;
}
}
+
+void
+swk_separator(SwkEvent *e) {
+ Rect r;
+ switch(e->type) {
+ case EExpose:
+ r = e->box->r;
+ if(e->win->box == e->box)
+ swk_gi_line(r.x, r.y+1, r.w, 0, ColorHI);
+ else swk_gi_line(r.x, r.y+1, r.w, 0, ColorFG);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/swk.h b/swk.h
@@ -66,6 +66,7 @@ struct SwkBox {
struct SwkWindow {
char *title;
+ int running;
Rect r;
SwkBox *boxes;
/* internal use */
@@ -75,7 +76,7 @@ struct SwkWindow {
int swk_init(SwkWindow *w);
void swk_update(SwkWindow *w);
-void swk_exit(void);
+void swk_exit(SwkWindow *w);
void swk_fit(SwkWindow *w);
void swk_loop(SwkWindow *w);
SwkEvent *swk_next_event(SwkWindow *w);
@@ -93,6 +94,7 @@ void swk_entry(SwkEvent *e);
void swk_password(SwkEvent *e);
void swk_filler(SwkEvent *e);
void swk_option(SwkEvent *e);
+void swk_separator(SwkEvent *e);
/* graphic backend */
@@ -107,6 +109,6 @@ void swk_gi_clear();
void swk_gi_flip();
void swk_gi_line(int x1, int y1, int x2, int y2, int color);
-void swk_gi_fill(Rect r, int color);
+void swk_gi_fill(Rect r, int color, int lil);
void swk_gi_rect(Rect r, int color);
void swk_gi_text(Rect r, const char *text);
diff --git a/test.c b/test.c
@@ -14,27 +14,30 @@ static void mybutton(SwkEvent *e) {
printf("Option: none\n");
else printf("Option: %s\n", opt->text);
if(count-- == 0)
- swk_exit();
+ swk_exit(e->win);
}
swk_button(e);
}
static SwkBox helloworld[] = {
{ .cb=swk_label, .text="Press a button", },
+ SWK_BOX_NEWLINE(1),
+ { .cb=swk_separator },
SWK_BOX_NEWLINE(2),
{ .cb=swk_label, .text="Username:", },
{ .cb=swk_entry, .text="____", },
- { .cb=swk_filler, },
SWK_BOX_NEWLINE(1),
{ .cb=swk_label, .text="Password:", },
{ .cb=swk_password, .text="1234", },
- { .cb=swk_filler, },
SWK_BOX_NEWLINE(-1),
{ .cb=mybutton, .text="yes" },
{ .cb=mybutton, .text="no" },
{ .cb=swk_filler, },
SWK_BOX_NEWLINE(2),
+ { .cb=swk_option, .text="zoot" },
+ SWK_BOX_NEWLINE(1),
{ .cb=swk_option, .text="remember values", .data=&opt },
+// { .cb=swk_option, .text="null" },
SWK_BOX_NEWLINE(1),
{ .cb=swk_option, .text="pasta barata", .data=&opt },
SWK_BOX_NEWLINE(5),