Mercurial > repos > blastem
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(¤t_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 } |