comparison nuklear_ui/blastem_nuklear.c @ 1474:c5c022c7aa54 nuklear_ui

Initial work on Nuklear-based UI
author Michael Pavone <pavone@retrodev.com>
date Tue, 21 Nov 2017 19:07:43 -0800
parents
children afa3fbb76bff
comparison
equal deleted inserted replaced
1473:152a60c6787e 1474:c5c022c7aa54
1 #define NK_IMPLEMENTATION
2 #define NK_SDL_GLES2_IMPLEMENTATION
3
4 #include <stdlib.h>
5 #include "blastem_nuklear.h"
6 #include "font.h"
7 #include "../render.h"
8 #include "../render_sdl.h"
9 #include "../util.h"
10 #include "../paths.h"
11 #include "../blastem.h"
12
13 static struct nk_context *context;
14
15 typedef void (*view_fun)(struct nk_context *);
16 static view_fun current_view;
17
18 void view_play(struct nk_context *context)
19 {
20
21 }
22
23 void view_load(struct nk_context *context)
24 {
25 static char *current_path;
26 static dir_entry *entries;
27 static size_t num_entries;
28 static uint32_t selected_entry;
29 get_initial_browse_path(&current_path);
30 if (!entries) {
31 entries = get_dir_list(current_path, &num_entries);
32 }
33 uint32_t width = render_width();
34 uint32_t height = render_height();
35 if (nk_begin(context, "Load ROM", nk_rect(0, 0, width, height), 0)) {
36 nk_layout_row_static(context, height - 100, width - 60, 1);
37 if (nk_group_begin(context, "Select ROM", NK_WINDOW_BORDER | NK_WINDOW_TITLE)) {
38 nk_layout_row_static(context, 28, width-100, 1);
39 for (uint32_t i = 0; i < num_entries; i++)
40 {
41 int selected = i == selected_entry;
42 nk_selectable_label(context, entries[i].name, NK_TEXT_ALIGN_LEFT, &selected);
43 if (selected) {
44 selected_entry = i;
45 }
46 }
47 nk_group_end(context);
48 }
49 nk_layout_row_static(context, 52, 300, 1);
50 if (nk_button_label(context, "Open")) {
51 if (entries[selected_entry].is_dir) {
52 char *old = current_path;
53 char const *pieces[] = {old, PATH_SEP, entries[selected_entry].name};
54 current_path = alloc_concat_m(3, pieces);
55 free(old);
56 free_dir_list(entries, num_entries);
57 entries = NULL;
58 } else {
59 //TODO: load ROM
60 current_view = view_play;
61 }
62 }
63 nk_end(context);
64 }
65 }
66
67 void view_about(struct nk_context *context)
68 {
69 }
70
71 typedef struct {
72 const char *title;
73 view_fun next_view;
74 } menu_item;
75
76 static void menu(struct nk_context *context, uint32_t num_entries, const menu_item *items)
77 {
78 const uint32_t button_height = 52;
79 const uint32_t ideal_button_width = 300;
80 const uint32_t button_space = 6;
81
82 uint32_t width = render_width();
83 uint32_t height = render_height();
84 uint32_t top = height/2 - (button_height * num_entries)/2;
85 uint32_t button_width = width > ideal_button_width ? ideal_button_width : width;
86 uint32_t left = width/2 - button_width/2;
87
88 nk_layout_space_begin(context, NK_STATIC, top + button_height * num_entries, num_entries);
89 for (uint32_t i = 0; i < num_entries; i++)
90 {
91 nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space));
92 if (nk_button_label(context, items[i].title)) {
93 current_view = items[i].next_view;
94 if (!current_view) {
95 exit(0);
96 }
97 }
98 }
99 nk_layout_space_end(context);
100 }
101
102 void view_menu(struct nk_context *context)
103 {
104 static menu_item items[] = {
105 {"Load ROM", view_load},
106 {"About", view_about},
107 {"Exit", NULL}
108 };
109
110 const uint32_t num_buttons = 3;
111 if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) {
112 menu(context, sizeof(items)/sizeof(*items), items);
113 nk_end(context);
114 }
115 }
116
117 void blastem_nuklear_render(void)
118 {
119 nk_input_end(context);
120 current_view(context);
121 glViewport(0, 0, render_width(), render_height());
122 /* glClear(GL_COLOR_BUFFER_BIT);
123 glClearColor(0, 0, 0, 0);*/
124 nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024);
125 //SDL_GL_SwapWindow(render_get_window());
126 nk_input_begin(context);
127 }
128
129 void idle_loop(void)
130 {
131 while (current_view != view_play)
132 {
133 render_update_display();
134 }
135 }
136 static void handle_event(SDL_Event *event)
137 {
138 nk_sdl_handle_event(event);
139 }
140
141 void blastem_nuklear_init(uint8_t file_loaded)
142 {
143 context = nk_sdl_init(render_get_window());
144
145 struct nk_font_atlas *atlas;
146 nk_sdl_font_stash_begin(&atlas);
147 char *font = default_font_path();
148 if (!font) {
149 fatal_error("Failed to find default font path\n");
150 }
151 struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL);
152 nk_sdl_font_stash_end();
153 nk_style_set_font(context, &def_font->handle);
154 current_view = file_loaded ? view_play : view_menu;
155 render_set_ui_render_fun(blastem_nuklear_render);
156 render_set_event_handler(handle_event);
157 idle_loop();
158 }