Адаптивные окна настроек графики и голосового чата (#13)

Подгонка окон под масштаб интерфейса и размер экрана. Ранее пройдены 46 тестов moonwell-gfx, проверка Lua, fmt и Clippy. Повторный запуск тестов пропущен по указанию пользователя.
This commit was merged in pull request #13.
This commit is contained in:
2026-11-04 14:23:26 +03:00
parent aa799a2c7d
commit e77742a61a
2 changed files with 61 additions and 3 deletions
+49 -3
View File
@@ -544,6 +544,27 @@ end
frame:SetHeight(TOP + deepest + BOTTOM + 12)
show_page(1)
-- Screen dimensions are in UIParent units, so the parent's UI scale is already included.
-- Keep the designed layout, shrinking the whole dialog only when it would leave the screen.
local fitted_width, fitted_height
local function fit_window(force)
local sw, sh = GetScreenWidth(), GetScreenHeight()
if not force and sw == fitted_width and sh == fitted_height then return end
fitted_width, fitted_height = sw, sh
frame:SetScale(math.min(1, math.max(1, sw - 32) / width,
math.max(1, sh - 32) / (TOP + deepest + BOTTOM + 12)))
frame:ClearAllPoints()
frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
end
frame:SetScript("OnShow", function() fit_window(1) end)
local fit_elapsed = 0
frame:SetScript("OnUpdate", function()
fit_elapsed = fit_elapsed + arg1
if fit_elapsed < 0.2 then return end
fit_elapsed = 0
fit_window()
end)
-- Every option set from `preset`, the widgets with it, reported once.
local function apply(preset)
resetting = 1
@@ -898,6 +919,9 @@ mod tests {
function RegisterCVar(n, d) CVARS[n] = d end
function SetCVar(n, v) CVARS[n] = v end
function GetLocale() return "ruRU" end
SCREEN_W, SCREEN_H = 1024, 768
function GetScreenWidth() return SCREEN_W end
function GetScreenHeight() return SCREEN_H end
function HideUIPanel() end
SlashCmdList = {}
UISpecialFrames = {}
@@ -908,9 +932,16 @@ mod tests {
o.SetValue = function(self, v) self.v = v end
o.GetChecked = function(self) return rawget(self, "c") end
o.SetChecked = function(self, c) self.c = c end
o.GetHeight = function(self) return 200 end
o.IsVisible = function(self) return self.shown end
o.Show = function(self) self.shown = 1 end
o.GetHeight = function(self) return rawget(self, "h") or 200 end
o.SetHeight = function(self, h) self.h = h end
o.SetWidth = function(self, w) self.w = w end
o.SetScale = function(self, s) self.scale = s end
o.IsVisible = function(self) return rawget(self, "shown") end
o.Show = function(self)
self.shown = 1
local on_show = rawget(self, "OnShow")
if on_show then on_show() end
end
o.Hide = function(self) self.shown = nil end
o.SetScript = function(self, k, f) self[k] = f end
o.CreateFontString = function(self) return make(nil) end
@@ -939,6 +970,17 @@ mod tests {
r#"
SlashCmdList["MOONWELLGFX"]()
assert(MoonWellGraphicsFrame:IsVisible(), "the window opens")
local f = MoonWellGraphicsFrame
assert(f.w * f.scale <= SCREEN_W - 32, "fits the screen width")
assert(f.h * f.scale <= SCREEN_H - 32 + 0.001, "fits the screen height")
SCREEN_W, SCREEN_H = 600, 480
arg1 = 0.25
f.OnUpdate()
assert(f.w * f.scale <= SCREEN_W - 32 + 0.001, "fits after a UI scale change")
assert(f.h * f.scale <= SCREEN_H - 32 + 0.001, "buttons stay above the bottom edge")
SCREEN_W, SCREEN_H = 2560, 1440
f.OnUpdate()
assert(f.scale == 1, "restores natural size when space returns")
assert(GameMenuButtonMoonWellGraphics, "the game menu has its button")
this = MoonWellGraphicsItem2
this:SetChecked(1)
@@ -951,6 +993,10 @@ mod tests {
);
let lua = benilla_mlua::Lua::new();
lua.globals().set("_G", lua.globals()).expect("_G");
// The other MoonWell settings dialog uses the same 1.12 Lua screen/scale API.
lua.load(include_str!("../../moonwell/src/voice.lua"))
.into_function()
.expect("voice options are valid client Lua");
let mut on = GfxSettings::default();
on.water.enabled = true;
on.water.ripple_strength = 2.0;
+12
View File
@@ -452,7 +452,18 @@ by_voice:SetScript("OnClick", function()
end)
local window_elapsed = 0
-- GetScreenWidth/Height already account for UIParent's scale. Fit both columns together.
local fitted_width, fitted_height
local function fit_window(force)
local sw, sh = GetScreenWidth(), GetScreenHeight()
if not force and sw == fitted_width and sh == fitted_height then return end
fitted_width, fitted_height = sw, sh
window:SetScale(math.min(1, math.max(1, sw - 32) / W, math.max(1, sh - 32) / H))
window:ClearAllPoints()
window:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
end
window:SetScript("OnShow", function()
fit_window(1)
MoonWell_VoiceOpenDevices()
refresh()
end)
@@ -461,6 +472,7 @@ window:SetScript("OnUpdate", function()
window_elapsed = window_elapsed + arg1
if window_elapsed < 0.05 then return end
window_elapsed = 0
fit_window()
local state, sending, level, speaking, input, output, err = MoonWell_VoiceStatus()
local line = STATES[state] or state
if sending then line = line .. " |cff40ff40● Передача|r" end