commit bc97ab55b639aaa9d2c4210a50cfd82789657917
parent 2d45bf507eaa7814eb4bf765d1970c8c6f8ee5d4
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Thu, 8 Sep 2022 23:28:04 +0200
General improvements and bug fixing
Diffstat:
7 files changed, 141 insertions(+), 66 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,12 +1,12 @@
-# GNU Makefile for C Interfaces and Implementations
+# GNU Makefile for Termbox2 based display library
#
# Usage: make [-f path\Makefile] [DEBUG=Y] target
-NAME = display
+NAME = pane
CC = gcc
SRC = src
-OBJ = .
+OBJ = obj
BIN = bin
INCLUDE = include
LATEX = docs/latex
@@ -20,15 +20,13 @@ OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
CFLAGS = -I$(INCLUDE)
ifeq ($(DEBUG),Y)
- CFLAGS += -Wall -ggdb -lciid
+ CFLAGS += -Wall -ggdb
SRCS := $(filter-out $(SRC)/mem.c, $(SRCS))
- LIBNAME =$(NAME)d
- LIB = $(OBJ)/lib$(LIBNAME)
+ LIB = $(OBJ)/lib$(NAME)d
else
- CFLAGS += -DNDEBUG -lcii
+ CFLAGS += -DNDEBUG
SRCS := $(filter-out $(SRC)/memchk.c, $(SRCS))
- LIBNAME = $(NAME)
- LIB = $(OBJ)/lib$(LIBNAME)
+ LIB = $(OBJ)/lib$(NAME)
endif
all: $(LIB) main
@@ -36,27 +34,23 @@ all: $(LIB) main
$(LIB): $(OBJS)
ar crs $@.a $^
-main: main.o
- gcc $(SRC)/main.c -o $(BIN)/main $(CFLAGS) $(LDFLAGS) -L. -l$(LIBNAME)
+main: $(OBJ)/main.o
+ gcc $(SRC)/main.c -o $(BIN)/main $(CFLAGS) $(LDFLAGS) -L. -l:$(LIB).a
$(OBJ)/%.o: $(SRC)/%.c
$(CC) -c $< -o $@ $(CFLAGS) $(LDFLAGS)
install:
install -d /usr/local/include/$(NAME)
- install -p -m 644 $(INCLUDE)/* /usr/local/include/
+ install -p -m 644 $(INCLUDE)/* /usr/local/include/$(NAME)
install -d /usr/local/lib
install -p -m 644 $(LIB).a /usr/local/lib
clean:
- -$(RM) $(OBJS) $(LIB).a
-
-docs:
- doxygen
- make -C $(LATEX)
+ -$(RM) $(BIN)/* $(OBJ)/*
help:
- @echo "Terbox2 based display library"
+ @echo "Termbox2 based display library"
@echo
@echo "Usage: make [-f path\Makefile] [DEBUG=Y] target"
@echo
@@ -65,7 +59,6 @@ help:
@echo " install - Installs the static library and header files"
@echo " clean - Clean the project by removing binaries"
@echo " help - Prints a help message with target rules"
- @echo " docs - Compile html and pdf documentation using doxygen and pdflatex"
@echo
@echo "Optional parameters:"
@echo " DEBUG - Compile binary file with debug flags enabled"
diff --git a/include/pane.h b/include/pane.h
@@ -3,6 +3,8 @@
#include <termbox.h>
+enum INPUT_SIGNALS { INPUT_IGNORED, INPUT_HANDLED, INPUT_REFORM };
+
#define T Pane_T
typedef struct T *T;
diff --git a/include/widgets.h b/include/widgets.h
@@ -0,0 +1,22 @@
+#ifndef WIDGETLIST_H
+#define WIDGETLIST_H
+
+#include <stdarg.h>
+#include "pane.h"
+
+typedef struct widgetList_T *widgetList_T;
+struct widgetList_T {
+ Pane_T pane;
+ size_t items_num;
+ size_t index_start;
+ int end;
+ int display_num;
+ int y_start;
+};
+
+widgetList_T widgetList_new(Pane_T pane, int size);
+void widgetList_cacl(widgetList_T self, int index_current);
+
+void widgetCenter_print(widget_T widget);
+
+#endif
diff --git a/src/main.c b/src/main.c
@@ -41,16 +41,10 @@ struct menuStyle_T mainMenuStyle2 = {
.spacing = 0,
};
-struct data_T mainMenu_payload = {
- .payload = (void *)&mainMenu,
- .handle_input = menu_hadleInput,
-};
-
struct menuInfo_T mainMenuInfo;
struct widget_T mainMenu_widget = {
.pane = NULL,
- .data = &mainMenu_payload,
.callback = pane_menu,
.title = "Main Menu",
.style = &mainMenuStyle,
@@ -63,7 +57,6 @@ struct widget_T mainMenu_widget2 = {
.pane = NULL,
.inited = 0,
.resized = 0,
- .data = &mainMenu_payload,
.callback = pane_menu,
.title = "Main Menu 2",
.style = &mainMenuStyle2,
@@ -82,6 +75,9 @@ int main(int argc, char **argv)
pane_vsplit(mids[0], 2, 1, 1);
+ data_T mainMenu_payload = data_new(&mainMenu, menu_hadleInput);
+ widget_setData(&mainMenu_widget, mainMenu_payload);
+ widget_setData(&mainMenu_widget2, mainMenu_payload);
widget_activate(&mainMenu_widget, mids[1]);
widget_activate(&mainMenu_widget2, bots[1]);
pane_event_loop();
diff --git a/src/menu.c b/src/menu.c
@@ -106,8 +106,6 @@ void pane_menu(widget_T widget)
info->start++;
}
- tb_printf(pane_x(pane), pane_y(pane), TB_GREEN, 0, "%d", info->start);
-
CLAMP(info->start, 0, menu->items_size - info->items_num);
/* CLAMP(menu->current, info->start, info->start + info->items_num); */
@@ -125,7 +123,8 @@ void pane_menu(widget_T widget)
int y = info->y;
for (i = info->start; i < info->start + info->items_num; i++) {
int color = (i == menu->current) ? TB_RED : TB_BLUE;
- tb_printf(info->x, y, color, 0, "%s", menu->items[i].name);
+ tb_printf(info->x, y, color, 0, "%.*s",
+ pane_width(widget->pane), menu->items[i].name);
y += style->spacing + 1;
}
diff --git a/src/pane.c b/src/pane.c
@@ -1,6 +1,5 @@
#include <termbox.h>
#include <stdarg.h>
-#include <mem.h>
#include <stdlib.h>
#include "pane.h"
@@ -112,12 +111,10 @@ void pane_draw_border(T self)
{
int x_max = self->x + self->width - 1;
int y_max = self->y + self->height - 1;
- uintattr_t color = (self == ACTIVE) ? TB_BLUE : TB_GREEN;
+ int color = (self == ACTIVE) ? TB_BLUE : TB_GREEN;
+
draw_border(self->x, self->y, x_max, y_max, color);
draw_title(self);
-
- /* tb_printf(self->x, self->y, TB_RED, 0, "%dx%d", self->height, */
- /* self->width); */
}
void pane_clear(T self, int clear_border)
@@ -322,6 +319,8 @@ void pane_unsplit(T self)
}
free(self->children);
free(self->rules);
+ self->children = NULL;
+ self->rules = NULL;
} else {
active = self->active;
}
@@ -368,8 +367,10 @@ T *pane_vsplit(T self, size_t count, ...)
void pane_setTitle(T self, char *title)
{
self->title = title;
- if (self->children_num == 0)
+ if (self->children_num == 0) {
+ pane_draw_border(self);
draw_title(self);
+ }
}
void setActive(int dir)
@@ -410,11 +411,17 @@ void setActive(int dir)
int centerVertical(Pane_T pane, int len)
{
+ if (len > pane_height(pane))
+ return pane_hasBorder(pane) ? 1 : 0;
+
return pane_y(pane) + (pane_height(pane) - len) / 2;
}
int centerHorisontal(Pane_T pane, int len)
{
+ if (len > pane_width(pane))
+ return pane_hasBorder(pane) ? 1 : 0;
+
return pane_x(pane) + (pane_width(pane) - len - 2) / 2 + 1;
}
@@ -425,6 +432,8 @@ data_T data_new(void *payload, data_handler handler)
data_T data = calloc(1, sizeof(*data));
data->handle_input = handler;
data->payload = payload;
+ data->widget_num = 0;
+ data->widgets = NULL;
return data;
}
@@ -432,8 +441,6 @@ data_T data_new(void *payload, data_handler handler)
int widget_activate(widget_T self, Pane_T pane)
{
- size_t i;
-
self->pane = pane;
pane->widget = self;
pane_setTitle(pane, self->title);
@@ -441,14 +448,6 @@ int widget_activate(widget_T self, Pane_T pane)
self->callback(self);
tb_present();
- data_T data = self->data;
- for (i = 0; i < data->widget_num; i++)
- if (data->widgets[i] == self)
- return 1;
-
- data->widgets = realloc(data->widgets, data->widget_num + 1);
- data->widgets[data->widget_num++] = self;
-
return 1;
}
@@ -472,48 +471,66 @@ int widget_deactivate(widget_T self)
void widget_setData(widget_T self, data_T data)
{
self->inited = 0;
- if (self->data) {
- data->widget_num = self->data->widget_num;
- data->widgets = self->data->widgets;
- }
self->data = data;
+ data->widgets = realloc(data->widgets, (data->widget_num + 1) *
+ sizeof(*data->widgets));
+ data->widgets[data->widget_num++] = self;
}
int pane_handle_input(Pane_T self, struct tb_event ev)
{
size_t i;
+ int res;
widget_T widget;
data_T data;
if ((widget = pane_widget(self)) && (data = widget->data)) {
- if (data->handle_input(data, ev)) {
- size_t size = data->widget_num;
- for (i = 0; i < size; i++) {
- widget = data->widgets[i];
- widget->callback(widget);
- size = data->widget_num;
+ if (data->handle_input) {
+ switch ((res = data->handle_input(data, ev))) {
+ case INPUT_HANDLED: {
+ data = widget->data;
+ size_t size = data->widget_num;
+ for (i = 0; i < size; i++) {
+ widget = data->widgets[i];
+ widget->callback(widget);
+ size = data->widget_num;
+ }
+ tb_present();
+ return 1;
+ }
+ case INPUT_IGNORED:
+ case INPUT_REFORM:
+ return res;
}
- tb_present();
- return 1;
}
}
- return 0;
+ return INPUT_IGNORED;
}
int pane_recursive_handle(Pane_T self, struct tb_event ev)
{
size_t i;
+ int res;
if (!self)
return 0;
- if (!pane_handle_input(self, ev)) {
- for (i = 0; i < self->children_num; i++)
- if (pane_recursive_handle(self->children[i], ev))
- return 1;
+ switch ((res = pane_handle_input(self, ev))) {
+ case INPUT_HANDLED:
+ case INPUT_REFORM:
+ return res;
}
- return 0;
+ for (i = 0; i < self->children_num; i++)
+ switch ((res = pane_recursive_handle(self->children[i], ev))) {
+ case INPUT_IGNORED:
+ continue;
+ case INPUT_HANDLED:
+ case INPUT_REFORM:
+ return res;
+ }
+
+ return INPUT_IGNORED;
}
void pane_event_loop(void)
@@ -527,7 +544,7 @@ void pane_event_loop(void)
pane_handle_resize();
continue;
case TB_EVENT_KEY: {
- if (ev.ch == 'q' || ev.key == TB_KEY_ESC) {
+ if (ev.key == TB_KEY_ESC) {
return;
}
@@ -556,5 +573,3 @@ void pane_event_loop(void)
}
}
}
-
-/* CENTER WIDGET */
diff --git a/src/widgets.c b/src/widgets.c
@@ -0,0 +1,48 @@
+#include <math.h>
+
+#include "pane.h"
+#include "widgets.h"
+#include "utils.h"
+
+widgetList_T widgetList_new(Pane_T pane, int size)
+{
+ widgetList_T list = calloc(1, sizeof(*list));
+ list->items_num = size;
+ list->pane = pane;
+
+ return list;
+}
+
+void widgetList_cacl(widgetList_T self, int index_current)
+{
+ int max_items = pane_height(self->pane);
+ self->display_num = ACLAMP(max_items, 0, self->items_num);
+
+ int relative = index_current - self->index_start;
+ if (relative < 0 && self->index_start > 0) {
+ self->index_start += relative;
+ } else if (relative > 0 && relative > self->display_num - 1) {
+ self->index_start += relative - (self->display_num - 1);
+ }
+ CLAMP(self->index_start, 0, self->items_num - self->display_num);
+}
+
+void widgetCenter_print(widget_T widget)
+{
+ size_t i;
+ char *message = (char *)widget->data->payload;
+ Pane_T pane = widget->pane;
+
+ pane_clear(pane, 0);
+
+ int len = strlen(message);
+ int width = pane_width(pane);
+ int lines = ceil((double)len / width);
+ int start_x = centerHorisontal(pane, MIN(len, width));
+ int y = centerVertical(pane, lines);
+
+ for (i = 0; i < lines; i++, y++)
+ tb_printf(start_x, y, TB_RED, 0, "%.*s", pane_width(pane),
+ message + i * width);
+ tb_present();
+}