BelegCufea / CompassHUD

A configurable compass strip showing player's heading along with questmarkers including distance and time to arive.
https://www.curseforge.com/wow/addons/compasshud
GNU General Public License v3.0
5 stars 0 forks source link

Not saving position #5

Closed Weischbier closed 2 months ago

Weischbier commented 2 months ago

First: GREAT idea developing this. I always felt this would be a wonderful addition to any classic themed UI!!!

I ran into an issue with positioning the compass. I want it to be at the top edge of my screen. Atfer every reload it switches to this position though: https://bit.ly/3Mc5YLJ

BelegCufea commented 2 months ago

Thank you for reporting this issue. I will look into it.

BelegCufea commented 2 months ago

OK, I’ve tried every possible configuration on my 1920x1080 monitor, but I haven’t been able to replicate that behavior.

From your screenshots, though, I can see that your HUD's FOV (Degrees shown) reset as well, which should never happen. BTW, even though I haven’t mentioned it anywhere, you can manually input a value up to 360 in the box below the FOV slider.

There are only two instances in the code where the HUD position is completely reset. One is when clicking on the Reset HUD Position option in the settings, and the second is on line 1676 of the CompassHUD.lua file.

Could you try changing the code on line 1676 from:

    if Options.PositionX < 0 then

to

    if Options.PositionX == Addon.Defaults.profile.PositionX and Options.PositionY == Addon.Defaults.profile.PositionY then

If this doesn't work, I’m afraid the issue might be related to my code logic regarding higher resolutions. Unfortunately, I won’t be able to test on a larger monitor anytime soon.

Weischbier commented 2 months ago

Good morning,

I tried your suggestions, and I sadly report that didn't fix it. I'm playing on 2560x1600 resolution (that's 1440p or 2k).

But I was able to narrow it down. (maybe)

I have my own little Addon that scales the UIParent frame and some choice Interfaceframes to the appropriate scale for my screen resolution. ElvUI does the same with its Auto-Adjust feature.

And this messes with your addon. How or why is anybody's guess.

Additionally, I lowered my resolution to 1920x1200 and used the Auto-Adjust (ElvUI) feature and it happend with that resolution too.

So, yeah, I think that's the culprit. If you want to figure this out, I'll be glad to help you.

BelegCufea commented 2 months ago

OK, this might be the cause of the issue as my addon dosen't behave well when changing scaling and need to be pushed around to position well. It is usually only done once per scale change so saw it as non-issue.

From a quick look at your code, I believe you need to add a specific frame to the list for it to be affected by your addon. Does this behavior still occur if the CompassHUD frame isn't there?

By the way, are you aware there's a Scale option in CompassHUD (on the right on the screenshot)? image

Weischbier commented 2 months ago

Oh my addon is nothing fancy: it just does this https://imgur.com/a/X5iOyP9

Yes, i scale your addon to 150%. Else it'd be too small. It gets scaled because I scale UIParent and your addon is part of it, so does ElvUI. So eventually ElvUI users will run into the same issue.

I think the only solution is to save the xy coords. I'm not sure where you grab the coords because this is a really long file^^

BelegCufea commented 2 months ago

I see, the X and Y coord in WoW are bit tricky. You just don't put X and Y somewhere. It depends on different scaling factors.

Maybe if i wont make it a UIParent, it may work. Give me a second. Or hour :-)

BelegCufea commented 2 months ago

OK, It may work, but it will mess with everyones HUD position.

Just an idea. Can you put CompassHUD into Custom Frames and put the reverse of UPParent (if I read it properly it should be 1/0.54 = 1.852).

Weischbier commented 2 months ago

Did you push an update?

I looked a little and trying to get the xy information and anchor point etc.

run this script with WoWLua:

local function GetFramePositionInfo(frame)
    if not frame then return nil, "No frame provided" end
    if not frame.GetPoint then return nil, "Invalid frame object" end

    local uiScale = UIParent:GetEffectiveScale()
    local screenWidth, screenHeight = GetPhysicalScreenSize()

    local numPoints = frame:GetNumPoints()
    if numPoints == 0 then
        return nil, "Frame has no anchor points set"
    end

    local anchorInfo = {}
    for i = 1, numPoints do
        local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint(i)
        table.insert(anchorInfo, {
            point = point,
            relativeTo = relativeTo and relativeTo:GetName() or "nil",
            relativePoint = relativePoint,
            xOfs = xOfs,
            yOfs = yOfs
        })
    end

    local x, y = frame:GetCenter()
    if x and y then
        x = x * uiScale
        y = y * uiScale
        x = x - screenWidth/2
        y = y - screenHeight/2
    else
        x, y = 0, 0
    end

    return {
        x = x,
        y = y,
        uiScale = uiScale,
        screenWidth = screenWidth,
        screenHeight = screenHeight,
        anchorInfo = anchorInfo
    }
