Thread Tools Display Modes
08-10-19, 11:27 AM   #1
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Ace3 Options: Refresh specific option after another option changes. How?

Hi Ladies and Gentleman, its me again.

Today I have a question about ace options. I have the following code:

Lua Code:
  1. position = {
  2.     type = "group",
  3.     inline = true,
  4.     order = 3,
  5.     name = LOCALE["POSITION"],
  6.     desc = LOCALE["POSITION_DESC"],
  7.     args = {
  8.         anchor = {
  9.             type = "select",
  10.             order = 1,
  11.             name = LOCALE["ANCHOR"],
  12.             desc = LOCALE["ANCHOR_MINI_MAP"],
  13.             values = CORE.Values.Anchors,
  14.             get = function()
  15.                 return LybrialMiniMap.db.profile.position.anchor;
  16.             end,
  17.             set = function(_, value)
  18.                 LybrialMiniMap.db.profile.position.anchor = value;
  19.                 LybrialMiniMap:OnUpdatePosition();
  20.             end,
  21.         },
  22.         offset = {
  23.             type = "group",
  24.             inline = true,
  25.             order = 2,
  26.             name = LOCALE["OFFSET"],
  27.             desc = LOCALE["OFFSET_DESC"],
  28.             args = {
  29.                 x = {
  30.                     type = "range",
  31.                     order = 1,
  32.                     name = LOCALE["OFFSET_X"],
  33.                     desc = LOCALE["OFFSET_X_DESC"],
  34.                     min = Minimap:GetMinOffsetX(LybrialMiniMap.db.profile.position.anchor),
  35.                     max = Minimap:GetMaxOffsetX(LybrialMiniMap.db.profile.position.anchor),
  36.                     step = 1,
  37.                     get = function()
  38.                         return LybrialMiniMap.db.profile.position.offset.x;
  39.                     end,
  40.                     set = function(_, value)
  41.                         LybrialMiniMap.db.profile.position.offset.x = value;
  42.                         LybrialMiniMap:OnUpdatePosition();
  43.                     end
  44.                 },
  45.                 y = {
  46.                     type = "range",
  47.                     order = 2,
  48.                     name = LOCALE["OFFSET_Y"],
  49.                     desc = LOCALE["OFFSET_Y_DESC"],
  50.                     min = Minimap:GetMinOffsetY(LybrialMiniMap.db.profile.position.anchor),
  51.                     max = Minimap:GetMaxOffsetY(LybrialMiniMap.db.profile.position.anchor),
  52.                     step = 1,
  53.                     get = function()
  54.                         return -LybrialMiniMap.db.profile.position.offset.y;
  55.                     end,
  56.                     set = function(_, value)
  57.                         LybrialMiniMap.db.profile.position.offset.y = -value;
  58.                         LybrialMiniMap:OnUpdatePosition();
  59.                     end
  60.                 },
  61.             },
  62.         },
  63.     },
  64. },

As you can see I have options for changing the position of my minimap. You can choose
the anchor ("TOP", "BOTTOM", "LEFT", etc.) and the x and y offset. However, for the min
and max values of the offsets I calculate the min and max x and y offset of the minimap
in relation to the anchor. Example:

Lua Code:
  1. --- Get the min x offset of the frame in relation to the UIParent or custom parent frame (if provided) at the given anchor.
  2. --- @param frame table The actual frame to get the min x offset for.
  3. --- @param anchor string The actual anchor to get the min x offset for.
  4. --- @param parent table The parent frame (optional) defaults to UIParent.
  5. local function GetMinOffsetX(frame, anchor, parent)
  6.     if (frame) then
  7.         if (anchor == "LEFT" or anchor == "TOPLEFT" or anchor == "BOTTOMLEFT") then
  8.             return 0;
  9.         elseif (anchor == "RIGHT" or anchor == "TOPRIGHT" or anchor == "BOTTOMRIGHT") then
  10.             if (parent) then
  11.                 return -(math.floor(parent:GetWidth()) - math.floor(frame:GetWidth()));
  12.             else
  13.                 return -(math.floor(SCREEN.info.width) - math.floor(frame:GetWidth()));
  14.             end
  15.         else
  16.             if (parent) then
  17.                 return -(math.floor(parent:GetWidth() / 2) - math.floor(frame:GetWidth() / 2));
  18.             else
  19.                 return -(math.floor(SCREEN.info.width / 2) - math.floor(frame:GetWidth() / 2));
  20.             end
  21.         end
  22.     end
  23. end

That means ofcourse that whenever the "anchor" option changes the offset min and max values
in the options need to get updated. How can I make the options refresh for the offsets after the anchor changed?
  Reply With Quote
