Compare commits

..

10 Commits

Author SHA1 Message Date
d7f8e7303d ScalingSize, onBuild, toString 2023-05-27 22:40:28 +06:00
b19c020235 cbuild v7 2023-05-24 22:24:07 +06:00
729888b9d9 grid deserialization 2023-05-24 08:01:26 +06:00
e48f7cd6b5 fixed all errors 2023-05-24 03:03:02 +06:00
4e2376f251 started implementing dtsod parsing 2023-05-22 04:08:56 +06:00
03f9f889cc resource_embedder 2023-05-22 03:07:33 +06:00
abc14336d4 setlocale 2023-05-19 23:51:59 +06:00
bb66d841f3 terminal functions 2023-05-19 23:45:56 +06:00
9febbe1de0 kt_register for all types 2023-05-19 20:21:55 +06:00
768c55af4a Grid 2023-05-19 19:54:52 +06:00
32 changed files with 1336 additions and 218 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
# build results
bin/
obj/
src/generated/
*.log
*.tmp

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
path = utf8proc
url = https://github.com/Timerix22/utf8proc.git
branch = my_branch
[submodule "resource_embedder"]
path = resource_embedder
url = https://github.com/Timerix22/resource_embedder.git

View File

@ -12,12 +12,12 @@ build_exec: profile
build_exec_dbg:
@cbuild/call_task.sh build_exec_dbg 2>&1 | tee make_raw.log
# recompile kerep.a in the next build task
# recompile libkerep.a in the next build task
rebuild_kerep:
@tasks/rebuild_lib.sh kerep
# recompile utf8proc.a in the next build task
@cbuild/rebuild_dep.sh libkerep.a 2>&1 | tee make_raw.log
# recompile libutf8proc.a in the next build task
rebuild_utf8proc:
@tasks/rebuild_lib.sh utf8proc
@cbuild/rebuild_dep.sh libutf8proc.a 2>&1 | tee make_raw.log
rebuild_all: rebuild_kerep rebuild_utf8proc
@ -45,7 +45,14 @@ profile:
# uses gprof2dot python script to generate function call tree
gprof:
@cbuild/call_task.sh gprof 2>&1 | tee make_raw.log
# compiles program and runs it with callgrind (part of valgrind)
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
# requires graphviz (https://www.graphviz.org/download/source/)
# P.S. detailed rezults can be viewed in KCacheGrind
callgrind:
@cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log
# compiles executable with sanitizers and executes it to find errors and warnings
sanitize:
@cbuild/call_task.sh sanitize 2>&1 | tee make_raw.log

View File

@ -1,2 +1,9 @@
# SCoLTE - Simple Command-Line Text Editor
I just wanted to edit text files from terminal, not to memorize a ton of weird shortcuts for nano or vim. So here it is - easy to use text editor.
## Dependencies
Included as git submodules:
+ [cbuild](https://github.com/Timerix22/cbuild) - my build system written in shell scripts
+ [kerep](https://github.com/Timerix22/kerep) - library with code i use in all my projects
+ [utf8proc](https://github.com/Timerix22/utf8proc/tree/my_branch) - unicode processing library
+ [resource_embedder](https://github.com/Timerix22/resource_embedder) - program that transforms files to array definitions in C

2
cbuild

@ -1 +1 @@
Subproject commit e8e42424d329ef1e75fb827ddf85d55b4cd89169
Subproject commit ef6a3f82c429ec232e1b910eecbdece76de933b3

View File

@ -1,6 +1,6 @@
#!/bin/bash
CBUILD_VERSION=6
CONFIG_VERSION=3
CBUILD_VERSION=7
CONFIG_VERSION=4
PROJECT="scolte"
CMP_C="gcc"
@ -14,6 +14,17 @@ SRC_CPP="$( find src -name '*.cpp')"
#TESTS_C="$( find tests -name '*.c')"
#TESTS_CPP="$(find tests -name '*.cpp')"
# dir with dependeicy dirs
DEPS_BASEDIR="."
# EXAMPLE: "dependency_dir='build_task out_dir lib_file'
# other_depndency_dir=..."
# Dependencies must be declared on separate lines
# Values can be override by resetting one of dependencies:
# DEPS="$DEPS
# dependency_dir='...'"
DEPS="kerep='build_static_lib bin libkerep.a'
utf8proc='libutf8proc.a . libutf8proc.a'"
# OBJDIR structure:
# ├── objects/ - dir where compiled *.o files are stored. cleans every call of build task
# ├── profile/ - dir where gcc *.gcda profiling info files stored
@ -41,12 +52,12 @@ case "$TASK" in
# -flto applies more optimizations across object files
# -flto=auto is needed to multithreaded copilation
# -fuse-linker-plugin is required to use static libs with lto, it strips away all
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=tasks/pre_build.sh
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
DEPS_BUILD_TASK=build_static_lib
;;
# creates executable with debug info and no optimizations
build_exec_dbg)
@ -55,7 +66,8 @@ case "$TASK" in
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=tasks/pre_build.sh
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
DEPS_BUILD_TASK=build_static_lib_dbg
DEPS="$DEPS
kerep='build_static_lib_dbg bin libkerep.a'"
;;
# executes $EXEC_FILE
exec)
@ -63,7 +75,7 @@ case "$TASK" in
;;
# executes $EXEC_FILE with valgrind memory checker
valgrind)
VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
;;
# generates profiling info
@ -95,6 +107,20 @@ case "$TASK" in
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT=cbuild/default_tasks/gprof.sh
;;
# compiles program and runs it with callgrind (part of valgrind)
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
# requires graphviz (https://www.graphviz.org/download/source/)
# P.S. detailed rezults can be viewed in KCacheGrind
callgrind)
OUTDIR="$OUTDIR/callgrind"
# -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=tasks/pre_build.sh
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
;;
# compiles executable with sanitizers and executes it to find errors and warnings
sanitize)
OUTDIR="$OUTDIR/sanitize"
@ -110,6 +136,9 @@ case "$TASK" in
TASK_SCRIPT=cbuild/default_tasks/clean.sh
POST_TASK_SCRIPT=tasks/clean_additions.sh
;;
# nothing to do
no_task)
;;
# unknown task
*)
error "task <$TASK> not found"

2
kerep

@ -1 +1 @@
Subproject commit 26b69f9b7bb7a816b8f048557efe0641428b9e80
Subproject commit aba67710c70c779fcf04af2bd01fb348ce75135d

1
resource_embedder Submodule

@ -0,0 +1 @@
Subproject commit 1708415900b0d5caed72c5e0aab3c5039517ee41

View File

@ -1,31 +0,0 @@
#include "tui_internal.h"
void Canvas_freeMembers(void* _self){
Canvas* self=(Canvas*)_self;
Autoarr_foreach(self->children, ch,
UIElement_destroy((UIElement*)ch));
Autoarr_freeWithoutMembers(self->children, true);
}
UI_Maybe Canvas_draw(Renderer* renderer, UIElement* _self, const DrawingArea area){
Canvas* self=(Canvas*)_self;
Autoarr_foreach(self->children, ch, ({
if(ch==NULL)
UI_safethrow(UIError_NullPtr,;);
UI_try(UIElement_draw(renderer, (UIElement*)ch, area),_,;);
}));
return MaybeNull;
}
kt_define(Canvas, Canvas_freeMembers, NULL);
Canvas* Canvas_create(){
Canvas* canvas=malloc(sizeof(Canvas));
canvas->base=__UIElement_createDefault(ktid_name(Canvas), Canvas_draw);
canvas->children=Autoarr_create(Pointer, 32, 64);
return canvas;
}
void Canvas_addChild(Canvas* self, UIElement* child){
Autoarr_add(self->children, child);
}

164
src/TUI/Dtsod/tui_dtsod.c Normal file
View File

