swk

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

commit ab43f010479fc493e5ef3b21762924a8dc5720b9
parent 8b8592e0ddfbb6cf903fecd4de0bcb068c555a7d
Author: pancake <pancake@nopcode.org>
Date:   Fri,  7 May 2010 12:18:48 +0200

initial import of ui.c (ascii-art UI description parser)
install missing swk.h
clean warnings
Diffstat:
Makefile | 8+++++++-
README | 8+++++---
gi_sdl.c | 37+++++++++++++++++++++----------------
test.c | 23+++++++++++++++++++++++
ui.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 163 insertions(+), 20 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,6 +3,7 @@ CFLAGS?=-Wall -g -std=c99 VERSION=0.1 DESTDIR?= PREFIX?=${DESTDIR}/usr/local +INCDIR?=${PREFIX}/include LIBDIR?=${PREFIX}/lib CFLAGS+=-I. @@ -13,7 +14,7 @@ GI_LIBS=-lSDL -lSDL_ttf -lSDL_image GI_OBJS=gi_${GI}.o GI_SRCS=gi_${GI}.c -all: static shared test +all: static shared test ui config.h: cp config.def.h config.h @@ -21,10 +22,15 @@ config.h: test: config.h test.o libswk.a ${CC} test.o -o test libswk.a ${GI_LIBS} +ui: ui.o + ${CC} ui.o -o ui libswk.a ${GI_LIBS} + clean: rm -f swk.pc swk.mk libswk.a libswk.so test.o swk.o test ${GI_OBJS} install: + mkdir -p ${DESTDIR}/${INCDIR} + cp swk.h ${DESTDIR}/${INCDIR} mkdir -p ${DESTDIR}/${LIBDIR} cp libswk.a ${DESTDIR}/${LIBDIR} cp libswk.so ${DESTDIR}/${LIBDIR} diff --git a/README b/README @@ -14,10 +14,12 @@ Maemo n900: apt-get install libsdl1.3-dev libsdl-image1.2-dev libsdl-ttf2.0-0 TODO ==== +* * receive fine-grained x,y in Point? for sketch or imaging stuff is important * support for clipboard (implemented in gi_ backend) * simple way to define callback for buttons instead of reimplementing widget -* scroll on focus +* full text editing widget +* scroll on focus (discuss) * mouse bindings in config.h * allow widgets to define to force size (height, width) * add support to resize images (scaling) @@ -32,8 +34,8 @@ Text format UI design \n -> newline \t -> swk_filler ".." -> swk_label - ---* -> swk_separator - ===* -> newline(-1) + ---- -> swk_separator + ==== -> newline(-1) [..] -> button (..) -> option <.*> -> image diff --git a/gi_sdl.c b/gi_sdl.c @@ -4,13 +4,15 @@ #include <SDL/SDL_image.h> #include <SDL/SDL_ttf.h> #include "swk.h" +#define SWK #include "config.h" #define FONTNAME "Inconsolata.otf" #define BPP 32 #define SDLFLAGS SDL_DOUBLEBUF|SDL_RESIZABLE -static int fs = FONTSIZE; +static int first = 1; +static int fs = FONTSIZE; // TODO: we need fsW and fsH static Uint32 pal[ColorLast]; static SDL_Color fontcolor = { TFCOLOR }; static SDL_Color bgcolor = { BGCOLOR }; @@ -66,13 +68,16 @@ swk_gi_fontsize(int sz) { int swk_gi_init(SwkWindow *w) { - if(SDL_Init(SDL_INIT_VIDEO)) { - fprintf(stderr, "Cannot initialize SDL\n"); - return 0; - } - if(TTF_Init()==-1) { - fprintf(stderr, "Cannot initialize TTF: %s\n", TTF_GetError()); - return 0; + if(first) { + if(SDL_Init(SDL_INIT_VIDEO)) { + fprintf(stderr, "Cannot initialize SDL\n"); + return 0; + } + if(TTF_Init()==-1) { + fprintf(stderr, "Cannot initialize TTF: %s\n", TTF_GetError()); + return 0; + } + first = 0; } SDL_SetVideoMode(w->r.w, w->r.h, BPP, SDLFLAGS); // double init is necesary to get window size @@ -245,8 +250,8 @@ swk_gi_fill(Rect r, int color, int lil) { area.w -= (s*2); area.h -= (s*2); } - if (!area.w) area.w = 1; - if (!area.h) area.h = 1; + if(!area.w) area.w = 1; + if(!area.h) area.h = 1; SDL_FillRect(screen, &area, pal[color]); } @@ -281,17 +286,17 @@ swk_gi_text(Rect r, const char *text) { void swk_gi_img(Rect r, void *img) { - SDL_Surface *s = (SDL_Surface*)img; - SDL_Rect area = { r.x*fs, r.y*fs, r.w*fs, r.h*fs }; - area.x++; - area.y++; - if(s) SDL_BlitSurface(s, NULL, screen, &area); + if(img) { + SDL_Rect area = { r.x*fs, r.y*fs, r.w*fs, r.h*fs }; + area.x++; area.y++; + SDL_BlitSurface((SDL_Surface*)img, NULL, screen, &area); + } } /* image api */ void* swk_gi_img_new(int w, int h, int color) { - return SDL_CreateRGBSurface(NULL, (w*fs)-2, (h*fs)-2, BPP, 0, 0, 0, 0); + return (void *)SDL_CreateRGBSurface(0, (w*fs)-2, (h*fs)-2, BPP, 0, 0, 0, 0); } void* diff --git a/test.c b/test.c @@ -78,6 +78,28 @@ static void mybutton_about(SwkEvent *e) { } swk_button(e); } +//--------- +static SwkBox scrollwin[] = { + SWK_BOX_NEWLINE(0), + { .cb=swk_label, .text="Scroll to change value", }, + SWK_BOX_NEWLINE(1), + { .cb=swk_separator }, + { .cb=swk_label, .text=".." }, + SWK_BOX_NEWLINE(1), + { .cb=swk_label, .text="bin" }, + SWK_BOX_NEWLINE(1), + { .cb=swk_label, .text="sbin" }, + SWK_BOX_NEWLINE(-1), + { .cb=NULL } +}; + +static void mybutton_numscroll(SwkEvent *e) { + if(e->type == EClick) { + e->win->boxes = scrollwin; + swk_update(e->win); + } + swk_button(e); +} static SwkBox helloworld[] = { { .cb=swk_label, .text="Press a button", }, @@ -112,6 +134,7 @@ static SwkBox helloworld[] = { SWK_BOX_NEWLINE(2), { .cb=swk_label, .text="--swktest", }, { .cb=mybutton_about, .text="about" }, + { .cb=mybutton_numscroll, .text="num" }, { .cb=NULL } }; diff --git a/ui.c b/ui.c @@ -0,0 +1,107 @@ +/* See LICENSE file for copyright and license details. */ +// ascii-art user interface // +#if 0 + {HelloWorld + 'Press a button' + ---------------- + (save password) + (store options) + [Ok] [Cancel] + ================ + 'This is new' + <image.png> + } +#endif + +#include <swk.h> +#include <stdio.h> + +// TODO: Rename to swk_win_ swk_window_ ? +void +swk_ui_free(SwkWindow *w) { + // leaks in box->text ? + free(w->boxes); + free(w->title); + free(w); +} + +SwkWindow * +swk_ui(const char *text) { + SwkBox *b; + SwkWindow *w = (SwkWindow*)malloc(sizeof(SwkWindow)); + int sz, stri = 0, mode = 0; + char str[128]; + const char *ptr = text; + + if(!w) return NULL; + memset(w, 0, sizeof(SwkWindow)); + + // TODO: count widgets and allocate stuff + for(sz=0; ptr && *ptr; ptr++) { + // TODO + switch(*ptr) { + case '\n': + case '[': + case '{': + case '\'': + sz++; + sz++; + default: + break; + } + } + printf("WINDETS=%d\n", sz); + + w->box = w->boxes = malloc(128*sizeof(SwkBox)); // Use sz after counting + memset(w->box, 0, 128*sizeof(SwkBox)); + + while(text && *text) { + switch(mode) { + case '\'': + if ((*text=='\''&&str[stri-1]!='\\') || *text=='\n') { + printf("label(%s)\n", str); + stri = 0; + mode = 0; + //w->boxes[count++] ... + w->title = strdup(str); + } else { + str[stri++] = *text; + str[stri] = 0; + } + break; + case '{': + if (*text=='}' || *text=='\n') { + printf("WINDOW TITLE(%s)\n", str); + stri = 0; + mode = 0; + w->title = strdup(str); + } else { + str[stri++] = *text; + str[stri] = 0; + } + break; + default: + mode = *text; + break; + } + text++; + } + return w; +} + +#define UI \ + "{Hello World}\n" \ + "'This is a label'\n" \ + "-----------------\n" \ + "^\n" \ + "[yes][no]\n" + +static SwkWindow *w = NULL; + +int main() { + w = swk_ui(UI); + if(!w||!swk_init(w)) + return 1; + swk_loop(w); + return 0; +}