From 75aa8ec4b2c893bba8c46b71cd0e23c3b6d4870c Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Thu, 14 Jun 2018 01:03:16 -0700 Subject: [PATCH] Add "Fit Viewport" verb to automatically size the map window (#38351) * Add a verb to automatically size the map window * Add a preference to auto-fit the viewport --- code/modules/client/client_procs.dm | 2 + code/modules/client/preferences.dm | 11 ++++- code/modules/client/preferences_savefile.dm | 3 ++ code/modules/client/verbs/ooc.dm | 46 +++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 1378f0069d3..407529c1ea3 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -773,6 +773,8 @@ GLOBAL_LIST_EMPTY(external_rsc_urls) if (isliving(mob)) var/mob/living/M = mob M.update_damage_hud() + if (prefs.auto_fit_viewport) + fit_viewport() /client/proc/generate_clickcatcher() if(!void) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e78a71ba15e..fecc8d3beff 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -114,6 +114,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/parallax var/ambientocclusion = TRUE + var/auto_fit_viewport = FALSE var/uplink_spawn_loc = UPLINK_PDA @@ -157,7 +158,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) return update_preview_icon() user << browse_rsc(preview_icon, "previewicon.png") - var/dat = "
" + var/list/dat = list("
") dat += "Character Settings" dat += "Game Preferences" @@ -512,6 +513,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" dat += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
" + dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
" if (CONFIG_GET(flag/maprotation)) var/p_map = preferred_map @@ -604,7 +606,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
" var/datum/browser/popup = new(user, "preferences", "
Character Setup
", 640, 770) - popup.set_content(dat) + popup.set_content(dat.Join()) popup.open(0) #undef APPEARANCE_CATEGORY_COLUMN @@ -1495,6 +1497,11 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen PM.backdrop(parent.mob) + if("auto_fit_viewport") + auto_fit_viewport = !auto_fit_viewport + if(auto_fit_viewport && parent) + parent.fit_viewport() + if("save") save_preferences() save_character() diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 8c92e59f767..199a0eab6b5 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -98,6 +98,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["clientfps"] >> clientfps S["parallax"] >> parallax S["ambientocclusion"] >> ambientocclusion + S["auto_fit_viewport"] >> auto_fit_viewport S["menuoptions"] >> menuoptions S["enable_tips"] >> enable_tips S["tip_delay"] >> tip_delay @@ -122,6 +123,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car clientfps = sanitize_integer(clientfps, 0, 1000, 0) parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null) ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion)) + auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport)) ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form)) ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) @@ -168,6 +170,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car WRITE_FILE(S["clientfps"], clientfps) WRITE_FILE(S["parallax"], parallax) WRITE_FILE(S["ambientocclusion"], ambientocclusion) + WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport) WRITE_FILE(S["menuoptions"], menuoptions) WRITE_FILE(S["enable_tips"], enable_tips) WRITE_FILE(S["tip_delay"], tip_delay) diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index cf27cc4da67..97b8fee9fce 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -298,3 +298,49 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR) set desc = "View the last round end report you've seen" SSticker.show_roundend_report(src, TRUE) + +/client/verb/fit_viewport() + set name = "Fit Viewport" + set category = "OOC" + set desc = "Fit the width of the map window to match the viewport" + + // Fetch aspect ratio + var/view_size = getviewsize(view) + var/aspect_ratio = view_size[1] / view_size[2] + + // Calculate desired pixel width using window size and aspect ratio + var/sizes = params2list(winget(src, "mainwindow.split;mapwindow", "size")) + var/map_size = splittext(sizes["mapwindow.size"], "x") + var/height = text2num(map_size[2]) + var/desired_width = round(height * aspect_ratio) + if (text2num(map_size[1]) == desired_width) + // Nothing to do + return + + var/split_size = splittext(sizes["mainwindow.split.size"], "x") + var/split_width = text2num(split_size[1]) + + // Calculate and apply a best estimate + // +4 pixels are for the width of the splitter's handle + var/pct = 100 * (desired_width + 4) / split_width + winset(src, "mainwindow.split", "splitter=[pct]") + + // Apply an ever-lowering offset until we finish or fail + var/delta + for(var/safety in 1 to 10) + var/after_size = winget(src, "mapwindow", "size") + map_size = splittext(after_size, "x") + var/got_width = text2num(map_size[1]) + + if (got_width == desired_width) + // success + return + else if (isnull(delta)) + // calculate a probable delta value based on the difference + delta = 100 * (desired_width - got_width) / split_width + else if ((delta > 0 && got_width > desired_width) || (delta < 0 && got_width < desired_width)) + // if we overshot, halve the delta and reverse direction + delta = -delta/2 + + pct += delta + winset(src, "mainwindow.split", "splitter=[pct]")