Reanchor dialog frame on mouse up
teelolws opened this issue ยท 14 comments
In Dialog.lua at line 87, when releasing the mouse after dragging the dialog frame, :StopMovingOrSizing() is called. This has an annoying side effect of re-anchoring the frame to a point (TOPLEFT, TOP, TOPRIGHT, etc) based on which one of those points on the screen is closest to the frame.
Ideally it would stay anchored to one of the "___LEFT" points, so that when we change tab and you resize the frame, the frame expands to the right. But if the frame got anchored to TOP or even CENTER, then it expands to the left and overlaps the PVEFrame.
The dirty workaround I came up with was to add to PGFDialog:OnMouseUp:
function PGFDialog:OnMouseUp(button)
if not PremadeGroupsFilterSettings.dialogMovable then return end
self:StopMovingOrSizing()
if button == "RightButton" then
self:ResetPosition()
else
local x, y = self:GetRect()
local x2, y2 = self:GetParent():GetRect()
self:ClearAllPoints()
self:SetPoint("TOPLEFT", self:GetParent(), "TOPLEFT", x-x2, y-y2)
end
end
I tried to implement your suggestion: a0875a3
It is a slight improvement, however it has two minor problems:
Issue 1
You already mentioned scaling. It does not work with scaling using GetRect() if one of the two frames is scaled by e.g. /run PremadeGroupsFilterDialog:SetScale(2)
. Using GetScaledRect() does not work at all, this makes the dialog jump a little bit even if not scaled at all.
Issue 2
PGF does not have the right position if I do the following:
- Press i for group finder, select premade category
- Press o for the Battle.net frame
- Type /reload
- Press i for group finder, select premade category
- Now the distance between PGF and PVEFrame is larger than it should
I also wonder if some players would like to move the window independently of PVEFrame. For example, you might want to move the PGF window to the bottom left of your screen and want it to stay there (relative to your screen) and not move with the PVEFrame.
Also I want to say a big thank your for your continued effort for this addon!
Well we could reparent it to UIParent but then we run into the reverse problem: you'll have players who want it to move with the PVEFrame.
You could add an option to settings for this, and have it reparent to UIParent instead, and in ResetPosition ignore these modifications we're talking about.
For Issue 2, I think we will need to overwrite the layout cache and save the x,y into addon settings instead. Save them OnMouseUp, restore them in ResetPosition, and wipe them in ResetPosition if keepParentOffset is false.
I don't know whats going on with GetScaledRect, its not returning the results that https://warcraft.wiki.gg/wiki/API_ScriptRegion_GetRect says it should.
self:GetRect() returns 392 241 273 278
self:GetScaledRect() returns 604 371 419 428
self:GetScale() returns 1
This is not what the docs say it should be doing.
Ok this one fixes the scaling issue: teelolws@bec788b
This one resets the anchoring to PVEFrame through a reload overwriting the layout cache per my comment earlier: teelolws@c8c0e47
To be honest I never understood how and when the frame position is persisted.
I noticed the same behavior than you did, especially after reloads or loading screens, where PGF seems to be fixed on the screen instead of being attached to the PVEFrame. So any solution is highly appreciated.
I create the PGF frame with parent PVEFrame, which makes sense imo. This seems to position the PGF frame just right.
The only time I really set a point is when the position is reset by right clicking. In this case I set my TOPLEFT to the TOPRIGHT of my parent PVEFrame.
This is after rightclicking to reset, and then reloading:
Even though you set it to TOPLEFT, it still loaded back out of the layout cache with a TOP anchor anyway.
This is from the layout cache:
Version: 1
Frame: PremadeGroupsFilterDialog
FrameLevel: 2
Anchor: TOP
X: -261
Y: -116
W: 300
H: 427
That frame isn't positioned from the layout cache until PLAYER_LOGIN, so we just need to reanchor it after PLAYER_LOGIN. A good time is to reanchor it on PVEFrame:OnShow, so at the bottom of Dialog.lua I put:
PVEFrame:HookScript("OnShow", function()
local self = PGFDialog
local x, y = self:GetRect()
local x2, y2 = self:GetParent():GetRect()
self:ClearAllPoints()
self:SetPoint("TOPLEFT", self:GetParent(), "TOPLEFT", x-x2, y-y2)
end)
Anchoring it to BOTTOMLEFT was making your resize code not work correctly, anchoring it to TOPLEFT sorted that.
Oh, that might have to use :GetScaledRect instead of :GetRect https://warcraft.wiki.gg/wiki/API_ScriptRegion_GetRect so it doesn't break if the player has another addon that changes the scale of PVEFrame or PremadeGroupsFilterDialog. I'm not sure about that as I don't run any such addon so I can't easily test it.
Just noticed it doesn't persist through reloads. It reanchors back to TOP again. Will need something similar for its position reload. I'm guessing its set in the layout cache, which is annoying to deal with.
Thanks for your two suggestions. I will consider and add them, but may take some days as I am very busy at the moment.
I'm reconsidering this one. It may not be worth the hassle. I've opted to just untick the option to move it, keep it anchored to the PVEFrame instead. The default UI just goes to too many lengths to make this difficult, imo.
Maybe you are right. Even getting it to 80% most likely creates a lot of code that is hard to understand and maintain when looking at it again in three months. Leaving it as-is might be just 50%, but also 100% simpler.
I also just tested your last version and it still does have some issues with correct positioning when using a scaling of either PVEFrame or PGF. I would drop the scaling thing alltogether. Not worth the hassle.