123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- #include "monolog.h"
- #include "zori.h"
- #include "zori_widget.h"
- #include "zori_caption.h"
- #include "zori_menu.h"
- struct zori_menu * zori_widget_to_menu(struct zori_widget * widget) {
- if (!zori_widget_is_type(widget, ZORI_WIDGET_TYPE_MENU)) return NULL;
- return ZORI_CONTAINER_OF(widget, struct zori_menu, widget);
- }
- struct zori_widget * zori_menu_get_selected(struct zori_menu * menu) {
- if (!menu) return NULL;
- if (menu->selected_index < 0) return NULL;
- return miao_unsafe_get(&menu->widget.children, menu->selected_index);
- }
- int zori_menu_select_index(struct zori_menu * menu, int index) {
- struct zori_widget * selected = NULL;
- size_t size = miao_size(&menu->widget.children);
- if (size < 1) return ZORI_HANDLE_ERROR;
- if (index < 0) return ZORI_HANDLE_DONE;
- if ((size_t)index >= size) return ZORI_HANDLE_DONE;
- menu->selected_index = index;
- selected = zori_menu_get_selected(menu);
- zori_mark_widget(selected);
- return ZORI_HANDLE_DONE;
- }
- int zori_menu_select_previous(struct zori_menu * menu) {
- size_t size = miao_size(&menu->widget.children);
- int new_selection = menu->selected_index - 1;
- /* "roll over" */
- if (new_selection < 0) {
- new_selection = (int)size - 1;
- }
- return zori_menu_select_index(menu, new_selection);
- }
- int zori_menu_select_next(struct zori_menu * menu) {
- size_t size = miao_size(&menu->widget.children);
- int new_selection = menu->selected_index + 1;
- /* "roll over" */
- if ((size_t)new_selection >= size) {
- new_selection = 0;
- }
- return zori_menu_select_index(menu, new_selection);
- }
- int zori_menu_select_first(struct zori_menu * menu) {
- return zori_menu_select_index(menu, 0);
- }
- int zori_menu_activate_selected(struct zori_menu * menu) {
- struct zori_widget * selected = zori_menu_get_selected(menu);
- if (selected) {
- LOG_NOTE("Item selected: %p!\n", selected);
- return zori_widget_raise_internal_action_event(selected);
- }
- LOG_WARNING("No item selected!\n");
- return ZORI_HANDLE_IGNORE;
- }
- int zori_menu_close(struct zori_menu * menu) {
- struct zori_widget * parent;
- parent = menu->widget.parent;
- zori_widget_raise_close_event(parent, &menu->widget);
- zori_widget_active_(&menu->widget, false);
- zori_widget_visible_(&menu->widget, false);
- zori_widget_set_closed_result(&menu->widget, 1);
- return ZORI_HANDLE_DONE;
- }
- int zori_menu_on_child_close(union zori_event * event) {
- struct zori_widget * widget = event->any.widget;
- struct zori_menu * menu = zori_widget_to_menu(widget);
- zori_mark_widget(zori_menu_get_selected(menu));
- return ZORI_HANDLE_DONE;
- }
-
- int zori_menu_on_key_down(union zori_event * event) {
- struct zori_widget * widget = event->any.widget;
- struct zori_menu * menu = zori_widget_to_menu(widget);
- struct zori_widget * item = NULL;
-
-
- if (miao_out_of_bounds(&menu->widget.children, menu->selected_index)) {
- return ZORI_HANDLE_IGNORE;
- }
-
- item = miao_unsafe_get(&widget->children, menu->selected_index);
- switch (event->sys.ev->keyboard.keycode) {
- case ALLEGRO_KEY_UP:
- return zori_menu_select_previous(menu);
-
- case ALLEGRO_KEY_DOWN:
- return zori_menu_select_next(menu);
-
- case ALLEGRO_KEY_ENTER:
- case ALLEGRO_KEY_SPACE:
- case ALLEGRO_KEY_LCTRL:
- case ALLEGRO_KEY_RCTRL:
- return zori_menu_activate_selected(menu);
-
- case ALLEGRO_KEY_BACKSPACE:
- case ALLEGRO_KEY_LSHIFT:
- case ALLEGRO_KEY_RSHIFT:
- return zori_menu_close(menu);
-
- default:
- return ZORI_HANDLE_IGNORE;
- }
- return ZORI_HANDLE_IGNORE;
- }
- int zori_menu_on_draw(union zori_event * event) {
- struct zori_widget * widget = event->any.widget;
- if (zori_widget_visible(widget)) {
- zori_widget_draw_background(widget);
- }
- return zori_widget_must_draw_children(widget);
- }
- struct zori_handler zori_menu_handlers[] = {
- { ZORI_SYSTEM_EVENT_KEY_DOWN, zori_menu_on_key_down , NULL},
- { ZORI_EVENT_DRAW , zori_menu_on_draw , NULL},
- { ZORI_EVENT_CLOSE , zori_menu_on_child_close , NULL},
- };
- struct zori_menu * zori_menu_init(
- struct zori_menu * menu, zori_id id, zori_id parent_id,
- zori_rebox * box, struct zori_style * style
- ) {
- struct zori_widget * parent = zori_get_widget(parent_id);
- if (!menu) return NULL;
- menu->selected_index = 0;
- zori_widget_initall(&menu->widget, ZORI_WIDGET_TYPE_MENU, id, parent, box, style,
- ZORI_ARRAY_AND_AMOUNT( zori_menu_handlers));
- zori_widget_hover_(&menu->widget, false);
- return menu;
- }
-
- struct zori_menu * zori_menu_new(zori_id id, zori_id parent_id, zori_box * box) {
- struct zori_menu * menu = NULL;
- menu = calloc(1, sizeof(*menu));
- if (!menu) return NULL;
- if (!zori_menu_init(menu, id, parent_id, box, NULL)) {
- free(menu);
- return NULL;
- }
- return menu;
- }
-
-
- zori_id zori_new_menu(zori_id id, zori_id parent, zori_box * box) {
- struct zori_menu * menu = zori_menu_new(id, parent, box);
- if (!menu) return ZORI_ID_ENOMEM;
- return menu->widget.id;
- }
|