#include #include "zori.h" #include "zori_widget.h" #include "zori_caption.h" #include "zori_page.h" #include "zori_screen.h" #include "monolog.h" /* Magic comment for runcprotoall: @generate_cproto@ */ struct zori_screen * zori_widget_to_screen(struct zori_widget * widget) { if (!zori_widget_is_type(widget, ZORI_WIDGET_TYPE_SCREEN)) return NULL; return ZORI_CONTAINER_OF(widget, struct zori_screen, widget); } struct zori_screen * zori_get_screen(zori_id id) { struct zori_widget * widget = zori_get_widget(id); return zori_widget_to_screen(widget); } /** Handles a mouse axis event and then pass it on to the active page. */ int zori_screen_on_mouse_axes(union zori_event * event) { struct zori_screen * screen = zori_widget_to_screen(event->any.widget); screen->cursors.mouse.p.x = event->sys.ev->mouse.x; screen->cursors.mouse.p.y = event->sys.ev->mouse.y; if (screen->active_page) { zori_widget_raise_system_event(&screen->active_page->widget, event->sys.ev); } return ZORI_HANDLE_DONE; } /** Handles a system event by passing it on to the active page. */ int zori_screen_on_sysevent(union zori_event * event) { struct zori_screen * screen = zori_widget_to_screen(event->any.widget); if (screen->active_page) { zori_widget_raise_system_event(&screen->active_page->widget, event->sys.ev); } return ZORI_HANDLE_DONE; } void zori_draw_cursor(const struct zori_cursor * cursor) { const struct zori_style * style = &cursor->style; if (cursor->bitmap) { al_draw_bitmap(cursor->bitmap, cursor->p.x, cursor->p.y, 0); } else { float x1, x2, x3, y1, y2, y3; x1 = cursor->p.x; y1 = cursor->p.y; x2 = x1 + 24 + 8; y2 = y1 + 24 - 8; x3 = x1 + 24 - 8; y3 = y1 + 24 + 8; al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, style->back.color); al_draw_triangle(x1, y1, x2, y2, x3, y3, style->border.color, style->border.size); } }; void zori_draw_cursors(const struct zori_cursors * cursors) { zori_draw_cursor(&cursors->keyjoy); zori_draw_cursor(&cursors->mouse); }; int zori_screen_on_overdraw(union zori_event * event) { struct zori_screen * screen = zori_widget_to_screen(event->any.widget); zori_draw_cursors(&screen->cursors); return ZORI_HANDLE_PASS; } /* Handlers must be set up for many events on screen to funnel them all into * the active page. */ struct zori_handler zori_screen_handlers[] = { { ZORI_SYSTEM_EVENT_KEY_DOWN , zori_screen_on_sysevent , NULL }, { ZORI_SYSTEM_EVENT_KEY_UP , zori_screen_on_sysevent , NULL }, { ZORI_SYSTEM_EVENT_KEY_CHAR , zori_screen_on_sysevent , NULL }, { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_DOWN , zori_screen_on_sysevent , NULL }, { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_UP , zori_screen_on_sysevent , NULL }, { ZORI_SYSTEM_EVENT_MOUSE_AXES , zori_screen_on_mouse_axes , NULL }, { ZORI_EVENT_OVERDRAW , zori_screen_on_overdraw , NULL }, { -1, NULL, NULL } }; struct zori_screen * zori_screen_init(struct zori_screen * screen, zori_display * display) { memset(&screen->cursors, 0, sizeof(screen->cursors)); /* the keyjoy cursor is hidden off-screen to begin with. */ screen->cursors.keyjoy.p.x = - 64; screen->cursors.keyjoy.p.y = - 64; /* Copy the styles, but set them a bit different */ screen->cursors.keyjoy.style = screen->widget.style; screen->cursors.mouse.style = screen->widget.style; screen->cursors.keyjoy.target_style = screen->widget.style; screen->cursors.mouse.target_style = screen->widget.style; screen->cursors.keyjoy.style.back.color = al_map_rgb(0, 0, 255); screen->cursors.keyjoy.style.border.color = al_map_rgb(255, 255, 0); screen->cursors.keyjoy.target_style.back.color = al_map_rgb(0, 191, 0); screen->cursors.mouse.target_style.back.color = al_map_rgb(31, 191, 32); screen->display = display; screen->active_page = NULL; return screen; } struct zori_screen * zori_screen_new(zori_id id, zori_display * display) { struct zori_screen * screen = NULL; zori_rebox box; box.at.x = 0; box.at.y = 0; if (!display) return NULL; screen = calloc(1, sizeof(*screen)); if (!screen) return NULL; box.size.x = al_get_display_width(display); box.size.y = al_get_display_height(display); zori_widget_initall(&screen->widget, ZORI_WIDGET_TYPE_SCREEN, id, zori_get_root_widget(), &box, NULL, ZORI_ARRAY_AND_AMOUNT(zori_screen_handlers)); if (!zori_screen_init(screen, display)) { free(screen); screen = NULL; } return screen; } zori_id zori_new_screen(zori_id id, zori_display * display) { struct zori_screen * screen = zori_screen_new(id, display); if (!screen) return ZORI_ID_ENOMEM; return screen->widget.id; } zori_id zori_active_page(zori_id screen_id) { struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id)); if (!screen) { return ZORI_ID_EINVAL; } if (!screen->active_page) { return ZORI_ID_EINVAL; } return screen->active_page->widget.id; } zori_id zori_screen_go(zori_id screen_id, zori_id page_id, void * data) { int index, stop; struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id)); struct zori_page * page = zori_widget_to_page(zori_get_widget(page_id)); if ((screen) && (page)) { if (screen->active_page) { /* XXX send event later. */ } /* disable all other page widgets. */ stop = zori_widget_count_children(&screen->widget); for (index = 0; index < stop; index ++) { struct zori_widget * cpw = zori_widget_get_child(&screen->widget, index); struct zori_page * cpp = zori_widget_to_page(cpw); if (!cpp) continue; zori_widget_live_(&cpp->widget, 0); } screen->active_page = page; zori_widget_raise_action_event(&page->widget); zori_widget_live_(&page->widget, 1); LOG_NOTE("Switched to page: %d, %d\n", page_id, zori_widget_visible(&page->widget)); return page->widget.id; } else { LOG_ERROR("Could not switch to page %d\n", page_id); return ZORI_ID_EINVAL; } } struct zori_cursor * zori_cursor_set_style(struct zori_cursor * cursor, struct zori_style style) { if (!cursor) return NULL; cursor->style = style; return cursor; } struct zori_screen * zori_screen_set_keyjoy_cursor_style(struct zori_screen * screen, struct zori_style style) { if (!screen) { return NULL; } zori_cursor_set_style(&screen->cursors.keyjoy, style); return screen; } struct zori_screen * zori_screen_set_mouse_cursor_style(struct zori_screen * screen, struct zori_style style) { if (!screen) { return NULL; } zori_cursor_set_style(&screen->cursors.mouse, style); return screen; } zori_id zori_set_keyjoy_cursor_style(zori_id id, struct zori_style style) { struct zori_screen * screen = zori_get_screen(id); if (!zori_screen_set_keyjoy_cursor_style(screen, style)) { return ZORI_ID_EINVAL; } return id; } zori_id zori_set_mouse_cursor_style(zori_id id, struct zori_style style) { struct zori_screen * screen = zori_get_screen(id); if (!zori_screen_set_mouse_cursor_style(screen, style)) { return ZORI_ID_EINVAL; } return id; }