Keyboard interaction between menubar entries

This commit is contained in:
K. Lange 2018-07-21 18:32:00 +09:00
parent 0e45293ced
commit b26104c156
5 changed files with 71 additions and 3 deletions

View File

@ -34,6 +34,7 @@ static void redraw_window(void) {
menu_bar.x = decor_left_width;
menu_bar.y = decor_top_height;
menu_bar.width = ctx->width - decor_width();
menu_bar.window = main_window;
menu_bar_render(&menu_bar, ctx);
flip(ctx);

View File

@ -34,6 +34,7 @@ static void redraw_window(void) {
menu_bar.x = decor_left_width;
menu_bar.y = decor_top_height;
menu_bar.width = ctx->width - decor_width();
menu_bar.window = main_window;
menu_bar_render(&menu_bar, ctx);
flip(ctx);

View File

@ -351,6 +351,7 @@ static void render_decors(void) {
terminal_menu_bar.x = decor_left_width;
terminal_menu_bar.y = decor_top_height;
terminal_menu_bar.width = window_width;
terminal_menu_bar.window = window;
menu_bar_render(&terminal_menu_bar, ctx);
}
yutani_window_advertise_icon(yctx, window, terminal_title_length ? terminal_title : "Terminal", "utilities-terminal");

View File

@ -55,6 +55,7 @@ struct MenuList {
struct MenuSet * set;
struct MenuList * child;
struct MenuList * parent;
struct menu_bar * _bar;
int closed;
};
@ -103,9 +104,14 @@ struct menu_bar {
struct menu_bar_entries * active_entry;
struct MenuList * active_menu;
int active_menu_wid;
int active_entry_idx;
yutani_window_t * window;
int num_entries;
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);
extern void menu_bar_show_menu(yutani_t * yctx, yutani_window_t * window, struct menu_bar * self, int offset, struct menu_bar_entries * _entries);

View File

@ -316,6 +316,7 @@ struct MenuList * menu_create(void) {
p->window = NULL;
p->set = NULL;
p->child = NULL;
p->_bar = NULL;
p->parent = NULL;
p->closed = 1;
return p;
@ -371,6 +372,7 @@ struct MenuSet * menu_set_from_description(const char * path, void (*callback)(s
p->window = NULL;
p->set = _out;
p->child = NULL;
p->_bar = NULL;
p->parent = NULL;
p->closed = 1;
hashmap_set(out, line+1, p);
@ -627,8 +629,28 @@ void menu_key_action(struct MenuList * menu, struct yutani_msg_key_event * me) {
hilighted->hilight = 1;
if (hilighted->_type == MenuEntry_Submenu) {
hilighted->activate(hilighted, 0);
} /* else next menu from bar? */
_menu_redraw(window,yctx,menu);
_menu_redraw(window,yctx,menu);
} else {
struct menu_bar * bar = NULL;
struct MenuList * p = menu;
do {
if (p->_bar) {
bar = p->_bar;
break;
}
} while ((p = p->parent));
if (bar) {
menu_definitely_close(p);
int active = (bar->active_entry_idx + 1 + bar->num_entries) % (bar->num_entries);
bar->active_entry = &bar->entries[active];
if (bar->redraw_callback) {
bar->redraw_callback();
}
menu_bar_show_menu(yctx, bar->window, bar, -1, bar->active_entry);
} else {
_menu_redraw(window,yctx,menu);
}
}
}
} else if (me->event.key == '\n') {
if (!hilighted) {
@ -643,7 +665,14 @@ void menu_key_action(struct MenuList * menu, struct yutani_msg_key_event * me) {
hovered_menu = menu->parent;
} /* else previous from menu bar? */
menu_definitely_close(menu);
if (menu->parent && menu->parent->window) {
if (menu->_bar) {
int active = (menu->_bar->active_entry_idx - 1 + menu->_bar->num_entries) % (menu->_bar->num_entries);
menu->_bar->active_entry = &menu->_bar->entries[active];
if (menu->_bar->redraw_callback) {
menu->_bar->redraw_callback();
}
menu_bar_show_menu(yctx, menu->_bar->window, menu->_bar, -1, menu->_bar->active_entry);
} else if (menu->parent && menu->parent->window) {
yutani_focus_window(yctx, menu->parent->window->wid);
}
} else if (me->event.keycode == KEY_ESCAPE) {
@ -785,6 +814,13 @@ void menu_bar_render(struct menu_bar * self, gfx_context_t * ctx) {
int offset = _x;
struct menu_bar_entries * _entries = self->entries;
if (!self->num_entries) {
while (_entries->title) {
_entries++;
self->num_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) {
@ -801,11 +837,34 @@ void menu_bar_render(struct menu_bar * self, gfx_context_t * ctx) {
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);
int i = 0;
if (offset == -1) {
/* Must calculate */
offset = self->x;
struct menu_bar_entries * e = self->entries;
while (e->title) {
if (e == _entries) break;
offset += draw_sdf_string_width(e->title, 16, SDF_FONT_THIN) + 10;
e++;
i++;
}
} else {
struct menu_bar_entries * e = self->entries;
while (e->title) {
if (e == _entries) break;
e++;
i++;
}
}
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->_bar = self;
self->active_menu_wid = new_menu->window->wid;
self->active_entry = _entries;
self->active_entry_idx = i;
if (self->redraw_callback) {
self->redraw_callback();
}