@ -0,0 +1,164 @@
#include "../tui_internal.h"
#include "tui_dtsod_internal.h"
#include "../../../kerep/src/Filesystem/filesystem.h"
//////////////////////////////////////
// UIDtsodFileModel //
//////////////////////////////////////
void UIDtsodFileModel_freeMembers(void* _fm){
UIDtsodFileModel* fm=_fm;
DtsodV24_free(fm->dtsod);
// free(fm->dtsod_text);
// free(fm->file_name);
}
kt_define(UIDtsodFileModel, UIDtsodFileModel_freeMembers, NULL);
Autoarr_define(UIDtsodFileModel, false);
//////////////////////////////////////
// UIDtsodParser //
//////////////////////////////////////
void _UIDtsodParser_freeMembers(void* _p){
UIDtsodParser* p=_p;
Autoarr_free(p->file_models, true);
if(!p->returned_context && p->context!=NULL){
UIContext_destroy(p->context);
}
}
void UIDtsodParser_destroy(UIDtsodParser* p){
_UIDtsodParser_freeMembers(p);
free(p);
}
kt_define(UIDtsodParser, _UIDtsodParser_freeMembers, NULL);
UIDtsodParser* UIDtsodParser_create(){
UIDtsodParser* parser=malloc(sizeof(UIDtsodParser));
parser->context=NULL;
parser->returned_context=false;
parser->file_models=Autoarr_create(UIDtsodFileModel, 64, 32);
return parser;
}
///@return UI_Maybe<void>
UI_Maybe UIDtsodParser_parseFile(UIDtsodParser* parser, char* file_path){
UI_try(file_open(file_path, FileOpenMode_Read), _m_file, ;);
FileHandle file=_m_file.value.VoidPtr;
char* file_content=NULL;
UI_try(file_readAll(file, &file_content), _m_bcount, ;)
UI_try(file_close(file), _m_1563, free(file_content));
UI_try(UIDtsodParser_parseText(parser, file_path, file_content), _6561, free(file_content));
return MaybeNull;
}
UI_Maybe UIDtsodParser_parseText(UIDtsodParser* parser, char* file_name_placeholder, char* text){
UI_try(DtsodV24_deserialize(text), _m_dtsod, ;);
UIDtsodFileModel fm={
.file_name=file_name_placeholder,
.dtsod_text=text,
.dtsod=_m_dtsod.value.VoidPtr
};
Autoarr_add(parser->file_models, fm);
return MaybeNull;
}
UI_Maybe UIElement_deserialize(Dtsod* dtsod){
char* type_name;
Dtsod_tryGet_cptr(dtsod, "type", type_name, true);
UITDescriptor* type=UITDescriptor_getByName(type_name);
if(type==NULL)
UI_safethrow_msg(cptr_concat("invalid type '", type_name, "'"), ;);
if(type->deserialize==NULL)
UI_safethrow(UIError_NullPtr, ;);
UI_try(type->deserialize(dtsod), _m_ui, ;);
return _m_ui;
}
//////////////////////////////////////
// UIContext //
//////////////////////////////////////
void _UIContext_freeMembers(void* _u){
UIContext* u=_u;
Hashtable_free(u->ui_elements);
}
void UIContext_destroy(UIContext* u){
_UIContext_freeMembers(u);
free(u);
}
kt_define(UIContext, _UIContext_freeMembers, NULL);
UI_Maybe UIDtsodParser_constructUIContext(UIDtsodParser* parser){
if(parser->context == NULL){
parser->context=malloc(sizeof(UIContext));
parser->context->ui_elements=Hashtable_create();
}
Autoarr_foreach(parser->file_models, fm,
i32 file_parser_version;
Dtsod_tryGet_i64(fm.dtsod, "parser_version", file_parser_version, true);
if(file_parser_version!=UIDtsodParser_version){
UI_safethrow(UIError_InvalidVersion,;);
}
char* file_namespace;
Dtsod_tryGet_cptr(fm.dtsod, "namespace", file_namespace, true);
Hashtable_foreach(fm.dtsod, dtsod_elem,
if(cptr_equals(dtsod_elem.key, "ui")) {
if(!UniCheckTypePtr(dtsod_elem.value, Autoarr(Unitype)))
UI_safethrow(UIError_InvalidFormat, ;);
Autoarr_Unitype* ui_ar=dtsod_elem.value.VoidPtr;
Autoarr_foreach(ui_ar, ui_el_dtsod,
UI_try(UIElement_deserialize(ui_el_dtsod.VoidPtr),_m_ui,;);
UIElement_Ptr new_el=_m_ui.value.VoidPtr;
// kprintf("[UIDtsodParser_constructUIContext] %s : %s\n", new_el->name, new_el->type->kt->name);
if(new_el->type->onBuild){
UI_try(new_el->type->onBuild(new_el, parser->context),_15151,;);
}
UI_try( UIContext_add(parser->context, file_namespace, new_el), _a76515, ;);
);
}
);
);
Autoarr_free(parser->file_models,true);
parser->file_models=Autoarr_create(UIDtsodFileModel, 64, 32);
parser->returned_context=true;
return SUCCESS(UniHeapPtr(UIContext, parser->context));
}
UI_Maybe UIContext_getAny(UIContext* context, char* name){
Unitype val;
// check name
if(!Hashtable_tryGet(context->ui_elements, name, &val))
UI_safethrow_msg(cptr_concat("can't get <", name, "> from context"), ;);
return SUCCESS(val);
}
UI_Maybe _UIContext_get(UIContext* context, char* name, ktid type_id){
UI_try(UIContext_getAny(context, name), _m_ui, ;);
UIElement* ptr=_m_ui.value.VoidPtr;
if(ptr->type->kt->id != type_id)
UI_safethrow_msg(cptr_concat(
"tried to get ",ktDescriptor_get(type_id)->name, " <",name,"> but it is of type ", ptr->type->kt->name
), ;);
return _m_ui;
}
UI_Maybe UIContext_add(UIContext* context, char* namespace, _UIElement_Ptr _new_el){
UIElement_Ptr new_el=_new_el;
Unitype u=UniPtr(new_el->type->kt->id, new_el, true);
char* namespace_and_name=cptr_concat(namespace, "_", new_el->name);
if(!Hashtable_tryAdd(context->ui_elements, namespace_and_name, u))
UI_safethrow_msg(cptr_concat("element with name <", new_el->name, "> already exists in context"),
free(namespace_and_name));
return MaybeNull;
}

127
src/TUI/Dtsod/tui_dtsod.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../../kerep/src/DtsodParser/DtsodV24.h"
#include "../UIError.h"
typedef Hashtable Dtsod;
typedef void* _UIElement_Ptr;
/*
HOW TO USE:
UIDtsodParser* p=UIDtsodParser_create();
UI_try(UIDtsodParser_parseFile("some_file.tui.dtsod"), _91624, UIDtsodParser_destroy(p));
UI_try(UIDtsodParser_parseFile("another_file.tui.dtsod"), _95927, UIDtsodParser_destroy(p));
UI_try(UIDtsodParser_constructUIContext(p), _m_ui_context, UIDtsodParser_destroy(p));
UIContext* ui_context=_m_ui_context.value.VoidPtr;
UIDtsodParser_destroy(p);
UIContext_get(ui_context, example_namespace, text_box, TextBlock, UIContext_destroy(ui_context));
example_namespace_text_box->text=string_fromCptr("text replaced");
*/
//////////////////////////////////////
// UIDtsodParser //
//////////////////////////////////////
#define UIDtsodParser_version 1
typedef struct UIDtsodParser UIDtsodParser;
UIDtsodParser* UIDtsodParser_create();
void UIDtsodParser_destroy(UIDtsodParser* p);
///@return UI_Maybe<void>
UI_THROWING_FUNC_DECL(UIDtsodParser_parseFile(UIDtsodParser* parser, char* file_name));
///@return UI_Maybe<void>
UI_THROWING_FUNC_DECL(UIDtsodParser_parseText(UIDtsodParser* parser, char* file_name_placeholder, char* text));
///@return UI_Maybe<UIContext*>
UI_THROWING_FUNC_DECL(UIDtsodParser_constructUIContext(UIDtsodParser* parser));
//////////////////////////////////////
// UIContext //
//////////////////////////////////////
STRUCT(UIContext,
Hashtable* ui_elements;
)
void UIContext_destroy(UIContext* u);
UI_Maybe UIContext_getAny(UIContext* context, char* name);
///@return UI_Maybe<UIElement*>
UI_THROWING_FUNC_DECL(_UIContext_get(UIContext* context, char* name, ktid type_id));
#define UIContext_get(CONTEXT, NAMESPACE, NAME, TYPE, FREECALLS_ON_ERROR) \
UI_try( \
_UIContext_get(CONTEXT, #NAMESPACE "_" #NAME, ktid_ptrName(TYPE)), \
_m_##NAMESPACE##_##NAME, \
FREECALLS_ON_ERROR); \
TYPE* NAMESPACE##_##NAME=_m_##NAMESPACE##_##NAME.value.VoidPtr;
///@return Maybe<void>
UI_THROWING_FUNC_DECL(UIContext_add(UIContext* context, char* _namespace, _UIElement_Ptr new_el));
//////////////////////////////////////
// Deserialization //
//////////////////////////////////////
/// universal function for UIElement ancestors deserializing
/// @return Maybe<UIElement_Ptr>
UI_THROWING_FUNC_DECL( UIElement_deserialize(Dtsod* dtsod) );
#define _Dtsod_tryGet(dtsod, key, var_name, is_necessary, TYPE, TYPE_ID, UNI_FIELD, code...) { \
Unitype uni; \
if(Hashtable_tryGet(dtsod, key, &uni)) { \
if(!UniCheckTypeId(uni, TYPE_ID)) \
UI_safethrow_msg(cptr_concat("tried to get '",key,"' of type '",#TYPE, \
"', but got invalid type id '",toString_i64(uni.typeId),"'"), ;); \
var_name=uni.UNI_FIELD; \
{ code; } \
} \
else if(is_necessary) \
UI_safethrow_msg(cptr_concat("can't find key '", key, "'"), ;); \
}
#define Dtsod_tryGet_i64(dtsod, key, var_name, is_necessary, code...) \
_Dtsod_tryGet(dtsod, key, var_name, is_necessary, i64, ktid_name(i64), Int64, code)
#define Dtsod_tryGet_u64(dtsod, key, var_name, is_necessary, code...) \
_Dtsod_tryGet(dtsod, key, var_name, is_necessary, u64, ktid_name(u64), UInt64, code)
#define Dtsod_tryGet_f64(dtsod, key, var_name, is_necessary, code...) \
_Dtsod_tryGet(dtsod, key, var_name, is_necessary, f64, ktid_name(f64), Float64, code)
#define Dtsod_tryGet_bool(dtsod, key, var_name, is_necessary, code...) \
_Dtsod_tryGet(dtsod, key, var_name, is_necessary, bool, ktid_name(bool), Bool, code)
#define Dtsod_tryGet_ptr(dtsod, key, type, var_name, is_necessary, code...) \
_Dtsod_tryGet(dtsod, key, var_name, is_necessary, type*, ktid_ptrName(type), VoidPtr, code)
#define Dtsod_tryGet_cptr(dtsod, key, var_name, is_necessary, code...) \
Dtsod_tryGet_ptr(dtsod, key, char, var_name, is_necessary, code)
#define Dtsod_tryGet_Hashtable(dtsod, key, var_name, is_necessary, code...) \
Dtsod_tryGet_ptr(dtsod, key, Hashtable, var_name, is_necessary, code)
#define Dtsod_tryGet_Autoarr(dtsod, key, var_name, is_necessary, code...) \
Dtsod_tryGet_ptr(dtsod, key, Autoarr(Unitype), var_name, is_necessary, code)
#define Dtsod_tryGet_ScalingSize(dtsod, key, var_name, is_necessary, code...) { \
Unitype uni; \
if(Hashtable_tryGet(dtsod, key, &uni)) { \
UI_try(ScalingSize_fromUnitype(uni, &(var_name)), _195, ;); \
{ code; } \
} \
else if(is_necessary) \
UI_safethrow_msg(cptr_concat("can't find key '", key, "'"), ;); \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,17 @@
#pragma once
#include "tui_dtsod.h"
STRUCT(UIDtsodFileModel,
char* file_name;
char* dtsod_text;
Dtsod* dtsod;
)
Autoarr_declare(UIDtsodFileModel)
STRUCT(UIDtsodParser,
Autoarr(UIDtsodFileModel)* file_models;
UIContext* context;
bool returned_context;
)

