[hackers] [swk] added sdl_ttf as dependency to draw text || pancake

From: <hg_AT_suckless.org>
Date: Wed, 21 Apr 2010 01:30:27 +0000 (UTC)

changeset: 10:e86c6a25ee1f
tag: tip
user: pancake <pancake_AT_nopcode.org>
date: Wed Apr 21 03:21:46 2010 +0200
files: Inconsolata.otf Makefile gi_sdl.c swk.c swk.h test.c
description:
added sdl_ttf as dependency to draw text
basic example is now working with layout and clicks
implemented basic drawing primitives in sdl backend
sdl backend can be configured with few defines
on mouse over and click change box selection
added 'Alt' modifier to SwkKeyMod

diff -r ac0dda7b826c -r e86c6a25ee1f Inconsolata.otf
Binary file Inconsolata.otf has changed
diff -r ac0dda7b826c -r e86c6a25ee1f Makefile
--- a/Makefile Tue Apr 20 23:56:55 2010 +0200
+++ b/Makefile Wed Apr 21 03:21:46 2010 +0200
@@ -4,18 +4,16 @@
 DESTDIR?=
 PREFIX?=${DESTDIR}/usr/local
 LIBDIR?=${PREFIX}/lib
+CFLAGS+=-I.
 
 # graphic backend
 GI?=sdl
-GI_LIBS=-lSDL
+GI_LIBS=-lSDL -lSDL_ttf
 
 GI_OBJS=gi_${GI}.o
 
 all: static test
 
-test.o:
- ${CC} -I. test.c -c -o test.o
-
 test: test.o libswk.a
         ${CC} test.o -o test libswk.a ${GI_LIBS}
 
diff -r ac0dda7b826c -r e86c6a25ee1f gi_sdl.c
--- a/gi_sdl.c Tue Apr 20 23:56:55 2010 +0200
+++ b/gi_sdl.c Wed Apr 21 03:21:46 2010 +0200
@@ -1,7 +1,46 @@
 #include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
 #include "swk.h"
 
+#define HICOLOR 0xa0,0x00,0x00
+#define FGCOLOR 0xa0,0xa0,0xa0
+#define BGCOLOR 0x00,0x00,0x00
+#define TFCOLOR 0xff,0xff,0xff
+#define FONTNAME "Inconsolata.otf"
+//#define FONTSIZE 16
+#define FONTSIZE 32
+#define FS FONTSIZE
+#define BPP 32
+/* --- */
+
+
+static Uint32 pal[ColorLast];
+static SDL_Color fontcolor = { TFCOLOR };
 static SDL_Surface *screen = NULL;
+static TTF_Font *font = NULL;
+
+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;
+#if BPP == 8
+ *p = pixel;
+#elif BPP == 16
+ *(Uint16 *)p = pixel;
+#elif BPP == 24
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ p[0] = (pixel >> 16) & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = pixel & 0xff;
+ #else
+ p[0] = pixel & 0xff;
+ p[1] = (pixel >> 8) & 0xff;
+ p[2] = (pixel >> 16) & 0xff;
+ #endif
+#elif BPP == 32
+ *(Uint32 *)p = pixel;
+#endif
+}
 
 int
 swk_gi_init(SwkWindow *w) {
@@ -9,17 +48,32 @@
                 fprintf(stderr, "Cannot initialize SDL\n");
                 return 0;
         }
- SDL_SetVideoMode(w->r.w, w->r.h, 32, SDL_DOUBLEBUF|SDL_RESIZABLE);
+ 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_WM_SetCaption(w->title, NULL);
         screen = SDL_GetVideoSurface();
         SDL_EnableUNICODE(1);
         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ 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);
+ if (font == NULL) {
+ fprintf(stderr, "Cannot open font '%s'\n", FONTNAME);
+ return 0;
+ }
         return 1;
 }
 
 int
 swk_gi_update(SwkWindow *w) {
- SDL_SetVideoMode(screen->w, screen->h, 32, SDL_DOUBLEBUF|SDL_RESIZABLE);
+ 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;
         return 1;
 }
 
@@ -28,18 +82,29 @@
         SDL_Quit();
 }
 
