Navigation menu
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
WoW
Talk
English
Views
Read
Edit
History
More
Search
Navigation
Home
Random page
Help using wiki
Editions
for WoW
for WildStar
for Solar2D
Documentation
for WoW
for WildStar
Reference
WoW
⦁ FrameXML
⦁ AddOns
⦁ API
⦁ WoW Lua
WildStar
⦁ AddOns
⦁ API
⦁ WildStar Lua
Engine
Tools
What links here
Related changes
Special pages
Page information
Site
Recent Changes
Editing
WoW:Creating GUI configuration options
(section)
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Making your config frame == Now that your mod is using your SavedVariable, and is both loading it's settings from it (or using the defaults), you need a configuration frame to allow users to modify their settings! There are many popular ways of doing this, you can create slash commands (learn more at [[HOWTO: Create a Slash Command]]), a right click menu, but for now we will stay simple, and just have a frame popup when you use myAddons to display the options. From inside the game, you can hit the 'ESCAPE' key and chose the 'Addons' item to have myAddons open. From there you can click on the name for your addon, and then click the 'Options' button on the bottom right. But it won't open your options right now, because you haven't made the frame yet! === config frame .xml === ==== Basic Frame with Backdrop ==== Let's flesh out a basic config frame: '''myClockConfigFrame.xml''' <Ui ...> <Script file="myClockConfigFrame.lua"/> <Frame name="myClockConfigFrame" toplevel="true" parent="UIParent" frameStrata="DIALOG" hidden="true" enableMouse="true"> <Size><AbsDimension x="260" y="280"/></Size> <Anchors><Anchor point="CENTER"/></Anchors> <!-- A nice backdrop --> <Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true"> <BackgroundInsets> <AbsInset left="11" right="12" top="12" bottom="11"/> </BackgroundInsets> <TileSize><AbsValue val="32"/></TileSize> <EdgeSize><AbsValue val="32"/></EdgeSize> </Backdrop> </Frame> </Ui> We now have a config frame, and if you go in-game you can see it in all it's splendor. Feel free to make it any size, and the ANCHOR point="CENTER" will make sure it is dead center on the screen no matter the resolution. You'll probably want some kind of title on it to say what mod's options it is, so here's some Layers info to do that: '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Backdrop ...> ... </Backdrop> <Layers> <Layer level="ARTWORK"> <Texture file="Interface\DialogFrame\UI-DialogBox-Header"> <Size><AbsDimension x="256" y="64"/></Size> <Anchors> <Anchor point="TOP"> <Offset><AbsDimension x="0" y="12"/></Offset> </Anchor> </Anchors> </Texture> </Layer> <Layer level="OVERLAY"> <FontString inherits="GameFontNormal" text="Clock Config"> <Anchors> <Anchor point="TOP" relativeTo="$parent"></Anchor> </Anchors> </FontString> </Layer> </Layers> </Frame> ... ==== Adding Close and Default Buttons ==== That should make a small title box appear, and you'll notice the FontString's text attribute is set to "Clock Config" -- you can change this to anything you want. If you're doing [[localization (ui)]], maybe even a constant! You might notice that once you display your config frame, there's no way to get rid of it! Let's fix that right away by adding a `Close' button: '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Frames> ... <Button name="$parentButtonClose" inherits="OptionsButtonTemplate" text="Close"> <Anchors> <Anchor point="BOTTOMRIGHT"> <Offset><AbsDimension x="-12" y="16"/></Offset> </Anchor> </Anchors> <Scripts> <OnClick> myClockConfigFrame:Hide(); </OnClick> </Scripts> </Button> ... </Frames> ... </Frame ...> ... This button, which you'll notice is anchored at the bottom right of the config frame, simply tells our configuration frame to hide. While we're at it, let's add a defaults button in the bottom left of the frame. '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Frames> ... <Button name="$parentButtonToDefault" inherits="OptionsButtonTemplate" text="Defaults"> <Anchors> <Anchor point="BOTTOMLEFT"> <Offset><AbsDimension x="13" y="16"/></Offset> </Anchor> </Anchors> <Scripts> <OnClick> grokClock_ConfigToDefault(); </OnClick> </Scripts> </Button> ... </Frames> ... </Frame ...> ... You'll notice all we really had to do here was call our ConfigToDefault function we made in 'myClockIndicatorFrame.lua' -- it will take care of updating our addon for us! Now we should be able to undo any damage should we mess around with our mod's config settings. ==== Checkboxes and Sliders ==== With most of the graphical frame stuff out of the way, it's time to add our checkboxes, and a slider for the offset (Dropdown menus are a lot more complicated, so this HOWTO won't be covering that). Your basic checkbox config will look like: '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Frames> ... <CheckButton name="$parentCheckButtonOn" inherits="OptionsCheckButtonTemplate"> <Anchors> <Anchor point="TOPLEFT" relativeTo="$parent"> <Offset><AbsDimension x="20" y="-30"/></Offset> </Anchor> </Anchors> <Scripts> <OnLoad> getglobal(this:GetName().."Text"):SetText("On"); </OnLoad> <OnClick> myClockConfigFrameOption_OnClick(); </OnClick> </Scripts> </CheckButton> ... </Frames> ... </Frame ...> ... You'll notice I'm using the '$parent' and 'this' variables here to make this code generic, able to be used anywhere. If this was the 2nd checkbox, my Anchor relativeTo would be '$parentCheckButtonOn', and so forth, so that each item in the config dialog was just a bit bellow the others. Of course you could use absolute positioning by just getting rid of the 'relativeTo' altogether. You should also see that the CheckButton has a OnLoad to set its text, since this will be an automatically created FontString. Again I use 'this:GetName().."Text"' to make this code generic. I've set the text to "On" in this case, but you can change this to whatever you want, even a [[localized (ui)]] variable! The OnClick simply loads a lua function, but it is important to note that we will use this function for '''ALL''' our CheckButtons. That's right, we can use the same function for all our CheckButton's! In our case we'll need to repeat this CheckButton xml code twice, once for 'on' and again for 'time24'. So go ahead and try to create another checkbox. Watch out for the offset! Look at the slider example bellow for how the offset should look after the 1rst item. Here's what our slider code might look like: '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Frames> ... <Slider name="$parentSliderOffset" inherits="OptionsSliderTemplate"> <Size> <AbsDimension x="220" y="16"/> </Size> <Anchors> <Anchor point="TOPLEFT" relativeTo="$parentCheckButtonTime24"> <Offset><AbsDimension x="0" y="-40"/></Offset> </Anchor> </Anchors> <Scripts> <OnLoad> getglobal(this:GetName().."Text"):SetText("Offset"); getglobal(this:GetName().."High"):SetText("12"); getglobal(this:GetName().."Low"):SetText("-12"); this:SetMinMaxValues(-12,12); this:SetValueStep(1); </OnLoad> <OnValueChanged> grokClockConfigFrameOption_OnClick(); </OnValueChanged> </Scripts> </Slider> ... </Frames> ... </Frame> ... You'll again notice that we're using the Anchor relativeTo on the last checkbox, which will be $parentCheckButtonTime24. We're again dynamically getting the FontStrings that WoW will create for us, like the 'Text' one set to "Offset". As well, because this is a slider, we have "High" and "Low" FontStrings, have to set the minimum and maximum values the slider has, and how many values are added or subtracted when you move the slider. What will most surprise you is that.. yes... we can still use that option function for our slider too! One function for all the basic config options! ==== Frame Scripts ==== It's also important that all our current settings are loaded into our config frame, and since they might change when we use a slash command or something, the best way would be to use a OnShow event. '''within myClockConfigFrame.xml''' ... <Frame ...> ... <Scripts> <OnShow> myClockConfigFrame_OnShow(); </OnShow> </Scripts> ... </Frame> ... === config frame .lua === Our lua file for the config frame then breaks down into just 2 functions, one for when the frame is shown, the other for when an option in the config frame (like a checkbox, or a slider is moved) changes. '''within myClockConfigFrame.lua''' -- OnShow function myClockConfigFrame_OnShow() -- make sure our profile has been loaded if ( not myClock_variablesLoaded ) then -- config not loaded this:Hide(); -- hide our config pane return; end -- read settings from profile, and change our checkbuttons and slider to represent them getglobal(this:GetName().."CheckButtonOn"):SetChecked( myClockConfig[myClockRealm][myClockChar].on ); getglobal(this:GetName().."CheckButtonTime24"):SetChecked( myClockConfig[myClockRealm][myClockChar].time24 ); getglobal(this:GetName().."SliderOffset"):SetValue( myClockConfig[myClockRealm].offset ); end You'll notice again that we have to make sure that the profile is there (or variables loaded). The code also uses the getglobal() function to construct the names of the controls, so it doesn't matter what we called our frame. After that it's a simple matter of using SetChecked() or SetValue() with our profile settings to make our config dialog look right. The last part is making sure that when they change something in the config dialog, it changes the profile. Here's what that would look like: '''within myClockConfigFrame.lua''' -- OnClick function grokClockConfigFrameOption_OnClick() -- make sure our profile has been loaded if ( not myClock_variablesLoaded ) then -- config not loaded this:GetParent():Hide(); -- hide our config pane (this is now a checkbox) return; end -- read setting out of checkbox (or slider) and put into profile -- use this:GetName() to know which checkbox was hit. if ( this:GetName() == (this:GetParent():GetName().."CheckButtonOn" ) ) then myClockConfig[myClockRealm][myClockChar].on = this:GetChecked(); -- set profile elseif ( this:GetName() == (this:GetParent():GetName().."CheckButtonTime24" ) ) then myClockConfig[myClockRealm][myClockChar].time24 = this:GetChecked(); elseif ( this:GetName() == (this:GetParent():GetName().."SliderOffset" ) ) then myClockConfig[myClockRealm].offset = this:GetValue(); end -- configuration was changed, make sure our addon changes too! -- notice our addon is changed right away, not when we hit 'done'. myClock_ConfigChange(); end Again we have a check to make sure our profile is loaded, and then a mock switch/case statement to determine which CheckButton was pressed. Once we know, it's a simple issue of using this:GetChecked() or this:GetValue() to set our profile config! At the end we make sure our main addon knows that something was changed. Alternatively you could leave out the 'myClock_ConfigChange();' of this function, and add it to the Done button OnClick event to make a Save/Cancel dialog. Generally speaking for a config people want to see the changes happen live so they can tweak them. You're done! Hopefully this provided some concrete examples on how to make a config dialog, and much thanks to Scheid for being the ginipig! You could easily go from here to make a more complex configuration pane, using tabs, multiple pages, or even using Cosmos' Khaos (another howto someday). [[Category:HOWTOs|Create GUI Config Options]]
Summary:
Please note that all contributions to AddOn Studio are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see
AddOn Studio Wiki:Copyrights
for details).
Submissions must be written by you, or copied from a public domain or similar free resource (see
AddOn Studio Wiki:Copyrights
for details).
Cancel
Editing help
(opens in new window)