--***************************************************************************** --* File: lua/modules/ui/dialogs/options.lua --* Author: Chris Blackwell --* Summary: Manages the options dialog --* --* Copyright © 2006 Gas Powered Games, Inc. All rights reserved. --***************************************************************************** local UIUtil = import('/lua/modules/ui/uiutil.lua') local LayoutHelpers = import('/lua/modules/maui/layouthelpers.lua') local Bitmap = import('/lua/modules/maui/bitmap.lua').Bitmap local Text = import('/lua/modules/maui/text.lua').Text local Button = import('/lua/modules/maui/button.lua').Button local MenuCommon = import('/lua/modules/ui/menus/menucommon.lua') local Group = import('/lua/modules/maui/group.lua').Group local Grid = import('/lua/modules/maui/grid.lua').Grid local Slider = import('/lua/modules/maui/slider.lua').Slider local Combo = import('/lua/modules/ui/controls/combo.lua').Combo local IntegerSlider = import('/lua/modules/maui/slider.lua').IntegerSlider local OptionsLogic = import('/lua/options/optionslogic.lua') local Tooltip = import('/lua/modules/ui/game/tooltip.lua') -- this will hold the working set of options, which won't be valid until applied local currentOptionsSet = false local currentTabButton = false local currentTabBitmap = false -- this table is keyed with the different types of controls that can be created -- each key's value is the function that actually creates the type -- the signature of the function is: fucntion(parent, optionItemData) and should return it's base control local controlTypeCreate = { toggle = function(parent, optionItemData) local combo = Combo(parent, 14, 10) combo.Width:Set(250) local itemArray = {} local default = 1 combo.keyMap = {} for index, val in optionItemData.custom.states do if currentOptionsSet[optionItemData.key] == val.key then default = index end itemArray[index] = val.text combo.keyMap[index] = val.key end combo.Key = optionItemData.default combo:AddItems(itemArray, default) combo.OnClick = function(self, index, text) currentOptionsSet[optionItemData.key] = combo.keyMap[index] if optionItemData.update then optionItemData.update(self, combo.keyMap[index]) end end return combo end, button = function(parent, optionItemData) local bg = Bitmap(parent, UIUtil.SkinnableFile('/dialogs/options/content-btn-line_bmp.dds')) bg._button = UIUtil.CreateButtonStd(bg, '/dialogs/standard-small_btn/standard-small', optionItemData.custom.text, 10, 0, 0, "UI_Opt_Mini_Button_Click", "UI_Opt_Mini_Button_Over") LayoutHelpers.AtCenterIn(bg._button, bg) bg._button.OnClick = function(self, modifiers) if optionItemData.update then optionItemData.update(self, 0) end end return bg end, slider = function(parent, optionItemData) local sliderGroup = Group(parent) sliderGroup.Width:Set(parent.Width) sliderGroup.Height:Set(parent.Height) sliderGroup._slider = false if optionItemData.custom.inc == 0 then sliderGroup._slider = Slider(sliderGroup, false, optionItemData.custom.min, optionItemData.custom.max, UIUtil.SkinnableFile('/slider02/slider_btn_up.dds'), UIUtil.SkinnableFile('/slider02/slider-back_bmp.dds')) else sliderGroup._slider = IntegerSlider(sliderGroup, false, optionItemData.custom.min, optionItemData.custom.max, optionItemData.custom.inc, UIUtil.SkinnableFile('/slider02/slider_btn_up.dds'), UIUtil.SkinnableFile('/dialogs/options/slider-back_bmp.dds')) end LayoutHelpers.AtLeftTopIn(sliderGroup._slider, sliderGroup) sliderGroup._value = UIUtil.CreateText(sliderGroup, "", 12) LayoutHelpers.RightOf(sliderGroup._value, sliderGroup._slider) sliderGroup._slider.OnValueChanged = function(self, newValue) sliderGroup._value:SetText(math.floor(tostring(newValue))) end sliderGroup._slider.OnValueSet = function(self, newValue) if optionItemData.update then optionItemData.update(self, newValue) end currentOptionsSet[optionItemData.key] = newValue end -- set initial value sliderGroup._slider:SetValue(currentOptionsSet[optionItemData.key]) return sliderGroup end, } local function CreateOption(parent, optionItemData) local bg = Bitmap(parent, UIUtil.SkinnableFile('/dialogs/options/content-box_bmp.dds')) bg._label = UIUtil.CreateText(bg, optionItemData.title, 12, UIUtil.titleFont) LayoutHelpers.AtLeftTopIn(bg._label, bg, 9, 6) bg._label._tipText = optionItemData.key bg._label.HandleEvent = function(self, event) if event.Type == 'MouseEnter' then Tooltip.CreateMouseoverDisplay(self, "options_" .. bg._label._tipText, .5, true) elseif event.Type == 'MouseExit' then Tooltip.DestroyMouseoverDisplay() end end -- this is here to help position the control --TODO get this data from layout! local controlGroup = Group(bg) LayoutHelpers.AtLeftTopIn(controlGroup, bg, 208, 5) controlGroup.Width:Set(252) controlGroup.Height:Set(24) if controlTypeCreate[optionItemData.type] then bg._control = controlTypeCreate[optionItemData.type](controlGroup, optionItemData) else LOG("Warning: Option item data [" .. optionItemData.key .. "] contains an unknown control type: " .. optionItemData.type .. ". Valid types are") for k,v in controlTypeCreate do LOG(k) end end if bg._control then LayoutHelpers.AtCenterIn(bg._control, controlGroup) end return bg end function CreateDialog(over, exitBehavior) currentOptionsSet = OptionsLogic.GetCurrent() local parent = false local dialog = false local panelArt = false -- lots of state local function KillDialog() currentTabButton = false currentTabBitmap = false if over then dialog:Destroy() else parent:Destroy() end end if over then parent = over panelArt = 'panel-ingame_bmp' else parent = UIUtil.CreateScreenGroup(GetFrame(0), "Options ScreenGroup") panelArt = 'panel-front-end_bmp' local background = MenuCommon.SetupBackground(GetFrame(0)) local exitButton = MenuCommon.CreateExitMenuButton(parent, background, "") exitButton.OnClick = function(self) KillDialog() if exitBehavior then exitBehavior() end end end dialog = Bitmap(parent, UIUtil.SkinnableFile('/dialogs/options/' .. panelArt .. '.dds')) LayoutHelpers.AtCenterIn(dialog, parent) if over then dialog.Depth:Set(GetFrame(over:GetRootFrame():GetTargetHead()):GetTopmostDepth() + 1) end -- layout buttons local okBtn = UIUtil.CreateButtonStd(dialog, '/dialogs/standard_btn/standard', "", 14, 2, 0, "UI_Opt_Yes_No", "UI_Opt_Affirm_Over") LayoutHelpers.RelativeTo(okBtn, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'l_cancel_btn', panelArt) local cancelBtn = UIUtil.CreateButtonStd(dialog, '/dialogs/standard_btn/standard', "", 14, 2, 0, "UI_Menu_Cancel_02", "UI_Opt_Affirm_Over") LayoutHelpers.RelativeTo(cancelBtn, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'l_ok_btn_up', panelArt) local applyBtn = UIUtil.CreateButtonStd(dialog, '/dialogs/standard_btn/standard', "", 14, 2, 0, "UI_Opt_Yes_No", "UI_Opt_Affirm_Over") LayoutHelpers.RelativeTo(applyBtn, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'l_apply_btn', panelArt) local resetBtn = UIUtil.CreateButtonStd(dialog, '/dialogs/standard_btn/standard', "", 14, 2, 0, "UI_Opt_Yes_No", "UI_Opt_Affirm_Over") LayoutHelpers.RelativeTo(resetBtn, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'l_reset_btn', panelArt) -- set up button logic okBtn.OnClick = function(self, modifiers) OptionsLogic.SetCurrent(currentOptionsSet) KillDialog() if exitBehavior then exitBehavior() end end cancelBtn.OnClick = function(self, modifiers) KillDialog() if exitBehavior then exitBehavior() end end applyBtn.OnClick = function(self, modifiers) OptionsLogic.SetCurrent(currentOptionsSet) end resetBtn.OnClick = function(self, modifiers) local function DoReset() OptionsLogic.ResetToDefaults() -- creating the dialog will reload the old options without saving the new ones and will reset all the controls KillDialog() CreateDialog(over, exitBehavior) end UIUtil.QuickDialog(dialog, "Are you sure you want to reset to default values?", "Yes", DoReset, "No", nil, nil, nil, true) end -- set up option grid local elementWidth, elementHeight = GetTextureDimensions(UIUtil.UIFile('/dialogs/options/content-box_bmp.dds')) local optionGrid = Grid(dialog, elementWidth, elementHeight) LayoutHelpers.RelativeTo(optionGrid, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'video_bmp', panelArt) LayoutHelpers.DimensionsRelativeTo(optionGrid, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'video_bmp') UIUtil.CreateVertScrollbarFor(optionGrid) -- set up a page function SetNewPage(tabControl) -- kill any other page if currentTabBitmap then currentTabBitmap:Destroy() currentTabBitmap = false currentTabButton:Show() end -- store the tab data for this tab for easy access local tabData = tabControl.tabData -- show the "selected" state of the tab, which hides the button and shows a bitmap currentTabButton = tabControl currentTabButton:Hide() currentTabBitmap = Bitmap(dialog, UIUtil.SkinnableFile('/dialogs/tab_btn/general_btn_selected.dds')) LayoutHelpers.AtCenterIn(currentTabBitmap, currentTabButton) local tabLabel = UIUtil.CreateText(currentTabBitmap, tabData.title, 11, UIUtil.titleFont) LayoutHelpers.AtCenterIn(tabLabel, currentTabBitmap) -- remove controls and populate grid optionGrid:DeleteAndDestroyAll(true) optionGrid:AppendCols(1, true) for index, option in tabData.items do optionGrid:AppendRows(1, true) local optCtrl = CreateOption(optionGrid, option) optionGrid:SetItem(optCtrl, 1, index, true) end optionGrid:EndBatch() end -- tab layout local prev = false local defaultTab = false -- get the tab data local options = import('/lua/options/options.lua').options local optionsOrder = import('/lua/options/options.lua').optionsOrder for index, key in optionsOrder do tabData = options[key] local curButton = UIUtil.CreateButtonStd(dialog, '/dialogs/tab_btn/general', tabData.title, 11, 0, 0, "UI_Opt_Menu_Top_Click", "UI_Opt_Menu_Top_Over") if prev then LayoutHelpers.RightOf(curButton, prev) else LayoutHelpers.RelativeTo(curButton, dialog, UIUtil.SkinnableFile('/dialogs/options/options_layout.lua'), 'l_gameplay_btn', panelArt) defaultTab = curButton end prev = curButton curButton.OnClick = function(self, modifiers) SetNewPage(self) end curButton.tabData = tabData end SetNewPage(defaultTab) end