2012-04-12 22:42:24 -05:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "lib/window.h"
|
|
|
|
#include "lib/graphics.h"
|
2012-04-13 01:21:01 -05:00
|
|
|
#include "lib/list.h"
|
2012-04-17 13:46:46 -05:00
|
|
|
#include "lib/shmemfonts.h"
|
2012-04-17 15:34:34 -05:00
|
|
|
#include "lib/decorations.h"
|
2012-04-13 01:21:01 -05:00
|
|
|
|
|
|
|
/* XXX TOOLKIT FUNCTIONS */
|
|
|
|
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 13:21:34 -05:00
|
|
|
gfx_context_t * ctx;
|
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
/* Active TTK window XXX */
|
2012-04-13 01:21:01 -05:00
|
|
|
static window_t * ttk_window = NULL;
|
2012-04-13 22:20:36 -05:00
|
|
|
|
|
|
|
/* TTK Window's objects XXX */
|
2012-04-13 01:21:01 -05:00
|
|
|
static list_t * ttk_objects = NULL;
|
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
#define TTK_BUTTON_TYPE 0x00000001
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Core TTK GUI object
|
|
|
|
*/
|
2012-04-13 01:21:01 -05:00
|
|
|
typedef struct {
|
2012-04-13 22:20:36 -05:00
|
|
|
uint32_t type; /* Object type indicator (for introspection) */
|
|
|
|
int32_t x; /* Coordinates */
|
2012-04-13 01:21:01 -05:00
|
|
|
int32_t y;
|
2012-04-13 22:20:36 -05:00
|
|
|
int32_t width; /* Sizes */
|
2012-04-13 01:21:01 -05:00
|
|
|
int32_t height;
|
2012-04-13 22:20:36 -05:00
|
|
|
void (*render_func)(void *); /* (Internal) function to render the object */
|
|
|
|
void (*click_callback)(void *, w_mouse_t *); /* Callback function for clicking */
|
2012-04-13 01:21:01 -05:00
|
|
|
} ttk_object;
|
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
/* TTK Button */
|
2012-04-13 01:21:01 -05:00
|
|
|
typedef struct {
|
2012-04-13 22:20:36 -05:00
|
|
|
ttk_object _super; /* Parent type (Object -> Button) */
|
|
|
|
char * title; /* Button text */
|
|
|
|
uint32_t fill_color; /* Fill color */
|
2012-04-17 13:46:46 -05:00
|
|
|
uint32_t fore_color; /* Text color */
|
2012-04-13 01:21:01 -05:00
|
|
|
} ttk_button;
|
|
|
|
|
|
|
|
void ttk_render_button(void * s) {
|
|
|
|
ttk_object * self = (ttk_object *)s;
|
2012-04-13 22:20:36 -05:00
|
|
|
/* Fill the button */
|
2012-04-13 01:21:01 -05:00
|
|
|
for (uint16_t y = self->y + 1; y < self->y + self->height; y++) {
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 13:21:34 -05:00
|
|
|
draw_line(ctx, self->x, self->x + self->width, y, y, ((ttk_button *)self)->fill_color);
|
2012-04-13 01:21:01 -05:00
|
|
|
}
|
2012-04-13 22:20:36 -05:00
|
|
|
/* Then draw the border */
|
2012-04-13 01:21:01 -05:00
|
|
|
uint32_t border_color = rgb(0,0,0);
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 13:21:34 -05:00
|
|
|
draw_line(ctx, self->x, self->x + self->width, self->y, self->y, border_color);
|
|
|
|
draw_line(ctx, self->x, self->x, self->y, self->y + self->height, border_color);
|
|
|
|
draw_line(ctx, self->x + self->width, self->x + self->width, self->y, self->y + self->height, border_color);
|
|
|
|
draw_line(ctx, self->x, self->x + self->width, self->y + self->height, self->y + self->height, border_color);
|
2012-04-17 13:46:46 -05:00
|
|
|
/* button-specific stuff */
|
2012-04-17 13:55:54 -05:00
|
|
|
uint32_t w = draw_string_width(((ttk_button * )self)->title);
|
|
|
|
uint16_t offset = (self->width - w) / 2;
|
|
|
|
draw_string(ctx, self->x + offset, self->y + self->height - 3, ((ttk_button *)self)->fore_color, ((ttk_button * )self)->title);
|
2012-04-13 01:21:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
ttk_button * ttk_new_button(char * title, void (*callback)(void *, w_mouse_t *)) {
|
|
|
|
ttk_button * out = malloc(sizeof(ttk_button));
|
|
|
|
out->title = title;
|
|
|
|
out->fill_color = rgb(100,100,100);
|
|
|
|
|
|
|
|
/* Standard */
|
|
|
|
ttk_object * obj = (ttk_object *)out;
|
|
|
|
obj->click_callback = callback;;
|
|
|
|
obj->render_func = ttk_render_button;
|
2012-04-13 22:20:36 -05:00
|
|
|
obj->type = TTK_BUTTON_TYPE;
|
|
|
|
obj->x = 0;
|
|
|
|
obj->y = 0;
|
|
|
|
obj->width = 20;
|
|
|
|
obj->height = 20;
|
2012-04-13 01:21:01 -05:00
|
|
|
|
|
|
|
list_insert(ttk_objects, obj);
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
/*
|
|
|
|
* Reposition a TTK object
|
|
|
|
*/
|
2012-04-13 01:21:01 -05:00
|
|
|
void ttk_position(ttk_object * obj, int x, int y, int width, int height) {
|
|
|
|
obj->x = x;
|
|
|
|
obj->y = y;
|
|
|
|
obj->width = width;
|
|
|
|
obj->height = height;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ttk_within(ttk_object * obj, w_mouse_t * evt) {
|
|
|
|
if (evt->new_x >= obj->x && evt->new_x < obj->x + obj->width &&
|
|
|
|
evt->new_y >= obj->y && evt->new_y < obj->y + obj->height) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ttk_check_click(w_mouse_t * evt) {
|
|
|
|
if (evt->command == WE_MOUSECLICK) {
|
|
|
|
foreach(node, ttk_objects) {
|
|
|
|
ttk_object * obj = (ttk_object *)node->value;
|
|
|
|
if (ttk_within(obj, evt)) {
|
|
|
|
if (obj->click_callback) {
|
|
|
|
obj->click_callback(obj, evt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ttk_render() {
|
|
|
|
foreach(node, ttk_objects) {
|
|
|
|
ttk_object * obj = (ttk_object *)node->value;
|
|
|
|
if (obj->render_func) {
|
|
|
|
obj->render_func(obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setup_ttk(window_t * window) {
|
|
|
|
ttk_window = window;
|
|
|
|
ttk_objects = list_create();
|
|
|
|
mouse_action_callback = ttk_check_click;
|
2012-04-17 13:46:46 -05:00
|
|
|
init_shmemfonts();
|
2012-04-13 01:21:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t drawing_color = 0;
|
2012-04-13 22:20:36 -05:00
|
|
|
uint16_t quit = 0;
|
2012-04-13 01:21:01 -05:00
|
|
|
|
|
|
|
static void set_color(void * button, w_mouse_t * event) {
|
|
|
|
ttk_button * self = (ttk_button *)button;
|
|
|
|
drawing_color = self->fill_color;
|
|
|
|
}
|
2012-04-12 22:42:24 -05:00
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
static void quit_app(void * button, w_mouse_t * event) {
|
|
|
|
quit = 1;
|
|
|
|
teardown_windowing();
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2012-04-17 16:06:44 -05:00
|
|
|
ttk_button * button_thick;
|
|
|
|
ttk_button * button_thin;
|
|
|
|
int thick = 0;
|
|
|
|
|
|
|
|
static void set_thickness_thick(void * button, w_mouse_t * event) {
|
|
|
|
button_thick->fill_color = rgb(127,127,127);
|
|
|
|
button_thick->fore_color = rgb(255,255,255);
|
|
|
|
button_thin->fill_color = rgb(40,40,40);
|
|
|
|
button_thin->fore_color = rgb(255,255,255);
|
|
|
|
thick = 1;
|
|
|
|
ttk_render();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void set_thickness_thin(void * button, w_mouse_t * event) {
|
|
|
|
button_thin->fill_color = rgb(127,127,127);
|
|
|
|
button_thin->fore_color = rgb(255,255,255);
|
|
|
|
button_thick->fill_color = rgb(40,40,40);
|
|
|
|
button_thick->fore_color = rgb(255,255,255);
|
|
|
|
thick = 0;
|
|
|
|
ttk_render();
|
|
|
|
}
|
|
|
|
|
2012-04-17 15:34:34 -05:00
|
|
|
void decors(window_t * win) {
|
|
|
|
render_decorations(win, win->buffer, "Draw!");
|
|
|
|
}
|
|
|
|
|
2012-04-12 22:42:24 -05:00
|
|
|
int main (int argc, char ** argv) {
|
|
|
|
int left = 30;
|
|
|
|
int top = 30;
|
|
|
|
|
|
|
|
int width = 450;
|
|
|
|
int height = 450;
|
|
|
|
|
|
|
|
setup_windowing();
|
|
|
|
|
|
|
|
/* Do something with a window */
|
|
|
|
window_t * wina = window_create(left, top, width, height);
|
Context-based graphics library.
All graphics library commands now take a gfx_context_t pointer, which
points to a simple datastructure describing a rendering context (width,
height, depth, total size, front buffer, backbuffer; where backbuffer =
front buffer when not in double-buffering mode, thus we always render to
backbuffer except on a flip). This may have caused a minor speed
reduction, but I don't really care as it's far more important that we
support multiple graphics contexts.
TODO:
- Shared Memory Fonts library (there are a couple of apps that use these
so-called "shmem fonts" on their own; we need a dedicated library for
them)
- Break off "TTK" GUI toolkit into its own library. Since it's just a
callback-based button framework, this shouldn't be too hard right now.
Also, with the previous tick, I'll be able to put labels on controls
and start using text in more places.
2012-04-17 13:21:34 -05:00
|
|
|
ctx = init_graphics_window(wina);
|
|
|
|
draw_fill(ctx, rgb(255,255,255));
|
2012-04-17 15:34:34 -05:00
|
|
|
init_decorations();
|
2012-04-12 22:42:24 -05:00
|
|
|
|
|
|
|
win_use_threaded_handler();
|
|
|
|
|
2012-04-13 01:21:01 -05:00
|
|
|
setup_ttk(wina);
|
|
|
|
ttk_button * button_blue = ttk_new_button("Blue", set_color);
|
2012-04-17 15:34:34 -05:00
|
|
|
ttk_position((ttk_object *)button_blue, decor_left_width + 3, decor_top_height + 3, 100, 20);
|
2012-04-13 01:21:01 -05:00
|
|
|
button_blue->fill_color = rgb(0,0,255);
|
2012-04-17 13:46:46 -05:00
|
|
|
button_blue->fore_color = rgb(255,255,255);
|
2012-04-13 01:21:01 -05:00
|
|
|
|
2012-04-17 13:46:46 -05:00
|
|
|
ttk_button * button_green = ttk_new_button("Green", set_color);
|
2012-04-17 15:34:34 -05:00
|
|
|
ttk_position((ttk_object *)button_green, decor_left_width + 106, decor_top_height + 3, 100, 20);
|
2012-04-13 01:21:01 -05:00
|
|
|
button_green->fill_color = rgb(0,255,0);
|
2012-04-17 13:46:46 -05:00
|
|
|
button_green->fore_color = rgb(0,0,0);
|
2012-04-13 01:21:01 -05:00
|
|
|
|
|
|
|
ttk_button * button_red = ttk_new_button("Red", set_color);
|
2012-04-17 15:34:34 -05:00
|
|
|
ttk_position((ttk_object *)button_red, decor_left_width + 209, decor_top_height + 3, 100, 20);
|
2012-04-13 01:21:01 -05:00
|
|
|
button_red->fill_color = rgb(255,0,0);
|
2012-04-17 13:46:46 -05:00
|
|
|
button_red->fore_color = rgb(255,255,255);
|
2012-04-13 01:21:01 -05:00
|
|
|
|
2012-04-17 16:06:44 -05:00
|
|
|
button_thick = ttk_new_button("Thick", set_thickness_thick);
|
|
|
|
ttk_position((ttk_object *)button_thick, decor_left_width + 312, decor_top_height + 3, 50, 20);
|
|
|
|
button_thick->fill_color = rgb(40,40,40);
|
|
|
|
button_thick->fore_color = rgb(255,255,255);
|
|
|
|
|
|
|
|
button_thin = ttk_new_button("Thin", set_thickness_thin);
|
|
|
|
ttk_position((ttk_object *)button_thin, decor_left_width + 362, decor_top_height + 3, 50, 20);
|
|
|
|
button_thin->fill_color = rgb(127,127,127);
|
|
|
|
button_thin->fore_color = rgb(255,255,255);
|
|
|
|
|
2012-04-17 13:46:46 -05:00
|
|
|
ttk_button * button_quit = ttk_new_button("X", quit_app);
|
2012-04-17 15:41:14 -05:00
|
|
|
ttk_position((ttk_object *)button_quit, width - 23, 2, 20, 20);
|
2012-04-17 13:46:46 -05:00
|
|
|
button_quit->fill_color = rgb(255,0,0);
|
|
|
|
button_quit->fore_color = rgb(255,255,255);
|
2012-04-13 22:20:36 -05:00
|
|
|
|
2012-04-13 01:21:01 -05:00
|
|
|
drawing_color = rgb(255,0,0);
|
|
|
|
|
2012-04-17 15:41:14 -05:00
|
|
|
decors(wina);
|
2012-04-13 01:21:01 -05:00
|
|
|
ttk_render();
|
|
|
|
|
2012-04-13 22:20:36 -05:00
|
|
|
while (!quit) {
|
2012-04-12 22:42:24 -05:00
|
|
|
w_keyboard_t * kbd = poll_keyboard();
|
|
|
|
if (kbd != NULL) {
|
|
|
|
if (kbd->key == 'q') {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
free(kbd);
|
|
|
|
}
|
|
|
|
w_mouse_t * mouse = poll_mouse();
|
|
|
|
if (mouse != NULL) {
|
2012-04-13 01:21:01 -05:00
|
|
|
if (mouse->command == WE_MOUSEMOVE && mouse->buttons & MOUSE_BUTTON_LEFT) {
|
2012-04-17 16:06:44 -05:00
|
|
|
if (thick) {
|
|
|
|
draw_line_thick(ctx, mouse->old_x, mouse->new_x, mouse->old_y, mouse->new_y, drawing_color, 2);
|
|
|
|
} else {
|
|
|
|
draw_line(ctx, mouse->old_x, mouse->new_x, mouse->old_y, mouse->new_y, drawing_color);
|
|
|
|
}
|
2012-04-17 15:34:34 -05:00
|
|
|
decors(wina);
|
2012-04-17 15:41:14 -05:00
|
|
|
ttk_render();
|
2012-04-12 22:42:24 -05:00
|
|
|
}
|
|
|
|
free(mouse);
|
|
|
|
}
|
|
|
|
syscall_yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
teardown_windowing();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|