TermCharInfo

This commit is contained in:
Timerix22 2023-05-18 07:27:15 +06:00
parent c8dfd8224e
commit 76b0909659
9 changed files with 66 additions and 41 deletions

2
kerep

@ -1 +1 @@
Subproject commit f6864de2c9c3a16c5ac1b56cdf43073490b81a28 Subproject commit 6aaf270aad6dec2accfa49addc8c6fa5cbe8b337

View File

@ -7,7 +7,7 @@ void Canvas_freeMembers(void* _self){
Autoarr_freeWithoutMembers(self->children, true); Autoarr_freeWithoutMembers(self->children, true);
} }
UI_Maybe Canvas_draw(Renderer* renderer, UIElement* _self, DrawingArea area){ UI_Maybe Canvas_draw(Renderer* renderer, UIElement* _self, const DrawingArea area){
Canvas* self=(Canvas*)_self; Canvas* self=(Canvas*)_self;
Autoarr_foreach(self->children, ch, ({ Autoarr_foreach(self->children, ch, ({
if(ch==NULL) if(ch==NULL)

View File

@ -1,5 +1,10 @@
#include "tui_internal.h" #include "tui_internal.h"
int TCI_fwrite(FILE* file, TermCharInfo tci){
kprint_setColor(tci.color);
return termchar_fwrite(file, tci.ch);
}
////////////////////////////////////// //////////////////////////////////////
// FrameBuffer // // FrameBuffer //
////////////////////////////////////// //////////////////////////////////////
@ -25,7 +30,7 @@ Maybe FrameBuffer_create(FrameBuffer* fb){
fb->data=malloc( sz* length); fb->data=malloc( sz* length);
for(u32 i=0; i<length; i++) for(u32 i=0; i<length; i++)
fb->data[i]=TERMCHAR('#'); fb->data[i]=TCI(TERMCHAR(' '), kp_bgGray|kp_fgGray);
return MaybeNull; return MaybeNull;
} }
@ -39,12 +44,12 @@ void Renderer_freeMembers(void * _self){
// Renderer // // Renderer //
////////////////////////////////////// //////////////////////////////////////
UI_Maybe __Renderer_set(Renderer* self, termchar c, u16 x, u16 y) { UI_Maybe __Renderer_set(Renderer* self, TermCharInfo tci, u16 x, u16 y) {
if(x >= self->frameBuffer.size.cols) if(x >= self->frameBuffer.size.cols)
UI_safethrow(UIError_InvalidX,;); UI_safethrow(UIError_InvalidX,;);
if(y >= self->frameBuffer.size.rows) if(y >= self->frameBuffer.size.rows)
UI_safethrow(UIError_InvalidY,;); UI_safethrow(UIError_InvalidY,;);
self->frameBuffer.data[self->frameBuffer.size.cols * y + x] = c; self->frameBuffer.data[self->frameBuffer.size.cols * y + x] = tci;
return MaybeNull; return MaybeNull;
} }
@ -58,10 +63,10 @@ UI_Maybe __Renderer_drawFrame(Renderer* self){
for(u16 y=0; y<buf.size.rows; y++){ for(u16 y=0; y<buf.size.rows; y++){
for(u16 x=0; x<buf.size.cols; x++){ for(u16 x=0; x<buf.size.cols; x++){
termchar c=buf.data[buf.size.cols*y + x]; TermCharInfo tci=buf.data[buf.size.cols*y + x];
int rez=termchar_print(c); int rez=TCI_print(tci);
if(rez<0){ if(rez<0){
char* chex=toString_hex(&c, sizeof(c), true, true, true); char* chex=toString_hex(&tci.ch, sizeof(tci.ch), true, true, true);
char* errnostr=toString_i64(errno); char* errnostr=toString_i64(errno);
char* errmsg=cptr_concat(nameof(UIError_PrintError)," (errno: ",errnostr,"): can't print char ",chex); char* errmsg=cptr_concat(nameof(UIError_PrintError)," (errno: ",errnostr,"): can't print char ",chex);
free(errnostr); free(errnostr);
@ -96,32 +101,32 @@ Renderer* Renderer_create(){
// drawing functions // // drawing functions //
////////////////////////////////////// //////////////////////////////////////
UI_Maybe Renderer_fill(Renderer* renderer, termchar c, DrawingArea area){ UI_Maybe Renderer_fill(Renderer* renderer, TermCharInfo tci, const DrawingArea area){
UI_try(DrawingArea_validate(area),_,;); UI_try(DrawingArea_validate(area),_,;);
for(u16 y=area.y; y<area.y+area.h; y++) for(u16 y=area.y; y<area.y+area.h; y++)
for(u16 x=area.x; x<area.x+area.w; x++){ for(u16 x=area.x; x<area.x+area.w; x++){
UI_try(Renderer_set(renderer, c, x, y),_,;); UI_try(Renderer_set(renderer, tci, x, y),_,;);
} }
return MaybeNull; return MaybeNull;
} }
UI_Maybe Renderer_drawLineX(Renderer* renderer, termchar c, u16 x, u16 y, u16 length){ UI_Maybe Renderer_drawLineX(Renderer* renderer, TermCharInfo tci, u16 x, u16 y, u16 length){
while(length>0){ while(length>0){
UI_try(Renderer_set(renderer, c, x, y),_,;); UI_try(Renderer_set(renderer, tci, x, y),_,;);
x++; length--; x++; length--;
} }
return MaybeNull; return MaybeNull;
} }
UI_Maybe Renderer_drawLineY(Renderer* renderer, termchar c, u16 x, u16 y, u16 length){ UI_Maybe Renderer_drawLineY(Renderer* renderer, TermCharInfo tci, u16 x, u16 y, u16 length){
while(length>0){ while(length>0){
UI_try(Renderer_set(renderer, c, x, y),_,;); UI_try(Renderer_set(renderer, tci, x, y),_,;);
y++; length--; y++; length--;
} }
return MaybeNull; return MaybeNull;
} }
UI_Maybe Renderer_drawBorder(Renderer* renderer, UIBorder border, DrawingArea area){ UI_Maybe Renderer_drawBorder(Renderer* renderer, UIBorder border, const DrawingArea area){
UI_try(DrawingArea_validate(area),_0,;); UI_try(DrawingArea_validate(area),_0,;);
//lines //lines
@ -133,13 +138,13 @@ UI_Maybe Renderer_drawBorder(Renderer* renderer, UIBorder border, DrawingArea ar
// TODO check neighbor borders and insert crossing chars like '╄' // TODO check neighbor borders and insert crossing chars like '╄'
UI_try(Renderer_drawLineX(renderer, topChar, area.x+1, area.y, area.w-2),_1,;) UI_try(Renderer_drawLineX(renderer, TCI(topChar, border.color), area.x+1, area.y, area.w-2),_1,;)
// bottom // bottom
UI_try(Renderer_drawLineX(renderer, bottomChar, area.x+1, area.y+area.h-1, area.w-2),_2,;) UI_try(Renderer_drawLineX(renderer, TCI(bottomChar, border.color), area.x+1, area.y+area.h-1, area.w-2),_2,;)
// left // left
UI_try(Renderer_drawLineY(renderer, leftChar, area.x, area.y+1, area.h-2),_3,;) UI_try(Renderer_drawLineY(renderer, TCI(leftChar, border.color), area.x, area.y+1, area.h-2),_3,;)
// right // right
UI_try(Renderer_drawLineY(renderer, rightChar, area.x+area.w-1, area.y+1, area.h-2),_4,;) UI_try(Renderer_drawLineY(renderer, TCI(rightChar, border.color), area.x+area.w-1, area.y+1, area.h-2),_4,;)
// corners // corners
termchar ltCornerChar = UIBorder_char_lt[border.left ][border.top ]; termchar ltCornerChar = UIBorder_char_lt[border.left ][border.top ];
@ -147,13 +152,13 @@ UI_Maybe Renderer_drawBorder(Renderer* renderer, UIBorder border, DrawingArea ar
termchar rbCornerChar = UIBorder_char_rb[border.right][border.bottom]; termchar rbCornerChar = UIBorder_char_rb[border.right][border.bottom];
termchar lbCornerChar = UIBorder_char_lb[border.left ][border.bottom]; termchar lbCornerChar = UIBorder_char_lb[border.left ][border.bottom];
// left top corner // left top corner
UI_try(Renderer_set(renderer, ltCornerChar, area.x, area.y),_5,;); UI_try(Renderer_set(renderer, TCI(ltCornerChar, border.color), area.x, area.y),_5,;);
// right top corner // right top corner
UI_try(Renderer_set(renderer, rtCornerChar, area.x+area.w-1, area.y),_6,;); UI_try(Renderer_set(renderer, TCI(rtCornerChar, border.color), area.x+area.w-1, area.y),_6,;);
// right bottom corner // right bottom corner
UI_try(Renderer_set(renderer, rbCornerChar, area.x+area.w-1, area.y+area.h-1),_7,;); UI_try(Renderer_set(renderer, TCI(rbCornerChar, border.color), area.x+area.w-1, area.y+area.h-1),_7,;);
// left bottom corner // left bottom corner
UI_try(Renderer_set(renderer, lbCornerChar, area.x, area.y+area.h-1),_8,;); UI_try(Renderer_set(renderer, TCI(lbCornerChar, border.color), area.x, area.y+area.h-1),_8,;);
return MaybeNull; return MaybeNull;
} }

View File

@ -5,11 +5,16 @@ void TextBlock_freeMembers(void* _self){
free(self->text.ptr); free(self->text.ptr);
} }
UI_Maybe TextBlock_draw(Renderer* renderer, UIElement* _self, DrawingArea area){ UI_Maybe TextBlock_draw(Renderer* renderer, UIElement* _self, const DrawingArea area){
TextBlock* self=(TextBlock*)_self; TextBlock* self=(TextBlock*)_self;
UI_try(UIElement_validate((UIElement*)self, area),_0,;); UI_try(UIElement_validate((UIElement*)self, area),_0,;);
UI_try(Renderer_fill(renderer, TERMCHAR(' '), area),_2,;); UI_try(Renderer_fill(renderer, TCI(TERMCHAR(' '), kp_bgBlack|kp_fgGray), area),_2,;);
UI_try(Renderer_drawBorder(renderer, self->base.borders, area),_1,;); UI_try(Renderer_drawBorder(renderer, self->base.border, area),_1,;);
for(u16 i=0; i<area.w-2 && i<self->text.length; i++){
u16 x=area.x+1+i;
u16 y=area.y+area.h/2;
UI_try(Renderer_set(renderer, TCI(self->text.ptr[i], kp_fgCyan), x, y), _2,;);
}
return MaybeNull; return MaybeNull;
} }

View File

@ -14,9 +14,10 @@ UIElement __UIElement_createDefault(ktid typeId, UIElement_draw_t drawFunc){
.fgColor=kp_fgWhite, .fgColor=kp_fgWhite,
.bgColor=kp_bgBlack, .bgColor=kp_bgBlack,
.anchor=UIAnchor_Center, .anchor=UIAnchor_Center,
.borders={ .border={
.left=UIBorder_Thin, .right=UIBorder_Thin, .left=UIBorder_Thin, .right=UIBorder_Thin,
.top=UIBorder_Thin, .bottom=UIBorder_Thin .top=UIBorder_Thin, .bottom=UIBorder_Thin,
.color=kp_bgBlack|kp_fgGray
}, },
.draw=drawFunc .draw=drawFunc
}; };

View File

@ -5,7 +5,7 @@ extern "C" {
#endif #endif
#include "../../kerep/src/String/string.h" #include "../../kerep/src/String/string.h"
#include "../../kerep/src/kprint/kprint_colors.h" #include "../../kerep/src/kprint/kprint_format.h"
#include "../../kerep/src/Array/Array.h" #include "../../kerep/src/Array/Array.h"
#include "../term/term.h" #include "../term/term.h"
#include "../encoding/encoding.h" #include "../encoding/encoding.h"
@ -55,14 +55,24 @@ STRUCT(UIBorder,
UIBorderThickness left; UIBorderThickness left;
UIBorderThickness top; UIBorderThickness top;
UIBorderThickness bottom; UIBorderThickness bottom;
kp_fmt 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 // // Renderer //
////////////////////////////////////// //////////////////////////////////////
STRUCT(FrameBuffer, STRUCT(FrameBuffer,
termchar* data; TermCharInfo* data;
TerminalSize size; TerminalSize size;
) )
@ -71,19 +81,19 @@ typedef struct Renderer Renderer;
STRUCT(Renderer, STRUCT(Renderer,
FrameBuffer frameBuffer; FrameBuffer frameBuffer;
UI_THROWING_FUNC_DECL((*drawFrame)(Renderer*)); UI_THROWING_FUNC_DECL((*drawFrame)(Renderer*));
UI_THROWING_FUNC_DECL((*set)(Renderer*, termchar c, u16 x, u16 y)); UI_THROWING_FUNC_DECL((*set)(Renderer*, TermCharInfo tci, u16 x, u16 y));
) )
#define Renderer_drawFrame(RENDERER) RENDERER->drawFrame(RENDERER) #define Renderer_drawFrame(RENDERER) RENDERER->drawFrame(RENDERER)
#define Renderer_set(RENDERER, CH, X, Y) RENDERER->set(RENDERER, CH, X, Y) #define Renderer_set(RENDERER, TCI, X, Y) RENDERER->set(RENDERER, TCI, X, Y)
Renderer* Renderer_create(); Renderer* Renderer_create();
void Renderer_destroy(Renderer* self); void Renderer_destroy(Renderer* self);
UI_THROWING_FUNC_DECL(Renderer_fill(Renderer* renderer, termchar c, DrawingArea area)); UI_THROWING_FUNC_DECL(Renderer_fill(Renderer* renderer, TermCharInfo tci, const DrawingArea area));
UI_THROWING_FUNC_DECL(Renderer_drawLineX(Renderer* renderer, termchar c, u16 x, u16 y, u16 length)); UI_THROWING_FUNC_DECL(Renderer_drawLineX(Renderer* renderer, TermCharInfo tci, u16 x, u16 y, u16 length));
UI_THROWING_FUNC_DECL(Renderer_drawLineY(Renderer* renderer, termchar c, u16 x, u16 y, u16 length)); 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, DrawingArea area)); UI_THROWING_FUNC_DECL(Renderer_drawBorder(Renderer* renderer, UIBorder border, const DrawingArea area));
////////////////////////////////////// //////////////////////////////////////
// UIElement abstract struct // // UIElement abstract struct //
@ -91,7 +101,7 @@ UI_THROWING_FUNC_DECL(Renderer_drawBorder(Renderer* renderer, UIBorder border, D
typedef struct UIElement UIElement; typedef struct UIElement UIElement;
typedef UIElement* UIElementPtr; typedef UIElement* UIElementPtr;
typedef UI_THROWING_FUNC_DECL((*UIElement_draw_t)(Renderer* renderer, UIElement* self, DrawingArea area)); typedef UI_THROWING_FUNC_DECL((*UIElement_draw_t)(Renderer* renderer, UIElement* self, const DrawingArea area));
#define UIElement_stretch (u16)-1 #define UIElement_stretch (u16)-1
@ -104,7 +114,7 @@ STRUCT(UIElement,
kp_fgColor fgColor; kp_fgColor fgColor;
kp_bgColor bgColor; kp_bgColor bgColor;
UIAnchor anchor; UIAnchor anchor;
UIBorder borders; UIBorder border;
UIElement_draw_t draw; UIElement_draw_t draw;
) )

View File

@ -18,7 +18,7 @@ int utf32char_fwrite(FILE* file, utf32char ch);
typedef utf32char termchar; typedef utf32char termchar;
#define TERMCHAR(CHAR) U##CHAR #define TERMCHAR(CHAR) U##CHAR
#define TERMSTR(STR) U##STR #define TERMSTR(STR) U##STR
#define termchar_print(CH) utf32char_fwrite(stdout, CH) #define termchar_fwrite utf32char_fwrite
#if __cplusplus #if __cplusplus
} }

View File

@ -1,6 +1,10 @@
#include "../kerep/src/Filesystem/filesystem.h" #include "../kerep/src/Filesystem/filesystem.h"
#include "TUI/tui.h" #include "TUI/tui.h"
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#if _WIN32 || _WIN64
#include <windows.h>
#endif
Maybe tryReadFile(char* filePath){ Maybe tryReadFile(char* filePath){
if(!file_exists(filePath)) if(!file_exists(filePath))
@ -12,7 +16,7 @@ Maybe tryReadFile(char* filePath){
try(file_close(file),_m_,;); try(file_close(file),_m_,;);
return SUCCESS(UniHeapPtr(char,fileContent)); return SUCCESS(UniHeapPtr(char,fileContent));
} }
#include <windows.h>
i32 main(const i32 argc, const char* const* argv){ i32 main(const i32 argc, const char* const* argv){
#if _WIN32 || _WIN64 #if _WIN32 || _WIN64
if(!SetConsoleOutputCP(CP_UTF8)){ if(!SetConsoleOutputCP(CP_UTF8)){
@ -42,7 +46,7 @@ i32 main(const i32 argc, const char* const* argv){
Canvas* mainCanvas=Canvas_create(); Canvas* mainCanvas=Canvas_create();
TextBlock* testTextBlock=TextBlock_create(string_fromCptr("some example text")); TextBlock* testTextBlock=TextBlock_create(string_fromCptr("some example text"));
Canvas_addChild(mainCanvas, (UIElement*)testTextBlock); Canvas_addChild(mainCanvas, (UIElement*)testTextBlock);
tryLast(UIElement_draw(renderer, (UIElement*)mainCanvas, ((DrawingArea){.x=4, .y=4, .h=4, .w=4})),_); tryLast(UIElement_draw(renderer, (UIElement*)mainCanvas, ((DrawingArea){.x=10, .y=4, .h=7, .w=24})),_);
tryLast(Renderer_drawFrame(renderer),_2); tryLast(Renderer_drawFrame(renderer),_2);
UIElement_destroy((UIElement*)mainCanvas); UIElement_destroy((UIElement*)mainCanvas);