ui: Add option to scale app UI elements

This commit is contained in:
Matt Borgerson 2020-03-29 00:46:10 -07:00
parent 80940258fe
commit be0c5f13cc
1 changed files with 94 additions and 66 deletions

View File

@ -97,33 +97,23 @@ static void ShowAboutWindow(bool* p_open);
bool show_demo_window = false; bool show_demo_window = false;
void xemu_hud_init(SDL_Window* window, void* sdl_gl_context) float ui_scale = 1.0;
bool trigger_style_update = true;
static void init_style(void)
{ {
xemu_monitor_init();
initialize_custom_ui_rendering();
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.IniFilename = NULL;
// Load fonts io.Fonts->Clear();
io.Fonts->AddFontFromFileTTF(xemu_get_resource_path("Roboto-Medium.ttf"), 16); io.Fonts->AddFontFromFileTTF(xemu_get_resource_path("Roboto-Medium.ttf"), 16*ui_scale);
fixed_width_font = io.Fonts->AddFontDefault(); ImFontConfig font_cfg = ImFontConfig();
font_cfg.OversampleH = font_cfg.OversampleV = 1;
font_cfg.PixelSnapH = true;
font_cfg.SizePixels = 13.0f*ui_scale;
fixed_width_font = io.Fonts->AddFontDefault(&font_cfg);
ImGui_ImplOpenGL3_CreateFontsTexture();
// Setup Platform/Renderer bindings ImGuiStyle style;
ImGui_ImplSDL2_InitForOpenGL(window, sdl_gl_context);
const char *glsl_version = "#version 150";
ImGui_ImplOpenGL3_Init(glsl_version);
// Set default theme, override
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
style.FrameRounding = 8.0; style.FrameRounding = 8.0;
style.GrabRounding = 12.0; style.GrabRounding = 12.0;
style.PopupRounding = 5.0; style.PopupRounding = 5.0;
@ -134,6 +124,11 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
style.PopupBorderSize = 0; style.PopupBorderSize = 0;
style.FrameBorderSize = 0; style.FrameBorderSize = 0;
style.TabBorderSize = 0; style.TabBorderSize = 0;
ImGui::GetStyle() = style;
ImGui::GetStyle().ScaleAllSizes(ui_scale);
// Set default theme, override
ImGui::StyleColorsDark();
ImVec4* colors = ImGui::GetStyle().Colors; ImVec4* colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f); colors[ImGuiCol_Text] = ImVec4(0.86f, 0.93f, 0.89f, 0.78f);
@ -184,6 +179,26 @@ void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.73f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.16f, 0.16f, 0.16f, 0.73f);
}
void xemu_hud_init(SDL_Window* window, void* sdl_gl_context)
{
xemu_monitor_init();
initialize_custom_ui_rendering();
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.IniFilename = NULL;
// Setup Platform/Renderer bindings
ImGui_ImplSDL2_InitForOpenGL(window, sdl_gl_context);
const char *glsl_version = "#version 150";
ImGui_ImplOpenGL3_Init(glsl_version);
show_first_boot_window = xemu_settings_did_fail_to_load(); show_first_boot_window = xemu_settings_did_fail_to_load();
if (show_first_boot_window) { if (show_first_boot_window) {
@ -249,7 +264,15 @@ static void ShowMainMenu()
if (ImGui::BeginMenu("View")) if (ImGui::BeginMenu("View"))
{ {
if (ImGui::Combo("Scaling Mode", &scaling_mode, "Center\0Scale\0Stretch\0\0")) { int ui_scale_combo = ui_scale - 1.0;
if (ui_scale_combo < 0) ui_scale_combo = 0;
if (ui_scale_combo > 1) ui_scale_combo = 1;
if (ImGui::Combo("UI Scale", &ui_scale_combo, "1x\0" "2x\0")) {
ui_scale = ui_scale_combo + 1;
trigger_style_update = true;
}
if (ImGui::Combo("Scaling Mode", &scaling_mode, "Center\0Scale\0Stretch\0")) {
xemu_settings_set_enum(XEMU_SETTINGS_DISPLAY_SCALE, scaling_mode); xemu_settings_set_enum(XEMU_SETTINGS_DISPLAY_SCALE, scaling_mode);
xemu_settings_save(); xemu_settings_save();
} }
@ -257,6 +280,7 @@ static void ShowMainMenu()
if (ImGui::MenuItem("Fullscreen", NULL, xemu_is_fullscreen(), true)) { if (ImGui::MenuItem("Fullscreen", NULL, xemu_is_fullscreen(), true)) {
xemu_toggle_fullscreen(); xemu_toggle_fullscreen();
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (ImGui::BeginMenu("Debug")) if (ImGui::BeginMenu("Debug"))
@ -272,11 +296,11 @@ static void ShowMainMenu()
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-100.0); ImGui::SetCursorPosX(ImGui::GetWindowWidth()-100.0*ui_scale);
extern float fps; extern float fps;
ImGui::Text("%.3f", fps); ImGui::Text("%.3f", fps);
ImGui::SameLine(); ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-300.0); ImGui::SetCursorPosX(ImGui::GetWindowWidth()-200.0*ui_scale);
ImGui::Text("%.3f", 1000.0/fps); ImGui::Text("%.3f", 1000.0/fps);
main_menu_height = ImGui::GetWindowHeight(); main_menu_height = ImGui::GetWindowHeight();
@ -418,6 +442,11 @@ void xemu_hud_render(SDL_Window *window)
// to navigate the HUD // to navigate the HUD
xemu_input_set_test_mode(controller_focus_capture); xemu_input_set_test_mode(controller_focus_capture);
if (trigger_style_update) {
init_style();
trigger_style_update = false;
}
// Start the Dear ImGui frame // Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
@ -531,7 +560,6 @@ void xemu_hud_render(SDL_Window *window)
ImGui::EndPopup(); ImGui::EndPopup();
} }
// Rendering
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
} }
@ -573,7 +601,7 @@ struct MonitorConsole
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520*ui_scale, 600*ui_scale), ImGuiCond_FirstUseEver);
if (!ImGui::Begin(title, p_open)) if (!ImGui::Begin(title, p_open))
{ {
ImGui::End(); ImGui::End();
@ -696,7 +724,7 @@ struct InputWindow
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(500,620), ImGuiCond_Appearing); ImGui::SetNextWindowSize(ImVec2(500*ui_scale,620*ui_scale), ImGuiCond_Appearing);
// Remove window X padding for this window to easily center stuff // Remove window X padding for this window to easily center stuff
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,ImGui::GetStyle().WindowPadding.y)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,ImGui::GetStyle().WindowPadding.y));
@ -738,7 +766,7 @@ struct InputWindow
bool port_is_bound = (xemu_input_get_bound(i) != NULL); bool port_is_bound = (xemu_input_get_bound(i) != NULL);
// Set an X offset to center the image button within the column // Set an X offset to center the image button within the column
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-b_w-2*port_padding)/2)); ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-b_w*ui_scale-2*port_padding*ui_scale)/2));
// We are using the same texture for all buttons, but ImageButton // We are using the same texture for all buttons, but ImageButton
// uses the texture as a unique ID. Push a new ID now to resolve // uses the texture as a unique ID. Push a new ID now to resolve
@ -747,7 +775,7 @@ struct InputWindow
float x = b_x+i*b_x_stride; float x = b_x+i*b_x_stride;
ImGui::PushStyleColor(ImGuiCol_Button, is_currently_selected ? color_active : color_inactive); ImGui::PushStyleColor(ImGuiCol_Button, is_currently_selected ? color_active : color_inactive);
bool activated = ImGui::ImageButton(id, bool activated = ImGui::ImageButton(id,
ImVec2(b_w,b_h), ImVec2(b_w*ui_scale,b_h*ui_scale),
ImVec2(x/t_w, (b_y+b_h)/t_h), ImVec2(x/t_w, (b_y+b_h)/t_h),
ImVec2((x+b_w)/t_w, b_y/t_h), ImVec2((x+b_w)/t_w, b_y/t_h),
port_padding); port_padding);
@ -778,12 +806,12 @@ struct InputWindow
// //
// Center the combo above the controller with the same width // Center the combo above the controller with the same width
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-controller_width)/2.0)); ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-controller_width*ui_scale)/2.0));
// Note: SetNextItemWidth applies only to the combo element, but not the // Note: SetNextItemWidth applies only to the combo element, but not the
// associated label which follows, so scale back a bit to make space for // associated label which follows, so scale back a bit to make space for
// the label. // the label.
ImGui::SetNextItemWidth(controller_width*0.75); ImGui::SetNextItemWidth(controller_width*0.75*ui_scale);
// List available input devices // List available input devices
const char *not_connected = "Not Connected"; const char *not_connected = "Not Connected";
@ -857,9 +885,9 @@ struct InputWindow
// update_sdl_controller_state(&state); // update_sdl_controller_state(&state);
// update_sdl_kbd_controller_state(&state); // update_sdl_kbd_controller_state(&state);
ImVec2 cur = ImGui::GetCursorPos(); ImVec2 cur = ImGui::GetCursorPos();
ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-controller_width)/2.0)); ImGui::SetCursorPosX(ImGui::GetCursorPosX()+(int)((ImGui::GetColumnWidth()-controller_width*ui_scale)/2.0));
ImGui::Image(id, ImGui::Image(id,
ImVec2(controller_width, controller_height), ImVec2(controller_width*ui_scale, controller_height*ui_scale),
ImVec2(0, controller_height/t_h), ImVec2(0, controller_height/t_h),
ImVec2(controller_width/t_w, 0)); ImVec2(controller_width/t_w, 0));
@ -867,8 +895,8 @@ struct InputWindow
// ImGui::SameLine(); // ImGui::SameLine();
const char *msg = "Please select an available input device"; const char *msg = "Please select an available input device";
ImVec2 dim = ImGui::CalcTextSize(msg); ImVec2 dim = ImGui::CalcTextSize(msg);
ImGui::SetCursorPosX(cur.x + (controller_width-dim.x)/2); ImGui::SetCursorPosX(cur.x + (controller_width*ui_scale-dim.x)/2);
ImGui::SetCursorPosY(cur.y +(controller_height-dim.y)/2); ImGui::SetCursorPosY(cur.y + (controller_height*ui_scale-dim.y)/2);
ImGui::Text("%s", msg); ImGui::Text("%s", msg);
ImGui::SameLine(); ImGui::SameLine();
} }
@ -978,7 +1006,7 @@ struct SettingsWindow
dirty = true; dirty = true;
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("Browse...", ImVec2(100, 0))) { if (ImGui::Button("Browse...", ImVec2(100*ui_scale, 0))) {
const char *selected = noc_file_dialog_open(NOC_FILE_DIALOG_OPEN, filters, buf, NULL); const char *selected = noc_file_dialog_open(NOC_FILE_DIALOG_OPEN, filters, buf, NULL);
if ((selected != NULL) && (strcmp(buf, selected) != 0)) { if ((selected != NULL) && (strcmp(buf, selected) != 0)) {
strncpy(buf, selected, len-1); strncpy(buf, selected, len-1);
@ -990,7 +1018,7 @@ struct SettingsWindow
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(550, 300), ImGuiCond_Appearing); ImGui::SetNextWindowSize(ImVec2(550*ui_scale, 300*ui_scale), ImGuiCond_Appearing);
if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse))
{ {
ImGui::End(); ImGui::End();
@ -1010,7 +1038,7 @@ struct SettingsWindow
ImGui::Text("Flash (BIOS) File"); ImGui::Text("Flash (BIOS) File");
ImGui::NextColumn(); ImGui::NextColumn();
float picker_width = ImGui::GetColumnWidth()-120; float picker_width = ImGui::GetColumnWidth()-120*ui_scale;
ImGui::SetNextItemWidth(picker_width); ImGui::SetNextItemWidth(picker_width);
FilePicker("###Flash", flash_path, MAX_STRING_LEN, rom_file_filters); FilePicker("###Flash", flash_path, MAX_STRING_LEN, rom_file_filters);
ImGui::NextColumn(); ImGui::NextColumn();
@ -1042,7 +1070,7 @@ struct SettingsWindow
ImGui::Text("System Memory"); ImGui::Text("System Memory");
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::SetNextItemWidth(ImGui::GetColumnWidth()*0.5); ImGui::SetNextItemWidth(ImGui::GetColumnWidth()*0.5);
if (ImGui::Combo("###mem", &memory_idx, "64 MiB\0" "128 MiB\0" "\0")) { if (ImGui::Combo("###mem", &memory_idx, "64 MiB\0" "128 MiB\0")) {
dirty = true; dirty = true;
} }
ImGui::NextColumn(); ImGui::NextColumn();
@ -1056,7 +1084,7 @@ struct SettingsWindow
ImGui::Columns(1); ImGui::Columns(1);
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+20)); ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+20)*ui_scale);
if (dirty) { if (dirty) {
ImGui::Text("Warning: Unsaved changes!"); ImGui::Text("Warning: Unsaved changes!");
ImGui::SameLine(); ImGui::SameLine();
@ -1065,11 +1093,11 @@ struct SettingsWindow
ImGui::SameLine(); ImGui::SameLine();
} }
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+25)); ImGui::SetCursorPosY(ImGui::GetWindowHeight()-(10+25)*ui_scale);
ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)); ImGui::SetCursorPosX(ImGui::GetWindowWidth()-(120+10)*ui_scale);
ImGui::SetItemDefaultFocus(); ImGui::SetItemDefaultFocus();
if (ImGui::Button("Save", ImVec2(120, 0))) { if (ImGui::Button("Save", ImVec2(120*ui_scale, 0))) {
Save(); Save();
dirty = false; dirty = false;
pending_restart = true; pending_restart = true;
@ -1105,7 +1133,7 @@ struct AboutWindow
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(400, 350), ImGuiCond_Appearing); ImGui::SetNextWindowSize(ImVec2(400*ui_scale, 350*ui_scale), ImGuiCond_Appearing);
if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse)) if (!ImGui::Begin(title, p_open, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse))
{ {
ImGui::End(); ImGui::End();
@ -1118,15 +1146,15 @@ struct AboutWindow
} }
uint32_t now = SDL_GetTicks() - time_start; uint32_t now = SDL_GetTicks() - time_start;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50); ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50*ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256*ui_scale)/2);
ImTextureID id = (ImTextureID)render_to_fbo(logo_fbo); ImTextureID id = (ImTextureID)render_to_fbo(logo_fbo);
float t_w = 256.0; float t_w = 256.0;
float t_h = 256.0; float t_h = 256.0;
float x_off = 0; float x_off = 0;
ImGui::Image(id, ImGui::Image(id,
ImVec2(t_w-x_off, t_h), ImVec2((t_w-x_off)*ui_scale, t_h*ui_scale),
ImVec2(x_off/t_w, t_h/t_h), ImVec2(x_off/t_w, t_h/t_h),
ImVec2(t_w/t_w, 0)); ImVec2(t_w/t_w, 0));
if (ImGui::IsItemClicked()) { if (ImGui::IsItemClicked()) {
@ -1134,21 +1162,21 @@ struct AboutWindow
} }
render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000); render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000);
render_to_default_fb(); render_to_default_fb();
ImGui::SetCursorPosX(10); ImGui::SetCursorPosX(10*ui_scale);
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-100); ImGui::SetCursorPosY(ImGui::GetCursorPosY()-100*ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(xemu_version).x)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(xemu_version).x)/2);
ImGui::Text("%s", xemu_version); ImGui::Text("%s", xemu_version);
ImGui::SetCursorPosX(10); ImGui::SetCursorPosX(10*ui_scale);
ImGui::Dummy(ImVec2(0,35)); ImGui::Dummy(ImVec2(0,35*ui_scale));
const char *msg = "Visit https://xemu.app for more information"; const char *msg = "Visit https://xemu.app for more information";
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg); ImGui::Text("%s", msg);
ImGui::Dummy(ImVec2(0,35)); ImGui::Dummy(ImVec2(0,35*ui_scale));
ImGui::PushFont(fixed_width_font); ImGui::PushFont(fixed_width_font);
ImGui::InputTextMultiline("##build_info", build_info_text, IM_ARRAYSIZE(build_info_text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 6), ImGuiInputTextFlags_ReadOnly); ImGui::InputTextMultiline("##build_info", build_info_text, IM_ARRAYSIZE(build_info_text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 6), ImGuiInputTextFlags_ReadOnly);
@ -1183,7 +1211,7 @@ struct FirstBootWindow
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
{ {
ImVec2 size(400, 300); ImVec2 size(400*ui_scale, 300*ui_scale);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImVec2 window_pos = ImVec2((io.DisplaySize.x - size.x)/2, (io.DisplaySize.y - size.y)/2); ImVec2 window_pos = ImVec2((io.DisplaySize.x - size.x)/2, (io.DisplaySize.y - size.y)/2);
@ -1201,38 +1229,38 @@ struct FirstBootWindow
} }
uint32_t now = SDL_GetTicks() - time_start; uint32_t now = SDL_GetTicks() - time_start;
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50); ImGui::SetCursorPosY(ImGui::GetCursorPosY()-50*ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-256*ui_scale)/2);
ImTextureID id = (ImTextureID)render_to_fbo(logo_fbo); ImTextureID id = (ImTextureID)render_to_fbo(logo_fbo);
float t_w = 256.0; float t_w = 256.0;
float t_h = 256.0; float t_h = 256.0;
float x_off = 0; float x_off = 0;
ImGui::Image(id, ImGui::Image(id,
ImVec2(t_w-x_off, t_h), ImVec2((t_w-x_off)*ui_scale, t_h*ui_scale),
ImVec2(x_off/t_w, t_h/t_h), ImVec2(x_off/t_w, t_h/t_h),
ImVec2(t_w/t_w, 0)); ImVec2(t_w/t_w, 0));
render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000); render_logo(now, 0x42e335ff, 0x42e335ff, 0x00000000);
render_to_default_fb(); render_to_default_fb();
ImGui::SetCursorPosX(10); ImGui::SetCursorPosX(10*ui_scale);
ImGui::SetCursorPosY(ImGui::GetCursorPosY()-75); ImGui::SetCursorPosY(ImGui::GetCursorPosY()-75*ui_scale);
const char *msg = "To get started, please configure machine settings."; const char *msg = "To get started, please configure machine settings.";
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg); ImGui::Text("%s", msg);
ImGui::Dummy(ImVec2(0,20)); ImGui::Dummy(ImVec2(0,20*ui_scale));
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-120)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-120*ui_scale)/2);
if (ImGui::Button("Settings", ImVec2(120, 0))) { if (ImGui::Button("Settings", ImVec2(120*ui_scale, 0))) {
show_settings_window = true; show_settings_window = true;
} }
ImGui::Dummy(ImVec2(0,20)); ImGui::Dummy(ImVec2(0,20*ui_scale));
ImGui::SetCursorPosX(10); ImGui::SetCursorPosX(10*ui_scale);
msg = "Visit https://xemu.app for more information"; msg = "Visit https://xemu.app for more information";
ImGui::SetCursorPosY(ImGui::GetWindowHeight()-ImGui::CalcTextSize(msg).y-10); ImGui::SetCursorPosY(ImGui::GetWindowHeight()-ImGui::CalcTextSize(msg).y-10*ui_scale);
ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2); ImGui::SetCursorPosX((ImGui::GetWindowWidth()-ImGui::CalcTextSize(msg).x)/2);
ImGui::Text("%s", msg); ImGui::Text("%s", msg);