swk

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

commit e1eecfd69f01deb4c423597a12bbb857783a6a52
Author: arg@localhost.localdomain <unknown>
Date:   Sat, 27 Mar 2010 22:10:33 +0000

initial stuff
Diffstat:
Makefile | 24++++++++++++++++++++++++
README | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
swk.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
swk.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
test.c | 17+++++++++++++++++
5 files changed, 246 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,24 @@ +CC?=gcc +DESTDIR?= +PREFIX?=${DESTDIR}/usr/local +LIBDIR?=${PREFIX}/lib + +all: static test + +test.o: + ${CC} -I. test.c -c -o test.o + +test: test.o + ${CC} test.o -o test libswk.a + +clean: + rm -f libswk.a test.o swk.o test + +install: + cp ${DESTDIR}/${LIBDIR} + +static: libswk.a + +libswk.a: swk.o + rm -f libswk.a + ar qcvf libswk.a swk.o diff --git a/README b/README @@ -0,0 +1,90 @@ +swk - the static widget toolkit +================================ +swk is a dynamic widget toolkit that provides the ability to create +keyboard-driven textual UIs very quickly on top of supported(*) window systems + +Historically the swk domain is covered by (n)curses based applications that run +completely in text mode. But this approach has numerous disadvatages, such as +archaic cursor handling, slow screen redraws, limitations through the use of +just text and characters, different behaviour in different terminal modes, and +so on. + +On the other hand full-featured UI toolkits like GTK or Qt are far too complex +and bloated to be anywhere close for rapid and effecient development, or to be +actually portable onto devices with limited memory and processing power. + +Design +------ +We believe lesser choice is better. + +swk has a very basic set of widgets, particularly only widgets with few +properties and function pointers to extend and override the behaviour and +appearance of such widgets. The overall widget structure is a tree of widgets, +where the root of the tree represents the lower-most widget which +contains all other widgets; and where all leafs represent the +top-most widgets. + +Each widget is parent relative and swk scales child widgets by maximising them +into the available space of the surrounding parent widget, unless a child +widget has no width or height factor specified. + +The layout algorithm fills child widgets horizontally until a break is inserted +that creates a new row. The swk layout algorithm does *not* support the use of +absolute x/y offsets or fixed width/height in order to guarantuee seamless +scaling, this is an advantage and increases the usability and look'n'feel of +swk user interfaces. + +The width/height of a widget is defined as float factor in between 0.0 and 1.0 +that is used for scaling it in a parent relative way. The sum of all widgets +in a row until a break should not exceed 1.0, the sum of the widget with the +greatest height in each row should not exceed 1.0 either in order that the +layout algorithm creates useful results. If the sum is greater than 1.0 or +negative swk will ignore all width/height factors until the developer has fixed +his mistake. + +typedef void * SwkBitmap; +typedef SwkWidget * SwkBreak; +typedef unsigned long SwkColor; +typedef char * SwkText; + +typedef struct { + SwkText *name; +} SwkFont; + +typedef struct { + SwkColor bg; + SwkColor text; + SwkColor border; + SwkFont *font; +} SwkGC; + +typedef struct _SwkWidget SwkWidget; +struct _SwkWidget { + float w_factor; + float h_factor; + SwkGC gc + SwkText *text + SwkWidget *parent + SwkWidget **childs + SwkBitmap *(*draw)(Widget *w, void *userdata, SwkBitmap *current, unsigned int current_w, unsigned int current_h); + void (*click)(Widget *w, void *userdata, unsigned int current_w, unsigned int current_h, int x, int y); + void (*keypress)(Widget *w, void *userdata, int keycode); + void (*focusin)(Widget *w, void *userdata); + void (*focusout)(Widget *w, void *userdata); +}; + +The content of each widget is a Bitmap, which is a platform dependent +representation of the actual content of the widget using in its current size. + +If you overload the draw function of a widget, it is expected that you return a +Bitmap covering the current actual size of the widget. + +There are also a bunch of swk manipulation functions that help you implementing +custom draw functions: + +void swk_copy_bitmap(Bitmap *target, Bitmap *source, int target_x, int target_y, int source_x, int source_y, uint source_w, uint source_h); +void swk_draw_text(Bitmap *target, int offset_x, int offset_y, Text *text); + +Remarks +------- +(*) Currently we the X Window System is the only supported environment. diff --git a/swk.c b/swk.c @@ -0,0 +1,64 @@ +/* Copyleft 2010 -- pancake <nopcode.org> */ + +#include <stdio.h> +#include <stdlib.h> +#include "swk.h" + +int swkret = 0; +SwkScene swkscene; + +int swk_init () { + swkscene.window = NULL; + swkscene.windows = NULL; +} + +SwkWindow *swk_widget () { +} + +SwkWindow *swk_box () { +} + +SwkWindow *swk_box_add (SwkBox *box) { +} + +// TODO: rename to box_layout ?? +int swk_window_layout_flow (SwkWindow *window) { + return 0; +} + +int swk_box_layout_flow (SwkBox *box) { + return 0; +} + +SwkWindow *swk_window () { + SwkWindow *w = (SwkWindow *) malloc (sizeof (SwkWindow)); + w->next = NULL; + if (swkscene.window) swkscene.window->next = w; + else swkscene.windows = w; + swkscene.window = w; + return w; +} + +int swk_window_add (SwkWindow *w) { +} + +SwkWidget* swk_label () { + /* .. */ +} + +int swk_window_delete (SwkWindow *w) { + SwkWindow *iter = swkscene.window; + // XXX + while (iter) { + if (iter == w) + return 1; + iter = iter->next; + } + return 0; +} + +int swk_event () { +} + +int swk_redraw () { +} diff --git a/swk.h b/swk.h @@ -0,0 +1,51 @@ +#define TRUE 1 +#define FALSE 0 +typedef int bool_t; + +typedef struct swk_widget_t { + int (*render) (struct swk_widget_t *widget, int w, int h); + int (*activate) (struct swk_widget_t *widget, int type); + void *user; +} SwkWidget; + +typedef struct container_t { + char *title; // nullable + int show; // boolean + struct SwkWidget *widget; + struct SwkBox *next; +} SwkBox; + +typedef struct swk_window_t { + char *title; + SwkWidget *selected; + SwkBox *box; + SwkBox *boxes; + int (*box_align) (struct swk_window_t *window); + struct swk_window_t *next; +} SwkWindow; + +typedef struct scene_t { + SwkWindow *windows; + SwkWindow *window; +} SwkScene; + +typedef enum { + CLICK, + RELEASE, + MOUSE_OVER, + MOUSE_OUT, +} SwkEvent; + +int swk_widget_set_event_mask (SwkWidget *w, int evmask); + +int swk_scene_next (SwkScene *s, int dir); +int swk_event (); + +void flow_layout_align (SwkScene *scene); + +extern SwkScene swkscene; +extern int swkret; + +// uhm? not here maybe +extern int swk_window_layout_flow (SwkWindow *window); +extern int swk_box_layout_flow (SwkBox* box); diff --git a/test.c b/test.c @@ -0,0 +1,17 @@ +#include <swk.h> + +int main () { + SwkWindow *w; + SwkBox *c; + + swk_init (); + + w = swk_window (swk_window_layout_flow); + c = swk_box (swk_box_layout_flow); + swk_box_add (c, swk_label ("Hello World")); + //swk_add_box (c); + + // TODO: not working with glib + while (swk_event ()); + return swkret; +}