WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   Lua/XML Help (https://www.wowinterface.com/forums/forumdisplay.php?f=16)
-   -   Ace3 Options: Refresh specific option after another option changes. How? (https://www.wowinterface.com/forums/showthread.php?t=57342)

Lybrial 08-10-19 11:27 AM

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?

myrroddin 08-11-19 06:01 AM

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

Lybrial 08-11-19 07:19 AM

Quote:

Originally Posted by myrroddin (Post 333147)
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.

Lybrial 08-12-19 03:38 AM

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. },

VincentSDSH 08-13-19 09:26 AM

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.

myrroddin 08-13-19 06:31 PM

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.


All times are GMT -6. The time now is 12:04 PM.

vBulletin © 2019, Jelsoft Enterprises Ltd
© 2004 - 2019 MMOUI