end

local function GetCompassHUDInfo()
    local compassFrame = _G["CompassHUD"]
    if not compassFrame then
        print("Error: CompassHUD frame not found. Make sure the addon is loaded and the frame exists.")
        return
    end

    local posInfo, errorMsg = GetFramePositionInfo(compassFrame)

    if posInfo then
        print("--- CompassHUD Frame Information ---")
        print("Name:", compassFrame:GetName())

        print("\nAnchor Points:")
        for i, anchor in ipairs(posInfo.anchorInfo) do
            print(string.format("  %d. %s to %s of %s (Offset: X = %.2f, Y = %.2f)",
                i, anchor.point, anchor.relativePoint, anchor.relativeTo, anchor.xOfs, anchor.yOfs))
        end
        -- Explanation: This shows all anchor points of the frame.
        -- Multiple anchor points can create complex positioning or responsive layouts.
        -- Example: "1. BOTTOM to BOTTOM of UIParent (Offset: X = 0.00, Y = 100.00)"
        --          means the bottom of CompassHUD is anchored to the bottom of the screen,
        --          then shifted 100 pixels up.

        print("\nCenter Position (relative to screen center):")
        print(string.format("  X = %.2f, Y = %.2f", posInfo.x, posInfo.y))
        -- Explanation: The frame's center position relative to the center of the screen.
        -- X: negative is left of center, positive is right of center
        -- Y: negative is below center, positive is above center

        print("\nAdditional Information:")
        print("UI Scale:", posInfo.uiScale)
        print("Screen Size:", posInfo.screenWidth, "x", posInfo.screenHeight)
        print("Frame Size:", compassFrame:GetWidth(), "x", compassFrame:GetHeight())
        print("Is Visible:", compassFrame:IsVisible())
        print("Is Shown:", compassFrame:IsShown())
        print("Number of Anchor Points:", #posInfo.anchorInfo)
    else
        print("Error getting CompassHUD frame info:", errorMsg)
    end
end

-- Run the function
GetCompassHUDInfo()

-- Understanding the output:
-- 1. Anchor Points: All points where the frame is anchored to its parent or other frames.
-- 2. Center Position: Where the frame's center is located relative to the screen center.
-- 3. Additional Information: UI scale, screen size, frame size, visibility status, and number of anchor points.

-- This information helps you understand:
-- - How CompassHUD is anchored and positioned in the UI, including complex multi-point anchoring.
-- - Its size and position relative to the screen.
-- - Whether it's currently visible in the game.
-- - How many anchor points are used, which can indicate complex or responsive positioning.

It prints me this info: image

PSA: Not 10000% certain this is the right code but it yields me results I think to be true.

BelegCufea commented 2 months ago

Nice, just put your desirable X and Y do SetPoint on the frame and run it at every login :-)

there is a macro you can use (just change the coordinates at the end. As you are using Weak auras, you can put it in custom code of On Show Action (just remove the /run):

/run CompassHUD:ClearAllPoints();CompassHUD:SetPoint("BOTTOMLEFT",UIParent,"BOTTOMLEFT",649.14,696.17)

I know it can be done and I tried it, but it will mess with everyone else saved position as the returned X and Y is Scale dependent :-( And that I do not want ... I know I should have included UIParent scale from the begining, but alas, I did not and now is too late.

BelegCufea commented 2 months ago

Was playing with WA and made following trigger.

Just use your aura you did for Compass (BTW, very nice) and make new trigger like so: image

content of the "Custom trigger" is:

function(event, ...)
    if CompassHUD then
            CompassHUD:ClearAllPoints()
            CompassHUD:SetPoint("BOTTOMLEFT",UIParent,"BOTTOMLEFT",649.14,696.17)
    end
end
Weischbier commented 2 months ago

I integrated the fix into my addon :P

Not fully done yet but i keeps the position!

BelegCufea commented 2 months ago

Nice. Sorry for the inconvenience.

Just a heads up: when changing any option, it will unfortunately reset the HUD's position. It will correct itself by your code on /reload though. I'll try to address this in the future, but for now, I’m not entirely sure how to prevent it.

I’m closing this issue for the moment. If you have any more input or run into additional problems, feel free to reopen it!