Menu bar in a separate library
This commit is contained in:
parent
30b327aca8
commit
d6afa06c80
100
apps/terminal.c
100
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);
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <toaru/graphics.h>
|
||||
#include <toaru/hashmap.h>
|
||||
#include <toaru/list.h>
|
||||
|
29
base/usr/include/toaru/menubar.h
Normal file
29
base/usr/include/toaru/menubar.h
Normal file
@ -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
lib/menubar.c
Normal file
74
lib/menubar.c
Normal file
@ -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;
|
||||
}
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user