all repos — mgba @ d724d914c89304c339d738d924bed5a929d8a891

mGBA Game Boy Advance Emulator

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			return GUI_MENU_EXIT_ACCEPT;
60		}
61		if (newInput & (1 << GUI_INPUT_BACK)) {
62			return GUI_MENU_EXIT_BACK;
63		}
64
65		params->drawStart();
66		if (menu->background) {
67			menu->background->draw(menu->background);
68		}
69		if (params->guiPrepare) {
70			params->guiPrepare();
71		}
72		unsigned y = GUIFontHeight(params->font);
73		GUIFontPrint(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, menu->title);
74		y += 2 * GUIFontHeight(params->font);
75		size_t i;
76		for (i = start; i < GUIMenuItemListSize(&menu->items); ++i) {
77			int color = 0xE0A0A0A0;
78			char bullet = ' ';
79			if (i == menu->index) {
80				color = 0xFFFFFFFF;
81				bullet = '>';
82			}
83			GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, GUIMenuItemListGetPointer(&menu->items, i)->title);
84			y += GUIFontHeight(params->font);
85			if (y + GUIFontHeight(params->font) > params->height) {
86				break;
87			}
88		}
89		if (params->guiFinish) {
90			params->guiFinish();
91		}
92		y += GUIFontHeight(params->font) * 2;
93
94		params->drawEnd();
95	}
96	return GUI_MENU_EXIT_CANCEL;
97}