Browse Source

Menu bar in a separate library

K. Lange 3 years ago
parent
commit
d6afa06c80
5 changed files with 115 additions and 93 deletions
  1. 8 92
      apps/terminal.c
  2. 2 0
      base/usr/include/toaru/menu.h
  3. 29 0
      base/usr/include/toaru/menubar.h
  4. 74 0
      lib/menubar.c
  5. 2 1
      util/auto-dep.py

+ 8 - 92
apps/terminal.c

@@ -44,6 +44,7 @@
 #include <toaru/spinlock.h>
 #include <toaru/list.h>
 #include <toaru/menu.h>
+#include <toaru/menubar.h>
 #include <toaru/sdf.h>
 
 #include "terminal-palette.h"
@@ -115,7 +116,7 @@ uint32_t window_height = 480;
 char   terminal_title[TERMINAL_TITLE_SIZE];
 size_t terminal_title_length = 0;
 gfx_context_t * ctx;
-static void render_decors();
+static void render_decors(void);
 void term_clear();
 void flush_unused_images(void);
 
@@ -333,26 +334,6 @@ void input_buffer_stuff(char * str) {
 	write(fd_master, str, s);
 }
 
-struct menu_bar_entries {
-	char * title;
-	char * action;
-};
-
-struct menu_bar {
-	int x;
-	int y;
-	int width;
-
-	struct menu_bar_entries * entries;
-
-	struct MenuSet * set;
-
-	struct menu_bar_entries * active_entry;
-	struct MenuList * active_menu;
-	int active_menu_wid;
-};
-
-
 struct menu_bar terminal_menu_bar = {0};
 struct menu_bar_entries terminal_menu_entries[] = {
 	{"File", "file"},
@@ -362,74 +343,8 @@ struct menu_bar_entries terminal_menu_entries[] = {
 	{NULL, NULL},
 };
 
-void menu_bar_render(struct menu_bar * self) {
-	int _x = self->x;
-	int _y = self->y;
-	int width = self->width;
-
-	uint32_t menu_bar_color = rgb(59,59,59);
-	for (int y = 0; y < menu_bar_height; ++y) {
-		for (int x = 0; x < width; ++x) {
-			GFX(ctx, x+_x,y+_y) = menu_bar_color;
-		}
-	}
-
-	/* for each menu entry */
-	int offset = _x;
-	struct menu_bar_entries * _entries = self->entries;
-
-	while (_entries->title) {
-		int w = draw_sdf_string_width(_entries->title, 16, SDF_FONT_THIN) + 10;
-		if ((self->active_menu && hashmap_has(menu_get_windows_hash(), (void*)self->active_menu_wid)) && _entries == self->active_entry) {
-			for (int y = _y; y < _y + 24; ++y) {
-				for (int x = offset + 2; x < offset + 2 + w; ++x) {
-					GFX(ctx, x, y) = rgb(93,163,236);
-				}
-			}
-		}
-		offset += draw_sdf_string(ctx, offset + 4, _y + 2, _entries->title, 16, rgb(255,255,255), SDF_FONT_THIN) + 10;
-		_entries++;
-	}
-}
-
-void menu_bar_show_menu(struct menu_bar * self, int offset, struct menu_bar_entries * _entries) {
-	struct MenuList * new_menu = menu_set_get_menu(self->set, _entries->action);
-	menu_show(new_menu, yctx);
-	yutani_window_move(yctx, new_menu->window, window->x + offset, window->y + self->y + 24);
-	self->active_menu = new_menu;
-	self->active_menu_wid = new_menu->window->wid;
-	self->active_entry = _entries;
-	render_decors(); /* XXX this is specific to terminal, needs a redraw callback */
-}
-
-int menu_bar_mouse_event(struct menu_bar * self, struct yutani_msg_window_mouse_event * me, int x, int y) {
-	if (x < self->x || x >= self->x + self->width || y < self->y || y >= self->y + 24 /* base height */) {
-		return 0;
-	}
 
-	int offset = self->x;
-
-	struct menu_bar_entries * _entries = self->entries;
-
-	while (_entries->title) {
-		int w = draw_sdf_string_width(_entries->title, 16, SDF_FONT_THIN) + 10;
-		if (x >= offset && x < offset + w) {
-			if (me->command == YUTANI_MOUSE_EVENT_CLICK) {
-				menu_bar_show_menu(self,offset,_entries);
-			} else if (self->active_menu && hashmap_has(menu_get_windows_hash(), (void*)self->active_menu_wid) && _entries != self->active_entry) {
-				menu_definitely_close(self->active_menu);
-				menu_bar_show_menu(self,offset,_entries);
-			}
-		}
-
-		offset += w;
-		_entries++;
-	}
-
-	return 0;
-}
-
-static void render_decors() {
+static void render_decors(void) {
 	/* XXX Make the decorations library support Yutani windows */
 	if (_fullscreen) return;
 	if (!_no_frame) {
@@ -437,8 +352,7 @@ static void render_decors() {
 		terminal_menu_bar.x = decor_left_width;
 		terminal_menu_bar.y = decor_top_height;
 		terminal_menu_bar.width = window_width;
-		terminal_menu_bar.entries = terminal_menu_entries;
-		menu_bar_render(&terminal_menu_bar);
+		menu_bar_render(&terminal_menu_bar, ctx);
 	}
 	yutani_window_advertise_icon(yctx, window, terminal_title_length ? terminal_title : "Terminal", "utilities-terminal");
 	l_x = 0; l_y = 0;
@@ -1753,7 +1667,7 @@ void * handle_incoming(void) {
 								break;
 						}
 
-						menu_bar_mouse_event(&terminal_menu_bar, me, me->new_x, me->new_y);
+						menu_bar_mouse_event(yctx, window, &terminal_menu_bar, me, me->new_x, me->new_y);
 					}
 
 					if (!_no_frame) {
@@ -1993,11 +1907,13 @@ int main(int argc, char ** argv) {
 	}
 
 	/* Set up menus */
+	terminal_menu_bar.entries = terminal_menu_entries;
+	terminal_menu_bar.redraw_callback = render_decors;
+
 	struct MenuEntry * _menu_exit = menu_create_normal("exit","exit","Exit", _menu_action_exit);
 	struct MenuEntry * _menu_copy = menu_create_normal(NULL, NULL, "Copy", _menu_action_copy);
 	struct MenuEntry * _menu_paste = menu_create_normal(NULL, NULL, "Paste", _menu_action_paste);
 
-
 	menu_right_click = menu_create();
 	menu_insert(menu_right_click, _menu_copy);
 	menu_insert(menu_right_click, _menu_paste);

+ 2 - 0
base/usr/include/toaru/menu.h

@@ -1,3 +1,5 @@
+#pragma once
+
 #include <toaru/graphics.h>
 #include <toaru/hashmap.h>
 #include <toaru/list.h>

+ 29 - 0
base/usr/include/toaru/menubar.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <toaru/menu.h>
+
+#define MENU_BAR_HEIGHT 24
+
+struct menu_bar_entries {
+	char * title;
+	char * action;
+};
+
+struct menu_bar {
+	int x;
+	int y;
+	int width;
+
+	struct menu_bar_entries * entries;
+
+	struct MenuSet * set;
+
+	struct menu_bar_entries * active_entry;
+	struct MenuList * active_menu;
+	int active_menu_wid;
+
+	void (*redraw_callback)(void);
+};
+
+extern void menu_bar_render(struct menu_bar * self, gfx_context_t * ctx);
+extern int menu_bar_mouse_event(yutani_t * yctx, yutani_window_t * window, struct menu_bar * self, struct yutani_msg_window_mouse_event * me, int x, int y);

+ 74 - 0
lib/menubar.c

@@ -0,0 +1,74 @@
+#include <toaru/yutani.h>
+#include <toaru/graphics.h>
+#include <toaru/menu.h>
+#include <toaru/menubar.h>
+#include <toaru/sdf.h>
+
+void menu_bar_render(struct menu_bar * self, gfx_context_t * ctx) {
+	int _x = self->x;
+	int _y = self->y;
+	int width = self->width;
+
+	uint32_t menu_bar_color = rgb(59,59,59);
+	for (int y = 0; y < MENU_BAR_HEIGHT; ++y) {
+		for (int x = 0; x < width; ++x) {
+			GFX(ctx, x+_x,y+_y) = menu_bar_color;
+		}
+	}
+
+	/* for each menu entry */
+	int offset = _x;
+	struct menu_bar_entries * _entries = self->entries;
+
+	while (_entries->title) {
+		int w = draw_sdf_string_width(_entries->title, 16, SDF_FONT_THIN) + 10;
+		if ((self->active_menu && hashmap_has(menu_get_windows_hash(), (void*)self->active_menu_wid)) && _entries == self->active_entry) {
+			for (int y = _y; y < _y + MENU_BAR_HEIGHT; ++y) {
+				for (int x = offset + 2; x < offset + 2 + w; ++x) {
+					GFX(ctx, x, y) = rgb(93,163,236);
+				}
+			}
+		}
+		offset += draw_sdf_string(ctx, offset + 4, _y + 2, _entries->title, 16, rgb(255,255,255), SDF_FONT_THIN) + 10;
+		_entries++;
+	}
+}
+
+void menu_bar_show_menu(yutani_t * yctx, yutani_window_t * window, struct menu_bar * self, int offset, struct menu_bar_entries * _entries) {
+	struct MenuList * new_menu = menu_set_get_menu(self->set, _entries->action);
+	menu_show(new_menu, yctx);
+	yutani_window_move(yctx, new_menu->window, window->x + offset, window->y + self->y + MENU_BAR_HEIGHT);
+	self->active_menu = new_menu;
+	self->active_menu_wid = new_menu->window->wid;
+	self->active_entry = _entries;
+	if (self->redraw_callback) {
+		self->redraw_callback();
+	}
+}
+
+int menu_bar_mouse_event(yutani_t * yctx, yutani_window_t * window, struct menu_bar * self, struct yutani_msg_window_mouse_event * me, int x, int y) {
+	if (x < self->x || x >= self->x + self->width || y < self->y || y >= self->y + 24 /* base height */) {
+		return 0;
+	}
+
+	int offset = self->x;
+
+	struct menu_bar_entries * _entries = self->entries;
+
+	while (_entries->title) {
+		int w = draw_sdf_string_width(_entries->title, 16, SDF_FONT_THIN) + 10;
+		if (x >= offset && x < offset + w) {
+			if (me->command == YUTANI_MOUSE_EVENT_CLICK) {
+				menu_bar_show_menu(yctx, window, self,offset,_entries);
+			} else if (self->active_menu && hashmap_has(menu_get_windows_hash(), (void*)self->active_menu_wid) && _entries != self->active_entry) {
+				menu_definitely_close(self->active_menu);
+				menu_bar_show_menu(yctx, window, self,offset,_entries);
+			}
+		}
+
+		offset += w;
+		_entries++;
+	}
+
+	return 0;
+}

+ 2 - 1
util/auto-dep.py

@@ -36,7 +36,8 @@ class Classifier(object):
         '<toaru/termemu.h>':     (None, '-ltoaru_termemu',     ['<toaru/graphics.h>']),
         '<toaru/sdf.h>':         (None, '-ltoaru_sdf',         ['<toaru/graphics.h>', '<toaru/hashmap.h>']),
         '<toaru/icon_cache.h>':  (None, '-ltoaru_icon_cache',  ['<toaru/graphics.h>', '<toaru/hashmap.h>']),
-        '<toaru/menu.h>':        (None, '-ltoaru_menu',        ['<toaru/yutani.h>', '<toaru/icon_cache.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
+        '<toaru/menu.h>':        (None, '-ltoaru_menu',        ['<toaru/sdf.h>', '<toaru/yutani.h>', '<toaru/icon_cache.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
+        '<toaru/menubar.h>':     (None, '-ltoaru_menubar',     ['<toaru/menu.h>', '<toaru/yutani.h>', '<toaru/icon_cache.h>', '<toaru/graphics.h>', '<toaru/hashmap.h>']),
     }
 
     def __init__(self, filename):