aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/meson.build2
-rw-r--r--src/ui/base.c76
-rw-r--r--src/ui/debug.c26
-rw-r--r--src/ui/dock.c23
-rw-r--r--src/ui/root.c79
-rw-r--r--src/ui/ui.internal.h21
6 files changed, 176 insertions, 51 deletions
diff --git a/src/meson.build b/src/meson.build
index d90d7c1..14e6269 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,4 +1,4 @@
-umps_srcs = files('main.c', 'ui/base.c', 'ui/dock.c')
+umps_srcs = files('main.c', 'ui/base.c', 'ui/dock.c', 'ui/root.c', 'ui/debug.c')
configure_file(input : 'config.h.in', output : 'config.h', configuration : conf_data)
umps_config_inc = include_directories('.')
diff --git a/src/ui/base.c b/src/ui/base.c
index 74855b1..5607f4e 100644
--- a/src/ui/base.c
+++ b/src/ui/base.c
@@ -8,8 +8,7 @@ struct ui_window_root *ui_root = NULL;
void ui__default_draw_proc(struct ui_window_base *base)
{
- redrawwin(base->cwindow);
- wrefresh(base->cwindow);
+ wnoutrefresh(base->cwindow); /* root window calls doupdate */
}
void ui__init_window_base(struct ui_window_base *base)
@@ -37,13 +36,15 @@ void ui__init_window_dock(struct ui_window_dock *dock)
dock->focus = UI__WINDOW_FOCUS_NONE;
}
-void ui__init_window_root(struct ui_window_root *root)
+void ui__init_window_root(struct ui_window_root *root, WINDOW *cwindow)
{
- ui__init_window_dock(&root->super);
- root->super.super.type = UI__WINDOW_TYPE_ROOT;
- root->super.super.draw_proc = &ui__root_draw_proc;
- root->super.super.layout_proc = &ui__root_layout_proc;
+ ui__init_window_base(&root->super);
+ root->super.cwindow = cwindow;
+ root->super.type = UI__WINDOW_TYPE_ROOT;
+ root->super.draw_proc = &ui__root_draw_proc;
+ root->super.layout_proc = &ui__root_layout_proc;
+ root->content = NULL;
root->floating = NULL;
}
@@ -53,10 +54,13 @@ void ui__destroy_window_dock(struct ui_window_dock *dock);
void ui__window_destroy_root(struct ui_window_root *root)
{
+ if (root->content)
+ ui__destroy_window(root->content);
+
if (root->floating)
ui__destroy_window(root->floating);
- ui__destroy_window_dock(&root->super);
+ ui__destroy_window_base(&root->super);
}
void ui__destroy_window_dock(struct ui_window_dock *dock)
@@ -83,10 +87,10 @@ void ui__destroy_window(struct ui_window_base *base)
switch (base->type)
{
case UI__WINDOW_TYPE_ROOT:
- ui__window_destroy_root((struct ui_window_root *)base);
+ ui__window_destroy_root(ui__cast(root, base));
break;
case UI__WINDOW_TYPE_DOCK:
- ui__destroy_window_dock((struct ui_window_dock *)base);
+ ui__destroy_window_dock(ui__cast(dock, base));
break;
case UI__WINDOW_TYPE_BASE:
ui__destroy_window_base(base);
@@ -98,17 +102,25 @@ void ui__destroy_window(struct ui_window_base *base)
* which brings it to the "foreground", squashing whatever is behind it. */
struct ui_window_base *ui__find_focused(void)
{
- struct ui_window_base *window = (struct ui_window_base *)ui_root;
- if (ui_root->floating) return ui_root->floating;
+ struct ui_window_base *window = ui__cast(base, ui_root);
- while (true)
- {
- switch (window->type)
- {
- case UI__WINDOW_TYPE_DOCK:
+ while (true) {
+ switch (window->type) {
case UI__WINDOW_TYPE_ROOT:
{
- struct ui_window_dock *dock = (struct ui_window_dock *)window;
+ struct ui_window_root *root = ui__cast(root, window);
+ if (root->floating) {
+ window = root->floating;
+ } else if (root->content) {
+ window = root->content;
+ } else {
+ return window;
+ }
+ break;
+ }
+ case UI__WINDOW_TYPE_DOCK:
+ {
+ struct ui_window_dock *dock = ui__cast(dock, window);
if (dock->focus == UI__WINDOW_FOCUS_NONE || !dock->children[dock->focus])
{
@@ -121,7 +133,7 @@ struct ui_window_base *ui__find_focused(void)
}
}
- return (struct ui_window_base *)dock; /* the dock is focused if it is really a leaf */
+ return window; /* the dock is focused if it is really a leaf */
}
childfound:
@@ -159,10 +171,9 @@ void ui__traces_draw_proc(struct ui_window_base *base)
getmaxyx(base->cwindow, maxy, maxx);
for (int i = 1; i < maxy-1; ++i)
{
- mvwhline(base->cwindow, i, 1, '%', maxx-2);
+ mvwhline(base->cwindow, i, 1, '.', maxx-2);
}
- touchwin(base->cwindow);
- wrefresh(base->cwindow);
+ wnoutrefresh(base->cwindow);
}
void ui_init(void)
@@ -178,21 +189,24 @@ void ui_init(void)
curs_set(0);
- ui__init_window_root(ui_root);
- ui_root->super.super.cwindow = stdscr; /* initialize the ncurses window ourselves */
+ ui__init_window_root(ui_root, stdscr);
/* set up UI */
+ struct ui_window_dock *maindock = malloc(sizeof(struct ui_window_dock));
+ ui__init_window_dock(maindock);
+ ui__root_set_content(ui_root, ui__cast(base, maindock));
+
for (int i = 0; i < UI__WINDOW_DOCK_MAX; ++i)
{
if (i == UI__WINDOW_DOCK_LEFT) continue;
struct ui_window_base *win_traces = malloc(sizeof(struct ui_window_base));
ui__init_window_base(win_traces);
- ui__dock_add_child((struct ui_window_dock *)ui_root, win_traces, i, 1./5);
+ ui__dock_add_child(maindock, win_traces, i, 1./5);
win_traces->draw_proc = &ui__traces_draw_proc;
}
- ui__call_draw_proc((struct ui_window_base *)ui_root);
+ ui__call_draw_proc(ui__cast(base, ui_root));
}
void ui_handle(void)
@@ -214,8 +228,14 @@ void ui_handle(void)
}
else if (inp == KEY_RESIZE)
{
- ui__call_layout_proc((struct ui_window_base *)ui_root);
- ui__call_draw_proc((struct ui_window_base *)ui_root);
+ ui__call_layout_proc(ui__cast(base, ui_root));
+ ui__call_draw_proc(ui__cast(base, ui_root));
+ } else if (inp == NS('h')) {
+ ui__status_text = "Hello...";
+ ui__call_draw_proc(ui__cast(base, ui_root));
+ } else if (inp == NS('w')) {
+ ui__status_text = "World!";
+ ui__call_draw_proc(ui__cast(base, ui_root));
}
}
diff --git a/src/ui/debug.c b/src/ui/debug.c
new file mode 100644
index 0000000..d4f2e94
--- /dev/null
+++ b/src/ui/debug.c
@@ -0,0 +1,26 @@
+#ifndef NDEBUG
+
+#include <assert.h>
+
+#include "ui.internal.h"
+
+struct ui_window_base *ui__check_cast_to_base(void *obj)
+{
+ return obj; /* this cast always succeeds */
+}
+
+struct ui_window_dock *ui__check_cast_to_dock(void *obj)
+{
+ struct ui_window_base *base = obj;
+ assert(base->type == UI__WINDOW_TYPE_DOCK);
+ return obj;
+}
+
+struct ui_window_root *ui__check_cast_to_root(void *obj)
+{
+ struct ui_window_base *base = obj;
+ assert(base->type == UI__WINDOW_TYPE_ROOT);
+ return obj;
+}
+
+#endif
diff --git a/src/ui/dock.c b/src/ui/dock.c
index 5b59b71..54c9fe9 100644
--- a/src/ui/dock.c
+++ b/src/ui/dock.c
@@ -16,7 +16,7 @@ unsigned ui__dock_position_opposite(unsigned position)
case UI__WINDOW_DOCK_RIGHT:
return UI__WINDOW_DOCK_LEFT;
default:
- assert(false); /* trap: this function should never be called here! */
+ assert(false); /* trap: the center dock has no opposite! (or position is invalid) */
}
}
@@ -139,7 +139,7 @@ void ui__dock_add_child(struct ui_window_dock *dock, struct ui_window_base *chil
void ui__dock_default_draw_proc(struct ui_window_base *base)
{
- struct ui_window_dock *dock = (struct ui_window_dock *)base;
+ struct ui_window_dock *dock = ui__cast(dock, base);
wrefresh(dock->super.cwindow);
for (unsigned i = 0; i < UI__WINDOW_DOCK_MAX; ++i)
@@ -151,7 +151,7 @@ void ui__dock_default_draw_proc(struct ui_window_base *base)
void ui__dock_default_layout_proc(struct ui_window_base *base)
{
- struct ui_window_dock *dock = (struct ui_window_dock *)base;
+ struct ui_window_dock *dock = ui__cast(dock, base);
/* fix the layout of children */
for (unsigned i = 0; i < UI__WINDOW_DOCK_MAX; ++i)
@@ -164,20 +164,3 @@ void ui__dock_default_layout_proc(struct ui_window_base *base)
ui__call_layout_proc(child);
}
}
-
-void ui__root_draw_proc(struct ui_window_base *base)
-{
- struct ui_window_root *root = (struct ui_window_root *)base;
- ui__dock_default_draw_proc(base);
-
- if (root->floating) ui__call_draw_proc(root->floating);
-}
-
-void ui__root_layout_proc(struct ui_window_base *base)
-{
- struct ui_window_root *root = (struct ui_window_root *)base;
- ui__dock_default_layout_proc(base);
-
- /* TODO: adjust floating window position :) */
- if (root->floating) ui__call_layout_proc(root->floating);
-}
diff --git a/src/ui/root.c b/src/ui/root.c
new file mode 100644
index 0000000..26ca0ac
--- /dev/null
+++ b/src/ui/root.c
@@ -0,0 +1,79 @@
+#include <assert.h>
+
+#include "ui.internal.h"
+
+/* top margin for menu bar */
+#define UI__ROOT_MARGIN_TOP (1)
+
+/* bottom margin for status bar */
+#define UI__ROOT_MARGIN_BOTTOM (1)
+
+#define UI__ROOT_MARGIN_LEFT (0)
+#define UI__ROOT_MARGIN_RIGHT (0)
+
+const char *ui__status_text = NULL;
+
+WINDOW *ui__root_place_content_window(struct ui_window_root *root)
+{
+ int maxy, maxx;
+ int begy, begx;
+ getmaxyx(root->super.cwindow, maxy, maxx);
+ getbegyx(root->super.cwindow, begy, begx);
+
+ begy += UI__ROOT_MARGIN_TOP;
+ maxy -= UI__ROOT_MARGIN_TOP + UI__ROOT_MARGIN_BOTTOM;
+
+ begx += UI__ROOT_MARGIN_LEFT;
+ begx -= UI__ROOT_MARGIN_LEFT + UI__ROOT_MARGIN_RIGHT;
+
+ return newwin(maxy, maxx, begy, begx);
+}
+
+void ui__root_draw_proc(struct ui_window_base *base)
+{
+ struct ui_window_root *root = ui__cast(root, base);
+
+ attron(A_REVERSE);
+ mvwhline(base->cwindow, 0, 0, ' ', getmaxx(base->cwindow));
+ mvwhline(base->cwindow, getmaxy(base->cwindow)-1, 0, ' ', getmaxx(base->cwindow));
+
+ if (ui__status_text) {
+ mvwprintw(base->cwindow, getmaxy(base->cwindow)-1, 1, "Status: %s", ui__status_text);
+ }
+
+ attroff(A_REVERSE);
+
+ wnoutrefresh(base->cwindow);
+
+ if (root->content) {
+ ui__call_draw_proc(root->content);
+ }
+
+ if (root->floating) {
+ ui__call_draw_proc(root->floating);
+ }
+
+ doupdate();
+}
+
+void ui__root_layout_proc(struct ui_window_base *base)
+{
+ struct ui_window_root *root = ui__cast(root, base);
+
+ if (root->content) {
+ delwin(root->content->cwindow);
+ root->content->cwindow = ui__root_place_content_window(root);
+ ui__call_layout_proc(root->content);
+ }
+}
+
+void ui__root_set_content(struct ui_window_root *root, struct ui_window_base *window)
+{
+ assert(!window->parent);
+ assert(!window->cwindow);
+ assert(!root->content);
+
+ window->cwindow = ui__root_place_content_window(root);
+ root->content = window;
+ window->parent = ui__cast(base, root);
+}
diff --git a/src/ui/ui.internal.h b/src/ui/ui.internal.h
index 7c53bd4..6107c94 100644
--- a/src/ui/ui.internal.h
+++ b/src/ui/ui.internal.h
@@ -19,6 +19,16 @@
#define UI__WINDOW_DOCK_MAX UI__WINDOW_DOCK_CENTER+1
+#ifdef NDEBUG
+#define ui__cast(_t, _v) ((struct ui_window_ ## _t *)(_v))
+#else
+#define ui__cast(_t, _v) (ui__check_cast_to_ ## _t(_v))
+
+struct ui_window_base *ui__check_cast_to_base(void *);
+struct ui_window_dock *ui__check_cast_to_dock(void *);
+struct ui_window_root *ui__check_cast_to_root(void *);
+#endif
+
/* concrete type definitions */
/* called to refresh the window (should refresh children as well) */
@@ -46,8 +56,9 @@ struct ui_window_dock {
};
struct ui_window_root {
- struct ui_window_dock super;
+ struct ui_window_base super;
+ struct ui_window_base *content;
struct ui_window_base *floating;
};
@@ -56,7 +67,7 @@ struct ui_window_root {
/* in-place constructors */
void ui__init_window_base(struct ui_window_base *);
void ui__init_window_dock(struct ui_window_dock *);
-void ui__init_window_root(struct ui_window_root *);
+void ui__init_window_root(struct ui_window_root *, WINDOW *);
struct ui_window_base *ui__find_focused(void);
@@ -78,4 +89,10 @@ void ui__dock_default_layout_proc(struct ui_window_base *base);
void ui__root_draw_proc(struct ui_window_base *);
void ui__root_layout_proc(struct ui_window_base *);
+/* root_window_utilities */
+
+void ui__root_set_content(struct ui_window_root *, struct ui_window_base *);
+
+extern const char *ui__status_text;
+
#endif /* include guard */