diff --git a/api/api.lua b/api/api.lua index 0405b00d..e2850c1a 100644 --- a/api/api.lua +++ b/api/api.lua @@ -992,28 +992,53 @@ function pfUI.api.GetBorderSize(pref) end end +-- The scale UIParent ends up with: one UI unit per screen pixel when pixel +-- perfect, else the game's own. The game applies its scale only after the +-- add-ons and their saved variables are loaded (CGGameUI::Initialize ends in +-- OnDisplaySizeChanged), so at load time it is worked out from the same +-- options and rules: uiScale while useUiScale is on and it is at least 0.64, +-- else 768 over the window height kept within 0.9 and 1. Windows narrower +-- than 4:3 cap either at 3/4 of their aspect. +local function GetUIScale() + if pfUI_config.global.pixelperfect == "1" then return PixelUtil.GetPixelToUIUnitFactor() end + + local width, height = GetPhysicalScreenSize() + local aspect = GetCVar("widescreen") == "1" and width / height or 4/3 + local function fit(scale) + return aspect < 4/3 and math.min(scale, aspect * .75) or scale + end + + if GetCVar("useUiScale") == "1" then + local scale = fit(tonumber(GetCVar("uiScale"))) + if scale >= .64 then return scale end + end + + return math.max(fit(height > 768 and 768 / height or 1), .9) +end + +-- [ UpdateUIScale ] +-- Gives UIParent the pixel perfect scale when enabled, else leaves the game's +-- own. The engine puts its own scale back on every window resize and scale +-- option change, so this runs again on each UI_SCALE_CHANGED. Borders keep +-- the pixel size they were built with, so a change of it offers a reload once. +function pfUI.api.UpdateUIScale() + if pfUI_config.global.pixelperfect == "1" then + UIParent:SetScale(PixelUtil.GetPixelToUIUnitFactor()) + end + + if not pfUI.pixel or pfUI.scaleprompt then return end + if math.abs(PixelUtil.GetPixelToUIUnitFactor() / UIParent:GetScale() - pfUI.pixel) < .0001 then return end + + pfUI.scaleprompt = true + CreateQuestionDialog(T["The UI-Scale has changed. Reload the UI to redraw the borders?"], ReloadUI) +end + -- [ GetPerfectPixel ] --- Returns a number that equals a real pixel on regular scaled frames. --- Respects the current UI-scale and calculates a real pixel based on --- the screen resolution and the 768px sized drawlayer. +-- Returns the size of one physical pixel in UIParent units. function pfUI.api.GetPerfectPixel() if pfUI.pixel then return pfUI.pixel end - if pfUI_config.appearance.border.pixelperfect == "1" then - local scale = GetCVar("useUiScale") == "1" and GetCVar("uiScale") or "1" - local resolution = GetCVar("gxResolution") - local _, _, screenwidth, screenheight = strfind(resolution, "(.+)x(.+)") - - pfUI.pixel = 768 / screenheight / scale - pfUI.pixel = pfUI.pixel > 1 and 1 or pfUI.pixel - - -- autodetect and zoom for HiDPI displays - if pfUI_config.appearance.border.hidpi == "1" then - pfUI.pixel = pfUI.pixel < .5 and pfUI.pixel * 2 or pfUI.pixel - end - else - pfUI.pixel = .7 - end + pfUI.pixel = PixelUtil.GetPixelToUIUnitFactor() / GetUIScale() pfUI.backdrop = { bgFile = "Interface\\BUTTONS\\WHITE8X8", tile = false, tileSize = 0, diff --git a/api/config.lua b/api/config.lua index 8987796c..5ee3ead3 100644 --- a/api/config.lua +++ b/api/config.lua @@ -129,9 +129,7 @@ function pfUI:LoadConfig() pfUI:UpdateConfig("appearance", "border", "color", "0.2,0.2,0.2,1") pfUI:UpdateConfig("appearance", "border", "shadow", "0") pfUI:UpdateConfig("appearance", "border", "shadow_intensity", ".35") - pfUI:UpdateConfig("appearance", "border", "pixelperfect", "1") pfUI:UpdateConfig("appearance", "border", "force_blizz", "0") - pfUI:UpdateConfig("appearance", "border", "hidpi", "1") pfUI:UpdateConfig("appearance", "border", "default", "3") pfUI:UpdateConfig("appearance", "border", "nameplates", "-1") pfUI:UpdateConfig("appearance", "border", "actionbars", "-1") diff --git a/init/modules.xml b/init/modules.xml index febafbdc..bfb2ece6 100644 --- a/init/modules.xml +++ b/init/modules.xml @@ -54,7 +54,6 @@ - diff --git a/modules/firstrun.lua b/modules/firstrun.lua index 072d408e..1f5c46e2 100644 --- a/modules/firstrun.lua +++ b/modules/firstrun.lua @@ -136,17 +136,19 @@ pfUI:RegisterModule("firstrun", function () local f = CreateFirstRunPage() f.text:SetText(T["A new installation of |cff33ffccpf|rUI ships with 4 prebuilt design profiles. Click below if you wish to load one of these profiles."]) + local function LoadProfile(name) + _G["pfUI_config"] = CopyTable(pfUI_profiles[name]) + pfUI_init.selected_profile = name + pfUI:LoadConfig() + ReloadUI() + end + f.Modern = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") f.Modern:SetSize(120, 20) f.Modern:SetPoint("BOTTOM", -65, 100) f.Modern:SetTextColor(1,1,1) f.Modern:SetText("Modern") - f.Modern:SetScript("OnClick", function() - _G["pfUI_config"] = CopyTable(pfUI_profiles["Modern"]) - pfUI_init.selected_profile = "Modern" - pfUI:LoadConfig() - ReloadUI() - end) + f.Modern:SetScript("OnClick", function() LoadProfile("Modern") end) SkinButton(f.Modern) f.Nostalgia = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") @@ -154,12 +156,7 @@ pfUI:RegisterModule("firstrun", function () f.Nostalgia:SetPoint("BOTTOM", 65, 100) f.Nostalgia:SetTextColor(1,1,1) f.Nostalgia:SetText("Nostalgia") - f.Nostalgia:SetScript("OnClick", function() - _G["pfUI_config"] = CopyTable(pfUI_profiles["Nostalgia"]) - pfUI_init.selected_profile = "Nostalgia" - pfUI:LoadConfig() - ReloadUI() - end) + f.Nostalgia:SetScript("OnClick", function() LoadProfile("Nostalgia") end) SkinButton(f.Nostalgia) f.Legacy = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") @@ -167,12 +164,7 @@ pfUI:RegisterModule("firstrun", function () f.Legacy:SetPoint("BOTTOM", 65, 75) f.Legacy:SetTextColor(1,1,1) f.Legacy:SetText("Legacy") - f.Legacy:SetScript("OnClick", function() - _G["pfUI_config"] = CopyTable(pfUI_profiles["Legacy"]) - pfUI_init.selected_profile = "Legacy" - pfUI:LoadConfig() - ReloadUI() - end) + f.Legacy:SetScript("OnClick", function() LoadProfile("Legacy") end) SkinButton(f.Legacy) f.Slim = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") @@ -180,12 +172,7 @@ pfUI:RegisterModule("firstrun", function () f.Slim:SetPoint("BOTTOM", -65, 75) f.Slim:SetTextColor(1,1,1) f.Slim:SetText("Slim") - f.Slim:SetScript("OnClick", function() - _G["pfUI_config"] = CopyTable(pfUI_profiles["Slim"]) - pfUI_init.selected_profile = "Slim" - pfUI:LoadConfig() - ReloadUI() - end) + f.Slim:SetScript("OnClick", function() LoadProfile("Slim") end) SkinButton(f.Slim) f.Slider = CreateFrame("Slider", "pfFirstRunWizardScaleSlider", f, "OptionsSliderTemplate") @@ -196,14 +183,14 @@ pfUI:RegisterModule("firstrun", function () f.Slider:SetSize(240, 20) f.Slider:SetPoint("BOTTOM", 0, 50) f.Slider:SetOrientation('HORIZONTAL') - f.Slider:SetMinMaxValues(0.5, 2.0) + -- the game drops a uiScale under 0.64 for its automatic scale at login + f.Slider:SetMinMaxValues(0.64, 2.0) f.Slider:SetValue(UIParent:GetScale()) f.Slider:SetScript("OnMouseUp", function() local scale = round(this:GetValue(),2) SetCVar("uiScale", scale) SetCVar("useUiScale", 1) - UIParent:SetScale(scale) this:SetValue(scale) end) diff --git a/modules/gui.lua b/modules/gui.lua index 77a325b7..03397952 100644 --- a/modules/gui.lua +++ b/modules/gui.lua @@ -130,7 +130,7 @@ pfUI:RegisterModule("gui", function () category = {} category[config] = tostring(GetCVar(config)) ufunc = function() - SetCVar(this:GetParent().config, this:GetParent().category[config]) + SetCVar(config, category[config]) end end @@ -881,14 +881,6 @@ pfUI:RegisterModule("gui", function () "35:35", "40:40", }, - ["scaling"] = { - "0:" .. T["Off"], - "4:" .. T["Huge (PixelPerfect)"], - "5:" .. T["Large"], - "6:" .. T["Medium"], - "7:" .. T["Small"], - "8:" .. T["Tiny (PixelPerfect)"], - }, ["abbrevnum"] = { "0:" .. T["Full Numbers (4250)"], "1:" .. T["Abbreviate 2 Decimals (4.25k)"], @@ -1508,7 +1500,24 @@ pfUI:RegisterModule("gui", function () CreateConfig(nil, T["Settings"], nil, nil, "header") CreateConfig(nil, T["Language"], C.global, "language", "dropdown", pfUI.gui.dropdowns.languages) - CreateConfig(U["pixelperfect"], T["Enable UI-Scale"], C.global, "pixelperfect", "dropdown", pfUI.gui.dropdowns.scaling) + -- the game's own scale options, as in its Video Options; the list keeps + -- a value set there that is none of these steps + CreateConfig(nil, T["Use UI-Scale"], "CVAR", "useUiScale", "checkbox") + CreateConfig(nil, T["UI-Scale"], "CVAR", "uiScale", "dropdown", function() + local current = GetCVar("uiScale") + local values, found = {}, nil + for _, scale in ipairs({ .64, .65, .7, .75, .8, .85, .9, .95, 1, 1.1, 1.2, 1.3, 1.4, 1.5 }) do + if math.abs(scale - tonumber(current)) < .001 then + found = true + table.insert(values, current .. ":" .. scale) + else + table.insert(values, tostring(scale)) + end + end + if not found then table.insert(values, 1, current .. ":" .. round(tonumber(current), 2)) end + return values + end) + CreateConfig(nil, string.format(T["Pixel Perfect UI-Scale: %s (Overrides UI-Scale)"], round(PixelUtil.GetPixelToUIUnitFactor(), 2)), C.global, "pixelperfect", "checkbox") CreateConfig(nil, T["Use Original Game Fonts"], C.global, "font_blizzard", "checkbox") CreateConfig(nil, T["Enable Region Compatible Font"], C.global, "force_region", "checkbox") CreateConfig(nil, T["Standard Text Font"], C.global, "font_default", "dropdown", pfUI.gui.dropdowns.fonts) @@ -1585,8 +1594,6 @@ pfUI:RegisterModule("gui", function () CreateConfig(nil, T["Frame Shadow Intensity"], C.appearance.border, "shadow_intensity", "dropdown", pfUI.gui.dropdowns.uf_debuff_indicator_size) CreateConfig(nil) -- spacer CreateConfig(nil, T["Force Blizzard Borders (|cffffaaaaExperimental|r)"], C.appearance.border, "force_blizz", "checkbox") - CreateConfig(nil, T["Enable Pixel Perfect Borders"], C.appearance.border, "pixelperfect", "checkbox") - CreateConfig(nil, T["Scale Border On HiDPI Displays"], C.appearance.border, "hidpi", "checkbox") CreateConfig(nil) -- spacer CreateConfig(nil, T["Global Border Size"], C.appearance.border, "default", "dropdown", pfUI.gui.dropdowns.border) CreateConfig(nil, T["Action Bar Border Size"], C.appearance.border, "actionbars", "dropdown", pfUI.gui.dropdowns.border) diff --git a/modules/pixelperfect.lua b/modules/pixelperfect.lua deleted file mode 100644 index 872b5d37..00000000 --- a/modules/pixelperfect.lua +++ /dev/null @@ -1,43 +0,0 @@ -pfUI:RegisterModule("pixelperfect", function () - -- pre-calculated min values - local statics = { - [4] = 1.4222222222222, - [5] = 1.1377777777778, - [6] = 0.94814814814815, - [7] = 0.81269841269841, - [8] = 0.71111111111111, - } - - -- pixel perfect - local function pixelperfect() - local conf = tonumber(C.global.pixelperfect) - if conf < 4 then - -- restore gamesettings - local scale = GetCVar("uiScale") - local use = GetCVar("useUiScale") - - if use == 1 then - UIParent:SetScale(tonumber(use)) - else - UIParent:SetScale(.9) - end - else - local scale = conf and statics[conf] or 1 - - SetCVar("uiScale", scale) - SetCVar("useUiScale", 1) - - UIParent:SetScale(scale) - end - end - - -- pixelperfect: native UIScale listener - if tonumber(C.global.pixelperfect) > 0 then - pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", pixelperfect) - pixelperfect() - end - - pfUI.pixelperfect = { - UpdateConfig = pixelperfect - } -end) diff --git a/pfUI.lua b/pfUI.lua index 6b1fe21d..ea9d3d0d 100644 --- a/pfUI.lua +++ b/pfUI.lua @@ -392,6 +392,10 @@ pfUI:SetScript("OnEvent", function() SetupConfigEnvironment() pfUI:UpdateFonts() + -- scale UIParent before the modules size their borders from it + pfUI.api.UpdateUIScale() + pfUI.events:RegisterFrameEventAndCallback("UI_SCALE_CHANGED", pfUI.api.UpdateUIScale) + -- load modules for _, m in pairs(this.modules) do if not ( pfUI_config["disabled"] and pfUI_config["disabled"][m] == "1" ) then