static void hat_widget(struct nk_context* nk, unsigned char state) { float radius; struct nk_rect area; struct nk_vec2 center; if (nk_widget(&area, nk) != NK_WIDGET_VALID) return; center = nk_vec2(area.x + area.w / 2.f, area.y + area.h / 2.f); radius = NK_MIN(area.w, area.h) / 2.f; nk_stroke_circle(nk_window_get_canvas(nk), nk_rect(center.x - radius, center.y - radius, radius * 2.f, radius * 2.f), 1.f, nk_rgb(175, 175, 175)); if (state) { const float angles[] = { 0.f, 0.f, NK_PI * 1.5f, NK_PI * 1.75f, NK_PI, 0.f, NK_PI * 1.25f, 0.f, NK_PI * 0.5f, NK_PI * 0.25f, 0.f, 0.f, NK_PI * 0.75f, 0.f, }; const float cosa = nk_cos(angles[state]); const float sina = nk_sin(angles[state]); const struct nk_vec2 p0 = nk_vec2(0.f, -radius); const struct nk_vec2 p1 = nk_vec2( radius / 2.f, -radius / 3.f); const struct nk_vec2 p2 = nk_vec2(-radius / 2.f, -radius / 3.f); nk_fill_triangle(nk_window_get_canvas(nk), center.x + cosa * p0.x + sina * p0.y, center.y + cosa * p0.y - sina * p0.x, center.x + cosa * p1.x + sina * p1.y, center.y + cosa * p1.y - sina * p1.x, center.x + cosa * p2.x + sina * p2.y, center.y + cosa * p2.y - sina * p2.x, nk_rgb(175, 175, 175)); } }
static void canvas_begin(struct nk_context *ctx, struct nk_canvas *canvas, nk_flags flags, uint32_t x, uint32_t y, uint32_t width, uint32_t height, struct nk_color background_color){ /* save style properties which will be overwritten */ canvas->panel_padding = ctx->style.window.padding; canvas->item_spacing = ctx->style.window.spacing; canvas->window_background = ctx->style.window.fixed_background; /* use the complete window space and set background */ ctx->style.window.spacing = nk_vec2(0,0); ctx->style.window.padding = nk_vec2(0,0); ctx->style.window.fixed_background = nk_style_item_color(background_color); /* create/update window and set position + size */ flags = flags & ~NK_WINDOW_DYNAMIC; nk_begin(ctx, "Window", nk_rect(x, y, width, height), NK_WINDOW_NO_SCROLLBAR|flags); //nk_window_set_bounds(ctx, nk_rect(x, y, width, height)); /* allocate the complete window space for drawing */ {struct nk_rect total_space; total_space = nk_window_get_content_region(ctx); nk_layout_row_dynamic(ctx, total_space.h, 1); nk_widget(&total_space, ctx); canvas->painter = nk_window_get_canvas(ctx);} }
/* =============================================================== * * CUSTOM WIDGET * * ===============================================================*/ static int ui_piemenu(struct nk_context *ctx, struct nk_vec2 pos, float radius, struct nk_image *icons, int item_count) { int ret = -1; struct nk_rect total_space; struct nk_rect bounds; int active_item = 0; /* pie menu popup */ struct nk_color border = ctx->style.window.border_color; struct nk_style_item background = ctx->style.window.fixed_background; ctx->style.window.fixed_background = nk_style_item_hide(); ctx->style.window.border_color = nk_rgba(0,0,0,0); total_space = nk_window_get_content_region(ctx); ctx->style.window.spacing = nk_vec2(0,0); ctx->style.window.padding = nk_vec2(0,0); if (nk_popup_begin(ctx, NK_POPUP_STATIC, "piemenu", NK_WINDOW_NO_SCROLLBAR, nk_rect(pos.x - total_space.x - radius, pos.y - radius - total_space.y, 2*radius,2*radius))) { int i = 0; struct nk_command_buffer* out = nk_window_get_canvas(ctx); const struct nk_input *in = &ctx->input; total_space = nk_window_get_content_region(ctx); ctx->style.window.spacing = nk_vec2(4,4); ctx->style.window.padding = nk_vec2(8,8); nk_layout_row_dynamic(ctx, total_space.h, 1); nk_widget(&bounds, ctx); /* outer circle */ nk_fill_circle(out, bounds, nk_rgb(50,50,50)); { /* circle buttons */ float step = (2 * 3.141592654f) / (float)(MAX(1,item_count)); float a_min = 0; float a_max = step; struct nk_vec2 center = nk_vec2(bounds.x + bounds.w / 2.0f, bounds.y + bounds.h / 2.0f); struct nk_vec2 drag = nk_vec2(in->mouse.pos.x - center.x, in->mouse.pos.y - center.y); float angle = (float)atan2(drag.y, drag.x); if (angle < -0.0f) angle += 2.0f * 3.141592654f; active_item = (int)(angle/step); for (i = 0; i < item_count; ++i) { struct nk_rect content; float rx, ry, dx, dy, a; nk_fill_arc(out, center.x, center.y, (bounds.w/2.0f), a_min, a_max, (active_item == i) ? nk_rgb(45,100,255): nk_rgb(60,60,60)); /* separator line */ rx = bounds.w/2.0f; ry = 0; dx = rx * (float)cos(a_min) - ry * (float)sin(a_min); dy = rx * (float)sin(a_min) + ry * (float)cos(a_min); nk_stroke_line(out, center.x, center.y, center.x + dx, center.y + dy, 1.0f, nk_rgb(50,50,50)); /* button content */ a = a_min + (a_max - a_min)/2.0f; rx = bounds.w/2.5f; ry = 0; content.w = 30; content.h = 30; content.x = center.x + ((rx * (float)cos(a) - ry * (float)sin(a)) - content.w/2.0f); content.y = center.y + (rx * (float)sin(a) + ry * (float)cos(a) - content.h/2.0f); nk_draw_image(out, content, &icons[i], nk_rgb(255,255,255)); a_min = a_max; a_max += step; } } { /* inner circle */ struct nk_rect inner; inner.x = bounds.x + bounds.w/2 - bounds.w/4; inner.y = bounds.y + bounds.h/2 - bounds.h/4; inner.w = bounds.w/2; inner.h = bounds.h/2; nk_fill_circle(out, inner, nk_rgb(45,45,45)); /* active icon content */ bounds.w = inner.w / 2.0f; bounds.h = inner.h / 2.0f; bounds.x = inner.x + inner.w/2 - bounds.w/2; bounds.y = inner.y + inner.h/2 - bounds.h/2; nk_draw_image(out, bounds, &icons[active_item], nk_rgb(255,255,255)); } nk_layout_space_end(ctx); if (!nk_input_is_mouse_down(&ctx->input, NK_BUTTON_RIGHT)) { nk_popup_close(ctx); ret = active_item; } } else ret = -2; ctx->style.window.spacing = nk_vec2(4,4); ctx->style.window.padding = nk_vec2(8,8); nk_popup_end(ctx); ctx->style.window.fixed_background = background; ctx->style.window.border_color = border; return ret; }
CharacterDialoguePopup::UpdateResult CharacterDialoguePopup::update(struct nk_context* ctx) { auto renderer = FARender::Renderer::get(); auto boxTex = renderer->loadImage(this->mWide ? "data/textbox.cel" : "data/textbox2.cel"); int32_t screenW, screenH; renderer->getWindowDimensions(screenW, screenH); nk_flags flags = NK_WINDOW_NO_SCROLLBAR; auto dialogRectangle = nk_rect(screenW / 2.0f - (boxTex->getWidth() / 2.0f), screenH / 2.0f - (boxTex->getHeight() / 2.0f), boxTex->getWidth(), boxTex->getHeight()); UpdateResult result = UpdateResult::DoNothing; mGuiManager.nk_fa_begin_image_window(ctx, "dialog", dialogRectangle, flags, boxTex->getNkImage(), [&]() { // apply black checkerboard in background { auto blackTex = renderer->loadImage("resources/black.png"); auto cbRect = nk_rect(dialogRectangle.x + 3, dialogRectangle.y + 3, dialogRectangle.w - 6, dialogRectangle.h - 6); ScopedApplyEffect effect(ctx, EffectType::checkerboarded); auto nkImage = nk_subimage_handle(blackTex->getNkImage().handle, blackTex->getWidth(), blackTex->getHeight(), cbRect); nk_draw_image(nk_window_get_canvas(ctx), cbRect, &nkImage, nk_rgb(0, 0, 0)); } nk_layout_row_dynamic(ctx, 30, 1); DialogData data = getDialogData(); for (const auto& line : data.introduction) GuiManager::smallText(ctx, line.c_str()); // fill the rest of the window struct nk_rect bounds = nk_widget_bounds(ctx); struct nk_rect panelSize = nk_window_get_bounds(ctx); float contentHeight = panelSize.h + panelSize.y - bounds.y; nk_layout_row_dynamic(ctx, contentHeight, 1); Misc::ScopedSetter<nk_style> styleSetter(ctx->style); // setup style for scrollbar { constexpr int32_t scrollUpButtonIndex = 9; constexpr int32_t scrollDownButtonIndex = 8; constexpr int32_t scrollbarBackgroundIndex = 13; // TODO: the "cursor" of the scrollbar is still the default nuklear look, which should change auto sliderImg = renderer->loadImage("data/textslid.cel"); // TODO: this image should repeat, not stretch ctx->style.scrollv.normal = nk_style_item_image(sliderImg->getNkImage(scrollbarBackgroundIndex)); ctx->style.scrollv.active = ctx->style.scrollv.normal; ctx->style.scrollv.hover = ctx->style.scrollv.normal; ctx->style.scrollv.cursor_active = ctx->style.scrollv.cursor_normal; ctx->style.scrollv.cursor_hover = ctx->style.scrollv.cursor_normal; ctx->style.scrollv.show_buttons = true; ctx->style.scrollv.dec_button.normal = nk_style_item_image(sliderImg->getNkImage(scrollUpButtonIndex)); ctx->style.scrollv.dec_symbol = NK_SYMBOL_NONE; ctx->style.scrollv.inc_button.normal = nk_style_item_image(sliderImg->getNkImage(scrollDownButtonIndex)); ctx->style.scrollv.inc_symbol = NK_SYMBOL_NONE; ctx->style.scrollv.dec_button.active = ctx->style.scrollv.dec_button.normal; ctx->style.scrollv.dec_button.hover = ctx->style.scrollv.dec_button.normal; ctx->style.scrollv.inc_button.active = ctx->style.scrollv.inc_button.normal; ctx->style.scrollv.inc_button.hover = ctx->style.scrollv.inc_button.normal; ctx->style.window.group_padding = nk_vec2(10, 10); ctx->style.window.scrollbar_size = nk_vec2(sliderImg->getWidth(), 0); } nk_group_scrolled_begin(ctx, &mScroll, "dialog_main", 0); { if (mDialogMenu.update(ctx, data.dialogOptions, mScroll) == MouseAndClickMenu::Result::Activated) result = data.dialogActions[mDialogMenu.getSelectedIndex()](); } nk_group_scrolled_end(ctx); }, true); return result; }
static int node_editor(struct nk_context *ctx) { int n = 0; struct nk_rect total_space; const struct nk_input *in = &ctx->input; struct nk_command_buffer *canvas; struct node *updated = 0; struct node_editor *nodedit = &nodeEditor; if (!nodeEditor.initialized) { node_editor_init(&nodeEditor); nodeEditor.initialized = 1; } if (nk_begin(ctx, "NodeEdit", nk_rect(0, 0, 800, 600), NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) { /* allocate complete window space */ canvas = nk_window_get_canvas(ctx); total_space = nk_window_get_content_region(ctx); nk_layout_space_begin(ctx, NK_STATIC, total_space.h, nodedit->node_count); { struct node *it = nodedit->begin; struct nk_rect size = nk_layout_space_bounds(ctx); struct nk_panel *node = 0; if (nodedit->show_grid) { /* display grid */ float x, y; const float grid_size = 32.0f; const struct nk_color grid_color = nk_rgb(50, 50, 50); for (x = (float)fmod(size.x - nodedit->scrolling.x, grid_size); x < size.w; x += grid_size) nk_stroke_line(canvas, x+size.x, size.y, x+size.x, size.y+size.h, 1.0f, grid_color); for (y = (float)fmod(size.y - nodedit->scrolling.y, grid_size); y < size.h; y += grid_size) nk_stroke_line(canvas, size.x, y+size.y, size.x+size.w, y+size.y, 1.0f, grid_color); } /* execute each node as a movable group */ while (it) { /* calculate scrolled node window position and size */ nk_layout_space_push(ctx, nk_rect(it->bounds.x - nodedit->scrolling.x, it->bounds.y - nodedit->scrolling.y, it->bounds.w, it->bounds.h)); /* execute node window */ if (nk_group_begin(ctx, it->name, NK_WINDOW_MOVABLE|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BORDER|NK_WINDOW_TITLE)) { /* always have last selected node on top */ node = nk_window_get_panel(ctx); if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, node->bounds) && (!(it->prev && nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_rect_to_screen(ctx, node->bounds)))) && nodedit->end != it) { updated = it; } /* ================= NODE CONTENT =====================*/ nk_layout_row_dynamic(ctx, 25, 1); nk_button_color(ctx, it->color); it->color.r = (nk_byte)nk_propertyi(ctx, "#R:", 0, it->color.r, 255, 1,1); it->color.g = (nk_byte)nk_propertyi(ctx, "#G:", 0, it->color.g, 255, 1,1); it->color.b = (nk_byte)nk_propertyi(ctx, "#B:", 0, it->color.b, 255, 1,1); it->color.a = (nk_byte)nk_propertyi(ctx, "#A:", 0, it->color.a, 255, 1,1); /* ====================================================*/ nk_group_end(ctx); } { /* node connector and linking */ float space; struct nk_rect bounds; bounds = nk_layout_space_rect_to_local(ctx, node->bounds); bounds.x += nodedit->scrolling.x; bounds.y += nodedit->scrolling.y; it->bounds = bounds; /* output connector */ space = node->bounds.h / (float)((it->output_count) + 1); for (n = 0; n < it->output_count; ++n) { struct nk_rect circle; circle.x = node->bounds.x + node->bounds.w-4; circle.y = node->bounds.y + space * (float)(n+1); circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); /* start linking process */ if (nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, circle, nk_true)) { nodedit->linking.active = nk_true; nodedit->linking.node = it; nodedit->linking.input_id = it->ID; nodedit->linking.input_slot = n; } /* draw curve from linked node slot to mouse position */ if (nodedit->linking.active && nodedit->linking.node == it && nodedit->linking.input_slot == n) { struct nk_vec2 l0 = nk_vec2(circle.x + 3, circle.y + 3); struct nk_vec2 l1 = in->mouse.pos; nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); } } /* input connector */ space = node->bounds.h / (float)((it->input_count) + 1); for (n = 0; n < it->input_count; ++n) { struct nk_rect circle; circle.x = node->bounds.x-4; circle.y = node->bounds.y + space * (float)(n+1); circle.w = 8; circle.h = 8; nk_fill_circle(canvas, circle, nk_rgb(100, 100, 100)); if (nk_input_is_mouse_released(in, NK_BUTTON_LEFT) && nk_input_is_mouse_hovering_rect(in, circle) && nodedit->linking.active && nodedit->linking.node != it) { nodedit->linking.active = nk_false; node_editor_link(nodedit, nodedit->linking.input_id, nodedit->linking.input_slot, it->ID, n); } } } it = it->next; } /* reset linking connection */ if (nodedit->linking.active && nk_input_is_mouse_released(in, NK_BUTTON_LEFT)) { nodedit->linking.active = nk_false; nodedit->linking.node = NULL; fprintf(stdout, "linking failed\n"); } /* draw each link */ for (n = 0; n < nodedit->link_count; ++n) { struct node_link *link = &nodedit->links[n]; struct node *ni = node_editor_find(nodedit, link->input_id); struct node *no = node_editor_find(nodedit, link->output_id); float spacei = node->bounds.h / (float)((ni->output_count) + 1); float spaceo = node->bounds.h / (float)((no->input_count) + 1); struct nk_vec2 l0 = nk_layout_space_to_screen(ctx, nk_vec2(ni->bounds.x + ni->bounds.w, 3.0f + ni->bounds.y + spacei * (float)(link->input_slot+1))); struct nk_vec2 l1 = nk_layout_space_to_screen(ctx, nk_vec2(no->bounds.x, 3.0f + no->bounds.y + spaceo * (float)(link->output_slot+1))); l0.x -= nodedit->scrolling.x; l0.y -= nodedit->scrolling.y; l1.x -= nodedit->scrolling.x; l1.y -= nodedit->scrolling.y; nk_stroke_curve(canvas, l0.x, l0.y, l0.x + 50.0f, l0.y, l1.x - 50.0f, l1.y, l1.x, l1.y, 1.0f, nk_rgb(100, 100, 100)); } if (updated) { /* reshuffle nodes to have least recently selected node on top */ node_editor_pop(nodedit, updated); node_editor_push(nodedit, updated); } /* node selection */ if (nk_input_mouse_clicked(in, NK_BUTTON_LEFT, nk_layout_space_bounds(ctx))) { it = nodedit->begin; nodedit->selected = NULL; nodedit->bounds = nk_rect(in->mouse.pos.x, in->mouse.pos.y, 100, 200); while (it) { struct nk_rect b = nk_layout_space_rect_to_screen(ctx, it->bounds); b.x -= nodedit->scrolling.x; b.y -= nodedit->scrolling.y; if (nk_input_is_mouse_hovering_rect(in, b)) nodedit->selected = it; it = it->next; } } /* contextual menu */ if (nk_contextual_begin(ctx, 0, nk_vec2(100, 220), nk_window_get_bounds(ctx))) { const char *grid_option[] = {"Show Grid", "Hide Grid"}; nk_layout_row_dynamic(ctx, 25, 1); if (nk_contextual_item_label(ctx, "New", NK_TEXT_CENTERED)) node_editor_add(nodedit, "New", nk_rect(400, 260, 180, 220), nk_rgb(255, 255, 255), 1, 2); if (nk_contextual_item_label(ctx, grid_option[nodedit->show_grid],NK_TEXT_CENTERED)) nodedit->show_grid = !nodedit->show_grid; nk_contextual_end(ctx); } } nk_layout_space_end(ctx); /* window content scrolling */ if (nk_input_is_mouse_hovering_rect(in, nk_window_get_bounds(ctx)) && nk_input_is_mouse_down(in, NK_BUTTON_MIDDLE)) { nodedit->scrolling.x += in->mouse.delta.x; nodedit->scrolling.y += in->mouse.delta.y; } } nk_end(ctx); return !nk_window_is_closed(ctx, "NodeEdit"); }
int main(int argc, char** argv) { if (argc > 2) message_and_abort_fmt("Usage: %s [filename]", argv[0]); Render::RenderSettings renderSettings; renderSettings.windowWidth = 800; renderSettings.windowHeight = 600; renderSettings.fullscreen = false; NuklearMisc::StandaloneGuiHandler guiHandler("Cel Viewer", renderSettings); nk_context* ctx = guiHandler.getNuklearContext(); Settings::Settings settings; settings.loadFromFile("resources/celview.ini"); bool faioInitDone = false; std::string listFile = settings.get<std::string>("celview", "listFile", "Diablo I.txt"); std::string mpqFile = settings.get<std::string>("celview", "mpqFile", "DIABDAT.MPQ"); std::vector<std::string> celFiles; std::string selectedImage = ""; std::unique_ptr<NuklearMisc::GuiSprite> image; std::unique_ptr<NuklearMisc::GuiSprite> nextImage; int animate = false; int32_t frame = 0; float rowHeight = 30; auto lastFrame = std::chrono::high_resolution_clock::now(); bool quit = false; while (!quit) { auto now = std::chrono::high_resolution_clock::now(); if (nextImage) image = std::unique_ptr<NuklearMisc::GuiSprite>(nextImage.release()); renderSettings = Render::getWindowSize(); if (nk_begin(ctx, "main_window", nk_rect(0, 0, renderSettings.windowWidth, renderSettings.windowHeight), NK_WINDOW_NO_SCROLLBAR)) { struct nk_rect bounds = nk_window_get_content_region(ctx); nk_layout_row_dynamic(ctx, bounds.h, 2); if (nk_group_begin(ctx, "image", 0)) { nk_layout_row_dynamic(ctx, rowHeight, 1); std::string label = selectedImage; if (selectedImage == "") label = "No image selected"; nk_label(ctx, label.c_str(), NK_TEXT_CENTERED); nk_checkbox_label(ctx, "Animate", &animate); if (image) { nk_label(ctx, (boost::format("Number of Frames: %1%") % image.get()->getSprite()->size()).str().c_str(), NK_TEXT_LEFT); nk_label(ctx, (boost::format("Width: %1%") % image->getSprite()->getWidth()).str().c_str(), NK_TEXT_LEFT); nk_label(ctx, (boost::format("Height: %1%") % image->getSprite()->getHeight()).str().c_str(), NK_TEXT_LEFT); frame = nk_propertyi(ctx, "Frame", 0, frame, image->getSprite()->size(), 1, 0.2f); if (nk_button_label(ctx, "save as png")) { nfdchar_t* outPath = NULL; nfdresult_t result = NFD_SaveDialog("png", NULL, &outPath); if (result == NFD_OKAY) { Render::SpriteGroup::toPng(selectedImage, outPath); free(outPath); } } if (nk_button_label(ctx, "save as gif")) { nfdchar_t* outPath = NULL; nfdresult_t result = NFD_SaveDialog("gif", NULL, &outPath); if (result == NFD_OKAY) { Render::SpriteGroup::toGif(selectedImage, outPath); free(outPath); } } auto msSinceLastFrame = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastFrame).count(); if (animate && msSinceLastFrame > 100) { lastFrame = now; frame++; } if (frame >= (int32_t)image.get()->getSprite()->size()) frame = 0; Render::Sprite sprite = image.get()->getSprite()->operator[](frame); int32_t w, h; Render::spriteSize(sprite, w, h); nk_layout_space_begin(ctx, NK_STATIC, h, 1); { nk_layout_space_push(ctx, nk_rect(0, 0, w, h)); auto canvas = nk_window_get_canvas(ctx); struct nk_rect imageRect; nk_widget(&imageRect, ctx); nk_fill_rect(canvas, imageRect, 0.0, nk_rgb(0, 255, 0)); auto img = image.get()->getNkImage(frame); nk_draw_image(canvas, imageRect, &img, nk_rgb(255, 255, 255)); } nk_layout_space_end(ctx); } nk_group_end(ctx); } if (nk_group_begin(ctx, "file list", 0)) { if (!faioInitDone) { nk_layout_row_dynamic(ctx, rowHeight * 2, 1); NuklearMisc::nk_file_pick(ctx, "DIABDAT.MPQ", mpqFile, "mpq,MPQ", rowHeight); NuklearMisc::nk_file_pick(ctx, "Diablo listfile", listFile, "txt", rowHeight); if (nk_button_label(ctx, "load")) { FAIO::init(mpqFile, listFile); celFiles = FAIO::listMpqFiles("*.cel"); auto tmp = FAIO::listMpqFiles("*.cl2"); celFiles.insert(celFiles.end(), tmp.begin(), tmp.end()); std::sort(celFiles.begin(), celFiles.end()); settings.set<std::string>("celview", "listFile", listFile); settings.set<std::string>("celview", "mpqFile", mpqFile); settings.save(); faioInitDone = true; if (argc > 1) { selectedImage = argv[1]; frame = 0; nextImage = std::unique_ptr<NuklearMisc::GuiSprite>(guiHandler.getSprite(new Render::SpriteGroup(selectedImage))); } } } nk_layout_row_dynamic(ctx, rowHeight, 1); for (size_t i = 0; i < celFiles.size(); i++) { auto buttonStyle = ctx->style.button; if (selectedImage == celFiles[i]) buttonStyle.normal = buttonStyle.hover; if (nk_button_label_styled(ctx, &buttonStyle, celFiles[i].c_str())) { selectedImage = celFiles[i]; frame = 0; nextImage = std::unique_ptr<NuklearMisc::GuiSprite>(guiHandler.getSprite(new Render::SpriteGroup(selectedImage))); } } nk_group_end(ctx); } } nk_end(ctx); quit = guiHandler.update(); } FAIO::quit(); return 0; }