217
src/TUI/Grid.c Normal file
View File

@ -0,0 +1,217 @@
#include "tui_internal.h"
#define grid_validate() \
if(row >= grid->rows) UI_safethrow(UIError_InvalidY,;); \
if(column >= grid->columns) UI_safethrow(UIError_InvalidX,;);
UI_Maybe Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value){
grid_validate();
UIElement_Ptr* ptr_ptr = grid->content + grid->columns*row + column;
*ptr_ptr=value;
return MaybeNull;
}
UI_Maybe Grid_get(Grid* grid, u16 column, u16 row){
grid_validate();
UIElement_Ptr* ptr_ptr = grid->content + grid->columns*row + column;
return SUCCESS(UniHeapPtr(UIElement, *ptr_ptr));
}
UI_Maybe _Grid_getName(Grid* grid, u16 column, u16 row) {
grid_validate();
char** str_ptr = grid->content_names + grid->columns*row + column;
return SUCCESS(UniHeapPtr(char, *str_ptr));
}
UI_Maybe Grid_onBuildUIContext(UIElement* _grid, UIContext* context) {
Grid* grid=(Grid*)_grid;
Autoarr(UIElement_Ptr)* content=Autoarr_create(UIElement_Ptr, 64, 16);
Grid_foreachName(grid, name,
UI_try(UIContext_getAny(context, name), m_uie, Autoarr_freeWithoutMembers(content,true));
UIElement_Ptr uie=m_uie.value.VoidPtr;
Autoarr_add(content, uie);
);
free(grid->content_names);
grid->content_names=NULL;
grid->content=Autoarr_toArray(content);
Autoarr_freeWithoutMembers(content, true);
return MaybeNull;
}
void Grid_freeMembers(void* _self){
Grid* self=(Grid*)_self;
free(self->column_widths);
free(self->row_heights);
if(self->content_names){
for(u16 r = 0; r < self->rows; r++){
for(u16 c = 0; c < self->columns; c++){
tryLast(Grid_get(self, c, r), m_el,
free(self->content);
free(self->content_names));
UIElement_Ptr el=m_el.value.VoidPtr;
UIElement_destroy(el);
}
}
free(self->content_names);
}
else free(self->content);
}
UI_Maybe Grid_draw(Renderer* renderer, UIElement_Ptr _self, const DrawingArea area){
Grid* self=(Grid*)_self;
Grid_foreach(self, el,
if(el==NULL)
UI_safethrow(UIError_NullPtr,;);
UI_try(UIElement_draw(renderer, el, area),_,;);
);
return MaybeNull;
}
UI_Maybe Grid_deserialize(Dtsod* dtsod){
Grid gr;
u16 columns=0, rows=0;
Autoarr(i16)* column_widths=Autoarr_create(i16, 16, 64);
Autoarr(i16)* row_heights=Autoarr_create(i16, 16, 64);
Autoarr(Pointer)* content_names=Autoarr_create(Pointer, 64, 16);
UI_try(UIElement_deserializeBase(dtsod, &gr.base), _91875, ;);
Autoarr(Unitype)* _column_widths;
Dtsod_tryGet_Autoarr(dtsod, "column_widths", _column_widths, true,
Autoarr_foreach(_column_widths, _cw,
ScalingSize cw;
UI_try(ScalingSize_fromUnitype(_cw, &cw), _18751,
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(column_widths, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
Autoarr_add(column_widths, cw);
);
);
columns=Autoarr_length(column_widths);
Autoarr(Unitype)* _row_heights;
Dtsod_tryGet_Autoarr(dtsod, "row_heights", _row_heights, true,
Autoarr_foreach(_row_heights, _rh,
ScalingSize rh;
UI_try(ScalingSize_fromUnitype(_rh, &rh), _18751,
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(row_heights, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
Autoarr_add(row_heights, rh);
);
);
rows=Autoarr_length(row_heights);
Autoarr(Unitype)* _content;
Dtsod_tryGet_Autoarr(dtsod, "content", _content, true);
if(rows != Autoarr_length(_content))
UI_safethrow(UIError_InvalidGrid,
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(column_widths, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
Autoarr_foreach(_content, _row,
if(!UniCheckTypePtr(_row, Autoarr(Unitype)))
UI_safethrow_msg(
cptr_concat("expected type Autoarr(Unitype), but has got type id '",
toString_i64(_row.typeId), "'"),
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(column_widths, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
Autoarr(Unitype)* row=_row.VoidPtr;
if(columns != Autoarr_length(row))
UI_safethrow(UIError_InvalidGrid,
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(column_widths, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
Autoarr_foreach(row, _elem_d,
if(!UniCheckTypePtr(_elem_d, char))
UI_safethrow_msg(
cptr_concat("expected type char*, but has got type id '",
toString_i64(_elem_d.typeId),"'"),
Autoarr_freeWithoutMembers(content_names, true);
Autoarr_freeWithoutMembers(column_widths, true);
Autoarr_freeWithoutMembers(row_heights, true);
);
char* elem_name=_elem_d.VoidPtr;
Autoarr_add(content_names, elem_name);
)
);
gr.content_names=(char**)Autoarr_toArray(content_names);
Autoarr_freeWithoutMembers(content_names, true);
gr.columns=columns;
gr.rows=rows;
gr.column_widths=Autoarr_toArray(column_widths);
Autoarr_freeWithoutMembers(column_widths, true);
gr.row_heights=Autoarr_toArray(row_heights);
Autoarr_freeWithoutMembers(row_heights, true);
gr.content=NULL;
Grid* ptr=malloc(sizeof(*ptr));
*ptr=gr;
return SUCCESS(UniHeapPtr(Grid, ptr));
}
char* Grid_toString(void* _gr, kp_fmt fmt){
Grid* gr=_gr;
StringBuilder* sb=StringBuilder_create();
adds("Grid {")
UIElement_appendToStringBuilder(sb, &gr->base);
adduf(gr,rows)
adduf(gr,columns)
adds(" row_heights: [ ")
for(u16 r=0; r < gr->rows; r++){
addi(gr->row_heights[r]) addc(' ')
}
adds("]"
" column_widths: [ ")
for(u16 c=0; c < gr->rows; c++){
addi(gr->row_heights[c]) addc(' ')
}
u32 count=gr->rows*gr->columns;
adds("]"
" content: [")
if(gr->content)
for(u32 i=0; i<count; i++){
UIElement_Ptr child=gr->content[i];
addc(' ')adds(child->name)addc(':')adds(child->type->kt->name)
}
else if(gr->content_names)
for(u32 i=0; i<count; i++){
char* child_name=gr->content_names[i];
addc(' ')adds(child_name)
}
adds(" ]"
" }")
return StringBuilder_build(sb).ptr;
}
uit_define(Grid, Grid_freeMembers, Grid_toString, Grid_draw, Grid_deserialize, Grid_onBuildUIContext);
Grid* Grid_create(char* name,
u16 columns, u16 rows,
ScalingSize* column_widths, ScalingSize* row_heights,
UIElement_Ptr* content)
{
Grid* grid=malloc(sizeof(Grid));
*grid=(Grid){
.base=_UIElement_initBaseDefault(name, &UITDescriptor_Grid),
.columns=columns,
.rows=rows,
.column_widths=column_widths,
.row_heights=row_heights,
.content=content,
.content_names=NULL
};
return grid;
}

View File

@ -1,10 +1,5 @@
#include "tui_internal.h"
int TCI_fwrite(FILE* file, TermCharInfo tci){
kprint_setColor(tci.color);
return termchar_fwrite(file, tci.ch);
}
//////////////////////////////////////
// FrameBuffer //
//////////////////////////////////////
@ -17,8 +12,7 @@ void FrameBuffer_freeMembers(void* _self){
kt_define(FrameBuffer, FrameBuffer_freeMembers, NULL);
/// creates new frame buffer and fills it with spaces
UI_THROWING_FUNC_DECL(FrameBuffer_create(FrameBuffer* fb));
Maybe FrameBuffer_create(FrameBuffer* fb){
void FrameBuffer_recreate(FrameBuffer* fb){
if(!term_getSize(&fb->size)){
fb->size=term_default_size;
//TODO log error
@ -31,8 +25,6 @@ Maybe FrameBuffer_create(FrameBuffer* fb){
for(u32 i=0; i<length; i++)
fb->data[i]=TCI(TERMCHAR(' '), kp_bgGray|kp_fgGray);
return MaybeNull;
}
void Renderer_freeMembers(void * _self){
@ -59,7 +51,7 @@ UI_Maybe __Renderer_drawFrame(Renderer* self){
// save current buffer
FrameBuffer buf=self->frameBuffer;
// recreate frame buffer
UI_try(FrameBuffer_create(&self->frameBuffer),_,;);
FrameBuffer_recreate(&self->frameBuffer);
for(u16 y=0; y<buf.size.rows; y++){
for(u16 x=0; x<buf.size.cols; x++){
@ -91,7 +83,7 @@ kt_define(Renderer, Renderer_freeMembers, NULL);
Renderer* Renderer_create(){
Renderer* renderer=malloc(sizeof(Renderer));
tryLast(FrameBuffer_create(&renderer->frameBuffer),_);
FrameBuffer_recreate(&renderer->frameBuffer);
renderer->set=__Renderer_set;
renderer->drawFrame=__Renderer_drawFrame;
return renderer;

View File

@ -1,13 +1,13 @@
#include "tui_internal.h"
void TextBlock_freeMembers(void* _self){
TextBlock* self=(TextBlock*)_self;
free(self->text.ptr);
// TextBlock* self=(TextBlock*)_self;
// free(self->text.ptr);
}
UI_Maybe TextBlock_draw(Renderer* renderer, UIElement* _self, const DrawingArea area){
UI_Maybe TextBlock_draw(Renderer* renderer, UIElement_Ptr _self, const DrawingArea area){
TextBlock* self=(TextBlock*)_self;
UI_try(UIElement_validate((UIElement*)self, area),_0,;);
UI_try(UIElement_validate((UIElement_Ptr)self, area),_0,;);
UI_try(Renderer_fill(renderer, TCI(TERMCHAR(' '), kp_bgBlack|kp_fgGray), area),_2,;);
UI_try(Renderer_drawBorder(renderer, self->base.border, area),_1,;);
for(u16 i=0; i<area.w-2 && i<self->text.length; i++){
@ -18,11 +18,34 @@ UI_Maybe TextBlock_draw(Renderer* renderer, UIElement* _self, const DrawingArea
return MaybeNull;
}
kt_define(TextBlock, TextBlock_freeMembers, NULL);
UI_Maybe TextBlock_deserialize(Dtsod* dtsod){
TextBlock tb;
TextBlock* TextBlock_create(string text){
UI_try(UIElement_deserializeBase(dtsod, &tb.base), _8751, ;);
char* _text;
Dtsod_tryGet_cptr(dtsod, "text", _text, true);
tb.text=string_fromCptr(_text);
TextBlock* ptr=malloc(sizeof(*ptr));
*ptr=tb;
return SUCCESS(UniHeapPtr(TextBlock, ptr));
}
char* TextBlock_toString(void* _tb, kp_fmt fmt){
TextBlock* tb=_tb;
StringBuilder* sb=StringBuilder_create();
adds("TextBlock {")
UIElement_appendToStringBuilder(sb, &tb->base);
addstrf(tb,text)
adds(" }")
return StringBuilder_build(sb).ptr;
}
uit_define(TextBlock, TextBlock_freeMembers, TextBlock_toString, TextBlock_draw, TextBlock_deserialize, NULL);
TextBlock* TextBlock_create(char* name, string text){
TextBlock* textBlock=malloc(sizeof(TextBlock));
textBlock->base=__UIElement_createDefault(ktid_name(TextBlock), TextBlock_draw);
textBlock->text=string_copy(text);
textBlock->base=_UIElement_initBaseDefault(name, &UITDescriptor_TextBlock);
textBlock->text=text;
return textBlock;
}

View File

@ -1,50 +1,118 @@
#include "tui_internal.h"
kt_define(UIElement, NULL, NULL);
void UIElement_appendToStringBuilder(StringBuilder* sb, UIElement_Ptr u){
char *s0;
addsf(u,name) addc(' ')
adds((s0=UITDescriptor_toString(u->type)));
adduf(u,min_width)
adduf(u,min_height)
addif(u,width)
addif(u,height)
adds(" color:") adds(kp_bgColor_toString(u->color))
addc('|') adds(kp_fgColor_toString(u->color))
adds(" border { t:") addu(u->border.top)
adds(" b:") addu(u->border.bottom)
adds(" l:") addu(u->border.left)
adds(" r:") addu(u->border.right)
adds(" color:") adds(kp_bgColor_toString(u->color))
addc('|') adds(kp_fgColor_toString(u->color))
adds(" }")
free(s0);
}
kt_define(UIElement, NULL, NULL);
Autoarr_define(UIElement_Ptr, true);
Array_define(UIElement);
// ktid is needed to check if it is uninitilized by calling ktDescriptor_get
UIElement __UIElement_createDefault(ktid typeId, UIElement_draw_t drawFunc){
inline UIElement _UIElement_initBaseDefault(char* name, UITDescriptor* uit){
return (UIElement){
.type=ktDescriptor_get(typeId),
.name=name,
.type=uit,
.min_width=2,
.max_width=UIElement_stretch,
.min_height=2,
.max_height=UIElement_stretch,
.fgColor=kp_fgWhite,
.bgColor=kp_bgBlack,
.anchor=UIAnchor_Center,
.width=size_enable_scaling(1),
.height=size_enable_scaling(1),
.color=kp_bgBlack|kp_fgGray,
.border={
.left=UIBorder_Thin, .right=UIBorder_Thin,
.top=UIBorder_Thin, .bottom=UIBorder_Thin,
.color=kp_bgBlack|kp_fgGray
},
.draw=drawFunc
};
}
void UIElement_destroy(UIElement* self){
if(self->type->freeMembers)
self->type->freeMembers(self);
void UIElement_destroy(UIElement_Ptr self){
if(self->type->kt->freeMembers)
self->type->kt->freeMembers(self);
free(self);
}
UI_Maybe DrawingArea_validate(DrawingArea a){
if(a.h<1) UI_safethrow(UIError_InvalidWidth,;);
if(a.w<1) UI_safethrow(UIError_InvalidHeight,;);
return MaybeNull;
}
UI_Maybe UIElement_validate(UIElement* u, DrawingArea a){
UI_Maybe UIElement_validate(UIElement_Ptr u, DrawingArea a){
UI_try(DrawingArea_validate(a),_,;);
if(u->max_height<u->min_height)
UI_safethrow(UIError_InvalidHeight,;);
if(u->max_width<u->min_width)
UI_safethrow(UIError_InvalidWidth,;);
if(u->min_height>a.h)
UI_safethrow(UIError_InvalidHeight,;);
if(u->min_width>a.w)
UI_safethrow(UIError_InvalidWidth,;);
return MaybeNull;
}
UI_Maybe UIElement_deserializeBase(Dtsod* dtsod, UIElement* base){
char* name;
Dtsod_tryGet_cptr(dtsod, "name", name, true);
char* type_name;
Dtsod_tryGet_cptr(dtsod, "type", type_name, true);
UITDescriptor* type=UITDescriptor_getByName(type_name);
if(type==NULL)
UI_safethrow_msg(cptr_concat("invalid type '", type_name, "'"), ;);
*base=_UIElement_initBaseDefault(cptr_copy(name), type);
Dtsod_tryGet_i64(dtsod, "min_width", base->min_width, false);
Dtsod_tryGet_i64(dtsod, "min_height", base->min_height, false);
Dtsod_tryGet_ScalingSize(dtsod, "width", base->width, false);
Dtsod_tryGet_ScalingSize(dtsod, "height", base->height, false);
char *bg_color_name, *fg_color_name;
Dtsod_tryGet_cptr(dtsod, "bg_color", bg_color_name, false,
set_color(bg_color_name, base->color);
);
Dtsod_tryGet_cptr(dtsod, "fg_color", fg_color_name, false,
set_color(fg_color_name, base->color);
);
base->border.color=base->color;
Dtsod* border_dtsod;
Dtsod_tryGet_Hashtable(dtsod, "border", border_dtsod, false, {
char* border_thickness_str;
Dtsod_tryGet_cptr(border_dtsod, "top", border_thickness_str, false,
set_border_thickness(border_thickness_str, base->border.top);
);
Dtsod_tryGet_cptr(border_dtsod, "bottom", border_thickness_str, false,
set_border_thickness(border_thickness_str, base->border.bottom);
);
Dtsod_tryGet_cptr(border_dtsod, "left", border_thickness_str, false,
set_border_thickness(border_thickness_str, base->border.left);
);
Dtsod_tryGet_cptr(border_dtsod, "right", border_thickness_str, false,
set_border_thickness(border_thickness_str, base->border.right);
);
char *bg_color_name, *fg_color_name;
Dtsod_tryGet_cptr(dtsod, "bg_color", bg_color_name, false,
set_color(bg_color_name, base->border.color);
);
Dtsod_tryGet_cptr(dtsod, "fg_color", fg_color_name, false,
set_color(fg_color_name, base->border.color);
);
});
return MaybeNull;
}

View File

@ -7,11 +7,15 @@ extern "C" {
#include "../../kerep/src/base/base.h"
PACKED_ENUM(UIError,
UIError_Success=0,
UIError_Success=ERR_IO_EOF+1,
UIError_NotImplemented,
UIError_NullPtr,
UIError_InvalidHeight, UIError_InvalidWidth,
UIError_InvalidX, UIError_InvalidY,
UIError_PrintError
UIError_PrintError,
UIError_InvalidVersion,
UIError_InvalidGrid,
UIError_InvalidFormat
)
// this macros can be changed later to improve debugging

109
src/TUI/enums_getByName.c Normal file
View File

@ -0,0 +1,109 @@
#include "tui_internal.h"
#define enum_pair(name, value) { cptr_copy(name), UniUInt64(value) }
Hashtable* _colors_table=NULL;
void termcolor_table_init(){
_colors_table=Hashtable_create();
KVPair pairs[]={
enum_pair("black", kp_bgBlack|kp_fgBlack),
enum_pair("white", kp_bgWhite|kp_fgWhite),
enum_pair("gray", kp_bgGray|kp_fgGray),
enum_pair("red", kp_bgRed|kp_fgRed),
enum_pair("green", kp_bgGreen|kp_fgGreen),
enum_pair("yellow", kp_bgYellow|kp_fgYellow),
enum_pair("blue", kp_bgBlue|kp_fgBlue),
enum_pair("magenta", kp_bgMagenta|kp_fgMagenta),
enum_pair("cyan", kp_bgCyan|kp_fgCyan),
enum_pair("gray_dark", kp_bgGrayD|kp_fgGrayD),
enum_pair("red_dark", kp_bgRedD|kp_fgRedD),
enum_pair("green_dark", kp_bgGreenD|kp_fgGreenD),
enum_pair("yellow_dark", kp_bgYellowD|kp_fgYellowD),
enum_pair("blue_dark", kp_bgBlueD|kp_fgBlueD),
enum_pair("magenta_dark", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("cyan_dark", kp_bgCyanD|kp_fgCyanD),
enum_pair("dark_gray", kp_bgGrayD|kp_fgGrayD),
enum_pair("dark_red", kp_bgRedD|kp_fgRedD),
enum_pair("dark_green", kp_bgGreenD|kp_fgGreenD),
enum_pair("dark_yellow", kp_bgYellowD|kp_fgYellowD),
enum_pair("dark_blue", kp_bgBlueD|kp_fgBlueD),
enum_pair("dark_magenta", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("dark_cyan", kp_bgCyanD|kp_fgCyanD),
enum_pair("gray_d", kp_bgGrayD|kp_fgGrayD),
enum_pair("red_d", kp_bgRedD|kp_fgRedD),
enum_pair("green_d", kp_bgGreenD|kp_fgGreenD),
enum_pair("yellow_d", kp_bgYellowD|kp_fgYellowD),
enum_pair("blue_d", kp_bgBlueD|kp_fgBlueD),
enum_pair("magenta_d", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("cyan_d", kp_bgCyanD|kp_fgCyanD),
enum_pair("d_gray", kp_bgGrayD|kp_fgGrayD),
enum_pair("d_red", kp_bgRedD|kp_fgRedD),
enum_pair("d_green", kp_bgGreenD|kp_fgGreenD),
enum_pair("d_yellow", kp_bgYellowD|kp_fgYellowD),
enum_pair("d_blue", kp_bgBlueD|kp_fgBlueD),
enum_pair("d_magenta", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("d_cyan", kp_bgCyanD|kp_fgCyanD),
enum_pair("gray_d", kp_bgGrayD|kp_fgGrayD),
enum_pair("red_d", kp_bgRedD|kp_fgRedD),
enum_pair("green_d", kp_bgGreenD|kp_fgGreenD),
enum_pair("yellow_d", kp_bgYellowD|kp_fgYellowD),
enum_pair("blue_d", kp_bgBlueD|kp_fgBlueD),
enum_pair("magenta_d", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("cyan_d", kp_bgCyanD|kp_fgCyanD),
enum_pair("dgray", kp_bgGrayD|kp_fgGrayD),
enum_pair("dred", kp_bgRedD|kp_fgRedD),
enum_pair("dgreen", kp_bgGreenD|kp_fgGreenD),
enum_pair("dyellow", kp_bgYellowD|kp_fgYellowD),
enum_pair("dblue", kp_bgBlueD|kp_fgBlueD),
enum_pair("dmagenta", kp_bgMagentaD|kp_fgMagentaD),
enum_pair("dcyan", kp_bgCyanD|kp_fgCyanD),
};
Hashtable_addMany(_colors_table, pairs, sizeof(pairs)/sizeof(KVPair));
}
Hashtable* _border_t_table=NULL;
void UIBorderThickness_table_init(){
_border_t_table=Hashtable_create();
KVPair pairs[]={
enum_pair("hidden", UIBorder_Hidden),
enum_pair("0", UIBorder_Hidden),
enum_pair("thin", UIBorder_Thin),
enum_pair("0.5", UIBorder_Thin),
enum_pair("thick", UIBorder_Thick),
enum_pair("1", UIBorder_Thick),
enum_pair("double", UIBorder_Double),
enum_pair("2", UIBorder_Double),
enum_pair("noborder", UiBorder_NoBorder),
enum_pair("no", UiBorder_NoBorder)
};
Hashtable_addMany(_border_t_table, pairs, sizeof(pairs)/sizeof(KVPair));
}
void UI_enum_tables_init(){
termcolor_table_init();
UIBorderThickness_table_init();
}
void UI_enum_tables_free(){
Hashtable_free(_colors_table);
Hashtable_free(_border_t_table);
}
int enum_getByName(Hashtable* table, char* name){
char* name_lower=cptr_toLower(name);
Unitype uni;
if(!Hashtable_tryGet(table, name_lower, &uni))
return -1;
free(name_lower);
return uni.UInt64;
}
int termcolor_getByName(char* name){ return enum_getByName(_colors_table, name); }
int UIBorderThickness_getByName(char* name){ return enum_getByName(_border_t_table, name); }

View File

@ -1,12 +1,130 @@
#include "tui.h"
#include "tui_internal.h"
#include "Dtsod/tui_dtsod_internal.h"
kt_define(DrawingArea, NULL, NULL);
kt_define(UIBorder, NULL, NULL);
UI_Maybe ScalingSize_fromUnitype(Unitype UNI, ScalingSize* SZ_VAR){
if(UniCheckType(UNI, i64)){
*SZ_VAR=UNI.Int64;
} else if(UniCheckTypePtr(UNI, char)){
char* _sz_str=UNI.VoidPtr;
u32 len=cptr_length(_sz_str);
bool has_asterisk=_sz_str[len-1]=='0';
if(has_asterisk)
_sz_str[len-1]=0;
int _sz=0;
if(sscanf(_sz_str, "%i", &_sz)!=1)
UI_safethrow(UIError_InvalidFormat, ;);
if(has_asterisk)
_sz=size_enable_scaling(_sz);
*SZ_VAR=_sz;
} else UI_safethrow_msg(
cptr_concat("expected type i64 or char*, but has got type id '",
toString_i64(UNI.typeId), "'"),;);
return MaybeNull;
}
//////////////////////////////////////
// TUI type system //
//////////////////////////////////////
char* UITDescriptor_toString(UITDescriptor* d){
const char* n="NULL";
char *s0=ktDescriptor_toString(d->kt);
char *s1= d->draw ? toString_hex(d->draw, sizeof(void*), 0,1,0) : n;
char *s2= d->deserialize ? toString_hex(d->deserialize, sizeof(void*), 0,1,0) : n;
char *s3= d->onBuild ? toString_hex(d->onBuild, sizeof(void*), 0,1,0) : n;
char* rez=cptr_concat("UITDescriptor { ",
s0,
" draw:",s1,
" deserialize:",s2,
" onBuild:",s3,
" }");
if(s0!=n) free(s0);
if(s1!=n) free(s1);
if(s2!=n) free(s2);
if(s3!=n) free(s3);
return rez;
}
char* _UITDescriptor_toString(void* _d, u32 fmt){ return UITDescriptor_toString(_d); }
kt_define(UITDescriptor, NULL, _UITDescriptor_toString);
Hashtable* _uit_hashtable=NULL;
u32 __kt_id_first=-1;
Autoarr(Pointer)* __uit_temp_arr=NULL;
UITDescriptor** __uit_descriptors=NULL;
/// call this between kt_beginInit() and kt_endInit()
void kt_beginInitTUI(){
_uit_hashtable=Hashtable_create();
__kt_id_first=ktid_last;
__uit_temp_arr=Autoarr_create(Pointer, 32, 32);
}
/// call this between kt_beginInit() and kt_endInit()
void kt_endInitTUI(){
__uit_descriptors=(UITDescriptor**)Autoarr_toArray(__uit_temp_arr);
Autoarr_free(__uit_temp_arr, true);
}
void kt_freeTUI(){
free(__uit_descriptors);
Hashtable_free(_uit_hashtable);
}
void __uit_register(ktDescriptor* kt, UITDescriptor* uit){
uit->kt=kt;
Hashtable_add(_uit_hashtable, cptr_copy(kt->name), UniStackPtr(UITDescriptor, uit));
}
UITDescriptor* UITDescriptor_getById(ktid id){
if(id > ktid_last)
throw(ERR_WRONGINDEX);
if(__uit_descriptors==NULL)
throw(ERR_NULLPTR);
return __uit_descriptors[id - __kt_id_first];
}
///@return NULL if not found
UITDescriptor* UITDescriptor_getByName(char* name){
Unitype val=Hashtable_get(_uit_hashtable, name);
if(Unitype_isUniNull(val)){
char* name_ptr=cptr_concat(name,"_Ptr");
val=Hashtable_get(_uit_hashtable, name_ptr);
free(name_ptr);
}
return val.VoidPtr;
}
void kt_initScolteTypes(){
// term.h
kt_register(TerminalSize);
kt_register(TermCharInfo);
// tui.h
kt_register(UITDescriptor)
kt_register(DrawingArea);
kt_register(UIBorder);
kt_register(FrameBuffer);
kt_register(Renderer);
kt_register(UIElement);
kt_register(Canvas);
kt_register(TextBlock);
uit_register(Grid);
uit_register(TextBlock);
// tui_dtsod.h
kt_register(UIDtsodFileModel);
kt_register(UIDtsodParser);
kt_register(UIContext);
}
/// call this between kt_beginInitTUI() and kt_endInitTUI()
void Scolte_init(){
kt_initScolteTypes();
UI_enum_tables_init();
}
// call this before kt_free()
void Scolte_free(){
UI_enum_tables_free();
kt_freeTUI();
}

View File

@ -5,33 +5,65 @@ extern "C" {
#endif
#include "../../kerep/src/String/string.h"
#include "../../kerep/src/kprint/kprint_format.h"
#include "../../kerep/src/Array/Array.h"
#include "../term/term.h"
#include "../encoding/encoding.h"
#include "Dtsod/tui_dtsod.h"
#include "UIError.h"
//////////////////////////////////////
// Prototypes //
//////////////////////////////////////
/// initializes type descriptors for this project's types
/// call this function between kt_beginInit() and kt_endInit()
void kt_initScolteTypes();
typedef struct UIElement UIElement;
typedef UIElement* UIElement_Ptr;
typedef struct Renderer Renderer;
typedef struct DrawingArea DrawingArea;
///@return Maybe<void>
typedef UI_THROWING_FUNC_DECL( (*UIElement_draw_t)(Renderer* renderer, UIElement_Ptr self, const DrawingArea area) );
///@return Maybe<UIElement_Ptr>
typedef UI_THROWING_FUNC_DECL( (*UIElement_deserialize_t)(Dtsod* dtsod) );
///@return Maybe<void>
typedef UI_THROWING_FUNC_DECL( (*UIElement_onBuildUIContext_t)(UIElement* self, UIContext* context) );
//////////////////////////////////////
// UI Type System //
//////////////////////////////////////
STRUCT(UITDescriptor,
ktDescriptor* kt;
UIElement_draw_t draw;
UIElement_deserialize_t deserialize;
UIElement_onBuildUIContext_t onBuild;
)
#define uit_declare(TYPE) extern UITDescriptor UITDescriptor_##TYPE;
#define uit_define(TYPE, FREE_F, TOSTRING_F, DRAW_F, DESERIALIZE_F, ON_BUILD_F) kt_define(TYPE, FREE_F, TOSTRING_F) \
UITDescriptor UITDescriptor_##TYPE={ \
.draw=DRAW_F, \
.deserialize=DESERIALIZE_F, \
.onBuild=ON_BUILD_F \
};
/// call this between kt_beginInit() and kt_endInit()
void kt_beginInitTUI();
/// call this between kt_beginInitTUI() and kt_endInitTUI()
void Scolte_init();
/// call this between kt_beginInit() and kt_endInit()
void kt_endInitTUI();
// call this before kt_free()
void Scolte_free();
UITDescriptor* UITDescriptor_getById(ktid i);
UITDescriptor* UITDescriptor_getByName(char* name);
//////////////////////////////////////
// Enums //
//////////////////////////////////////
PACKED_ENUM(UIAnchor,
UIAnchor_Center=0,
UIAnchor_Left=1,
UIAnchor_Right=2,
UIAnchor_Top=4,
UIAnchor_Bottom=8,
UIAnchor_RightTop=UIAnchor_Right|UIAnchor_Top,
UIAnchor_RightBottom=UIAnchor_Right|UIAnchor_Bottom,
UIAnchor_LeftTop=UIAnchor_Left|UIAnchor_Top,
UIAnchor_LeftBottom=UIAnchor_Left|UIAnchor_Bottom
)
PACKED_ENUM(UIBorderThickness,
UIBorder_Hidden, /* blank space */
UIBorder_Thin,
@ -40,10 +72,19 @@ PACKED_ENUM(UIBorderThickness,
UiBorder_NoBorder /* no space */
)
//////////////////////////////////////
// Small structs //
//////////////////////////////////////
typedef i16 ScalingSize;
#define is_size_scaling(SZ) (SZ<0)
#define size_enable_scaling(SZ) (SZ < 0 ? SZ : (-1*SZ))
#define size_disable_scaling(SZ) (SZ >= 0 ? SZ : (-1*SZ))
///@return Maybe<void>
UI_THROWING_FUNC_DECL( ScalingSize_fromUnitype(Unitype UNI, ScalingSize* SZ_VAR) );
STRUCT(DrawingArea,
/* right-top corner */
u16 x; u16 y;
@ -55,17 +96,9 @@ STRUCT(UIBorder,
UIBorderThickness left;
UIBorderThickness top;
UIBorderThickness bottom;
kp_fmt color;
termcolor color;
)
STRUCT(TermCharInfo,
termchar ch;
kp_fmt color; /* background + foreground */
)
#define TCI(CH,COLOR)(TermCharInfo){.ch=CH, .color=COLOR}
int TCI_fwrite(FILE* file, TermCharInfo tci);
#define TCI_print(tci) TCI_fwrite(stdout, tci);
//////////////////////////////////////
// Renderer //
@ -95,49 +128,81 @@ UI_THROWING_FUNC_DECL(Renderer_drawLineX(Renderer* renderer, TermCharInfo tci, u
UI_THROWING_FUNC_DECL(Renderer_drawLineY(Renderer* renderer, TermCharInfo tci, u16 x, u16 y, u16 length));
UI_THROWING_FUNC_DECL(Renderer_drawBorder(Renderer* renderer, UIBorder border, const DrawingArea area));
//////////////////////////////////////
// UIElement abstract struct //
//////////////////////////////////////
typedef struct UIElement UIElement;
typedef UIElement* UIElementPtr;
typedef UI_THROWING_FUNC_DECL((*UIElement_draw_t)(Renderer* renderer, UIElement* self, const DrawingArea area));
#define UIElement_stretch (u16)-1
STRUCT(UIElement,
ktDescriptor* type;
UITDescriptor* type;
char* name;
u16 min_width;
u16 max_width;
u16 min_height;
u16 max_height;
kp_fgColor fgColor;
kp_bgColor bgColor;
UIAnchor anchor;
ScalingSize width;
ScalingSize height;
termcolor color;
UIBorder border;
UIElement_draw_t draw;
)
Autoarr_declare(UIElement_Ptr)
Array_declare(UIElement)
/// proper way to free UIElement and all its members
void UIElement_destroy(UIElement* self);
void UIElement_destroy(UIElement_Ptr self);
#define UIElement_draw(RENDERER, UIE_PTR, PLACE_RECT) \
((UIElement*)UIE_PTR)->draw(RENDERER, UIE_PTR, PLACE_RECT)
(UIE_PTR)->type->draw(RENDERER, UIE_PTR, PLACE_RECT)
//////////////////////////////////////
// UIElement derivatives //
//////////////////////////////////////
////// Canvas //////
////// Grid //////
STRUCT(Canvas,
STRUCT(Grid,
UIElement base;
/* Autoarr(UIElementPtr) */
Autoarr(Pointer)* children;
u16 columns;
u16 rows;
ScalingSize* row_heights;
ScalingSize* column_widths;
char** content_names;
UIElement_Ptr* content; /* UIElement[rows][columns] */
)
uit_declare(Grid);
Canvas* Canvas_create();
void Canvas_addChild(Canvas* self, UIElement* child);
Grid* Grid_create(char* name, u16 columns, u16 rows, ScalingSize* column_widths, ScalingSize* row_heights, UIElement_Ptr* content);
///@return Maybe<UIElement*>
UI_THROWING_FUNC_DECL( Grid_get(Grid* grid, u16 column, u16 row) );
///@return maybe<void>
UI_THROWING_FUNC_DECL( Grid_set(Grid* grid, u16 column, u16 row, UIElement_Ptr value));
///@return Maybe<char*>
UI_THROWING_FUNC_DECL( _Grid_getName(Grid* grid, u16 column, u16 row) );
#define Grid_foreach(GRID, ELEM_VAR_NAME, CODE...) { \
if(!GRID->content) \
UI_safethrow_msg(cptr_concat("grid '", GRID->base.type->kt->name, \
"' content has not been bound"),;); \
for(u16 _g_r = 0; _g_r < GRID->rows; _g_r++){ \
for(u16 _g_c = 0; _g_c < GRID->columns; _g_c++){ \
UI_try(Grid_get(GRID, _g_c, _g_r), _m_g_el,;); \
UIElement_Ptr ELEM_VAR_NAME=_m_g_el.value.VoidPtr; \
{ CODE; } \
} \
} \
}
#define Grid_foreachName(GRID, ELEM_VAR_NAME, CODE...) { \
if(!GRID->content_names) \
UI_safethrow_msg(cptr_concat("grid '", GRID->base.type->kt->name, \
"' content has been already bound"),;); \
for(u16 _g_r = 0; _g_r < GRID->rows; _g_r++){ \
for(u16 _g_c = 0; _g_c < GRID->columns; _g_c++){ \
UI_try(_Grid_getName(GRID, _g_c, _g_r), _m_g_nm,;); \
char* ELEM_VAR_NAME=_m_g_nm.value.VoidPtr; \
{ CODE; } \
} \
} \
}
////// TextBlock //////
@ -145,9 +210,10 @@ STRUCT(TextBlock,
UIElement base;
string text;
)
uit_declare(TextBlock);
/// creates a TextBlock with a copy of text
TextBlock* TextBlock_create(string text);
TextBlock* TextBlock_create(char* name, string text);
#if __cplusplus
}

View File

@ -5,10 +5,14 @@ extern "C" {
#endif
#include "tui.h"
#include "../../kerep/src/String/StringBuilder.h"
UIElement __UIElement_createDefault(ktid typeId, UIElement_draw_t drawFunc);
UI_THROWING_FUNC_DECL(DrawingArea_validate(DrawingArea a));
UI_THROWING_FUNC_DECL(UIElement_validate(UIElement* u, DrawingArea a));
extern UIElement _UIElement_initBaseDefault(char* name, UITDescriptor* type);
UI_THROWING_FUNC_DECL( DrawingArea_validate(DrawingArea a) );
UI_THROWING_FUNC_DECL( UIElement_validate(UIElement_Ptr u, DrawingArea a) );
UI_THROWING_FUNC_DECL( UIElement_deserializeBase(Dtsod* dtsod, UIElement* base) );
extern termchar UIBorder_char_h[4];
extern termchar UIBorder_char_v[4];
@ -17,6 +21,48 @@ extern termchar UIBorder_char_rt[4][4];
extern termchar UIBorder_char_rb[4][4];
extern termchar UIBorder_char_lb[4][4];
/// extended kt_register
void __uit_register(ktDescriptor* kt, UITDescriptor* uit);
#define uit_register(TYPE) kt_register(TYPE); __uit_register(&ktDescriptor_##TYPE##_Ptr, &UITDescriptor_##TYPE)
void UI_enum_tables_init();
void UI_enum_tables_free();
int termcolor_getByName(char* color_name);
int UIBorderThickness_getByName(char* name);
#define set_color(name, var){ \
int color=termcolor_getByName(name); \
if(color==-1) \
UI_safethrow(cptr_concat("incorrect color name: ", name), ;); \
var|=(termcolor)color; \
}
#define set_border_thickness(name, var){ \
int th=UIBorderThickness_getByName(name); \
if(th==-1) \
UI_safethrow(cptr_concat("incorrect UIBorderThickness name: ", name), ;); \
var=(UIBorderThickness)th; \
}
#define addstr(V) StringBuilder_append_string(sb, V);
#define addstrf(O,F) adds(" "#F":'") addstr(O->F) addc('\'')
#define adds(V) StringBuilder_append_cptr(sb, V);
#define addsf(O,F) adds(" "#F":'") adds(O->F) addc('\'')
#define addc(V) StringBuilder_append_char(sb, V);
#define addcf(O,F) adds(" "#F":") addc(O->F)
#define addi(V) StringBuilder_append_i64(sb, V);
#define addif(O,F) adds(" "#F":") addi(O->F)
#define addu(V) StringBuilder_append_u64(sb, V);
#define adduf(O,F) adds(" "#F":") addu(O->F)
#define addf(V) StringBuilder_append_f64(sb, V);
#define addff(O,F) adds(" "#F":") addf(O->F)
char* UITDescriptor_toString(UITDescriptor* d);
void UIElement_appendToStringBuilder(StringBuilder* sb, UIElement_Ptr u);
#if __cplusplus
}
#endif

View File

@ -15,11 +15,6 @@ typedef u32 utf32char;
///@returns <0 error code of fputc
int utf32char_fwrite(FILE* file, utf32char ch);
typedef utf32char termchar;
#define TERMCHAR(CHAR) U##CHAR
#define TERMSTR(STR) U##STR
#define termchar_fwrite utf32char_fwrite
#if __cplusplus
}
#endif

View File

@ -1,20 +1,64 @@
#include "../kerep/src/Filesystem/filesystem.h"
#include "TUI/tui.h"
#include "TUI/Dtsod/tui_dtsod.h"
#include "../kerep/src/Filesystem/filesystem.h"
#include <unistd.h>
#include <errno.h>
#if _WIN32 || _WIN64
#include <windows.h>
#endif
Maybe tryReadFile(char* filePath){
if(!file_exists(filePath))
kprintf("file doesnt exist, creating new\n");
try(file_open(filePath, FileOpenMode_ReadAppend), _m_file,;);
FileHandle file=_m_file.value.VoidPtr;
char* fileContent=NULL;
try(file_readAll(file, &fileContent), _m_bcount,;)
try(file_close(file),_m_,;);
return SUCCESS(UniHeapPtr(char,fileContent));
#define EMBEDDED_RESOURCE_POSTFIX view
#include "generated/view.h"
void on_exit(){
Scolte_free();
kt_free();
term_resetColors();
term_cursorHide(false);
}
// Maybe tryReadFile(char* filePath){
// if(!file_exists(filePath))
// kprintf("file doesnt exist, creating new\n");
// try(file_open(filePath, FileOpenMode_ReadAppend), _m_file,;);
// FileHandle file=_m_file.value.VoidPtr;
// char* fileContent=NULL;
// try(file_readAll(file, &fileContent), _m_bcount,;)
// try(file_close(file),_m_,;);
// return SUCCESS(UniHeapPtr(char,fileContent));
// }
UI_THROWING_FUNC_DECL(test_example_ui_build());
UI_Maybe test_example_ui_build() {
// ui from dtsod build example
UIDtsodParser* p=UIDtsodParser_create();
for(unsigned int i=0; i<EmbeddedResourceFile_table_view_count; i++){
EmbeddedResourceFile rs=EmbeddedResourceFile_table_view[i];
UI_try(UIDtsodParser_parseText(p, rs.path, rs.data),
_91624, UIDtsodParser_destroy(p));
}
UI_try(UIDtsodParser_constructUIContext(p), _m_ui_context, UIDtsodParser_destroy(p));
UIContext* ui_context=_m_ui_context.value.VoidPtr;
UIDtsodParser_destroy(p);
UIContext_get(ui_context, example, textblock, TextBlock, UIContext_destroy(ui_context));
example_textblock->text=string_fromCptr("text replaced");
u32 n=0;
Hashtable_foreach(ui_context->ui_elements, el_pair,
UIElement* el=el_pair.value.VoidPtr;
toString_t elToString=el->type->kt->toString;
if(elToString){
char* str_tmp=elToString(el,0);
char* str=cptr_replace(str_tmp, " ", "\n");
kprintf("[%u] %s\n", n, str);
free(str_tmp);
free(str);
}
else kprintf("[%u] %s\n", n, el->name);
n++;
);
UIContext_destroy(ui_context);
return MaybeNull;
}
i32 main(const i32 argc, const char* const* argv){
@ -27,31 +71,50 @@ i32 main(const i32 argc, const char* const* argv){
kprintf("\e[93msetlocale failed! (%i)\n", errno);
}
term_cursorHide(true);
term_clear();
// kerep type system
kt_beginInit();
kt_initKerepTypes();
kt_initScolteTypes();
kt_beginInitTUI();
Scolte_init();
kt_endInitTUI();
kt_endInit();
// print command line arguments
kprintf("\e[37margs:");
for(i32 i=0; i<argc; i++)
kprintf(" %s", argv[i]);
kprintf("\n");
/*char* filePath= argc>1 ? argv[argc-1] : "new_file.txt";
tryLast(tryReadFile(filePath), _m_text);
// create file
/* char* filePath= argc>1 ? argv[argc-1] : "new_file.txt";
tryLast(tryReadFile(filePath), _m_text, on_exit());
char* text=(char*)_m_text.value.VoidPtr;
fputs(text,stdout);*/
fputs(text,stdout); */
Renderer* renderer=Renderer_create();
Canvas* mainCanvas=Canvas_create();
TextBlock* testTextBlock=TextBlock_create(string_fromCptr("some example text"));
Canvas_addChild(mainCanvas, (UIElement*)testTextBlock);
tryLast(UIElement_draw(renderer, (UIElement*)mainCanvas, ((DrawingArea){.x=10, .y=4, .h=7, .w=24})),_);
tryLast(Renderer_drawFrame(renderer),_2);
UIElement_destroy((UIElement*)mainCanvas);
Renderer_destroy(renderer);
// render ui
// Renderer* renderer=Renderer_create();
// TextBlock* testTextBlock=TextBlock_create("TextBlock1", string_fromCptr("some example text"));
// Autoarr(UIElement_Ptr)* grid_content=Autoarr_create(UIElement_Ptr, 1, 64);
// Autoarr_add(grid_content, (UIElement_Ptr)testTextBlock);
// Grid* mainGrid=Grid_create("MainGrid", 1,1, Autoarr_toArray(grid_content));
// Autoarr_free(grid_content, true);
// tryLast(UIElement_draw(renderer, (UIElement_Ptr)mainGrid,
// ((DrawingArea){.x=10, .y=4, .h=7, .w=24})),
// _, on_exit());
// tryLast(Renderer_drawFrame(renderer),_2);
// // free ui memory
// UIElement_destroy((UIElement_Ptr)mainGrid);
// Renderer_destroy(renderer);
kt_free();
// TODO signal( SIGWINCH, redraw );
for(u32 n=0; n<1; n++){
tryLast(test_example_ui_build(), _6981751, on_exit());
}
on_exit();
return 0;
}

8
src/term/TermCharInfo.c Normal file
View File

@ -0,0 +1,8 @@
#include "term.h"
kt_define(TermCharInfo, NULL, NULL);
int TCI_fwrite(FILE* file, TermCharInfo tci){
kprint_setColor(tci.color);
return termchar_fwrite(file, tci.ch);
}

View File

@ -3,13 +3,23 @@
#include <unistd.h>
#include IFWIN("windows.h", "sys/ioctl.h")
void term_moveCursor(u16 row, u16 column){
printf("\e[%u;%uf",row,column);
char* TerminalSize_toString(TerminalSize t){
char buf[64];
sprintf_s(buf, sizeof(buf), "(%ux%u)", t.cols, t.rows);
return cptr_copy(buf);
}
void term_clear() {
printf("\e[2j");
char* __TerminalSize_toString(void* _t, u32 fmt){ return TerminalSize_toString(*(TerminalSize*)_t); }
kt_define(TerminalSize, NULL, __TerminalSize_toString);
TerminalSize term_default_size={.cols=80, .rows=16};
int getenv_int(const char* var_name){
char* str=getenv(var_name);
if(str==NULL)
return -1;
return strtol(str, NULL, 0);
}
bool term_getSize(TerminalSize* out) {
@ -24,15 +34,30 @@ bool term_getSize(TerminalSize* out) {
.rows=consoleInfo.srWindow.Bottom-consoleInfo.srWindow.Top+1
};
#else
struct winsize w={0,0,0,0};
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &w)!=0)
return false;
*out=(TerminalSize){
.cols=w.ws_col,
.rows=w.ws_row
};
struct winsize ws={0,0,0,0};
// tries to get terminal size from stdin, stdout, stderr
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)==0 ||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws)==0 ||
ioctl(STDERR_FILENO, TIOCGWINSZ, &ws)==0 ){
out->cols=ws.ws_col;
out->rows=ws.ws_row;
}
// tries to get size from environtent variables
else{
out->cols=getenv_int("COLUMNS");
out->rows=getenv_int("LINES");
}
#endif
return true;
return out->cols > 0 && out->cols < 720 && out->rows > 0 && out->rows < 480;
}
TerminalSize term_default_size={.cols=80, .rows=16};
/*
Most of escape sequences can be found at:
https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
*/
void term_resetCursor() { printf("\e[H"); }
void term_resetColors() { printf("\e[0m"); }
void term_clear() { printf("\e[0m\e[H\e[2J"); }
void term_cursorMove(u16 row, u16 column) { printf("\e[%u;%uH",row,column); }
void term_cursorHide(bool hide) { printf( hide ? "\e[?25l" : "\e[?25h"); }

View File

@ -5,13 +5,18 @@ extern "C" {
#endif
#include "../../kerep/src/base/base.h"
#include "../../kerep/src/kprint/kprint_format.h"
#include "../encoding/encoding.h"
void term_moveCursor(u16 row, u16 column);
void term_resetCursor();
void term_resetColors();
void term_clear();
void term_cursorMove(u16 row, u16 column);
void term_cursorHide(bool hide);
STRUCT(TerminalSize,
u16 rows;
u16 cols;
u16 rows;
)
///@return TRUE if have got terminal size, otherwise FALSE
@ -20,6 +25,21 @@ bool term_getSize(TerminalSize* out) WARN_UNUSED_REZULT;
/// can be used if term_getSize() fails
extern TerminalSize term_default_size;
typedef kp_fmt termcolor;
typedef utf32char termchar;
#define TERMCHAR(CHAR) U##CHAR
#define TERMSTR(STR) U##STR
#define termchar_fwrite utf32char_fwrite
STRUCT(TermCharInfo,
termchar ch;
termcolor color; /* background + foreground */
)
#define TCI(CH,COLOR)(TermCharInfo){.ch=CH, .color=COLOR}
int TCI_fwrite(FILE* file, TermCharInfo tci);
#define TCI_print(tci) TCI_fwrite(stdout, tci);
#if __cplusplus
}
#endif

17
tasks/build_view.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
set -eo pipefail
mkdir -p "obj"
clean_dir "obj/objects"
mkdir -p "src"
mkdir -p "src/generated"
cd resource_embedder
./build.sh
cd ..
embedder_args="-o src/generated/view.h"
for guifile in $(find "view" -name '*.tui.dtsod'); do
embedder_args="$embedder_args -i $guifile"
done
resource_embedder/resource_embedder $embedder_args

View File

@ -1,10 +1,4 @@
#!/usr/bin/bash
for tmpfile in $(ls -a | grep -e '\.rebuild.*\.tmp'); do
try_delete_dir_or_file "$tmpfile"
done
set -eo pipefail
for submodule in kerep utf8proc; do
cd "$submodule"
make clean
cd ..
done
try_delete_dir_or_file src/generated

View File

@ -1,25 +1,5 @@
#!/bin/bash
set -eo pipefail
# if $lib_project.a doesn't exist or rebuild_* task was executed, builds static lib
function handle_static_dependency {
local lib_project="$1"
local lib_build_task="$2"
local lib_build_rezults="$3"
if [ ! -f "$OBJDIR/libs/$lib_project.a" ] || [ -f .rebuild_$lib_project.tmp ]; then
[[ -z "$lib_build_task" ]] && error "lib_build_task is empty"
myprint "${BLUE}making $lib_project task <$lib_build_task>"
cd $lib_project
if ! make "$lib_build_task"; then
exit 1
fi
cd ..
cp $lib_build_rezults $OBJDIR/libs/
myprint "${GREEN}copied ${CYAN}$lib_project.a"
rm -f .rebuild_$lib_project.tmp
fi
}
handle_static_dependency kerep "$DEPS_BUILD_TASK" kerep/bin/kerep.a
handle_static_dependency utf8proc libutf8proc.a utf8proc/libutf8proc.a
# generate source code for views/*.tui.dtsod
source tasks/build_view.sh

View File

@ -1,6 +0,0 @@
#!/bin/bash
source cbuild/colors.sh
source cbuild/functions.sh
touch ".rebuild_$1.tmp"
rm -fv "obj/libs/$1.a"
myprint "${YELLOW}$1.a will be rebuilt in the next build task"

37
view/example.tui.dtsod Normal file
View File

@ -0,0 +1,37 @@
parser_version: 1;
namespace: "example";
$ui: {
name: "textblock",
type: "TextBlock",
min_width: 4,
max_width: 4,
width: 20,
height: "3",
bg_color: "black",
fg_color: "white",
border: {
top: "hidden",
bottom: "no",
left: "thick",
right: "double",
fg_color: "dark_cyan",
bg_color: "gray";
},
text: "UwU",
};
$ui: {
name: "Grid",
type: "Grid",
row_heights: [
"1*",
-1,
],
column_widths: [ "-8*" ],
content: [
# column
[ "example_textblock" ], # row
[ "example_textblock" ], # row
];
};

17
view/main.tui.dtsod Normal file
View File

@ -0,0 +1,17 @@
parser_version: 1;
namespace: "main";
# $ui: {
# name: "main_grid",
# type: "Grid",
# row_heights: [
# "1*",
# # -1,
# # ],
# # column_widths: [ "-8*" ],
# content: [
# # column
# # [ "namespace.element0" ], # row
# # [ "namespace.element1" ], # row
# ];
# };