zori_screen.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "zori.h"
  2. #include "zori_widget.h"
  3. #include "zori_caption.h"
  4. #include "zori_page.h"
  5. #include "zori_screen.h"
  6. struct zori_screen * zori_widget_to_screen(struct zori_widget * widget) {
  7. if (!zori_widget_is_type(widget, ZORI_WIDGET_TYPE_SCREEN)) return NULL;
  8. return ZORI_CONTAINER_OF(widget, struct zori_screen, widget);
  9. }
  10. /** Handles a mouse axis event and then pass it on to the active page. */
  11. int zori_screen_on_mouse_axes(union zori_event * event) {
  12. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  13. screen->cursors.mouse.p.x = event->sys.ev->mouse.x;
  14. screen->cursors.mouse.p.y = event->sys.ev->mouse.y;
  15. if (screen->active_page) {
  16. return zori_widget_raise_system_event(&screen->active_page->widget,
  17. event->sys.ev);
  18. }
  19. return ZORI_HANDLE_PASS;
  20. }
  21. /** Handles a system event by passing it on to the active page. */
  22. int zori_screen_on_sysevent(union zori_event * event) {
  23. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  24. if (screen->active_page) {
  25. return zori_widget_raise_system_event(&screen->active_page->widget,
  26. event->sys.ev);
  27. }
  28. return ZORI_HANDLE_PASS;
  29. }
  30. void zori_draw_cursor(const struct zori_cursor * cursor, const struct zori_style * style) {
  31. if (cursor->bitmap) {
  32. al_draw_bitmap(cursor->bitmap, cursor->p.x, cursor->p.y, 0);
  33. } else {
  34. float x1, x2, x3, y1, y2, y3;
  35. x1 = cursor->p.x;
  36. y1 = cursor->p.y;
  37. x2 = x1 + 24 + 8;
  38. y2 = y1 + 24 - 8;
  39. x3 = x1 + 24 - 8;
  40. y3 = y1 + 24 + 8;
  41. al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, style->fore.color);
  42. al_draw_triangle(x1, y1, x2, y2, x3, y3, style->back.color, 1.0);
  43. }
  44. };
  45. void zori_draw_cursors(const struct zori_cursors * cursors, const struct zori_style * style) {
  46. zori_draw_cursor(&cursors->keyjoy, style);
  47. zori_draw_cursor(&cursors->mouse, style);
  48. };
  49. int zori_screen_on_overdraw(union zori_event * event) {
  50. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  51. zori_draw_cursors(&screen->cursors, &screen->widget.style);
  52. return ZORI_HANDLE_PASS;
  53. }
  54. /* Handlers must beset up for many events on screen to funnel them all into
  55. * the active page. */
  56. struct zori_handler zori_screen_handlers[] = {
  57. { ZORI_SYSTEM_EVENT_KEY_DOWN , zori_screen_on_sysevent , NULL },
  58. { ZORI_SYSTEM_EVENT_KEY_UP , zori_screen_on_sysevent , NULL },
  59. { ZORI_SYSTEM_EVENT_KEY_CHAR , zori_screen_on_sysevent , NULL },
  60. { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_DOWN , zori_screen_on_sysevent , NULL },
  61. { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_UP , zori_screen_on_sysevent , NULL },
  62. { ZORI_SYSTEM_EVENT_MOUSE_AXES , zori_screen_on_mouse_axes , NULL },
  63. { ZORI_EVENT_OVERDRAW , zori_screen_on_overdraw , NULL },
  64. { -1, NULL, NULL }
  65. };
  66. struct zori_screen *
  67. zori_screen_init(struct zori_screen * screen, zori_display * display) {
  68. memset(&screen->cursors, 0, sizeof(screen->cursors));
  69. /* the keyjoy cursor is hidden off-screen to begin with. */
  70. screen->cursors.keyjoy.p.x = - 64;
  71. screen->cursors.keyjoy.p.y = - 64;
  72. screen->display = display;
  73. screen->active_page = NULL;
  74. return screen;
  75. }
  76. struct zori_screen * zori_screen_new(zori_id id, zori_display * display) {
  77. struct zori_screen * screen = NULL; zori_rebox box;
  78. box.at.x = 0;
  79. box.at.y = 0;
  80. if (!display) return NULL;
  81. screen = calloc(1, sizeof(*screen));
  82. if (!screen) return NULL;
  83. box.size.x = al_get_display_width(display);
  84. box.size.y = al_get_display_height(display);
  85. zori_widget_initall(&screen->widget, ZORI_WIDGET_TYPE_SCREEN, id, &zori_get_root()->widget,
  86. &box, NULL, ZORI_ARRAY_AND_AMOUNT(zori_screen_handlers));
  87. if (!zori_screen_init(screen, display)) {
  88. free(screen);
  89. screen = NULL;
  90. }
  91. return screen;
  92. }
  93. zori_id zori_new_screen(zori_id id, zori_display * display) {
  94. struct zori_screen * screen = zori_screen_new(id, display);
  95. if (!screen) return ZORI_ID_ENOMEM;
  96. return screen->widget.id;
  97. }
  98. zori_id zori_active_page(zori_id screen_id) {
  99. struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
  100. if (!screen) {
  101. return ZORI_ID_EINVAL;
  102. }
  103. if (!screen->active_page) {
  104. return ZORI_ID_EINVAL;
  105. }
  106. return screen->active_page->widget.id;
  107. }
  108. zori_id zori_screen_go(zori_id screen_id, zori_id page_id, void * data) {
  109. struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
  110. struct zori_page * page = zori_widget_to_page(zori_get_widget(page_id));
  111. if ((screen) && (page)) {
  112. screen->active_page = page;
  113. zori_widget_raise_action_event(&page->widget);
  114. return page->widget.id;
  115. } else {
  116. return ZORI_ID_EINVAL;
  117. }
  118. }