Skip to content

Commit

Permalink
[feat][hotfix]: Improved compatibility with LibDBIcon-1.0 minimap b…
Browse files Browse the repository at this point in the history
…uttons

- adds a `UseLibDBIcon` option available when the user has `LibDBIcon-1.0` installed which lets LibDBIcon handle the minimap button.
  - disabled by default, unless the user currently has the `lockDistance`` option enabled which attaches the minimap button to the minimap.
  - ![WowClassic_uQ41NujKUa](https://github.com/user-attachments/assets/5619a479-3c72-46f4-bf3d-f32ab9783255)
- Better aligns our minimap button with LibDBIcon-1.0 buttons if any exist.
- Minimap button can no longer be dragged off the right side of the screen when not anchored to the Minimap.
  • Loading branch information
juemrami committed Aug 20, 2024
1 parent 7d38277 commit 4f8e394
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 42 deletions.
121 changes: 80 additions & 41 deletions LFGBulletinBoard/LibGPIMinimapButton.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
local TOCNAME,Addon = ...
---@type String
local TOCNAME,
---@class Addon_LibMinimapButton: Addon_LibGPIOptions
Addon = ...
Addon.MinimapButton=Addon.MinimapButton or {}
local MinimapButton=Addon.MinimapButton
local LibDBIcon = LibStub("LibDBIcon-1.0", true)
MinimapButton.isLibDBIconAvailable = LibDBIcon ~= nil
local SavedVarHandle = Addon.OptionsBuilder.GetSavedVarHandle

local function BottomZoom(button)
local deltaX, deltaY = 0, 0
Expand All @@ -11,36 +17,43 @@ local function BottomZoom(button)
button.Lib_GPI_MinimapButton.icon:SetTexCoord( deltaX, 1 - deltaX, deltaY, 1 - deltaY)
end

-- Calculates the the angle and distance of the minimap button based on cursor position about the minimap center.
---@param button MinimapButton
local function onUpdate(button)
local mx, my = Minimap:GetCenter()
local px, py = GetCursorPosition()
local w=((Minimap:GetWidth() / 2) + 5)
local scale = Minimap:GetEffectiveScale()
px, py = px / scale, py / scale
local dx,dy= px - mx,py - my
local dist=math.sqrt(dx*dx+dy*dy)/w
px, py = (px / scale), (py / scale);
local dx, dy = (px - mx), (py - my);

-- calculate the angle of the button based on the cursor position offset from the minimap center
button.Lib_GPI_MinimapButton.db.position = math.deg(math.atan2(dy, dx)) % 360

-- calculate a distance ratio for the position of the button based on radius.
-- ie `2` means the button is located 2x the size of the radius away from the center
if button.Lib_GPI_MinimapButton.db.lockDistance then
dist=1
button.Lib_GPI_MinimapButton.db.distance = 1 -- locked the perimeter of minimap
else
if dist<1 then dist=1 elseif dist>2 then dist=2 end
local radius = (Minimap:GetWidth() / 2) + 5;
local dist = math.sqrt(dx*dx+dy*dy) / radius
button.Lib_GPI_MinimapButton.db.distance = Clamp(dist, 1, 2) -- clamp the distance ratio between 1 and 2
end

button.Lib_GPI_MinimapButton.db.distance=dist
button.Lib_GPI_MinimapButton.db.position = math.deg(math.atan2(dy, dx)) % 360
button.Lib_GPI_MinimapButton.UpdatePosition()
end

-- Handles the positioning of the minimap button when dragged around the minimap
---@param button MinimapButton
local function onDragStart(button)
button.Lib_GPI_MinimapButton.isMouseDown = true
if button.Lib_GPI_MinimapButton.db.lock==false then
button:LockHighlight()
BottomZoom(button)
button:SetScript("OnUpdate", onUpdate)
button.Lib_GPI_MinimapButton.isDraggingButton = true
end
if button.Lib_GPI_MinimapButton.db.lock then return end; -- ignore drag if position locked
button:LockHighlight()
BottomZoom(button)
button:SetScript("OnUpdate", onUpdate)
button.Lib_GPI_MinimapButton.isDraggingButton = true
GameTooltip:Hide()
end

-- Handles any cleanup after the button has finished being dragged
local function onDragStop(button)
button:SetScript("OnUpdate", nil)
button.Lib_GPI_MinimapButton.isMouseDown = false
Expand Down Expand Up @@ -76,24 +89,47 @@ local function onMouseUp(button)
button.Lib_GPI_MinimapButton.isMouseDown = false
BottomZoom(button)
end

function MinimapButton.Init(DB,Texture,DoOnClick,Tooltip)
-- use LibDBIcon when available and user enabled
if MinimapButton.isLibDBIconAvailable and DB.UseLibDBIcon then
LibDBIcon:Register(TOCNAME, {
OnClick = DoOnClick,
icon = Texture,
OnTooltipShow = Tooltip and function(tooltip)
tooltip:AddLine(Tooltip)
end or nil,
}, DB)
-- sync to our dropdown settings for the minimap button to libDBIcon functions
-- see `GBB.Popup_Minimap`
SavedVarHandle(DB, 'lock'):AddUpdateHook(function(isLocked)
LibDBIcon[isLocked and 'Lock' or 'Unlock'](LibDBIcon, TOCNAME);
end);
SavedVarHandle(DB, 'visible'):AddUpdateHook(function(isVisible)
DB.hide = not isVisible
LibDBIcon[isVisible and 'Show' or 'Hide'](LibDBIcon, TOCNAME)
end);
MinimapButton.isUsingLibDBIcon = true -- flag for early exit in `MinimapButton.UpdatePosition`
return; -- don't create our own button!
end

---@class MinimapButtonModule
MinimapButton.db=DB
MinimapButton.onClick=DoOnClick
MinimapButton.Tooltip=Tooltip
MinimapButton.isMinimapButton=true

local button = CreateFrame("Button", "Lib_GPI_Minimap_"..TOCNAME, Minimap)

MinimapButton.button=button
button.Lib_GPI_MinimapButton=MinimapButton

button:SetFrameStrata("MEDIUM")

---@class MinimapButton: Button
local button = CreateFrame('Button', TOCNAME..'MinimapButton', Minimap)
button:SetFrameStrata('MEDIUM')
button:SetSize(31, 31)
button:SetFrameLevel(8)
button:RegisterForClicks("anyUp")
button:RegisterForDrag("LeftButton")
button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight"
button:SetClampedToScreen(true) -- dont allow to be dragged outside of game window
button:SetClampRectInsets(0, -3, 0, 0) -- with 3px grace on the right side of the minimap
button.Lib_GPI_MinimapButton = MinimapButton
local overlay = button:CreateTexture(nil, "OVERLAY")
overlay:SetSize(53, 53)
overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder"
Expand All @@ -106,30 +142,31 @@ function MinimapButton.Init(DB,Texture,DoOnClick,Tooltip)
icon:SetSize(17, 17)
icon:SetTexture(Texture)
icon:SetPoint("TOPLEFT", 7, -6)

MinimapButton.icon = icon
MinimapButton.button = button
MinimapButton.isMouseDown = false
MinimapButton.isDraggingButton = false

button:SetScript("OnEnter", onEnter)
button:SetScript("OnLeave", onLeave)


button:SetScript("OnClick", onClick)

button:SetScript("OnDragStart", onDragStart)
button:SetScript("OnDragStop", onDragStop)

button:SetScript("OnMouseDown", onMouseDown)
button:SetScript("OnMouseUp", onMouseUp)
button:SetScript("OnMouseUp", onMouseUp)

if MinimapButton.db.position==nil then MinimapButton.db.position=225 end
if MinimapButton.db.distance==nil then MinimapButton.db.distance=1 end
if MinimapButton.db.visible==nil then MinimapButton.db.visible=true end
if MinimapButton.db.lock==nil then MinimapButton.db.lock=false end
if MinimapButton.db.lockDistance==nil then MinimapButton.db.lockDistance=false end


-- sync "visible" with the LibDBIcon's "hide" (incase user switches to using LibDBIcon)
SavedVarHandle(MinimapButton.db, 'visible'):AddUpdateHook(function(visible)
MinimapButton.db.hide = not visible
end);

BottomZoom(button)
MinimapButton.UpdatePosition()
end
Expand All @@ -155,12 +192,14 @@ local MinimapShapes = {
["TRICORNER-BOTTOMRIGHT"] = {false, true, true, true},
}

-- Updates the position of the minimap button based on the calculated distance and angle.
function MinimapButton.UpdatePosition()
local w = ((Minimap:GetWidth() / 2) + 10) * MinimapButton.db.distance
local h = ((Minimap:GetHeight() / 2) + 10) * MinimapButton.db.distance
--local r=math.rad(MinimapButton.db.position)
--MinimapButton.button:SetPoint("CENTER", Minimap, "CENTER", w * math.cos(r), h * math.sin(r))
local rounding=10
if MinimapButton.isUsingLibDBIcon then --[[position updates handled by LibDBIcon]] return end;

local radiusOffset = LibDBIcon and LibDBIcon.radius or 10 -- better align with any LibDBIcons.
local w = (floor(Minimap:GetWidth() / 2) + radiusOffset) * MinimapButton.db.distance
local h = (floor(Minimap:GetHeight() / 2) + radiusOffset) * MinimapButton.db.distance

local angle = math.rad(MinimapButton.db.position) -- determine position on your own
local y = math.sin(angle)
local x = math.cos(angle)
Expand All @@ -177,19 +216,19 @@ function MinimapButton.UpdatePosition()
x = x*w;
y = y*h;
else
local rounding = 10
local diagRadius = math.sqrt(2*(w)^2)-rounding
x = math.max(-w, math.min(x*diagRadius, w))
local diagRadius = math.sqrt(2*(h)^2)-rounding
y = math.max(-h, math.min(y*diagRadius, h))
end
MinimapButton.button:SetPoint("CENTER", Minimap, "CENTER", x, y)



if MinimapButton.db.visible then
MinimapButton.Show()
else
MinimapButton.Hide()
end
end
end

function MinimapButton.Show()
Expand Down
1 change: 1 addition & 0 deletions LFGBulletinBoard/Localization.lua
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ GBB.locales = {
["Cboxshowminimapbutton"]="Show minimap button",
["CboxLockMinimapButton"]="Lock minimap button position",
["CboxLockMinimapButtonDistance"]="Minimize minimap button distance",
USE_LIBDBICON = "Manage minimap button using LibDBIcon (requires /reload)",
["CboxShowTotalTime"]="Show total time instead last update",
["CboxOnDebug"]="Show debug information",
["CboxNotifyChat"]="On new request make a chat notification",
Expand Down
5 changes: 4 additions & 1 deletion LFGBulletinBoard/Options.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local TOCNAME,
---@class Addon_Options : Addon_Localization, Addon_CustomFilters, Addon_Dungeons, Addon_Tags, Addon_LibGPIOptions
---@class Addon_Options : Addon_Localization, Addon_CustomFilters, Addon_Dungeons, Addon_Tags, Addon_LibGPIOptions, Addon_LibMinimapButton
GBB= ...;
local ChannelIDs
local isClassicEra = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC
Expand Down Expand Up @@ -304,6 +304,9 @@ function GBB.OptionsInit ()
GBB.OptionsBuilder.AddCheckBoxToCurrentPanel(GBB.DB.MinimapButton,"visible",true,GBB.L["Cboxshowminimapbutton"])
GBB.OptionsBuilder.AddCheckBoxToCurrentPanel(GBB.DB.MinimapButton,"lock",false,GBB.L["CboxLockMinimapButton"])
GBB.OptionsBuilder.AddCheckBoxToCurrentPanel(GBB.DB.MinimapButton,"lockDistance",true,GBB.L["CboxLockMinimapButtonDistance"])
if GBB.MinimapButton.isLibDBIconAvailable then
GBB.OptionsBuilder.AddCheckBoxToCurrentPanel(GBB.DB.MinimapButton, 'UseLibDBIcon', false, GBB.L.USE_LIBDBICON)
end
GBB.OptionsBuilder.AddSpacerToPanel()
CheckBox("ShowTotalTime",false)
CheckBox("OrderNewTop",true)
Expand Down

0 comments on commit 4f8e394

Please sign in to comment.