Nuklear
This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window/input handling but instead provides a highly modular, library-based approach, with simple input state for input and draw commands describing primitive shapes as output. So instead of providing a layered library that tries to abstract over a number of platform and render backends, it focuses only on the actual UI.
 
Loading...
Searching...
No Matches
nuklear_popup.c
1#include "nuklear.h"
2#include "nuklear_internal.h"
3
4/* ===============================================================
5 *
6 * POPUP
7 *
8 * ===============================================================*/
9NK_API nk_bool
10nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type,
11 const char *title, nk_flags flags, struct nk_rect rect)
12{
13 struct nk_window *popup;
14 struct nk_window *win;
15 struct nk_panel *panel;
16
17 int title_len;
18 nk_hash title_hash;
19 nk_size allocated;
20
21 NK_ASSERT(ctx);
22 NK_ASSERT(title);
23 NK_ASSERT(ctx->current);
24 NK_ASSERT(ctx->current->layout);
25 if (!ctx || !ctx->current || !ctx->current->layout)
26 return 0;
27
28 win = ctx->current;
29 panel = win->layout;
30 NK_ASSERT(!((int)panel->type & (int)NK_PANEL_SET_POPUP) && "popups are not allowed to have popups");
31 (void)panel;
32 title_len = (int)nk_strlen(title);
33 title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP);
34
35 popup = win->popup.win;
36 if (!popup) {
37 popup = (struct nk_window*)nk_create_window(ctx);
38 popup->parent = win;
39 win->popup.win = popup;
40 win->popup.active = 0;
41 win->popup.type = NK_PANEL_POPUP;
42 }
43
44 /* make sure we have correct popup */
45 if (win->popup.name != title_hash) {
46 if (!win->popup.active) {
47 nk_zero(popup, sizeof(*popup));
48 win->popup.name = title_hash;
49 win->popup.active = 1;
50 win->popup.type = NK_PANEL_POPUP;
51 } else return 0;
52 }
53
54 /* popup position is local to window */
55 ctx->current = popup;
56 rect.x += win->layout->clip.x;
57 rect.y += win->layout->clip.y;
58
59 /* setup popup data */
60 popup->parent = win;
61 popup->bounds = rect;
62 popup->seq = ctx->seq;
63 popup->layout = (struct nk_panel*)nk_create_panel(ctx);
64 popup->flags = flags;
65 popup->flags |= NK_WINDOW_BORDER;
66 if (type == NK_POPUP_DYNAMIC)
67 popup->flags |= NK_WINDOW_DYNAMIC;
68
69 popup->buffer = win->buffer;
70 nk_start_popup(ctx, win);
71 allocated = ctx->memory.allocated;
72 nk_push_scissor(&popup->buffer, nk_null_rect);
73
74 if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) {
75 /* popup is running therefore invalidate parent panels */
76 struct nk_panel *root;
77 root = win->layout;
78 while (root) {
79 root->flags |= NK_WINDOW_ROM;
80 root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM;
81 root = root->parent;
82 }
83 win->popup.active = 1;
84 popup->layout->offset_x = &popup->scrollbar.x;
85 popup->layout->offset_y = &popup->scrollbar.y;
86 popup->layout->parent = win->layout;
87 return 1;
88 } else {
89 /* popup was closed/is invalid so cleanup */
90 struct nk_panel *root;
91 root = win->layout;
92 while (root) {
93 root->flags |= NK_WINDOW_REMOVE_ROM;
94 root = root->parent;
95 }
96 win->popup.buf.active = 0;
97 win->popup.active = 0;
98 ctx->memory.allocated = allocated;
99 ctx->current = win;
100 nk_free_panel(ctx, popup->layout);
101 popup->layout = 0;
102 return 0;
103 }
104}
105NK_LIB nk_bool
106nk_nonblock_begin(struct nk_context *ctx,
107 nk_flags flags, struct nk_rect body, struct nk_rect header,
108 enum nk_panel_type panel_type)
109{
110 struct nk_window *popup;
111 struct nk_window *win;
112 struct nk_panel *panel;
113 int is_active = nk_true;
114
115 NK_ASSERT(ctx);
116 NK_ASSERT(ctx->current);
117 NK_ASSERT(ctx->current->layout);
118 if (!ctx || !ctx->current || !ctx->current->layout)
119 return 0;
120
121 /* popups cannot have popups */
122 win = ctx->current;
123 panel = win->layout;
124 NK_ASSERT(!((int)panel->type & (int)NK_PANEL_SET_POPUP));
125 (void)panel;
126 popup = win->popup.win;
127 if (!popup) {
128 /* create window for nonblocking popup */
129 popup = (struct nk_window*)nk_create_window(ctx);
130 popup->parent = win;
131 win->popup.win = popup;
132 win->popup.type = panel_type;
133 nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON);
134 } else {
135 /* close the popup if user pressed outside or in the header */
136 int pressed, in_body, in_header;
137#ifdef NK_BUTTON_TRIGGER_ON_RELEASE
138 pressed = nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT);
139#else
140 pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT);
141#endif
142 in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body);
143 in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header);
144 if (pressed && (!in_body || in_header))
145 is_active = nk_false;
146 }
147 win->popup.header = header;
148
149 if (!is_active) {
150 /* remove read only mode from all parent panels */
151 struct nk_panel *root = win->layout;
152 while (root) {
153 root->flags |= NK_WINDOW_REMOVE_ROM;
154 root = root->parent;
155 }
156 return is_active;
157 }
158 popup->bounds = body;
159 popup->parent = win;
160 popup->layout = (struct nk_panel*)nk_create_panel(ctx);
161 popup->flags = flags;
162 popup->flags |= NK_WINDOW_BORDER;
163 popup->flags |= NK_WINDOW_DYNAMIC;
164 popup->seq = ctx->seq;
165 win->popup.active = 1;
166 NK_ASSERT(popup->layout);
167
168 nk_start_popup(ctx, win);
169 popup->buffer = win->buffer;
170 nk_push_scissor(&popup->buffer, nk_null_rect);
171 ctx->current = popup;
172
173 nk_panel_begin(ctx, 0, panel_type);
174 win->buffer = popup->buffer;
175 popup->layout->parent = win->layout;
176 popup->layout->offset_x = &popup->scrollbar.x;
177 popup->layout->offset_y = &popup->scrollbar.y;
178
179 /* set read only mode to all parent panels */
180 {struct nk_panel *root;
181 root = win->layout;
182 while (root) {
183 root->flags |= NK_WINDOW_ROM;
184 root = root->parent;
185 }}
186 return is_active;
187}
188NK_API void
189nk_popup_close(struct nk_context *ctx)
190{
191 struct nk_window *popup;
192 NK_ASSERT(ctx);
193 if (!ctx || !ctx->current) return;
194
195 popup = ctx->current;
196 NK_ASSERT(popup->parent);
197 NK_ASSERT((int)popup->layout->type & (int)NK_PANEL_SET_POPUP);
198 popup->flags |= NK_WINDOW_HIDDEN;
199}
200NK_API void
201nk_popup_end(struct nk_context *ctx)
202{
203 struct nk_window *win;
204 struct nk_window *popup;
205
206 NK_ASSERT(ctx);
207 NK_ASSERT(ctx->current);
208 NK_ASSERT(ctx->current->layout);
209 if (!ctx || !ctx->current || !ctx->current->layout)
210 return;
211
212 popup = ctx->current;
213 if (!popup->parent) return;
214 win = popup->parent;
215 if (popup->flags & NK_WINDOW_HIDDEN) {
216 struct nk_panel *root;
217 root = win->layout;
218 while (root) {
219 root->flags |= NK_WINDOW_REMOVE_ROM;
220 root = root->parent;
221 }
222 win->popup.active = 0;
223 }
224 nk_push_scissor(&popup->buffer, nk_null_rect);
225 nk_end(ctx);
226
227 win->buffer = popup->buffer;
228 nk_finish_popup(ctx, win);
229 ctx->current = win;
230 nk_push_scissor(&win->buffer, win->layout->clip);
231}
232NK_API void
233nk_popup_get_scroll(const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y)
234{
235 struct nk_window *popup;
236
237 NK_ASSERT(ctx);
238 NK_ASSERT(ctx->current);
239 NK_ASSERT(ctx->current->layout);
240 if (!ctx || !ctx->current || !ctx->current->layout)
241 return;
242
243 popup = ctx->current;
244 if (offset_x)
245 *offset_x = popup->scrollbar.x;
246 if (offset_y)
247 *offset_y = popup->scrollbar.y;
248}
249NK_API void
250nk_popup_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y)
251{
252 struct nk_window *popup;
253
254 NK_ASSERT(ctx);
255 NK_ASSERT(ctx->current);
256 NK_ASSERT(ctx->current->layout);
257 if (!ctx || !ctx->current || !ctx->current->layout)
258 return;
259
260 popup = ctx->current;
261 popup->scrollbar.x = offset_x;
262 popup->scrollbar.y = offset_y;
263}
main API and documentation file
@ NK_WINDOW_HIDDEN
Hides window and stops any window interaction and drawing.
Definition nuklear.h:5494
@ NK_WINDOW_ROM
sets window widgets into a read only mode and does not allow input changes
Definition nuklear.h:5492
@ NK_WINDOW_DYNAMIC
special window type growing up in height while being filled to a certain maximum height
Definition nuklear.h:5491
@ NK_WINDOW_REMOVE_ROM
Removes read only mode at the end of the window.
Definition nuklear.h:5497
NK_API void nk_end(struct nk_context *ctx)
nk_size allocated
!< growing factor for dynamic memory management
Definition nuklear.h:4195