src/util/gui/menu.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "menu.h"
7
8#include "util/gui.h"
9#include "util/gui/font.h"
10
11DEFINE_VECTOR(GUIMenuItemList, struct GUIMenuItem);
12
13enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem* item) {
14 size_t start = 0;
15 size_t pageSize = params->height / GUIFontHeight(params->font);
16 if (pageSize > 4) {
17 pageSize -= 4;
18 } else {
19 pageSize = 1;
20 }
21
22 GUIInvalidateKeys(params);
23 while (true) {
24 int newInput = 0;
25 GUIPollInput(params, &newInput, 0);
26
27 if (newInput & (1 << GUI_INPUT_UP) && menu->index > 0) {
28 --menu->index;
29 }
30 if (newInput & (1 << GUI_INPUT_DOWN) && menu->index < GUIMenuItemListSize(&menu->items) - 1) {
31 ++menu->index;
32 }
33 if (newInput & (1 << GUI_INPUT_LEFT)) {
34 if (menu->index >= pageSize) {
35 menu->index -= pageSize;
36 } else {
37 menu->index = 0;
38 }
39 }
40 if (newInput & (1 << GUI_INPUT_RIGHT)) {
41 if (menu->index + pageSize < GUIMenuItemListSize(&menu->items)) {
42 menu->index += pageSize;
43 } else {
44 menu->index = GUIMenuItemListSize(&menu->items) - 1;
45 }
46 }
47
48 if (menu->index < start) {
49 start = menu->index;
50 }
51 while ((menu->index - start + 4) * GUIFontHeight(params->font) > params->height) {
52 ++start;
53 }
54 if (newInput & (1 << GUI_INPUT_CANCEL)) {
55 break;
56 }
57 if (newInput & (1 << GUI_INPUT_SELECT)) {
58 *item = *GUIMenuItemListGetPointer(&menu->items, menu->index);
59 if (item->submenu) {
60 enum GUIMenuExitReason reason = GUIShowMenu(params, item->submenu, item);
61 if (reason != GUI_MENU_EXIT_BACK) {
62 return reason;
63 }
64 } else {
65 return GUI_MENU_EXIT_ACCEPT;
66 }
67 }
68 if (newInput & (1 << GUI_INPUT_BACK)) {
69 return GUI_MENU_EXIT_BACK;
70 }
71
72 params->drawStart();
73 if (menu->background) {
74 menu->background->draw(menu->background);
75 }
76 if (params->guiPrepare) {
77 params->guiPrepare();
78 }
79 unsigned y = GUIFontHeight(params->font);
80 GUIFontPrint(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->title);
81 y += 2 * GUIFontHeight(params->font);
82 size_t i;
83 for (i = start; i < GUIMenuItemListSize(&menu->items); ++i) {
84 int color = 0xE0A0A0A0;
85 char bullet = ' ';
86 if (i == menu->index) {
87 color = 0xFFFFFFFF;
88 bullet = '>';
89 }
90 GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, GUIMenuItemListGetPointer(&menu->items, i)->title);
91 y += GUIFontHeight(params->font);
92 if (y + GUIFontHeight(params->font) > params->height) {
93 break;
94 }
95 }
96 if (params->guiFinish) {
97 params->guiFinish();
98 }
99 y += GUIFontHeight(params->font) * 2;
100
101 params->drawEnd();
102 }
103 return GUI_MENU_EXIT_CANCEL;
104}