08-11-19, 06:01 AM   #2
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
You have a few options, depending on how you want to code.
  1. Call AceConfigDialog-3.0's NotifyChange(appName) which is usually used if you have both a Broker button and the Interface Options panel
  2. Redraw your minimap, which you probably need to do even with the first option
  Reply With Quote
08-11-19, 07:19 AM   #3
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Originally Posted by myrroddin View Post
You have a few options, depending on how you want to code.
  1. Call AceConfigDialog-3.0's NotifyChange(appName) which is usually used if you have both a Broker button and the Interface Options panel
  2. Redraw your minimap, which you probably need to do even with the first option
Hi,

AceConfigDialog does not seem to have a NotifyChange(appName) function:
https://www.wowace.com/projects/ace3...fig-dialog-3-0

EDIT:

I guess you meant AceConfigRegistry... I tried it:

Lua Code:
  1. CONFIG:RegisterOptionsTable("LybrialUIMiniMap", LybrialUI.options.args.miniMap);

Lua Code:
  1. anchor = {
  2.     type = "select",
  3.     order = 1,
  4.     name = LOCALE["ANCHOR"],
  5.     desc = LOCALE["ANCHOR_MINI_MAP"],
  6.     values = CORE.Values.Anchors,
  7.     get = function()
  8.         return LybrialMiniMap.db.profile.position.anchor;
  9.     end,
  10.     set = function(_, value)
  11.         LybrialMiniMap.db.profile.position.anchor = value;
  12.         LybrialMiniMap:OnUpdatePosition();
  13.  
  14.         CONFIG_REGISTRY:NotifyChange("LybrialUIMiniMap");
  15.     end,
  16. },

Seems like NotifyChange has no effect at all.

Last edited by Lybrial : 08-11-19 at 10:44 AM.
  Reply With Quote
08-12-19, 03:38 AM   #4
Lybrial
A Flamescale Wyrmkin
AddOn Compiler - Click to view compilations
Join Date: Jan 2010
Posts: 120
Turned out that NotifyChange will have no effect when called from within a setter since
setting a value already leads to a GUI refresh automatically. The thing is that min and max
is only initialized once at creation. Currently there is no way to add a function here. So I need
to set the min max values manually:

Lua Code:
  1. anchor = {
  2.     type = "select",
  3.     order = 1,
  4.     name = LOCALE["ANCHOR"],
  5.     desc = LOCALE["ANCHOR_MINI_MAP"],
  6.     values = CORE.Values.Anchors,
  7.     get = function()
  8.         return LybrialMiniMap.db.profile.position.anchor;
  9.     end,
  10.     set = function(_, value)
  11.         LybrialMiniMap.db.profile.position.anchor = value;
  12.         LybrialMiniMap:OnUpdatePosition();
  13.  
  14.         LybrialUI.options.args.miniMap.args.position.args.offset.args.x.min = Minimap:GetMinOffsetX(value);
  15.         LybrialUI.options.args.miniMap.args.position.args.offset.args.x.max = Minimap:GetMaxOffsetX(value);
  16.     end,
  17. },
  Reply With Quote
08-13-19, 09:26 AM   #5
VincentSDSH
Non-Canadian Luzer!
 
VincentSDSH's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2006
Posts: 350
If I'm understanding correctly, it's something that I have to deal with in Executive Assistant.

You can look at the code in there (link in signature) to see how it's done. There's a bit of a trick to it, involving pruning and rebuilding that part of the tree so that the control reacts dynamically in the configuration. (ea_Options.lua :: ExecAssist:semiSmart_regrow() if memory serves)

In this case, after you change the 'anchor' control, you'd prune and rebuild the offset.args.x and offset.args.y controls.
__________________
AddonsExecutive Assistant User Configurable To-Do ListLegible Mail Choose the Font for Your Mail
  Reply With Quote
08-13-19, 06:31 PM   #6
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
The other idea is that each time the user changes the anchor, run the function that sets or gets the x and y offsets immediately after, within the options to change the anchor.

This means you will need to rewrite slightly:
Lua Code:
  1. -- this is the get for the anchor option code
  2. get = function()
  3.     local x, y = MyAddOn:GetXYOffsets()
  4.     -- or return GetXYOffsets() if the function is local to file scope
  5.     -- update your anchor
  6.     -- followed by updating your x, y offsets
  7. end
  8.  
  9. function:MyAddOn:GetXYOffsets()
  10.     return self.db.profile.x, self.db.profile.y -- or whatever your DB is actually
  11. end
You get the idea, I hope.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Ace3 Options: Refresh specific option after another option changes. How?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off