zori_screen.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. #include <allegro5/allegro_color.h>
  2. #include "zori.h"
  3. #include "zori_widget.h"
  4. #include "zori_caption.h"
  5. #include "zori_page.h"
  6. #include "zori_screen.h"
  7. #include "monolog.h"
  8. /* Magic comment for runcprotoall: @generate_cproto@ */
  9. struct zori_screen * zori_widget_to_screen(struct zori_widget * widget) {
  10. if (!zori_widget_is_type(widget, ZORI_WIDGET_TYPE_SCREEN)) return NULL;
  11. return ZORI_CONTAINER_OF(widget, struct zori_screen, widget);
  12. }
  13. struct zori_screen * zori_get_screen(zori_id id) {
  14. struct zori_widget * widget = zori_get_widget(id);
  15. return zori_widget_to_screen(widget);
  16. }
  17. /** Handles a mouse axis event and then pass it on to the active page. */
  18. int zori_screen_on_mouse_axes(union zori_event * event) {
  19. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  20. screen->cursors.mouse.p.x = event->sys.ev->mouse.x;
  21. screen->cursors.mouse.p.y = event->sys.ev->mouse.y;
  22. if (screen->active_page) {
  23. zori_widget_raise_system_event(&screen->active_page->widget,
  24. event->sys.ev);
  25. }
  26. return ZORI_HANDLE_DONE;
  27. }
  28. /** Handles a system event by passing it on to the active page. */
  29. int zori_screen_on_sysevent(union zori_event * event) {
  30. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  31. if (screen->active_page) {
  32. zori_widget_raise_system_event(&screen->active_page->widget,
  33. event->sys.ev);
  34. }
  35. return ZORI_HANDLE_DONE;
  36. }
  37. void zori_draw_cursor(const struct zori_cursor * cursor) {
  38. const struct zori_style * style = &cursor->style;
  39. if (cursor->bitmap) {
  40. al_draw_bitmap(cursor->bitmap, cursor->p.x, cursor->p.y, 0);
  41. } else {
  42. float x1, x2, x3, y1, y2, y3;
  43. x1 = cursor->p.x;
  44. y1 = cursor->p.y;
  45. x2 = x1 + 24 + 8;
  46. y2 = y1 + 24 - 8;
  47. x3 = x1 + 24 - 8;
  48. y3 = y1 + 24 + 8;
  49. al_draw_filled_triangle(x1, y1, x2, y2, x3, y3, style->back.color);
  50. al_draw_triangle(x1, y1, x2, y2, x3, y3, style->border.color, style->border.size);
  51. }
  52. };
  53. void zori_draw_cursors(const struct zori_cursors * cursors) {
  54. zori_draw_cursor(&cursors->keyjoy);
  55. zori_draw_cursor(&cursors->mouse);
  56. };
  57. int zori_screen_on_overdraw(union zori_event * event) {
  58. struct zori_screen * screen = zori_widget_to_screen(event->any.widget);
  59. zori_draw_cursors(&screen->cursors);
  60. return ZORI_HANDLE_PASS;
  61. }
  62. /* Handlers must be set up for many events on screen to funnel them all into
  63. * the active page. */
  64. struct zori_handler zori_screen_handlers[] = {
  65. { ZORI_SYSTEM_EVENT_KEY_DOWN , zori_screen_on_sysevent , NULL },
  66. { ZORI_SYSTEM_EVENT_KEY_UP , zori_screen_on_sysevent , NULL },
  67. { ZORI_SYSTEM_EVENT_KEY_CHAR , zori_screen_on_sysevent , NULL },
  68. { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_DOWN , zori_screen_on_sysevent , NULL },
  69. { ZORI_SYSTEM_EVENT_MOUSE_BUTTON_UP , zori_screen_on_sysevent , NULL },
  70. { ZORI_SYSTEM_EVENT_MOUSE_AXES , zori_screen_on_mouse_axes , NULL },
  71. { ZORI_EVENT_OVERDRAW , zori_screen_on_overdraw , NULL },
  72. { -1, NULL, NULL }
  73. };
  74. struct zori_screen *
  75. zori_screen_init(struct zori_screen * screen, zori_display * display) {
  76. memset(&screen->cursors, 0, sizeof(screen->cursors));
  77. /* the keyjoy cursor is hidden off-screen to begin with. */
  78. screen->cursors.keyjoy.p.x = - 64;
  79. screen->cursors.keyjoy.p.y = - 64;
  80. /* Copy the styles, but set them a bit different */
  81. screen->cursors.keyjoy.style = screen->widget.style;
  82. screen->cursors.mouse.style = screen->widget.style;
  83. screen->cursors.keyjoy.target_style = screen->widget.style;
  84. screen->cursors.mouse.target_style = screen->widget.style;
  85. screen->cursors.keyjoy.style.back.color = al_map_rgb(0, 0, 255);
  86. screen->cursors.keyjoy.style.border.color = al_map_rgb(255, 255, 0);
  87. screen->cursors.keyjoy.target_style.back.color = al_map_rgb(0, 191, 0);
  88. screen->cursors.mouse.target_style.back.color = al_map_rgb(31, 191, 32);
  89. screen->display = display;
  90. screen->active_page = NULL;
  91. return screen;
  92. }
  93. struct zori_screen * zori_screen_new(zori_id id, zori_display * display) {
  94. struct zori_screen * screen = NULL; zori_rebox box;
  95. box.at.x = 0;
  96. box.at.y = 0;
  97. if (!display) return NULL;
  98. screen = calloc(1, sizeof(*screen));
  99. if (!screen) return NULL;
  100. box.size.x = al_get_display_width(display);
  101. box.size.y = al_get_display_height(display);
  102. zori_widget_initall(&screen->widget, ZORI_WIDGET_TYPE_SCREEN, id,
  103. zori_get_root_widget(), &box, NULL,
  104. ZORI_ARRAY_AND_AMOUNT(zori_screen_handlers));
  105. if (!zori_screen_init(screen, display)) {
  106. free(screen);
  107. screen = NULL;
  108. }
  109. return screen;
  110. }
  111. zori_id zori_new_screen(zori_id id, zori_display * display) {
  112. struct zori_screen * screen = zori_screen_new(id, display);
  113. if (!screen) return ZORI_ID_ENOMEM;
  114. return screen->widget.id;
  115. }
  116. zori_id zori_active_page(zori_id screen_id) {
  117. struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
  118. if (!screen) {
  119. return ZORI_ID_EINVAL;
  120. }
  121. if (!screen->active_page) {
  122. return ZORI_ID_EINVAL;
  123. }
  124. return screen->active_page->widget.id;
  125. }
  126. zori_id zori_screen_go(zori_id screen_id, zori_id page_id, void * data) {
  127. int index, stop;
  128. struct zori_screen * screen = zori_widget_to_screen(zori_get_widget(screen_id));
  129. struct zori_page * page = zori_widget_to_page(zori_get_widget(page_id));
  130. if ((screen) && (page)) {
  131. if (screen->active_page) {
  132. /* XXX send event later. */
  133. }
  134. /* disable all other page widgets. */
  135. stop = zori_widget_count_children(&screen->widget);
  136. for (index = 0; index < stop; index ++) {
  137. struct zori_widget * cpw = zori_widget_get_child(&screen->widget, index);
  138. struct zori_page * cpp = zori_widget_to_page(cpw);
  139. if (!cpp) continue;
  140. zori_widget_live_(&cpp->widget, 0);
  141. }
  142. screen->active_page = page;
  143. zori_widget_raise_action_event(&page->widget);
  144. zori_widget_live_(&page->widget, 1);
  145. LOG_NOTE("Switched to page: %d, %d\n", page_id,
  146. zori_widget_visible(&page->widget));
  147. return page->widget.id;
  148. } else {
  149. LOG_ERROR("Could not switch to page %d\n", page_id);
  150. return ZORI_ID_EINVAL;
  151. }
  152. }
  153. struct zori_cursor * zori_cursor_set_style(struct zori_cursor * cursor,
  154. struct zori_style style) {
  155. if (!cursor) return NULL;
  156. cursor->style = style;
  157. return cursor;
  158. }
  159. struct zori_screen * zori_screen_set_keyjoy_cursor_style(struct zori_screen * screen, struct zori_style style) {
  160. if (!screen) {
  161. return NULL;
  162. }
  163. zori_cursor_set_style(&screen->cursors.keyjoy, style);
  164. return screen;
  165. }
  166. struct zori_screen * zori_screen_set_mouse_cursor_style(struct zori_screen * screen, struct zori_style style) {
  167. if (!screen) {
  168. return NULL;
  169. }
  170. zori_cursor_set_style(&screen->cursors.mouse, style);
  171. return screen;
  172. }
  173. zori_id zori_set_keyjoy_cursor_style(zori_id id, struct zori_style style) {
  174. struct zori_screen * screen = zori_get_screen(id);
  175. if (!zori_screen_set_keyjoy_cursor_style(screen, style)) {
  176. return ZORI_ID_EINVAL;
  177. }
  178. return id;
  179. }
  180. zori_id zori_set_mouse_cursor_style(zori_id id, struct zori_style style) {
  181. struct zori_screen * screen = zori_get_screen(id);
  182. if (!zori_screen_set_mouse_cursor_style(screen, style)) {
  183. return ZORI_ID_EINVAL;
  184. }
  185. return id;
  186. }