pane

Termbox2 based terminal UI library
git clone git://git.dimitrijedobrota.com/pane.git
Log | Files | Refs

commit f03c95750611845c993f4fe486b743636e6a67e7
parent 2ad2a19cc37a2aa1e13be9949ce6abb43e16643a
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Wed, 31 Aug 2022 16:22:43 +0200

Switch between each pain

Diffstat:
M.gitignore | 2++
Dbin/main | 0
Minclude/pane.h | 3++-
Minclude/utils.h | 1+
Msrc/main.c | 23++++++++++++++++++++---
Msrc/pane.c | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
6 files changed, 157 insertions(+), 14 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,6 +1,8 @@ .ccls-cache/ .ccls docs/* +bin +bin/* # Prerequisites *.d diff --git a/bin/main b/bin/main Binary files differ. diff --git a/include/pane.h b/include/pane.h @@ -34,6 +34,7 @@ struct menu_T { }; void pane_menu(menu_T self); - +void setActive(int direction); +void printDiagram(T self); #undef T #endif diff --git a/include/utils.h b/include/utils.h @@ -7,6 +7,7 @@ #define MIN(a, b) ((a < b) ? a : b) #define CLAMP(a, x, y) ((a) = (MAX(x, MIN(a, y)))) #define ACLAMP(a, x, y) (MAX(x, MIN(a, y))) +#define WCLAMP(a, x) ((a + x) % x) #define UNIMPLEMENTED \ do { \ diff --git a/src/main.c b/src/main.c @@ -7,7 +7,7 @@ #include "pane.h" #include "utils.h" -extern Pane_T MAIN; +extern Pane_T MAIN, ACTIVE; void load(char *pass, int index) { @@ -45,8 +45,9 @@ int main(int argc, char **argv) pane_vsplit(mids[0], 2, 1, 1); mainMenu.pane = mids[1]; - pane_menu(&mainMenu); + /* pane_menu(&mainMenu); */ + Pane_T active = MAIN; tb_present(); while (1) { tb_poll_event(&ev); @@ -55,13 +56,29 @@ int main(int argc, char **argv) HANDLE_RESIZE; break; case TB_EVENT_KEY: - switch (ev.ch) + switch (ev.ch) { case 'q': goto end; + } + switch (ev.key) { + case TB_KEY_ARROW_UP: + setActive(0); + break; + case TB_KEY_ARROW_RIGHT: + setActive(1); + break; + case TB_KEY_ARROW_DOWN: + setActive(2); + break; + case TB_KEY_ARROW_LEFT: + setActive(3); + break; + } } } } end: pane_stop(); + printDiagram(MAIN); return 0; } diff --git a/src/pane.c b/src/pane.c @@ -20,9 +20,20 @@ struct T { int x; int y; + + int active; + T left; + T right; + T up; + T down; + + int index; + int child_no; + T parent; }; Pane_T MAIN; +Pane_T ACTIVE; #define BORDER_HORIZONTAL "─" #define BORDER_VERTICAL "│" @@ -44,23 +55,23 @@ void draw_border(T self) int x_max = self->x + self->width - 1; int y_max = self->y + self->height - 1; + int color = (self->active) ? TB_BLUE : TB_GREEN; for (i = self->x + 1; i < x_max; i++) { - tb_print(i, self->y, TB_GREEN, 0, BORDER_HORIZONTAL); - tb_print(i, y_max, TB_GREEN, 0, BORDER_HORIZONTAL); + tb_print(i, self->y, color, 0, BORDER_HORIZONTAL); + tb_print(i, y_max, color, 0, BORDER_HORIZONTAL); } for (i = self->y + 1; i < y_max; i++) { - tb_print(self->x, i, TB_GREEN, 0, BORDER_VERTICAL); - tb_print(x_max, i, TB_GREEN, 0, BORDER_VERTICAL); + tb_print(self->x, i, color, 0, BORDER_VERTICAL); + tb_print(x_max, i, color, 0, BORDER_VERTICAL); } - tb_print(self->x, self->y, TB_GREEN, 0, BORDER_CORNER_1); - tb_print(x_max, self->y, TB_GREEN, 0, BORDER_CORNER_2); - tb_print(self->x, y_max, TB_GREEN, 0, BORDER_CORNER_3); - tb_print(x_max, y_max, TB_GREEN, 0, BORDER_CORNER_4); + tb_print(self->x, self->y, color, 0, BORDER_CORNER_1); + tb_print(x_max, self->y, color, 0, BORDER_CORNER_2); + tb_print(self->x, y_max, color, 0, BORDER_CORNER_3); + tb_print(x_max, y_max, color, 0, BORDER_CORNER_4); - tb_printf(self->x + 1, self->y + 1, TB_RED, 0, "%d-%d", self->x, - self->y, self->width, self->height); + tb_printf(self->x + 1, self->y + 1, TB_RED, 0, "%d", self->index); draw_title(self); } @@ -153,8 +164,17 @@ int pane_start(void) { tb_init(); MAIN = calloc(1, sizeof(*MAIN)); + MAIN->height = tb_height(); + MAIN->width = tb_width(); + MAIN->active = 1; + MAIN->parent = MAIN; + /* MAIN->up = MAIN; */ + /* MAIN->down = MAIN; */ + /* MAIN->left = MAIN; */ + /* MAIN->right = MAIN; */ pane_handle_resize(); + ACTIVE = MAIN; return 1; } @@ -170,6 +190,7 @@ T pane_child(T self, int index) void split(T self, size_t count, va_list ap) { + static int index = 1; int current; size_t i; @@ -180,13 +201,29 @@ void split(T self, size_t count, va_list ap) for (i = 0; i < self->children_num; i++) { self->children[i] = calloc(1, sizeof(struct T)); self->rules[i] = va_arg(ap, int); + + self->children[i]->index = index++; + self->children[i]->parent = self; + self->children[i]->child_no = i; + } + + if (self->active) { + self->active = 0; + self->children[0]->active = 1; + ACTIVE = self->children[0]; } pane_resize(self); } +#define wrap_or_slap(direction, index) \ + child->direction = (self->direction && self->direction != self) ? \ + (self->direction) : \ + self->children[index]; + T *pane_split(T self, size_t count, ...) { + size_t i; va_list ap; self->horizontal = 1; @@ -194,11 +231,29 @@ T *pane_split(T self, size_t count, ...) split(self, count, ap); va_end(ap); + T child; + for (i = 0; i < self->children_num; i++) { + child = self->children[i]; + wrap_or_slap(up, i); + wrap_or_slap(down, i); + } + + for (i = 1; i < self->children_num; i++) + self->children[i]->left = self->children[i - 1]; + child = self->children[0]; + wrap_or_slap(left, self->children_num - 1); + + for (i = 0; i < self->children_num - 1; i++) + self->children[i]->right = self->children[i + 1]; + child = self->children[self->children_num - 1]; + wrap_or_slap(right, 0); + return self->children; } T *pane_vsplit(T self, size_t count, ...) { + size_t i; va_list ap; self->horizontal = 0; @@ -206,6 +261,23 @@ T *pane_vsplit(T self, size_t count, ...) split(self, count, ap); va_end(ap); + T child; + for (i = 0; i < self->children_num; i++) { + child = self->children[i]; + wrap_or_slap(left, i); + wrap_or_slap(right, i); + } + + for (i = 1; i < self->children_num; i++) + self->children[i]->up = self->children[i - 1]; + child = self->children[0]; + wrap_or_slap(up, self->children_num - 1); + + for (i = 0; i < self->children_num - 1; i++) + self->children[i]->down = self->children[i + 1]; + child = self->children[self->children_num - 1]; + wrap_or_slap(down, 0); + return self->children; } @@ -345,3 +417,53 @@ redraw:; } } } + +void setActive(int dir) +{ + T old = ACTIVE, tmp; + + T arr[] = { ACTIVE->up, ACTIVE->right, ACTIVE->down, ACTIVE->left }; + ACTIVE = arr[dir]; + + while (ACTIVE->children_num) { + int last = ACTIVE->children_num - 1; + if (!ACTIVE->horizontal) { + if (dir == 0 || dir == 2) { + ACTIVE = ACTIVE->children[dir == 2 ? 0 : last]; + continue; + } + } else { + if (dir == 1 || dir == 3) { + ACTIVE = ACTIVE->children[dir == 1 ? 0 : last]; + continue; + } + } + ACTIVE = ACTIVE->children[ACTIVE->active]; + } + + old->active = 0; + ACTIVE->active = 1; + + for (tmp = ACTIVE; tmp->parent != tmp; tmp = tmp->parent) { + tmp->parent->active = tmp->child_no; + } + + draw_border(old); + draw_border(ACTIVE); + tb_present(); +} + +void printDiagram(T self) +{ + static int index = 0; + size_t i; + + if (self != MAIN) + printf("%p:%d: parent:%d up:%d;down:%d;left:%d;right:%d;\n", + self, self->index, self->parent->index, self->up->index, + self->down->index, self->left->index, + self->right->index); + + for (i = 0; i < self->children_num; i++) + printDiagram(self->children[i]); +}