+
+static int has_event = 0;
+static SDL_Event lastev = {.type=-1};
+
+int
+swk_gi_has_event() {
+ if (!has_event)
+ has_event = SDL_PollEvent(&lastev);
+ return has_event;
+}
+
 SwkEvent *
 swk_gi_event(int dowait) {
- int evret;
         SDL_Event event;
         static SwkEvent ev;
         SwkEvent *ret = NULL;
 
- if (dowait) evret = SDL_WaitEvent(&event);
- else evret = SDL_PollEvent(&event);
+ if(has_event) {
+ event = lastev;
+ } else has_event = SDL_WaitEvent(&event);
 
- if (evret)
- switch (event.type) {
+ if (has_event);
+ switch(event.type) {
         case SDL_VIDEORESIZE:
                 fprintf(stderr, "resize %d %d\n", event.resize.w, event.resize.h);
                 SDL_SetVideoMode(event.resize.w, event.resize.h,
@@ -53,17 +118,17 @@
         case SDL_MOUSEMOTION:
                 ret = &ev;
                 ev.type = EMotion;
- ev.data.motion.x = event.motion.x;
- ev.data.motion.y = event.motion.y;
- fprintf(stderr, "event: motion %d %d\n",
- event.motion.x, event.motion.y);
+ ev.data.motion.x = event.motion.x / FS;
+ ev.data.motion.y = event.motion.y / FS;
+ // fprintf(stderr, "event: motion %d %d\n",
+ // event.motion.x, event.motion.y);
                 break;
         case SDL_MOUSEBUTTONDOWN:
                 ret = &ev;
                 ev.type = EClick;
                 ev.data.click.button = event.button.button;
- ev.data.click.point.x = event.button.x;
- ev.data.click.point.y = event.button.y;
+ ev.data.click.point.x = event.button.x / FS;
+ ev.data.click.point.y = event.button.y / FS;
                 fprintf(stderr, "event: click %d\n", event.button.button);
                 break;
         case SDL_KEYDOWN:
@@ -72,14 +137,13 @@
                         ev.type = EKey;
                         ev.data.key.keycode = event.key.keysym.unicode;
                         ev.data.key.modmask = 0;
- if(event.key.keysym.mod & KMOD_LCTRL ||
- event.key.keysym.mod & KMOD_RCTRL)
+ if(event.key.keysym.mod & KMOD_CTRL)
                                 ev.data.key.modmask |= Ctrl;
- if(event.key.keysym.mod & KMOD_LSHIFT||
- event.key.keysym.mod & KMOD_RSHIFT)
+ if(event.key.keysym.mod & KMOD_SHIFT)
                                 ev.data.key.modmask |= Shift;
- if(event.key.keysym.mod & KMOD_LMETA ||
- event.key.keysym.mod & KMOD_RMETA)
+ if(event.key.keysym.mod & KMOD_ALT)
+ ev.data.key.modmask |= Alt;
+ if(event.key.keysym.mod & KMOD_META)
                                 ev.data.key.modmask |= Meta;
                         fprintf(stderr, "event: key %d %d\n",
                                 ev.data.key.modmask, ev.data.key.keycode);
@@ -91,28 +155,53 @@
                 ret = &ev;
                 break;
         }
+ has_event = 0;
         return ret;
 }
 
 void
+swk_gi_clear() {
+ SDL_Rect rect = { 0, 0, screen->w, screen->h };
+ SDL_FillRect(screen, &rect, pal[ColorBG]);
+}
+
+void
 swk_gi_flip() {
- fprintf(stderr, "flip\n");
- SDL_Flip(screen);
+ SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
 }
 
 /* -- drawing primitives -- */
 void
-swk_gi_line(int x, int y, int w, int h) {
+swk_gi_line(int x, int y, int w, int h, int color) {
+ int i;
+ x *= FS; y *= FS;
+ w *= FS; h *= FS;
+
+ if (w==0) for(i=0;i<h;i++) putpixel(x, y+i, pal[color]);
+ else
+ if (h==0) for(i=0;i<w;i++) putpixel(x+i, y, pal[color]);
 }
 
 void
-swk_gi_box(int x, int y, int w, int h) {
+swk_gi_fill(int x, int y, int w, int h, int color) {
+ SDL_Rect area = { x*FS, y*FS, w*FS, h*FS };
+ SDL_FillRect(screen, &area, pal[color]);
 }
 
 void
-swk_gi_rect(int x, int y, int w, int h) {
+swk_gi_rect(int x, int y, int w, int h, int color) {
+ swk_gi_line(x, y, w, 0, color);
+ swk_gi_line(x, y+h, w, 0, color);
+ swk_gi_line(x, y, 0, h, color);
+ swk_gi_line(x+w, y, 0, h, color);
 }
 
 void
 swk_gi_text(int x, int y, const char *text) {
+ SDL_Surface *ts = TTF_RenderText_Solid(font, text, fontcolor);
+ if (ts) {
+ SDL_Rect to = { x*FS, 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 -r ac0dda7b826c -r e86c6a25ee1f swk.c
--- a/swk.c Tue Apr 20 23:56:55 2010 +0200
+++ b/swk.c Wed Apr 21 03:21:46 2010 +0200
@@ -13,16 +13,25 @@
                 w->r.w = 640;
                 w->r.h = 480;
         }
- if (swk_gi_init(w))
+ if (swk_gi_init(w)) {
                 running = 1;
+ swk_update();
+ }
         return running;
 }
 
 void
 swk_update() {
- if (!swk_gi_update(w))
- running = 0;
- else swk_gi_flip();
+ SwkEvent ev = { .type = EExpose };
+ if (swk_gi_update(w)) {
+ SwkBox *b = w->boxes;
+ swk_fit();
+ for(;b->cb; b++) {
+ ev.box = b;
+ b->cb(&ev);
+ }
+ swk_gi_flip();
+ } else running = 0;
 }
 
 void
@@ -38,12 +47,37 @@
                         swk_event_handle(e);
         } while (!e || e->type != EQuit);
 }
+void
+swk_fit_row(SwkBox *a, SwkBox *b, int y) {
+ int count, x = 0;
+ SwkBox *btmp;
+ count = 0;
+ for(btmp=a; btmp<b; btmp++)
+ count++;
+ if (count) {
+ int winc = w->r.w / count;
+ for(btmp=a; btmp<b; btmp++) {
+ btmp->r.x = x;
+ btmp->r.y = y;
+ btmp->r.w = winc;
+ btmp->r.h = 1;
+ x+=winc;
+ }
+ }
+}
 
 void
 swk_fit() {
- SwkBox *b;
- for(b=w->boxes; b->cb; b++)
- printf("Handler: %p text: \"%s\"\n", b->cb, b->text);
+ int y = 0;
+ SwkBox *b, *b2;
+ for(b=b2=w->boxes; b->cb; b++) {
+ if(b->r.w==-1 && b->r.h==-1) {
+ swk_fit_row(b2, b, y);
+ y += (int)(size_t)b->data;
+ b2 = b+1;
+ }
+ }
+ swk_fit_row(b2, b, y);
 }
 
 SwkEvent *
@@ -57,14 +91,45 @@
 
 void
 swk_event_handle(SwkEvent *e) {
+ SwkBox *b;
         switch(e->type) {
         case EKey:
- case EClick:
- if (w->box && w->box->cb)
+ if (e->data.key.keycode == 9) {
+ /* not working */
+ if (e->data.key.modmask&Ctrl)
+ swk_focus_prev();
+ else swk_focus_next();
+ swk_update();
+ }
+ // send key to focused box
+ e->box = w->box;
+ if (w->box)
                         w->box->cb(e);
                 break;
+ case EMotion:
+ for(b=w->boxes;b->cb;b++) {
+ Point p = e->data.motion;
+ if (p.x>=b->r.x && p.x<=(b->r.x+b->r.w)
+ && p.y>=b->r.y && p.y<=(b->r.y+b->r.h)) {
+ w->box = e->box = b;
+ b->cb(e);
+ swk_update();
+ break;
+ }
+ }
+ break;
+ case EClick:
+ for(b=w->boxes;b->cb;b++) {
+ Point p = e->data.click.point;
+ if (p.x>=b->r.x && p.x<=(b->r.x+b->r.w)
+ && p.y>=b->r.y && p.y<=(b->r.y+b->r.h)) {
+ e->box = w->box = b;
+ e->box->cb(e);
+ swk_update();
+ }
+ }
+ break;
         case EExpose:
- swk_fit();
                 swk_update();
                 break;
         case EQuit:
@@ -94,6 +159,15 @@
 /* widgets */
 void
 swk_label(SwkEvent *e) {
+ Rect r;
+ switch(e->type) {
+ case EExpose:
+ r = e->box->r;
+ swk_gi_text(r.x, r.y, e->box->text);
+ break;
+ default:
+ break;
+ }
 }
 
 void
@@ -102,10 +176,14 @@
 
 void
 swk_button(SwkEvent *e) {
+ Rect r;
         switch(e->type) {
         case EExpose:
- // TODO: use box position
- swk_gi_rect(0, 0, 10, 10);
+ r = e->box->r;
+ if (w->box == e->box)
+ swk_gi_rect(r.x, r.y, r.w, r.h, ColorHI);
+ else swk_gi_rect(r.x, r.y, r.w, r.h, ColorFG);
+ swk_gi_text(r.x+1, r.y, e->box->text);
                 break;
         default:
                 break;
diff -r ac0dda7b826c -r e86c6a25ee1f swk.h
--- a/swk.h Tue Apr 20 23:56:55 2010 +0200
+++ b/swk.h Wed Apr 21 03:21:46 2010 +0200
@@ -1,8 +1,10 @@
 /* See LICENSE file for copyright and license details. */
-#define SWK_NEWLINE .h=-1, .w=-1
+
+#define SWK_NEWLINE(x) .data=(void*)(size_t)x, .r.w=-1, .r.h=-1, .cb = swk_filler
 
 typedef enum { EVoid, EClick, EMotion, EKey, EExpose, EQuit, ELast } SwkEventType;
-typedef enum { Shift=1, Ctrl=2, Meta=4 } SwkKeyMod;
+typedef enum { Shift=1, Ctrl=2, Alt=4, Meta=8 } SwkKeyMod;
+typedef enum { ColorFG, ColorBG, ColorHI, ColorLast } Palete;
 
 typedef struct SwkBox SwkBox;
 
@@ -37,14 +39,14 @@
                 Point motion;
                 Key key;
                 Rect expose;
+ int rows;
         } data;
 } SwkEvent;
 
 typedef void (*SwkEventCallback)(SwkEvent *e);
 
 struct SwkBox {
- int w;
- int h;
+ Rect r;
         SwkEventCallback cb;
         char *text;
         void *data;
@@ -59,10 +61,14 @@
 
 int swk_init(SwkWindow *w);
 int swk_gi_update(SwkWindow *w);
+void swk_update();
 void swk_exit();
 void swk_fit();
+void swk_loop();
+void swk_fit_row(SwkBox *a, SwkBox *b, int y);
 SwkEvent * swk_event();
 void swk_event_handle(SwkEvent *e);
+int swk_gi_has_event();
 
 void swk_focus_next();
 void swk_focus_prev();
@@ -80,7 +86,7 @@
 
 void swk_gi_flip();
 
-void swk_gi_line(int x, int y, int w, int h);
-void swk_gi_box(int x, int y, int w, int h);
-void swk_gi_rect(int x, int y, int w, int h);
+void swk_gi_line(int x, int y, int w, int h, int color);
+void swk_gi_fill(int x, int y, int w, int h, int color);
+void swk_gi_rect(int x, int y, int w, int h, int color);
 void swk_gi_text(int x, int y, const char *text);
diff -r ac0dda7b826c -r e86c6a25ee1f test.c
--- a/test.c Tue Apr 20 23:56:55 2010 +0200
+++ b/test.c Wed Apr 21 03:21:46 2010 +0200
@@ -2,21 +2,34 @@
 #include "swk.h"
 
 static int count = 3;
+static char text[64];
+static SwkBox helloworld[];
 
 static void mybutton(SwkEvent *e) {
         if (e->type == EClick) {
- fprintf(stderr, "Button clicked %d\n", count);
+ sprintf(text, "Do it again %d times\n", count);
+ helloworld[0].text = text;
                 if (count-- == 0)
                         swk_exit();
         }
         swk_button(e);
 }
 
+
 static SwkBox helloworld[] = {
- { .cb=swk_label, .text="Press this button", },
- { SWK_NEWLINE },
+ { SWK_NEWLINE(1) },
+ { .cb=swk_label, .text="Press a button", },
+ { SWK_NEWLINE(2) },
+ { .cb=mybutton, .text="yes" },
         { .cb=swk_filler, },
- { .cb=mybutton, .text="clickme" },
+ { .cb=mybutton, .text="no" },
+#if 0
+ { SWK_NEWLINE(1) },
+ { .cb=mybutton, .text="yes" },
+ { .cb=mybutton, .text="no" },
+#endif
+ { SWK_NEWLINE(5) },
+ { .cb=swk_label, .text="--swktest", },
         { .cb=NULL }
 };
 
@@ -26,7 +39,6 @@
                 .title="Hello World",
                 .boxes=helloworld
         };
-
         if (!swk_init(&w))
                 return 1;
         swk_loop();
Received on Wed Apr 21 2010 - 01:30:27 UTC

This archive was generated by hypermail 2.2.0 : Wed Apr 21 2010 - 01:36:03 UTC