-- Screen written by Kyzentun, so if it's confusingly advanced/simple, that's -- why. -- The names of the elements in this table will be used to know the names of -- the preferences they affect. local valtex_buttons= { CenterImageAddWidth= {"d", "a"}, CenterImageAddHeight= {"w", "s"}, CenterImageTranslateX= {"l", "j"}, CenterImageTranslateY= {"k", "i"}, } -- valtex will be used to store the actors that show the current values for -- easy access. local valtex= {} -- change_center_val is a convenience function so that things that need to -- change a value only need one line of code, and so that if the method for -- changing a value changes, it only needs to be changed here. local function change_center_val(valname, amount) local new_val= PREFSMAN:GetPreference(valname) + amount PREFSMAN:SetPreference(valname, new_val) valtex[valname]:settext(new_val) update_centering() end -- valtext_frames will store the ActorFrames that each name and value actor -- is inside. Then each ActorFrame can update widest_name and tell all the -- frames to adjust their position for the new width. This is how the text -- is reasonably centered. local valtex_frames= {} local widest_name= 0 -- valtexact is a convenience function because each preference needs the same -- actors: one for the name and buttons, and one for the value. This way, -- there are fewer lines of code, and they all behave the same. -- The value is left aligned and the name right aligned so they don't overlap. -- Normally, all text displayed should be translated by using THEME:GetString, -- but in this case, these are the exact names of the preferences, so it's -- important for people to be able to find them easily in Preferences.ini by -- recognizing the name shown on the screen. local function valtexact(name, x, y, c) return Def.ActorFrame{ InitCommand= function(self) valtex_frames[name]= self local name_w= self:GetChild("Name"):GetWidth() if name_w > widest_name then widest_name= name_w end self:y(y) for frame_name, frame in pairs(valtex_frames) do frame:playcommand("recenter") end end, recenterCommand= function(self) self:x(x + (widest_name / 2)) end, Def.BitmapText{ Font= "Common Normal", Name= "Value", InitCommand= function(self) valtex[name]= self self:x(4):settext(PREFSMAN:GetPreference(name)):horizalign(left) end, }, Def.BitmapText{ Font= "Common Normal", Name= "Name", InitCommand= function(self) self:x(-4):settext( name .. "(" .. valtex_buttons[name][1] .. " or " .. valtex_buttons[name][2] .. "): "):horizalign(right):diffuse(c) end, }, } end -- This is the callback that processes input. It ignores releases so only -- first press and repeat events are processed. It uses valtex_buttons to -- figure out what value was modified. This way, all the prefs have the same -- interface, and the definition of that interface is short and simple. -- One button to increase the value by one, one button to decrease by one. local function input(event) if event.type == "InputEventType_Release" then return false end local button= ToEnumShortString(event.DeviceInput.button) local gamebutton = event.GameButton local input_functions = { Start= function() SCREENMAN:GetTopScreen():StartTransitioningScreen("SM_GoToNextScreen") SOUND:PlayOnce(THEME:GetPathS("Common", "Start"), true) end, Back= function() SCREENMAN:GetTopScreen():Cancel() end }; if input_functions[gamebutton] then input_functions[gamebutton]() end for valname, button_set in pairs(valtex_buttons) do if button == button_set[1] then change_center_val(valname, 1) elseif button == button_set[2] then change_center_val(valname, -1) end end end -- Another convenience function, this time for a simple aligned quad. local function quaid(x, y, w, h, c, ha, va) return Def.Quad{ InitCommand= function(self) self:xy(x, y):setsize(w, h):diffuse(c):horizalign(ha):vertalign(va) end } end -- Simple colors. Note that the quads and the text are color coded: the text -- for the prefs that affect the width and the vertical quads on the sides are -- the same color. The text for the prefs that affect the height is the same -- color as the quads at the top and bottom. local red= color("#ff0000") local blue= color("#0000ff") local args= { OnCommand= function(self) SCREENMAN:GetTopScreen():AddInputCallback(input) end, -- Note that the quads are aligned. This way, they are drawn entirely -- inside the screen, and their edge starts at the edge of the screen. -- This is important because the user needs them to verify that their -- settings bring everything into view. quaid(0, 0, _screen.w, 1, red, left, top), quaid(0, _screen.h, _screen.w, 1, red, left, bottom), quaid(0, 0, 1, _screen.h, blue, left, top), quaid(_screen.w, 0, 1, _screen.h, blue, right, top), -- The text is centered to minimize the chance of some of it being cut off. valtexact("CenterImageAddHeight", _screen.cx, _screen.cy-36, red), valtexact("CenterImageAddWidth", _screen.cx, _screen.cy-12, blue), valtexact("CenterImageTranslateX", _screen.cx, _screen.cy+12, blue), valtexact("CenterImageTranslateY", _screen.cx, _screen.cy+36, red), } return Def.ActorFrame(args)