f***ed up and needed to rework packages
This commit is contained in:
parent
b43ab1702f
commit
f7a87d7519
78 changed files with 3713 additions and 0 deletions
147
packages/console/ncurses/buffer/line.c
Normal file
147
packages/console/ncurses/buffer/line.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include "arc/console/buffer/line.h"
|
||||
|
||||
#include "arc/console/view.h"
|
||||
#include "arc/std/string.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct ARC_ConsoleLineBuffer {
|
||||
ARC_Vector *bufferLines;
|
||||
};
|
||||
|
||||
void ARC_ConsoleLineBuffer_Create(ARC_ConsoleLineBuffer **buffer){
|
||||
*buffer = (ARC_ConsoleLineBuffer *)malloc(sizeof(ARC_ConsoleLineBuffer));
|
||||
|
||||
ARC_Vector_Create(&((*buffer)->bufferLines));
|
||||
|
||||
//add first line to vector
|
||||
ARC_Vector_Add((*buffer)->bufferLines, NULL);
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_Destroy(ARC_ConsoleLineBuffer *buffer){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i);
|
||||
|
||||
if(bufferLine != NULL){
|
||||
ARC_String_Destroy(bufferLine);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(buffer->bufferLines);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_Clear(ARC_ConsoleLineBuffer *buffer){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(buffer->bufferLines); i++){
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i);
|
||||
|
||||
if(bufferLine != NULL){
|
||||
ARC_String_Destroy(bufferLine);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(buffer->bufferLines);
|
||||
ARC_Vector_Create(&(buffer->bufferLines));
|
||||
|
||||
//add first line to vector
|
||||
ARC_Vector_Add(buffer->bufferLines, NULL);
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_Render(ARC_ConsoleLineBuffer *buffer, ARC_ConsoleView *view){
|
||||
ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view);
|
||||
|
||||
uint32_t bufferStartIndex = 0;
|
||||
if(ARC_Vector_Size(buffer->bufferLines) > (uint32_t)viewBounds.h){
|
||||
bufferStartIndex = ARC_Vector_Size(buffer->bufferLines) - viewBounds.h;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < (uint32_t)viewBounds.h; i++){
|
||||
if(i + bufferStartIndex > ARC_Vector_Size(buffer->bufferLines)){
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + bufferStartIndex);
|
||||
if(bufferLine == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_RenderSection(ARC_ConsoleLineBuffer *buffer, ARC_ConsoleView *view, uint32_t startIndex, uint32_t lines){
|
||||
ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view);
|
||||
|
||||
for(uint32_t i = 0; i < lines; i++){
|
||||
if(i + startIndex >= ARC_Vector_Size(buffer->bufferLines)){
|
||||
break;
|
||||
}
|
||||
|
||||
if(i >= (uint32_t)viewBounds.h){
|
||||
break;
|
||||
}
|
||||
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, i + startIndex);
|
||||
if(bufferLine == NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, bufferLine, (ARC_Point){ 0, i });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_AddChar(ARC_ConsoleLineBuffer *buffer, char character){
|
||||
if(character == '\n'){
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
//get the last line and add a char to it
|
||||
ARC_String *bufferLine = (ARC_String *)ARC_Vector_Get(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1);
|
||||
ARC_Vector_RemoveIndex(buffer->bufferLines, ARC_Vector_Size(buffer->bufferLines) - 1);
|
||||
|
||||
if(bufferLine == NULL){
|
||||
ARC_String_Create(&bufferLine, &character, 1);
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine);
|
||||
return;
|
||||
}
|
||||
|
||||
//add char to the end of the bufferline
|
||||
ARC_String *nextChar;
|
||||
ARC_String_Create(&nextChar, &character, 1);
|
||||
|
||||
ARC_String *tempBufferLine = bufferLine;
|
||||
ARC_String_Merge(&bufferLine, tempBufferLine, nextChar);
|
||||
|
||||
ARC_String_Destroy(tempBufferLine);
|
||||
ARC_String_Destroy(nextChar);
|
||||
|
||||
//add buffer line back to the bufferLines
|
||||
ARC_Vector_Add(buffer->bufferLines, (void *)bufferLine);
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_AddString(ARC_ConsoleLineBuffer *buffer, ARC_String *string){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < string->length; i++){
|
||||
ARC_ConsoleLineBuffer_AddChar(buffer, string->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_AddCString(ARC_ConsoleLineBuffer *buffer, char *cstring, uint64_t length){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < length; i++){
|
||||
ARC_ConsoleLineBuffer_AddChar(buffer, cstring[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleLineBuffer_AddCStringWithStrlen(ARC_ConsoleLineBuffer *buffer, char *cstring){
|
||||
//TODO: this in a more efficient way
|
||||
for(uint64_t i = 0; i < strlen(cstring); i++){
|
||||
ARC_ConsoleLineBuffer_AddChar(buffer, cstring[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ARC_ConsoleLineBuffer_GetLineNumbers(ARC_ConsoleLineBuffer *buffer){
|
||||
return ARC_Vector_Size(buffer->bufferLines);
|
||||
}
|
||||
51
packages/console/ncurses/buffer/view.c
Normal file
51
packages/console/ncurses/buffer/view.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "arc/console/buffer/view.h"
|
||||
|
||||
#include "arc/console/view.h"
|
||||
#include "arc/math/point.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct ARC_ConsoleViewBuffer {
|
||||
ARC_Point bounds;
|
||||
char **buffer;
|
||||
};
|
||||
|
||||
void ARC_ConsoleViewBuffer_Create(ARC_ConsoleViewBuffer **buffer, ARC_ConsoleView *view){
|
||||
*buffer = (ARC_ConsoleViewBuffer *)malloc(sizeof(ARC_ConsoleViewBuffer));
|
||||
|
||||
ARC_Rect viewBounds = ARC_ConsoleView_GetBounds(view);
|
||||
(*buffer)->bounds = (ARC_Point){ viewBounds.w - viewBounds.x, viewBounds.h - viewBounds.y };
|
||||
|
||||
//create the buffer array
|
||||
(*buffer)->buffer = (char **)malloc(sizeof(char *) * (*buffer)->bounds.y);
|
||||
for(int32_t y = 0; y < (*buffer)->bounds.y ; y++){
|
||||
(*buffer)->buffer[y] = (char *)malloc(sizeof(char) * (*buffer)->bounds.x);
|
||||
}
|
||||
|
||||
ARC_ConsoleViewBuffer_Clear(*buffer);
|
||||
}
|
||||
|
||||
void ARC_ConsoleViewBuffer_Destroy(ARC_ConsoleViewBuffer *buffer){
|
||||
for(int32_t y = 0; y < buffer->bounds.y; y++){
|
||||
free(buffer->buffer[y]);
|
||||
}
|
||||
|
||||
free(buffer->buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void ARC_ConsoleViewBuffer_Clear(ARC_ConsoleViewBuffer *buffer){
|
||||
for(int32_t y = 0; y < buffer->bounds.y ; y++){
|
||||
for(int32_t x = 0; x < buffer->bounds.x; x++){
|
||||
buffer->buffer[y][x] = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleViewBuffer_Render(ARC_ConsoleViewBuffer *buffer, ARC_ConsoleView *view){
|
||||
for(int32_t y = 0; y < buffer->bounds.y ; y++){
|
||||
for(int32_t x = 0; x < buffer->bounds.x; x++){
|
||||
ARC_ConsoleView_RenderCharAt(view, buffer->buffer[y][x], (ARC_Point){ x, y });
|
||||
}
|
||||
}
|
||||
}
|
||||
52
packages/console/ncurses/element.c
Normal file
52
packages/console/ncurses/element.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#include "arc/console/element.h"
|
||||
#include "arc/console/view.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
void ARC_ConsoleElement_Create(ARC_ConsoleElement **element, uint32_t type, uint8_t flags, ARC_String *string, ARC_Point pos, ARC_ConsoleElement_RenderFn renderFn){
|
||||
*element = (ARC_ConsoleElement *)malloc(sizeof(ARC_ConsoleElement));
|
||||
|
||||
(*element)->type = type;
|
||||
(*element)->flags = flags;
|
||||
(*element)->string = string;
|
||||
(*element)->pos = pos;
|
||||
(*element)->renderFn = renderFn;
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_Destroy(ARC_ConsoleElement *element){
|
||||
free(element);
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_DefaultRenderFn(ARC_ConsoleView *view, ARC_ConsoleElement *element){
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTED){
|
||||
ARC_ConsoleView_SetAttribute(view, ARC_CONSOLE_VIEW_ATTRIBUTE_REVERSE);
|
||||
}
|
||||
|
||||
ARC_ConsoleView_RenderStringAt(view, element->string, element->pos);
|
||||
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTED){
|
||||
ARC_ConsoleView_SetAttribute(view, ARC_CONSOLE_VIEW_ATTRIBUTE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleElement_IsSelectable(ARC_ConsoleElement *element){
|
||||
if(element->flags & ARC_CONSOLE_ELEMENT_FLAG_SELECTABLE){
|
||||
return ARC_True;
|
||||
}
|
||||
|
||||
return ARC_False;
|
||||
}
|
||||
|
||||
void ARC_ConsoleElement_SetSelected(ARC_ConsoleElement *element, ARC_Bool selected){
|
||||
if(selected){
|
||||
element->flags |= ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
return;
|
||||
}
|
||||
|
||||
element->flags &= ~ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
}
|
||||
|
||||
void ARC_NCursesElement_ToggleSelected(ARC_ConsoleElement *element){
|
||||
element->flags ^= ARC_CONSOLE_ELEMENT_FLAG_SELECTED;
|
||||
}
|
||||
161
packages/console/ncurses/key.c
Normal file
161
packages/console/ncurses/key.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
#include "arc/console/key.h"
|
||||
#include "key.h"
|
||||
#include "arc/std/bool.h"
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void ARC_ConsoleKey_Create(ARC_ConsoleKey **consoleKey, ARC_ConsoleKey_Key *key){
|
||||
*consoleKey = (ARC_ConsoleKey *)malloc(sizeof(ARC_ConsoleKey));
|
||||
(*consoleKey)->key = 0;
|
||||
|
||||
if(key != NULL){
|
||||
(*consoleKey)->key = *key;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleKey_Destroy(ARC_ConsoleKey *consoleKey){
|
||||
free(consoleKey);
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleKey_Equals(ARC_ConsoleKey consoleKey, ARC_ConsoleKey_Key key){
|
||||
return consoleKey.key == ARC_Keyboard_GetConsoleKey(key).key;
|
||||
}
|
||||
|
||||
ARC_Bool ARC_ConsoleKey_EqualsPointer(ARC_ConsoleKey *consoleKey, ARC_ConsoleKey_Key key){
|
||||
return consoleKey->key == ARC_Keyboard_GetConsoleKey(key).key;
|
||||
}
|
||||
|
||||
ARC_ConsoleKey ARC_Keyboard_GetConsoleKey(enum ARC_ConsoleKey_Key key){
|
||||
switch(key){
|
||||
case ARC_KEY_A:
|
||||
return (ARC_ConsoleKey){ (int32_t)'a' };
|
||||
|
||||
case ARC_KEY_B:
|
||||
return (ARC_ConsoleKey){ (int32_t)'b' };
|
||||
|
||||
case ARC_KEY_C:
|
||||
return (ARC_ConsoleKey){ (int32_t)'c' };
|
||||
|
||||
case ARC_KEY_D:
|
||||
return (ARC_ConsoleKey){ (int32_t)'d' };
|
||||
|
||||
case ARC_KEY_E:
|
||||
return (ARC_ConsoleKey){ (int32_t)'e' };
|
||||
|
||||
case ARC_KEY_F:
|
||||
return (ARC_ConsoleKey){ (int32_t)'f' };
|
||||
|
||||
case ARC_KEY_G:
|
||||
return (ARC_ConsoleKey){ (int32_t)'g' };
|
||||
|
||||
case ARC_KEY_H:
|
||||
return (ARC_ConsoleKey){ (int32_t)'h' };
|
||||
|
||||
case ARC_KEY_I:
|
||||
return (ARC_ConsoleKey){ (int32_t)'i' };
|
||||
|
||||
case ARC_KEY_J:
|
||||
return (ARC_ConsoleKey){ (int32_t)'j' };
|
||||
|
||||
case ARC_KEY_K:
|
||||
return (ARC_ConsoleKey){ (int32_t)'k' };
|
||||
|
||||
case ARC_KEY_L:
|
||||
return (ARC_ConsoleKey){ (int32_t)'l' };
|
||||
|
||||
case ARC_KEY_M:
|
||||
return (ARC_ConsoleKey){ (int32_t)'m' };
|
||||
|
||||
case ARC_KEY_N:
|
||||
return (ARC_ConsoleKey){ (int32_t)'n' };
|
||||
|
||||
case ARC_KEY_O:
|
||||
return (ARC_ConsoleKey){ (int32_t)'o' };
|
||||
|
||||
case ARC_KEY_P:
|
||||
return (ARC_ConsoleKey){ (int32_t)'p' };
|
||||
|
||||
case ARC_KEY_Q:
|
||||
return (ARC_ConsoleKey){ (int32_t)'q' };
|
||||
|
||||
case ARC_KEY_R:
|
||||
return (ARC_ConsoleKey){ (int32_t)'r' };
|
||||
|
||||
case ARC_KEY_S:
|
||||
return (ARC_ConsoleKey){ (int32_t)'s' };
|
||||
|
||||
case ARC_KEY_T:
|
||||
return (ARC_ConsoleKey){ (int32_t)'t' };
|
||||
|
||||
case ARC_KEY_U:
|
||||
return (ARC_ConsoleKey){ (int32_t)'u' };
|
||||
|
||||
case ARC_KEY_V:
|
||||
return (ARC_ConsoleKey){ (int32_t)'v' };
|
||||
|
||||
case ARC_KEY_W:
|
||||
return (ARC_ConsoleKey){ (int32_t)'w' };
|
||||
|
||||
case ARC_KEY_X:
|
||||
return (ARC_ConsoleKey){ (int32_t)'x' };
|
||||
|
||||
case ARC_KEY_Y:
|
||||
return (ARC_ConsoleKey){ (int32_t)'y' };
|
||||
|
||||
case ARC_KEY_Z:
|
||||
return (ARC_ConsoleKey){ (int32_t)'z' };
|
||||
|
||||
case ARC_KEY_0:
|
||||
return (ARC_ConsoleKey){ (int32_t)'0' };
|
||||
|
||||
case ARC_KEY_1:
|
||||
return (ARC_ConsoleKey){ (int32_t)'1' };
|
||||
|
||||
case ARC_KEY_2:
|
||||
return (ARC_ConsoleKey){ (int32_t)'2' };
|
||||
|
||||
case ARC_KEY_3:
|
||||
return (ARC_ConsoleKey){ (int32_t)'3' };
|
||||
|
||||
case ARC_KEY_4:
|
||||
return (ARC_ConsoleKey){ (int32_t)'4' };
|
||||
|
||||
case ARC_KEY_5:
|
||||
return (ARC_ConsoleKey){ (int32_t)'5' };
|
||||
|
||||
case ARC_KEY_6:
|
||||
return (ARC_ConsoleKey){ (int32_t)'6' };
|
||||
|
||||
case ARC_KEY_7:
|
||||
return (ARC_ConsoleKey){ (int32_t)'7' };
|
||||
|
||||
case ARC_KEY_8:
|
||||
return (ARC_ConsoleKey){ (int32_t)'8' };
|
||||
|
||||
case ARC_KEY_9:
|
||||
return (ARC_ConsoleKey){ (int32_t)'9' };
|
||||
|
||||
case ARC_KEY_UP:
|
||||
return (ARC_ConsoleKey){ KEY_UP };
|
||||
|
||||
case ARC_KEY_DOWN:
|
||||
return (ARC_ConsoleKey){ KEY_DOWN };
|
||||
|
||||
case ARC_KEY_LEFT:
|
||||
return (ARC_ConsoleKey){ KEY_LEFT };
|
||||
|
||||
case ARC_KEY_RIGHT:
|
||||
return (ARC_ConsoleKey){ KEY_RIGHT };
|
||||
|
||||
//TODO: This is escape and alt, need to fix
|
||||
case ARC_KEY_ESC:
|
||||
return (ARC_ConsoleKey){ 27 };
|
||||
|
||||
default:
|
||||
return (ARC_ConsoleKey){ 0 };
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ARC_ConsoleKey_GetCharFromKey(ARC_ConsoleKey *consoleKey){
|
||||
return consoleKey->key;
|
||||
}
|
||||
19
packages/console/ncurses/key.h
Normal file
19
packages/console/ncurses/key.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef ARC_CONSOLE_NCURSES_KEY_H_
|
||||
#define ARC_CONSOLE_NCURSES_KEY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "arc/console/key.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct ARC_ConsoleKeyType {
|
||||
int32_t key;
|
||||
} ARC_ConsoleKeyType;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !ARC_CONSOLE_NCURSES_KEY_H_
|
||||
57
packages/console/ncurses/shell.c
Normal file
57
packages/console/ncurses/shell.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "arc/console/shell.h"
|
||||
|
||||
#include "arc/console/buffer.h"
|
||||
#include "arc/std/string.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void ARC_ConsoleShell_Create(ARC_ConsoleShell **shell, ARC_ConsoleView *view, ARC_ConsoleShell_UpdateFn updateFn){
|
||||
*shell = (ARC_ConsoleShell *)malloc(sizeof(ARC_ConsoleShell));
|
||||
|
||||
(*shell)->view = view;
|
||||
ARC_ConsoleBuffer_Create(&((*shell)->buffer));
|
||||
(*shell)->bufferLineIndex = 0;
|
||||
|
||||
ARC_Vector_Create(&((*shell)->history));
|
||||
(*shell)->historyIndex = 0;
|
||||
|
||||
(*shell)->updateFn = updateFn;
|
||||
(*shell)->currentLine = NULL;
|
||||
(*shell)->userInput = NULL;
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Destroy(ARC_ConsoleShell *shell){
|
||||
ARC_ConsoleBuffer_Destroy(shell->buffer);
|
||||
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(shell->history); i++){
|
||||
ARC_String *temp = (ARC_String *)ARC_Vector_Get(shell->history, i);
|
||||
|
||||
if(temp != NULL){
|
||||
ARC_String_Destroy(temp);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Vector_Destroy(shell->history);
|
||||
free(shell);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Update(ARC_ConsoleShell *shell){
|
||||
shell->updateFn(shell);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_Render(ARC_ConsoleShell *shell){
|
||||
ARC_ConsoleBuffer_Render(shell->buffer, shell->view);
|
||||
}
|
||||
|
||||
void ARC_ConsoleShell_AddHistory(ARC_ConsoleShell *shell, ARC_String *string){
|
||||
ARC_Vector_Add(shell->history, (void *)string);
|
||||
}
|
||||
|
||||
ARC_String *ARC_ConsoleShell_GetHistoryAt(ARC_ConsoleShell *shell, uint32_t index){
|
||||
uint32_t maxHistory = ARC_Vector_Size(shell->history);
|
||||
if(index >= maxHistory){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (ARC_String *)ARC_Vector_Get(shell->history, (maxHistory - 1) - index);
|
||||
}
|
||||
268
packages/console/ncurses/view.c
Normal file
268
packages/console/ncurses/view.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
#include "arc/console/view.h"
|
||||
|
||||
#include "key.h"
|
||||
#include "arc/console/element.h"
|
||||
#include "arc/std/bool.h"
|
||||
#include "arc/std/errno.h"
|
||||
#include "arc/std/vector.h"
|
||||
#include "arc/std/string.h"
|
||||
#include <locale.h>
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint8_t arc_ncurses_win_size = 0;
|
||||
|
||||
struct ARC_ConsoleView {
|
||||
WINDOW *window;
|
||||
ARC_Rect bounds;
|
||||
ARC_Bool echo;
|
||||
|
||||
ARC_Vector *elements;
|
||||
};
|
||||
|
||||
void ARC_ConsoleView_Create(ARC_ConsoleView **view, ARC_Rect bounds){
|
||||
if(arc_ncurses_win_size == ~(uint8_t)0){
|
||||
arc_errno = ARC_ERRNO_OVERFLOW;
|
||||
ARC_DEBUG_ERR("ARC_NCurses_Create(ncurses), max num of ARC_NCurses have been created, consider making arc_ncurses_win_size a uint32_t to increase the max");
|
||||
*view = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
//if this is the first ncurses, init ncurses
|
||||
if(arc_ncurses_win_size == 0){
|
||||
setlocale(LC_ALL, "");
|
||||
initscr();
|
||||
//start_color();
|
||||
cbreak();
|
||||
keypad(stdscr, TRUE);
|
||||
refresh();
|
||||
}
|
||||
|
||||
*view = (ARC_ConsoleView *)malloc(sizeof(ARC_ConsoleView));
|
||||
|
||||
ARC_Rect viewBounds = { 0, 0, COLS, LINES };
|
||||
if(bounds.w != 0 && bounds.h != 0){
|
||||
viewBounds = bounds;
|
||||
}
|
||||
|
||||
(*view)->window = newwin(viewBounds.h, viewBounds.w, viewBounds.y, viewBounds.x);
|
||||
(*view)->bounds = viewBounds;
|
||||
|
||||
keypad((*view)->window, TRUE);
|
||||
|
||||
noecho();
|
||||
(*view)->echo = false;
|
||||
|
||||
ARC_Vector_Create(&(*view)->elements);
|
||||
|
||||
wrefresh((*view)->window);
|
||||
|
||||
arc_ncurses_win_size++;
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_Destroy(ARC_ConsoleView *ncurses){
|
||||
arc_ncurses_win_size--;
|
||||
|
||||
ARC_Vector_Destroy(ncurses->elements);
|
||||
|
||||
delwin(ncurses->window);
|
||||
free(ncurses);
|
||||
|
||||
if(arc_ncurses_win_size == 0){
|
||||
endwin();
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_AddElement(ARC_ConsoleView *view, ARC_ConsoleElement *element){
|
||||
ARC_Vector_Add(view->elements, (void *)element);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RemoveElement(ARC_ConsoleView *view, uint32_t index){
|
||||
ARC_Vector_RemoveIndex(view->elements, index);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_Clear(ARC_ConsoleView *view){
|
||||
wclear(view->window);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderCharAt(ARC_ConsoleView *view, char character, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%c", character);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderWCharAt(ARC_ConsoleView *view, wchar_t character, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%lc", character);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderKeyAt(ARC_ConsoleView *view, ARC_ConsoleKey key, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%c", (char)key.key);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderUint32At(ARC_ConsoleView *view, uint32_t uint32, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%d", uint32);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderStringAt(ARC_ConsoleView *view, ARC_String *text, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%s", text->data);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderCStringWithStrlenAt(ARC_ConsoleView *view, char *cstr, ARC_Point pos){
|
||||
mvwprintw(view->window, pos.y, pos.x, "%s", cstr);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderRect(ARC_ConsoleView *view, ARC_Rect bounds){
|
||||
//render corners
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┌', (ARC_Point){ bounds.x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'└', (ARC_Point){ bounds.x, (bounds.h - 1) + bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┐', (ARC_Point){ (bounds.w - 1) + bounds.x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'┘', (ARC_Point){ (bounds.w - 1) + bounds.x, (bounds.h - 1) + bounds.y });
|
||||
|
||||
//render virticle lines
|
||||
for(int32_t x = 1; x < bounds.w - 1; x++){
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'─', (ARC_Point){ bounds.x + x, bounds.y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'─', (ARC_Point){ bounds.x + x, (bounds.h - 1) + bounds.y });
|
||||
}
|
||||
|
||||
//render horizontal lines
|
||||
for(int32_t y = 1; y < bounds.h - 1; y++){
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'│', (ARC_Point){ bounds.x, bounds.y + y });
|
||||
ARC_ConsoleView_RenderWCharAt(view, L'│', (ARC_Point){ (bounds.w - 1) + bounds.x, bounds.y + y });
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_RenderElements(ARC_ConsoleView *view){
|
||||
for(uint32_t i = 0; i < ARC_Vector_Size(view->elements); i++){
|
||||
ARC_ConsoleElement *element = (ARC_ConsoleElement *)ARC_Vector_Get(view->elements, i);
|
||||
element->renderFn(view, element);
|
||||
wrefresh(view->window);
|
||||
}
|
||||
}
|
||||
|
||||
ARC_Rect ARC_ConsoleView_GetBounds(ARC_ConsoleView *view){
|
||||
return view->bounds;
|
||||
}
|
||||
|
||||
ARC_ConsoleElement *ARC_ConsoleView_GetElement(ARC_ConsoleView *view, uint32_t index){
|
||||
return (ARC_ConsoleElement *)ARC_Vector_Get(view->elements, index);
|
||||
}
|
||||
|
||||
char ARC_ConsoleView_GetChar(ARC_ConsoleView *view){
|
||||
return wgetch(view->window);
|
||||
}
|
||||
|
||||
char ARC_ConsoleView_GetCharAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
return mvwgetch(view->window, pos.y, pos.x);
|
||||
}
|
||||
|
||||
ARC_ConsoleKey ARC_ConsoleView_GetConsoleKeyAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
return (ARC_ConsoleKey){ mvwgetch(view->window, pos.y, pos.x) };
|
||||
}
|
||||
|
||||
ARC_ConsoleKey *ARC_ConsoleView_GetCreateConsoleKeyAt(ARC_ConsoleView *view, ARC_Point pos){
|
||||
ARC_ConsoleKey *key;
|
||||
ARC_ConsoleKey_Create(&key, NULL);
|
||||
key->key = mvwgetch(view->window, pos.y, pos.x);
|
||||
return key;
|
||||
}
|
||||
|
||||
ARC_String *ARC_ConsoleView_GetStringInput(ARC_ConsoleView *view, ARC_Point pos, ARC_ConsoleView_OverrideCharInputFn *overrideCharInputFn, void *userdata){
|
||||
noecho();
|
||||
|
||||
uint32_t cstringSize = view->bounds.w - pos.x;
|
||||
char cstring[view->bounds.w - pos.x];
|
||||
|
||||
ARC_ConsoleKey temp = ARC_ConsoleView_GetConsoleKeyAt(view, pos);
|
||||
uint32_t index = 0;
|
||||
while(temp.key != '\n'){
|
||||
//store the last size to be able to clear efficeintly
|
||||
uint32_t lastSize = index;
|
||||
|
||||
//if override function exists and it overrode the current char
|
||||
if(overrideCharInputFn != NULL && (*overrideCharInputFn)(&temp, cstring, &index, cstringSize, userdata)){
|
||||
for(uint32_t i = 0; i < lastSize; i++){
|
||||
ARC_ConsoleView_RenderCharAt(view, ' ', (ARC_Point){ pos.x + i, pos.y });
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < index; i++){
|
||||
ARC_ConsoleView_RenderCharAt(view, cstring[i], (ARC_Point){ pos.x + i, pos.y });
|
||||
}
|
||||
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
if(temp.key == KEY_BACKSPACE || temp.key == KEY_DC || temp.key == 127){
|
||||
if(index == 0){
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
index--;
|
||||
ARC_ConsoleView_RenderCharAt(view, ' ', (ARC_Point){ pos.x + index, pos.y });
|
||||
cstring[index] = '\0';
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
continue;
|
||||
}
|
||||
|
||||
if(index < (view->bounds.w - 1) - pos.x){
|
||||
ARC_ConsoleView_RenderCharAt(view, (char)(temp.key), (ARC_Point){ pos.x + index, pos.y });
|
||||
cstring[index] = (char)(temp.key);
|
||||
index++;
|
||||
}
|
||||
|
||||
temp = ARC_ConsoleView_GetConsoleKeyAt(view, (ARC_Point){ pos.x + index, pos.y });
|
||||
}
|
||||
|
||||
if(view->echo){
|
||||
echo();
|
||||
}
|
||||
|
||||
if(index == 0){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ARC_String *string;
|
||||
ARC_String_Create(&string, cstring, index);
|
||||
return string;
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetCursorVisibility(ARC_ConsoleView *view, uint8_t visibility){
|
||||
switch(visibility){
|
||||
case ARC_CONSOLE_VIEW_CURSOR_HIDDEN:
|
||||
curs_set(0);
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_CURSOR_VISIBLE:
|
||||
curs_set(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetBorder(ARC_ConsoleView *view, uint32_t border){
|
||||
switch(border){
|
||||
case ARC_CONSOLE_VIEW_BORDER_NONE:
|
||||
wborder(view->window, ' ', ' ', ' ',' ',' ',' ',' ',' ');
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_BORDER_DEFAULT:
|
||||
box(view->window, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
wrefresh(view->window);
|
||||
}
|
||||
|
||||
void ARC_ConsoleView_SetAttribute(ARC_ConsoleView *view, uint32_t attribute){
|
||||
switch(attribute){
|
||||
case ARC_CONSOLE_VIEW_ATTRIBUTE_NONE:
|
||||
wattroff(view->window, A_REVERSE);
|
||||
break;
|
||||
case ARC_CONSOLE_VIEW_ATTRIBUTE_REVERSE:
|
||||
wattron(view->window, A_REVERSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue