From f738227d2f27b56453386678fe52744d1ed0b167 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Sat, 13 Jul 2019 13:19:35 +0100 Subject: Initial code commit --- CMakeLists.txt | 8 +++ README | 32 +++++++++++ termkit.c | 72 +++++++++++++++++++++++++ termkit.h | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 276 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 README create mode 100644 termkit.c create mode 100644 termkit.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..99b1c0e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 2.8.11) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c99") + +project(termkit) +add_library(termkit SHARED termkit.c) +target_link_library(termkit termbox) +target_include_directories(termkit PUBLIC ".") + diff --git a/README b/README new file mode 100644 index 0000000..b356638 --- /dev/null +++ b/README @@ -0,0 +1,32 @@ +libtermkit +========== + +A powerful and easy to use terminal widget UI library, based on termbox. +Provides a convenient API around event listeners, event propagation, +widgets, menus, decorators and stylesheets. + + +How to build +------------ + +An out-of-source build is recommended. `termbox` [0] is a build dependency. + +``` +$> mkdir build; cd build +$> cmake .. +$> make -j 2 +``` + +[0]: https://github.com/nsf/termbox + + +License +------- + +This program is free software; you can redistribute it and/or modify + +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +I hope you enjoy ❤ diff --git a/termkit.c b/termkit.c new file mode 100644 index 0000000..9775f7d --- /dev/null +++ b/termkit.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include + +#include +#include "termkit.h" + +#define OK 0 +#define ER 1 +#define USR_ERR 2 + +int tk_sty_init(tk_style_t **sty, uint16_t fg, uint16_t bg) +{ + (*sty) = calloc(sizeof(tk_style_t), 1); + CHECK(*sty, ERR) + + err_t e; + e = bowl_malloc(&(*sty)->styles, HASH); + if(e) goto fail; + + e = bowl_malloc(&(*sty)->decorators, HASH); + if(e) goto fail; + + return OK; + +fail: + free((*sty)->styles); + free((*sty)->decorators); + free(*sty); + return ERR; +} + +int tk_sty_add_col(tk_style_t *sty, char *name, uint16_t fg, uint16_t bg) +{ + CHECK(sty, USR_ERR) + + + + return OK; +} + +// int init() +// { +// return tb_init(); +// } + +// void draw(char *str, int rootX, int rootY, uint16_t fg, uint16_t bg) +// { +// size_t len = strlen(str); +// int x = rootX; + +// for(int i = 0; i < len; i++) { +// tb_change_cell(x, rootY, str[i], fg, bg); +// x += 1; +// } +// } + +// void draw_xy(char *str, int rootX, int rootY, +// int8_t h, int8_t v, +// uint16_t fg, uint16_t bg) +// { +// size_t len = strlen(str); +// int x = rootX; +// int y = rootY; + +// for(int i = 0; i < len; i++) { +// tb_change_cell(x, y, str[i], fg, bg); +// x += h; y += v; +// } +// } + diff --git a/termkit.h b/termkit.h new file mode 100644 index 0000000..36028aa --- /dev/null +++ b/termkit.h @@ -0,0 +1,164 @@ +// This file is part of libtermkit, a small utility library around +// libtermbox, an alternative to libncurses. It aims to provide a +// convenient and easy to use widget abstraction to build terminal +// based GUIs, in C99. +// +// In principle, termkit only wraps functions provided by termbox, +// but does so while providing state handling and render utilities. +// In termkit, the smallest element is a "node", not a cell. This +// means that the smallest unit is a sentence or visual element. +// A visual element can then either simply be that sentence, or have +// decorations applied to it via `tk_style_t` which is a shared +// style-sheet across an application. +// +// libtermkit is free software, written by Katharina Fey, and licensed +// under the GNU Public License 3.0 or later. See the included license +// reference provided with a copy of this library source code. + +#ifndef term_h_INCLUDED +#define term_h_INCLUDED + +#include +#include + +/** + * A common stylesheet for termkit applications + * + * A stylesheet determines the way that an application looks, + * beyond setting individual cells to certain fg and bg colours. + * It supports labels that can be associated with different + * colour styles (via `tk_sty_color(...)`) or even decorations + * with `tk_sty_decor(...)` that are applied to an element. + */ +typedef struct { + uint16_t fg, bg; + struct bowl *styles; + struct bowl *decorators; +} tk_style_t; + +/** + * A decorator element for widgets + * + * A decorator is visible "stuff", that's not directly data related. This + * could be a colourful frame or shadows. By using characters in the area + * data, this can be used to also draw UTF-8 compatible characters as + * outlines. + * Each decoration element get's colour values from a stylesheet. + * + * See the type constructor for more information. + */ +typedef struct { + uint32_t ***area; // FIXME: A hack for UTF-8 + tk_style_t *sty; + char *sty_name; + // Spans open a container box + uint16_t ux, uy, lx, ly; +} tk_decor_t; + +/** Allocate a new stylesheet */ +int tk_sty_init(tk_style_t **, uint16_t fg, uint16_t bg); + +/** Add a new color style to the stylesheet */ +int tk_sty_add_col(tk_style_t *, char *name, uint16_t fg, uint16_t bg); + +/** Add a new dectoration type (TODO: How to express?) */ +int tk_sty_add_decor(tk_style_t *, char *name, tk_decor_t *); + +/** Get a color from the stylesheet, if it exists */ +int tk_sty_color(tk_style_t *, char *name, uint16_t *fg, uint16_t *bg); + +/** Get a decorator from the stylesheet, if it exists */ +int tk_sty_decor(tk_style_t *, char *name, tk_decor_t **); + +/** Free all stylesheet resources */ +int tk_sty_free(tk_style_t *); + +/** A common termkit orientation descriptor */ +enum tk_ori { + HORIZONTAL, + VERTICAL, + DIAGONAL, + REV_HORIZONTAL, + REV_VERTICAL, + REV_DIAGONAL, +}; + +typedef struct { + tk_style_t *sty; + char *sty_name, *decor; + char *value; + uint16_t x, y; + enum tk_ori ori; + bool clickable; +} tk_widget_t; + +/** Initialise a termkit window system */ +int tk_init(); + +/** Draw a termkit widget */ +int tk_draw_widget(tk_widget_t *); + +/** Simple low-level draw function for termkit elements */ +int tk_draw_default(char *str, int x, int y, tk_style_t *sty); + +/** Full low-level draw function for termkit elements + * + * If `style_name` or `decor` are set to `NULL` it will + * assume the default style provided by the tk_style_t + * sheet and render without decorators. + * + * Missing any other parameter will yield an error. + */ +int tk_draw(tk_style_t *sty, char *str, int x, int y, + char *style_name, char *decor, enum tk_ori ori); + +/** A TermKit menu wrapper */ +typedef struct { + // References the application's stylesheet + tk_style_t *style; + // Actual menu styles used + char *sty_name, *decor; + // Determines render orientation + enum tk_ori ori; + // List of items + tk_widget_t **items; + // Number an selection of items + uint8_t count, select; + // (x, y) position on screen + uint16_t x, y; + // Maximum (width, height) of widget + uint16_t w, h; +} tk_menu_t; + +/** Initialise an empty termkit menu + * + * Note that only HORIZONTAL, VERTICAL, REV_HORIZONTAL and REV_VERTICAL + * are accepted orientations to this function (no diagonals...). + * The function will return an error otherwise. + */ +int tk_menu_init(tk_menu_t **, uint16_t x, uint16_t y, + tk_style_t *style, enum tk_ori ori); + +/** Set a special style and decoration type for this menu */ +int tk_menu_set_style(tk_menu_t *, char *style, char *decor); + +/** Set the selected item index */ +int tk_menu_set_select(tk_menu_t *, uint8_t select); + +/** Get the selected item */ +int tk_menu_get_selected(tk_menu_t *, char **select); + +/** Add a new item */ +int tk_menu_add(tk_menu_t *, char *item); + +/** Remove an existing item, compacting following items */ +int tk_menu_remove(tk_menu_t *, uint8_t idx); + +/** Render the menu via termbox */ +int tk_menu_draw(tk_menu_t *); + +/** Free all resources */ +int tk_menu_free(tk_menu_t *); + +#endif // term_h_INCLUDED + -- cgit v1.2.3