10 static char logbuf
[64000];
11 static int logbuf_updated
= 0;
12 static float bg
[3] = { 90, 95, 100 };
15 static void write_log(const char *text
) {
16 if (logbuf
[0]) { strcat(logbuf
, "\n"); }
22 static void test_window(mu_Context
*ctx
) {
24 if (mu_begin_window(ctx
, "Demo Window", mu_rect(40, 40, 300, 450))) {
25 mu_Container
*win
= mu_get_current_container(ctx
);
26 win
->rect
.w
= mu_max(win
->rect
.w
, 240);
27 win
->rect
.h
= mu_max(win
->rect
.h
, 300);
30 if (mu_header(ctx
, "Window Info")) {
31 mu_Container
*win
= mu_get_current_container(ctx
);
33 mu_layout_row(ctx
, 2, (int[]) { 54, -1 }, 0);
34 mu_label(ctx
,"Position:");
35 sprintf(buf
, "%d, %d", win
->rect
.x
, win
->rect
.y
); mu_label(ctx
, buf
);
36 mu_label(ctx
, "Size:");
37 sprintf(buf
, "%d, %d", win
->rect
.w
, win
->rect
.h
); mu_label(ctx
, buf
);
40 /* labels + buttons */
41 if (mu_header_ex(ctx
, "Test Buttons", MU_OPT_EXPANDED
)) {
42 mu_layout_row(ctx
, 3, (int[]) { 86, -110, -1 }, 0);
43 mu_label(ctx
, "Test buttons 1:");
44 if (mu_button(ctx
, "Button 1")) { write_log("Pressed button 1"); }
45 if (mu_button(ctx
, "Button 2")) { write_log("Pressed button 2"); }
46 mu_label(ctx
, "Test buttons 2:");
47 if (mu_button(ctx
, "Button 3")) { write_log("Pressed button 3"); }
48 if (mu_button(ctx
, "Popup")) { mu_open_popup(ctx
, "Test Popup"); }
49 if (mu_begin_popup(ctx
, "Test Popup")) {
50 mu_button(ctx
, "Hello");
51 mu_button(ctx
, "World");
57 if (mu_header_ex(ctx
, "Tree and Text", MU_OPT_EXPANDED
)) {
58 mu_layout_row(ctx
, 2, (int[]) { 140, -1 }, 0);
59 mu_layout_begin_column(ctx
);
60 if (mu_begin_treenode(ctx
, "Test 1")) {
61 if (mu_begin_treenode(ctx
, "Test 1a")) {
62 mu_label(ctx
, "Hello");
63 mu_label(ctx
, "world");
66 if (mu_begin_treenode(ctx
, "Test 1b")) {
67 if (mu_button(ctx
, "Button 1")) { write_log("Pressed button 1"); }
68 if (mu_button(ctx
, "Button 2")) { write_log("Pressed button 2"); }
73 if (mu_begin_treenode(ctx
, "Test 2")) {
74 mu_layout_row(ctx
, 2, (int[]) { 54, 54 }, 0);
75 if (mu_button(ctx
, "Button 3")) { write_log("Pressed button 3"); }
76 if (mu_button(ctx
, "Button 4")) { write_log("Pressed button 4"); }
77 if (mu_button(ctx
, "Button 5")) { write_log("Pressed button 5"); }
78 if (mu_button(ctx
, "Button 6")) { write_log("Pressed button 6"); }
81 if (mu_begin_treenode(ctx
, "Test 3")) {
82 static int checks
[3] = { 1, 0, 1 };
83 mu_checkbox(ctx
, "Checkbox 1", &checks
[0]);
84 mu_checkbox(ctx
, "Checkbox 2", &checks
[1]);
85 mu_checkbox(ctx
, "Checkbox 3", &checks
[2]);
88 mu_layout_end_column(ctx
);
90 mu_layout_begin_column(ctx
);
91 mu_layout_row(ctx
, 1, (int[]) { -1 }, 0);
92 mu_text(ctx
, "Lorem ipsum dolor sit amet, consectetur adipiscing "
93 "elit. Maecenas lacinia, sem eu lacinia molestie, mi risus faucibus "
94 "ipsum, eu varius magna felis a nulla.");
95 mu_layout_end_column(ctx
);
98 /* background color sliders */
99 if (mu_header_ex(ctx
, "Background Color", MU_OPT_EXPANDED
)) {
100 mu_layout_row(ctx
, 2, (int[]) { -78, -1 }, 74);
102 mu_layout_begin_column(ctx
);
103 mu_layout_row(ctx
, 2, (int[]) { 46, -1 }, 0);
104 mu_label(ctx
, "Red:"); mu_slider(ctx
, &bg
[0], 0, 255);
105 mu_label(ctx
, "Green:"); mu_slider(ctx
, &bg
[1], 0, 255);
106 mu_label(ctx
, "Blue:"); mu_slider(ctx
, &bg
[2], 0, 255);
107 mu_layout_end_column(ctx
);
109 mu_Rect r
= mu_layout_next(ctx
);
110 mu_draw_rect(ctx
, r
, mu_color(bg
[0], bg
[1], bg
[2], 255));
112 sprintf(buf
, "#%02X%02X%02X", (int) bg
[0], (int) bg
[1], (int) bg
[2]);
113 mu_draw_control_text(ctx
, buf
, r
, MU_COLOR_TEXT
, MU_OPT_ALIGNCENTER
);
121 static void log_window(mu_Context
*ctx
) {
122 if (mu_begin_window(ctx
, "Log Window", mu_rect(350, 40, 300, 200))) {
123 /* output text panel */
124 mu_layout_row(ctx
, 1, (int[]) { -1 }, -25);
125 mu_begin_panel(ctx
, "Log Output");
126 mu_Container
*panel
= mu_get_current_container(ctx
);
127 mu_layout_row(ctx
, 1, (int[]) { -1 }, -1);
128 mu_text(ctx
, logbuf
);
130 if (logbuf_updated
) {
131 panel
->scroll
.y
= panel
->content_size
.y
;
135 /* input textbox + submit button */
136 static char buf
[128];
138 mu_layout_row(ctx
, 2, (int[]) { -70, -1 }, 0);
139 if (mu_textbox(ctx
, buf
, sizeof(buf
)) & MU_RES_SUBMIT
) {
140 mu_set_focus(ctx
, ctx
->last_id
);
143 if (mu_button(ctx
, "Submit")) { submitted
= 1; }
154 static int uint8_slider(mu_Context
*ctx
, unsigned char *value
, int low
, int high
) {
156 mu_push_id(ctx
, &value
, sizeof(value
));
158 int res
= mu_slider_ex(ctx
, &tmp
, low
, high
, 0, "%.0f", MU_OPT_ALIGNCENTER
);
165 static void style_window(mu_Context
*ctx
) {
166 static struct { const char *label
; int idx
; } colors
[] = {
167 { "text:", MU_COLOR_TEXT
},
168 { "border:", MU_COLOR_BORDER
},
169 { "windowbg:", MU_COLOR_WINDOWBG
},
170 { "titlebg:", MU_COLOR_TITLEBG
},
171 { "titletext:", MU_COLOR_TITLETEXT
},
172 { "panelbg:", MU_COLOR_PANELBG
},
173 { "button:", MU_COLOR_BUTTON
},
174 { "buttonhover:", MU_COLOR_BUTTONHOVER
},
175 { "buttonfocus:", MU_COLOR_BUTTONFOCUS
},
176 { "base:", MU_COLOR_BASE
},
177 { "basehover:", MU_COLOR_BASEHOVER
},
178 { "basefocus:", MU_COLOR_BASEFOCUS
},
179 { "scrollbase:", MU_COLOR_SCROLLBASE
},
180 { "scrollthumb:", MU_COLOR_SCROLLTHUMB
},
184 if (mu_begin_window(ctx
, "Style Editor", mu_rect(350, 250, 300, 240))) {
185 int sw
= mu_get_current_container(ctx
)->body
.w
* 0.14;
186 mu_layout_row(ctx
, 6, (int[]) { 80, sw
, sw
, sw
, sw
, -1 }, 0);
187 for (int i
= 0; colors
[i
].label
; i
++) {
188 mu_label(ctx
, colors
[i
].label
);
189 uint8_slider(ctx
, &ctx
->style
->colors
[i
].r
, 0, 255);
190 uint8_slider(ctx
, &ctx
->style
->colors
[i
].g
, 0, 255);
191 uint8_slider(ctx
, &ctx
->style
->colors
[i
].b
, 0, 255);
192 uint8_slider(ctx
, &ctx
->style
->colors
[i
].a
, 0, 255);
193 mu_draw_rect(ctx
, mu_layout_next(ctx
), ctx
->style
->colors
[i
]);
200 static void process_frame(mu_Context
*ctx
) {
209 static int text_width(mu_Font font
, const char *text
, int len
) {
210 if (len
== -1) { len
= strlen(text
); }
211 return r_get_text_width(text
, len
);
214 static int text_height(mu_Font font
) {
215 return r_get_text_height();
218 int main(int argc
, char **argv
) {
222 mu_Context
*ctx
= malloc(sizeof(mu_Context
));
224 ctx
->text_width
= text_width
;
225 ctx
->text_height
= text_height
;
228 int mousex
= 0, mousey
= 0;
232 int64_t before
= r_get_time();
233 if (r_mouse_moved(&mousex
, &mousey
)) {
234 mu_input_mousemove(ctx
, mousex
, mousey
);
236 if (r_mouse_down()) {
237 mu_input_mousedown(ctx
, mousex
, mousey
, MU_MOUSE_LEFT
);
238 } else if (r_mouse_up()) {
239 mu_input_mouseup(ctx
, mousex
, mousey
, MU_MOUSE_LEFT
);
242 if (r_key_down(0x1b)) { break; } // esc
243 if (r_key_down('\n')) { mu_input_keydown(ctx
, MU_KEY_RETURN
); }
244 else if (r_key_up('\n')) { mu_input_keyup(ctx
, MU_KEY_RETURN
); }
245 if (r_key_down('\b')) { mu_input_keydown(ctx
, MU_KEY_BACKSPACE
); }
246 else if (r_key_up('\b')) { mu_input_keyup(ctx
, MU_KEY_BACKSPACE
); }
247 for (int i
= 0; i
< 256; i
++) {
249 if (' ' <= i
&& i
<= '~') {
250 char text
[2] = {i
, 0};
252 if (!r_shift_pressed()) {
253 text
[0] = tolower(i
);
257 // TODO(kartik): depends on keyboard layout
259 mu_input_text(ctx
, text
);
270 r_clear(mu_color(bg
[0], bg
[1], bg
[2], 255));
271 mu_Command
*cmd
= NULL
;
272 while (mu_next_command(ctx
, &cmd
)) {
274 case MU_COMMAND_TEXT
: r_draw_text(cmd
->text
.str
, cmd
->text
.pos
, cmd
->text
.color
); break;
275 case MU_COMMAND_RECT
: r_draw_rect(cmd
->rect
.rect
, cmd
->rect
.color
); break;
276 case MU_COMMAND_ICON
: r_draw_icon(cmd
->icon
.id
, cmd
->icon
.rect
, cmd
->icon
.color
); break;
277 case MU_COMMAND_CLIP
: r_set_clip_rect(cmd
->clip
.rect
); break;
281 int64_t after
= r_get_time();
282 int64_t paint_time_ms
= after
- before
;
283 int64_t frame_budget_ms
= 1000 / fps
;
284 int64_t sleep_time_ms
= frame_budget_ms
- paint_time_ms
;
285 if (sleep_time_ms
> 0) {
286 r_sleep(sleep_time_ms
);