You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1157 lines
42 KiB

local MDT = MDT
local L = MDT.L
local sizex, sizey = 350, 33
local AceGUI = LibStub("AceGUI-3.0")
local db
local toolbarTools = {}
local drawingActive = false
local currentTool
local objectDrawLayer = "OVERLAY"
local twipe, tinsert, tremove, tgetn, CreateFrame, tonumber, pi, max, min, atan2, abs, pairs, ipairs, GetCursorPosition, GameTooltip = table
.wipe, table.insert, table.remove, table.getn, CreateFrame, tonumber, math.pi, math.max, math.min, math.atan2,
math.abs, pairs, ipairs, GetCursorPosition, GameTooltip
---sets up the toolbar frame and the widgets in it
function MDT:initToolbar(frame)
db = MDT:GetDB()
frame.toolbar = CreateFrame("Frame", "MDTToolbarFrame", frame)
frame.toolbar:SetFrameStrata("HIGH")
frame.toolbar:SetFrameLevel(5)
frame.toolbar.tex = frame.toolbar:CreateTexture(nil, "HIGH", nil, 6)
frame.toolbar.tex:SetAllPoints()
frame.toolbar.tex:SetColorTexture(unpack(MDT.BackdropColor))
frame.toolbar.toggleButton = CreateFrame("Button", nil, frame);
frame.toolbar.toggleButton:SetFrameStrata("HIGH")
frame.toolbar.toggleButton:SetFrameLevel(6)
frame.toolbar.toggleButton:SetPoint("TOP", frame, "TOP")
frame.toolbar.toggleButton:SetSize(32, 11)
frame.toolbar.toggleButton:SetNormalTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\arrows")
frame.toolbar.toggleButton:GetNormalTexture():SetTexCoord(0, 1, 0.7, 1)
frame.toolbar:Hide()
frame.toolbar:SetScript("OnHide", function()
MDT:UpdateSelectedToolbarTool(nil)
end)
frame.toolbar.toggleButton:SetScript("OnClick", function()
if frame.toolbar:IsShown() then
frame.toolbar:Hide()
frame.toolbar.toggleButton:ClearAllPoints()
frame.toolbar.toggleButton:SetPoint("TOP", frame, "TOP")
frame.toolbar.toggleButton:GetNormalTexture():SetTexCoord(0, 1, 0.7, 1)
db.toolbarExpanded = false
else
frame.toolbar:Show()
frame.toolbar.toggleButton:ClearAllPoints()
frame.toolbar.toggleButton:SetPoint("TOP", frame.toolbar, "BOTTOM")
frame.toolbar.toggleButton:GetNormalTexture():SetTexCoord(0, 1, 0.05, 0.35)
db.toolbarExpanded = true
end
end)
frame.toolbar.widgetGroup = AceGUI:Create("SimpleGroup")
frame.toolbar.widgetGroup.frame:ClearAllPoints()
frame.toolbar.widgetGroup.frame:SetAllPoints(frame.toolbar)
if not frame.toolbar.widgetGroup.frame.SetBackdrop then
Mixin(frame.toolbar.widgetGroup.frame, BackdropTemplateMixin)
end
frame.toolbar.widgetGroup.frame:SetBackdropColor(0, 0, 0, 0)
--frame.toolbar.widgetGroup:SetWidth(350)
--frame.toolbar.widgetGroup:SetHeight(15)
--frame.toolbar.widgetGroup:SetPoint("TOP",frame.toolbar,"TOP",0,0)
frame.toolbar.widgetGroup:SetLayout("Flow")
frame.toolbar.widgetGroup.frame:SetFrameStrata("High")
frame.toolbar.widgetGroup.frame:SetFrameLevel(7)
MDT:FixAceGUIShowHide(frame.toolbar.widgetGroup, frame.toolbar)
do
--dirty hook to make widgetgroup show/hide
local originalShow, originalHide = frame.Show, frame.Hide
function frame:Show(...)
if frame.toolbar:IsShown() then
frame.toolbar.widgetGroup.frame:Show()
end
return originalShow(self, ...)
end
function frame:Hide(...)
frame.toolbar.widgetGroup.frame:Hide()
return originalHide(self, ...)
end
end
---TOOLBAR WIDGETS
local widgetWidth = 24
local widgets = {}
MDT.tempWidgets = widgets
---back
local back = AceGUI:Create("Icon")
back:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.5, 0.75, 0.55, 0.8)
back:SetCallback("OnClick", function(widget, callbackName)
self:PresetObjectStepBack()
end)
back.tooltipText = L["Undo"]
local t = back.frame:CreateTexture(nil, "ARTWORK")
back.frame:SetHighlightTexture(t)
tinsert(widgets, back)
---forward
local forward = AceGUI:Create("Icon")
forward:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.75, 1, 0.55, 0.8)
forward:SetCallback("OnClick", function(widget, callbackName)
self:PresetObjectStepForward()
end)
forward.tooltipText = L["Redo"]
tinsert(widgets, forward)
---colorPicker
local colorPicker = AceGUI:Create("ColorPicker")
--colorPicker:SetHasAlpha(true)
colorPicker:SetColor(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b, db.toolbar.color.a)
colorPicker:SetCallback("OnValueConfirmed", function(widget, callbackName, r, g, b, a)
db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b, db.toolbar.color.a = r, g, b, a
colorPicker:SetColor(r, g, b, a)
end)
colorPicker.tooltipText = L["Colorpicker"]
tinsert(widgets, colorPicker)
local sizeIndicator
---minus
local minus = AceGUI:Create("Icon")
minus:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0, 0.25, 0.5, 0.75)
minus:SetCallback("OnClick", function(widget, callbackName)
db.toolbar.brushSize = db.toolbar.brushSize - 1
if db.toolbar.brushSize < 1 then db.toolbar.brushSize = 1 end
sizeIndicator:SetText(db.toolbar.brushSize)
end)
minus.tooltipText = L["Decrease Brush Size"]
tinsert(widgets, minus)
---sizeIndicator
sizeIndicator = AceGUI:Create("EditBox")
sizeIndicator:DisableButton(true)
sizeIndicator:SetMaxLetters(2)
sizeIndicator.editbox:SetNumeric(true)
sizeIndicator:SetText(db.toolbar.brushSize)
local function updateBrushSize(size)
db.toolbar.brushSize = size
end
sizeIndicator:SetCallback("OnEnterPressed", function(widget, callback, text)
sizeIndicator:ClearFocus()
local size = tonumber(text)
updateBrushSize(size)
end)
sizeIndicator:SetCallback("OnTextChanged", function(widget, callback, text)
local size = tonumber(text)
updateBrushSize(size)
end)
--Enable mousewheel scrolling
sizeIndicator.editbox:EnableMouseWheel(true)
sizeIndicator.editbox:SetScript("OnMouseWheel", function(self, delta)
local newSize = db.toolbar.brushSize + delta
if newSize < 1 then newSize = 1 end
if newSize > 99 then newSize = 99 end
db.toolbar.brushSize = newSize
sizeIndicator:SetText(db.toolbar.brushSize)
end)
sizeIndicator.tooltipText = L["Brush Size"]
tinsert(widgets, sizeIndicator)
---plus
local plus = AceGUI:Create("Icon")
plus:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.25, 0.5, 0.5, 0.75)
plus:SetCallback("OnClick", function(widget, callbackName)
db.toolbar.brushSize = db.toolbar.brushSize + 1
sizeIndicator:SetText(db.toolbar.brushSize)
end)
plus.tooltipText = L["Increase Brush Size"]
tinsert(widgets, plus)
---pencil
local pencil = AceGUI:Create("Icon")
pencil:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0, 0.25, 0, 0.25)
toolbarTools["pencil"] = pencil
pencil:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "pencil" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("pencil") end
end)
pencil.tooltipText = L["Drawing: Freehand"]
tinsert(widgets, pencil)
---line
local line = AceGUI:Create("Icon")
line:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0, 0.25, 0.75, 1)
toolbarTools["line"] = line
line:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "line" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("line") end
end)
line.tooltipText = L["Drawing: Line"]
tinsert(widgets, line)
---arrow
local arrow = AceGUI:Create("Icon")
arrow:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.25, 0.5, 0, 0.25)
toolbarTools["arrow"] = arrow
arrow:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "arrow" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("arrow") end
end)
arrow.tooltipText = L["Drawing: Arrow"]
tinsert(widgets, arrow)
---note
local note = AceGUI:Create("Icon")
note:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.75, 1, 0, 0.25)
toolbarTools["note"] = note
note:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "note" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("note") end
end)
note.tooltipText = L["Insert Note"]
tinsert(widgets, note)
---mover
local mover = AceGUI:Create("Icon")
mover:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.5, 0.75, 0, 0.25)
toolbarTools["mover"] = mover
mover:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "mover" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("mover") end
end)
mover.tooltipText = L["Move Object"]
tinsert(widgets, mover)
---cogwheel
local cogwheel = AceGUI:Create("Icon")
cogwheel:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0, 0.25, 0.25, 0.5)
cogwheel:SetCallback("OnClick", function(widget, callbackName)
InterfaceOptionsFrame_OpenToCategory("MythicDungeonTools")
InterfaceOptionsFrame_OpenToCategory("MythicDungeonTools")
MDT:HideInterface()
end)
cogwheel.tooltipText = L["Settings"]
--tinsert(widgets,cogwheel)
---eraser
local eraser = AceGUI:Create("Icon")
eraser:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.25, 0.5, 0.25, 0.5)
toolbarTools["eraser"] = eraser
eraser:SetCallback("OnClick", function(widget, callbackName)
if currentTool == "eraser" then MDT:UpdateSelectedToolbarTool() else MDT:UpdateSelectedToolbarTool("eraser") end
end)
eraser.tooltipText = L["Drawing: Eraser"]
tinsert(widgets, eraser)
---delete
local delete = AceGUI:Create("Icon")
delete:SetImage("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons", 0.25, 0.5, 0.75, 1)
delete:SetCallback("OnClick", function(widget, callbackName)
local prompt = string.format(L["deleteAllDrawingsPrompt"], "\n", "\n", "\n")
self:OpenConfirmationFrame(450, 150, L["Delete ALL drawings"], L["Delete"], prompt, function()
self:DeletePresetObjects()
if self.liveSessionActive then self:LiveSession_SendCommand("deletePresetObjects") end
end)
end)
delete.tooltipText = L["Delete ALL drawings"]
tinsert(widgets, delete)
for k, widget in ipairs(widgets) do
widget:SetWidth(widgetWidth)
if widget.type == "EditBox" then widget:SetWidth(30) end
if widget.SetImageSize then widget:SetImageSize(20, 20) end
widget:SetCallback("OnEnter", function(widget, callbackName)
MDT:ToggleToolbarTooltip(true, widget)
end)
widget:SetCallback("OnLeave", function()
MDT:ToggleToolbarTooltip(false)
end)
frame.toolbar.widgetGroup:AddChild(widget)
end
frame.toolbar:SetSize(sizex, sizey)
frame.toolbar:ClearAllPoints()
frame.toolbar:SetPoint("TOP", frame, "TOP", 0, 0)
MDT:CreateBrushPreview(frame)
MDT:UpdateSelectedToolbarTool()
end
---TexturePool
local activeTextures = {}
local texturePool = {}
local notePoolCollection
local function getTexture()
local size = tgetn(texturePool)
if size == 0 then
return MDT.main_frame.mapPanelFrame:CreateTexture(nil, "OVERLAY")
else
local tex = texturePool[size]
tremove(texturePool, size)
tex:SetRotation(0)
tex:SetTexCoord(0, 1, 0, 1)
tex:ClearAllPoints()
tex.coords = nil
tex.points = nil
return tex
end
end
local function releaseTexture(tex)
tex:Hide()
tinsert(texturePool, tex)
end
---ReleaseAllActiveTextures
function MDT:ReleaseAllActiveTextures()
for k, tex in pairs(activeTextures) do
releaseTexture(tex)
end
twipe(activeTextures)
if notePoolCollection then notePoolCollection:ReleaseAll() end
end
---CreateBrushPreview
function MDT:CreateBrushPreview(frame)
frame.brushPreview = CreateFrame("Frame", "MythicDungeonToolsBrushPreview", UIParent)
frame.brushPreview:SetFrameStrata("HIGH")
frame.brushPreview:SetFrameLevel(4)
frame.brushPreview:SetSize(1, 1)
frame.brushPreview.tex = frame.brushPreview:CreateTexture(nil, "OVERLAY")
frame.brushPreview.tex:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\ring")
frame.brushPreview.tex:SetAllPoints()
end
---EnableBrushPreview
function MDT:EnableBrushPreview(tool)
local frame = MDT.main_frame
if tool == "mover" then return end
frame.brushPreview:Show()
frame.brushPreview:SetScript("OnUpdate", function(self, tick)
if MouseIsOver(MDTScrollFrame) and not MouseIsOver(MDTToolbarFrame) then
local x, y = GetCursorPosition()
x = x / UIParent:GetScale()
y = y / UIParent:GetScale()
self:ClearAllPoints()
self:SetPoint("CENTER", UIParent, "BOTTOMLEFT", x, y)
if tool == "eraser" then
frame.brushPreview.tex:SetVertexColor(1, 1, 1, 1)
else
frame.brushPreview.tex:SetVertexColor(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b,
db.toolbar.color.a)
end
frame.brushPreview:SetSize(30, 30)
frame.brushPreview.tex:ClearAllPoints()
frame.brushPreview.tex:SetAllPoints()
frame.brushPreview.tex:Show()
else
frame.brushPreview.tex:Hide()
end
end)
end
---DisableBrushPreview
function MDT:DisableBrushPreview()
local frame = MDT.main_frame
frame.brushPreview:Hide()
frame.brushPreview.tex:Hide()
frame.brushPreview:SetScript("OnUpdate", nil)
end
---ToggleToolbarTooltip
function MDT:ToggleToolbarTooltip(show, widget)
if not show then
GameTooltip:Hide()
else
local yOffset = -1
if widget.type == "EditBox" then yOffset = yOffset - 1 end
if widget.type == "ColorPicker" then yOffset = yOffset - 3 end
GameTooltip:SetOwner(widget.frame, "ANCHOR_BOTTOM", 0, yOffset)
GameTooltip:SetText(widget.tooltipText, 1, 1, 1, 1)
GameTooltip:Show()
end
end
---UpdateSelectedToolbarTool
---Called when a tool is selected/deselected
function MDT:UpdateSelectedToolbarTool(widgetName)
local toolbar = MDT.main_frame.toolbar
if not widgetName or (not toolbarTools[widgetName]) then
if toolbar.highlight then toolbar.highlight:Hide() end
MDT:RestoreScrollframeScripts()
MDT:DisableBrushPreview()
if drawingActive then
if currentTool == "pencil" then MDT:StopPencilDrawing() end
if currentTool == "arrow" then MDT:StopArrowDrawing() end
if currentTool == "line" then MDT:StopLineDrawing() end
if currentTool == "mover" then MDT:StopMovingDrawing() end
if currentTool == "eraser" then MDT:StopEraserDrawing() end
end
currentTool = nil
toolbar:SetScript("OnUpdate", nil)
return
end
local widget = toolbarTools[widgetName]
currentTool = widgetName
toolbar.highlight = toolbar.highlight or toolbar:CreateTexture(nil, "HIGH", nil, 7)
toolbar.highlight:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\icons")
toolbar.highlight:SetTexCoord(0.5, 0.75, 0.25, 0.5)
toolbar.highlight:SetSize(widget.frame:GetWidth(), widget.frame:GetWidth())
toolbar.highlight:ClearAllPoints()
toolbar.highlight:SetPoint("CENTER", widget.frame, "CENTER")
MDT:OverrideScrollframeScripts()
MDT:EnableBrushPreview(currentTool)
toolbar.highlight:Show()
end
---OverrideScrollframeScripts
---Take control of the map scrollframe mouse event scripts
---Called when the user starts drawing on the map
function MDT:OverrideScrollframeScripts()
local frame = MDT.main_frame
frame.scrollFrame:SetScript("OnMouseDown", function(self, button)
if button == "LeftButton" then
if currentTool == "pencil" then MDT:StartPencilDrawing() end
if currentTool == "arrow" then MDT:StartArrowDrawing() end
if currentTool == "line" then MDT:StartLineDrawing() end
if currentTool == "mover" then MDT:StartMovingObject() end
if currentTool == "eraser" then MDT:StartEraserDrawing() end
end
if button == "RightButton" then
local scrollFrame = MDT.main_frame.scrollFrame
if scrollFrame.zoomedIn then
scrollFrame.panning = true;
scrollFrame.cursorX, scrollFrame.cursorY = GetCursorPosition()
end
scrollFrame.oldX = scrollFrame.cursorX
scrollFrame.oldY = scrollFrame.cursorY
end
end)
frame.scrollFrame:SetScript("OnMouseUp", function(self, button)
if button == "LeftButton" then
if currentTool == "pencil" then MDT:StopPencilDrawing() end
if currentTool == "arrow" then MDT:StopArrowDrawing() end
if currentTool == "line" then MDT:StopLineDrawing() end
if currentTool == "mover" then MDT:StopMovingObject() end
if currentTool == "eraser" then MDT:StopEraserDrawing() end
if currentTool == "note" then MDT:StartNoteDrawing() end
end
if button == "RightButton" then
local scrollFrame = MDT.main_frame.scrollFrame
if scrollFrame.panning then scrollFrame.panning = false end
--only ping if we didnt pan
if scrollFrame.oldX == scrollFrame.cursorX or scrollFrame.oldY == scrollFrame.cursorY then
local x, y = MDT:GetCursorPosition()
MDT:PingMap(x, y)
local sublevel = MDT:GetCurrentSubLevel()
if MDT.liveSessionActive then MDT:LiveSession_SendPing(x, y, sublevel) end
end
end
end)
--make notes draggable
if notePoolCollection then
if currentTool == "mover" then
for note, _ in pairs(notePoolCollection.pools.QuestPinTemplate.activeObjects) do
note:SetMovable(true)
note:RegisterForDrag("LeftButton")
local xOffset, yOffset
note:SetScript("OnMouseDown", function()
local currentPreset = MDT:GetCurrentPreset()
local x, y = MDT:GetCursorPosition()
local scale = MDT:GetScale()
x = x * (1 / scale)
y = y * (1 / scale)
local nx = currentPreset.objects[note.objectIndex].d[1]
local ny = currentPreset.objects[note.objectIndex].d[2]
xOffset = x - nx
yOffset = y - ny
end)
note:SetScript("OnDragStart", function()
note:StartMoving()
end)
note:SetScript("OnDragStop", function()
note:StopMovingOrSizing()
local x, y = MDT:GetCursorPosition()
local scale = MDT:GetScale()
x = x * (1 / scale)
y = y * (1 / scale)
local currentPreset = MDT:GetCurrentPreset()
currentPreset.objects[note.objectIndex].d[1] = x - xOffset
currentPreset.objects[note.objectIndex].d[2] = y - yOffset
if MDT.liveSessionActive then MDT:LiveSession_SendNoteCommand("move", note.objectIndex, x - xOffset, y -
yOffset)
end
MDT:DrawAllPresetObjects()
end)
end
else
for note, _ in pairs(notePoolCollection.pools.QuestPinTemplate.activeObjects) do
note:SetMovable(false)
note:RegisterForDrag()
end
end
end
end
---RestoreScrollframeScripts
---Restore original functionality to the map scrollframe: Clicking on enemies, rightclick context menu
---Called when the user is done drawing on the map
function MDT:RestoreScrollframeScripts()
local frame = MDT.main_frame
frame.scrollFrame:SetScript("OnMouseDown", MDT.OnMouseDown)
frame.scrollFrame:SetScript("OnMouseUp", MDT.OnMouseUp)
--make notes not draggable
if notePoolCollection then
for note, _ in pairs(notePoolCollection.pools.QuestPinTemplate.activeObjects) do
note:SetMovable(false)
note:RegisterForDrag()
end
end
end
---returns cursor position relative to the map frame
function MDT:GetCursorPosition()
local frame = MDT.main_frame
local scrollFrame = frame.scrollFrame
local relativeFrame = UIParent --UIParent
local mapPanelFrame = MDT.main_frame.mapPanelFrame
local cursorX, cursorY = GetCursorPosition()
local mapScale = mapPanelFrame:GetScale()
local scrollH = scrollFrame:GetHorizontalScroll()
local scrollV = scrollFrame:GetVerticalScroll()
local frameX = (cursorX / relativeFrame:GetScale()) - scrollFrame:GetLeft()
local frameY = scrollFrame:GetTop() - (cursorY / relativeFrame:GetScale())
frameX = (frameX / mapScale) + scrollH
frameY = (frameY / mapScale) + scrollV
return frameX - 1, -frameY
end
---GetHighestFrameLevelAtCursor
function MDT:GetHighestFrameLevelAtCursor()
local currentSublevel = -8
for k, v in pairs(activeTextures) do
if MouseIsOver(v) and v:IsShown() and (not v.isOwn) then
local _, sublevel = v:GetDrawLayer()
currentSublevel = max(currentSublevel, sublevel + 1)
end
end
if currentSublevel > 7 then currentSublevel = 7 end
return currentSublevel
end
local nobj
---StartArrowDrawing
function MDT:StartArrowDrawing()
drawingActive = true
local frame = MDT.main_frame
local startx, starty = MDT:GetCursorPosition()
local line = getTexture()
line:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\Square_White")
line:SetVertexColor(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b, db.toolbar.color.a)
line:Show()
local arrow = getTexture()
arrow:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\triangle")
arrow:SetVertexColor(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b, db.toolbar.color.a)
line.isOwn = true
arrow.isOwn = true
tinsert(activeTextures, line)
tinsert(activeTextures, arrow)
local drawLayer = -8
---new object for storage
---d: size,lineFactor,sublevel,shown,colorstring,drawLayer,[smooth]
---l: x1,y1,x2,y2,...
---t: triangleroation
local arrowBrushSize = db.toolbar.brushSize + 8 --we want arrows to be thicker by default compared to lines
nobj = { d = { arrowBrushSize, 1, MDT:GetCurrentSubLevel(), true,
MDT:RGBToHex(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b) }, l = {} }
nobj.l = { MDT:Round(startx, 1), MDT:Round(starty, 1) }
nobj.t = {}
local scale = MDT:GetScale()
frame.toolbar:SetScript("OnUpdate", function(self, tick)
if not MouseIsOver(MDTScrollFrame) then return end
local x, y = MDT:GetCursorPosition()
local currentDrawLayer = MDT:GetHighestFrameLevelAtCursor()
drawLayer = max(drawLayer, currentDrawLayer)
if x ~= startx and y ~= starty then
DrawLine(line, MDT.main_frame.mapPanelTile1, startx, starty, x, y, (arrowBrushSize * 0.3) * scale, 1, "TOPLEFT")
nobj.l[3] = MDT:Round(x, 1)
nobj.l[4] = MDT:Round(y, 1)
end
--position arrow head
arrow:Show()
arrow:SetWidth(1 * arrowBrushSize * scale)
arrow:SetHeight(1 * arrowBrushSize * scale)
--calculate rotation
local rotation = atan2(starty - y, startx - x)
arrow:SetRotation(rotation + pi)
arrow:ClearAllPoints()
arrow:SetPoint("CENTER", MDT.main_frame.mapPanelTile1, "TOPLEFT", x, y)
arrow:SetDrawLayer(objectDrawLayer, drawLayer)
line:SetDrawLayer(objectDrawLayer, drawLayer)
nobj.d[6] = drawLayer
nobj.t[1] = rotation
end)
end
---StopArrowDrawing
function MDT:StopArrowDrawing()
local frame = MDT.main_frame
MDT:StorePresetObject(nobj)
if self.liveSessionActive then self:LiveSession_SendObject(nobj) end
frame.toolbar:SetScript("OnUpdate", nil)
for k, v in pairs(activeTextures) do
v.isOwn = nil
end
drawingActive = false
end
local startx, starty, endx, endy
---StartLineDrawing
function MDT:StartLineDrawing()
drawingActive = true
local frame = MDT.main_frame
startx, starty = MDT:GetCursorPosition()
local line = getTexture()
line:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\Square_White")
line:SetVertexColor(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b, db.toolbar.color.a)
line.isOwn = true
tinsert(activeTextures, line)
local circle1 = getTexture()
tinsert(activeTextures, circle1)
local circle2 = getTexture()
tinsert(activeTextures, circle2)
local drawLayer = -8
---new object
---d: size,lineFactor,sublevel,shown,colorstring,drawLayer,[smooth]
---l: x1,y1,x2,y2,...
nobj = { d = { db.toolbar.brushSize, 1.1, MDT:GetCurrentSubLevel(), true,
MDT:RGBToHex(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b), nil, true }, l = {} }
nobj.l = {}
local scale = MDT:GetScale()
frame.toolbar:SetScript("OnUpdate", function(self, tick)
if not MouseIsOver(MDTScrollFrame) then return end
local currentDrawLayer = MDT:GetHighestFrameLevelAtCursor()
drawLayer = max(drawLayer, currentDrawLayer)
endx, endy = MDT:GetCursorPosition()
if endx ~= startx and endy ~= starty then
DrawLine(line, MDT.main_frame.mapPanelTile1, startx, starty, endx, endy, (db.toolbar.brushSize * 0.3) * 1.1 * scale
, 1.00, "TOPLEFT")
line:SetDrawLayer(objectDrawLayer, drawLayer)
line:Show()
MDT:DrawCircle(startx, starty, (db.toolbar.brushSize * 0.3) * scale, db.toolbar.color, objectDrawLayer, drawLayer,
true, nil, circle1, true)
MDT:DrawCircle(endx, endy, (db.toolbar.brushSize * 0.3) * scale, db.toolbar.color, objectDrawLayer, drawLayer, true
, nil, circle2, true)
nobj.d[6] = drawLayer
end
end)
end
---StopLineDrawing
function MDT:StopLineDrawing()
local frame = MDT.main_frame
frame.toolbar:SetScript("OnUpdate", nil)
for k, v in pairs(activeTextures) do
v.isOwn = nil
end
--split the line into multiple parts
local d = math.sqrt((endx - startx) ^ 2 + (endy - starty) ^ 2)
local numSegments = d * 2 / (math.max(db.toolbar.brushSize, 5))
numSegments = math.max(numSegments, 1)
local x, y = startx, starty
for i = 1, numSegments do
local t = i / numSegments
local newx = startx + (endx - startx) * t
local newy = starty + (endy - starty) * t
nobj.l[4 * i - 3] = MDT:Round(x, 1)
nobj.l[4 * i - 2] = MDT:Round(y, 1)
nobj.l[4 * i - 1] = MDT:Round(newx, 1)
nobj.l[4 * i] = MDT:Round(newy, 1)
x, y = newx, newy
end
tinsert(nobj.l, MDT:Round(x, 1))
tinsert(nobj.l, MDT:Round(y, 1))
tinsert(nobj.l, MDT:Round(endx, 1))
tinsert(nobj.l, MDT:Round(endy, 1))
MDT:StorePresetObject(nobj)
if self.liveSessionActive then self:LiveSession_SendObject(nobj) end
drawingActive = false
MDT:DrawAllPresetObjects()
end
local oldx, oldy
---StartPencilDrawing
---Starts the pencil drawing script, fired on mouse down with pencil tool selected
function MDT:StartPencilDrawing()
drawingActive = true
local frame = MDT.main_frame
oldx = nil
oldy = nil
local layerSublevel = -8
local thresholdDefault = 10
---new object
---d: size,lineFactor,sublevel,shown,colorstring,drawLayer,[smooth]
---l: x1,y1,x2,y2,...
nobj = { d = { db.toolbar.brushSize, 1.1, MDT:GetCurrentSubLevel(), true,
MDT:RGBToHex(db.toolbar.color.r, db.toolbar.color.g, db.toolbar.color.b), 0, true }, l = {} }
nobj.l = {}
local lineIdx = 1
local scale = MDT:GetScale()
frame.toolbar:SetScript("OnUpdate", function(self, tick)
if not MouseIsOver(MDTScrollFrame) then return end
local currentDrawLayer = MDT:GetHighestFrameLevelAtCursor()
layerSublevel = max(layerSublevel, currentDrawLayer)
local x, y = MDT:GetCursorPosition()
local mapScale = MDT.main_frame.mapPanelFrame:GetScale()
local threshold = thresholdDefault * 1 / mapScale
if not oldx or not oldy then
oldx, oldy = x, y
return
end
if (oldx and abs(x - oldx) > threshold) or (oldy and abs(y - oldy) > threshold) then
MDT:DrawLine(oldx, oldy, x, y, (db.toolbar.brushSize * 0.3) * scale, db.toolbar.color, true, objectDrawLayer,
layerSublevel, nil, true)
nobj.d[6] = layerSublevel
nobj.l[lineIdx] = MDT:Round(oldx, 1)
nobj.l[lineIdx + 1] = MDT:Round(oldy, 1)
nobj.l[lineIdx + 2] = MDT:Round(x, 1)
nobj.l[lineIdx + 3] = MDT:Round(y, 1)
lineIdx = lineIdx + 4
oldx, oldy = x, y
end
end)
end
---StopPencilDrawing
---End the pencil drawing script, fired on mouse up with the pencil tool selected
function MDT:StopPencilDrawing()
local frame = MDT.main_frame
local x, y = MDT:GetCursorPosition()
local layerSublevel = MDT:GetHighestFrameLevelAtCursor()
local scale = MDT:GetScale()
--finish line
if x ~= oldx or y ~= oldy then
MDT:DrawLine(oldx, oldy, x, y, (db.toolbar.brushSize * 0.3) * scale, db.toolbar.color, true, objectDrawLayer,
layerSublevel)
--store it
local size = 0
for k, v in ipairs(nobj.l) do
size = size + 1
end
nobj.l[size + 1] = MDT:Round(oldx, 1)
nobj.l[size + 2] = MDT:Round(oldy, 1)
nobj.l[size + 3] = MDT:Round(x, 1)
nobj.l[size + 4] = MDT:Round(y, 1)
end
frame.toolbar:SetScript("OnUpdate", nil)
--clear own flags
for k, v in pairs(activeTextures) do
v.isOwn = nil
end
local lineCount = 0
for _, _ in pairs(nobj.l) do
lineCount = lineCount + 1
end
if lineCount > 0 then
--draw end circle, dont need to store it as we draw it when we restore the line from db
MDT:DrawCircle(x, y, db.toolbar.brushSize * 0.3 * scale, db.toolbar.color, objectDrawLayer, layerSublevel)
MDT:StorePresetObject(nobj)
--nobj will be scaled after StorePresetObject so no need to rescale again
if self.liveSessionActive then self:LiveSession_SendObject(nobj) end
end
drawingActive = false
end
---StartMovingObject
local objectIndex
local originalX, originalY
function MDT:StartMovingObject()
--we have to redraw all objects first, as the objectIndex needs to be set on every texture
MDT:DrawAllPresetObjects()
drawingActive = true
local frame = MDT.main_frame
objectIndex = MDT:GetHighestPresetObjectIndexAtCursor()
local startx, starty = MDT:GetCursorPosition()
originalX, originalY = MDT:GetCursorPosition()
frame.toolbar:SetScript("OnUpdate", function(self, tick)
if not MouseIsOver(MDTScrollFrame) then return end
local x, y = MDT:GetCursorPosition()
if x ~= startx or y ~= starty then
for j, tex in pairs(activeTextures) do
if tex.objectIndex == objectIndex then
for i = 1, tex:GetNumPoints() do
local point, relativeTo, relativePoint, xOffset, yOffset = tex:GetPoint(i)
tex:SetPoint(point, relativeTo, relativePoint, xOffset + (x - startx), yOffset + (y - starty))
end
end
end
startx, starty = MDT:GetCursorPosition()
end
end)
end
---HideAllPresetObjects
---Hide textures during rescaling
function MDT:HideAllPresetObjects()
--drawings
for _, tex in pairs(activeTextures) do
tex:Hide()
end
--notes
if notePoolCollection then
local notes = notePoolCollection.pools.QuestPinTemplate.activeObjects
for note, _ in pairs(notes) do
note:Hide()
end
end
end
---StopMovingDrawing
function MDT:StopMovingObject()
local frame = MDT.main_frame
frame.toolbar:SetScript("OnUpdate", nil)
if objectIndex then
local newX, newY = MDT:GetCursorPosition()
MDT:UpdatePresetObjectOffsets(objectIndex, originalX - newX, originalY - newY)
if self.liveSessionActive then self:LiveSession_SendObjectOffsets(objectIndex, originalX - newX, originalY - newY) end
end
objectIndex = nil
drawingActive = false
end
---GetHighestPresetObjectIndexAtCursor
function MDT:GetHighestPresetObjectIndexAtCursor()
local currentSublevel = -8
local highestTexture
for k, v in pairs(activeTextures) do
if MouseIsOver(v) and v:IsShown() then
local _, sublevel = v:GetDrawLayer()
if sublevel >= currentSublevel then
highestTexture = v
end
currentSublevel = max(currentSublevel, sublevel + 1)
end
end
if highestTexture then
return highestTexture.objectIndex
end
end
---StartEraserDrawing
local changedObjects = {}
function MDT:StartEraserDrawing()
MDT:DrawAllPresetObjects()
drawingActive = true
local frame = MDT.main_frame
local startx, starty
local scale = MDT:GetScale()
twipe(changedObjects)
frame.toolbar:SetScript("OnUpdate", function(self, tick)
if not MouseIsOver(MDTScrollFrame) then return end
local x, y = MDT:GetCursorPosition()
if x ~= startx or y ~= starty then
local highestObjectIdx = MDT:GetHighestPresetObjectIndexAtCursor()
for j, tex in pairs(activeTextures) do
if MouseIsOver(tex) and tex:IsShown() and tex.objectIndex == highestObjectIdx then --tex.coords means this is a line
tex:Hide()
if tex.coords then
local x1, y1, x2, y2 = unpack(tex.coords)
--hide circle textures of lines
for k, v in pairs(activeTextures) do
if v.points then
if (v.points[1] == x1 and v.points[2] == y1) or (v.points[1] == x2 and v.points[2] == y2) then
v:Hide()
end
end
end
--delete saved lines
local currentPreset = MDT:GetCurrentPreset()
for objectIndex, obj in pairs(currentPreset.objects) do
if objectIndex == highestObjectIdx then
for coordIdx, coord in pairs(obj.l) do
if coord * scale == x1 and obj.l[coordIdx + 1] * scale == y1 and obj.l[coordIdx + 2] * scale == x2 and
obj.l[coordIdx + 3] * scale == y2 then
for i = 1, 4 do tremove(obj.l, coordIdx) end
changedObjects[objectIndex] = obj
break
end
end
end
end
end
break
end
end
startx, starty = x, y
end
end)
end
---StopEraserDrawing
function MDT:StopEraserDrawing()
local frame = MDT.main_frame
frame.toolbar:SetScript("OnUpdate", nil)
if self.liveSessionActive then self:LiveSession_SendUpdatedObjects(changedObjects) end
MDT:DrawAllPresetObjects()
drawingActive = false
end
---StartNoteDrawing
function MDT:StartNoteDrawing()
--check if we have less than 25 notes
if notePoolCollection and notePoolCollection.pools.QuestPinTemplate.numActiveObjects > 24 then
MDT:UpdateSelectedToolbarTool()
return
end
---new object for storage
---x,y,sublevel,shown,text,n=true
local x, y = MDT:GetCursorPosition()
nobj = { d = { x, y, MDT:GetCurrentSubLevel(), true, "" } }
nobj.n = true
MDT:StorePresetObject(nobj)
if self.liveSessionActive then self:LiveSession_SendObject(nobj) end
MDT:DrawAllPresetObjects()
if not IsShiftKeyDown() then
MDT:UpdateSelectedToolbarTool()
end
end
---DrawCircle
function MDT:DrawCircle(x, y, size, color, layer, layerSublevel, isOwn, objectIndex, tex, noinsert, extrax, extray)
local circle = tex or getTexture()
if not layer then layer = objectDrawLayer end
circle:SetDrawLayer(layer, layerSublevel)
circle:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\Circle_White")
circle:SetVertexColor(color.r, color.g, color.b, color.a)
circle:SetWidth(1.1 * size)
circle:SetHeight(1.1 * size)
circle:ClearAllPoints()
circle:SetPoint("CENTER", MDT.main_frame.mapPanelTile1, "TOPLEFT", x, y)
circle:Show()
circle.isOwn = isOwn
circle.objectIndex = objectIndex
circle.points = { x, y, extrax, extray }
if not noinsert then
tinsert(activeTextures, circle)
end
end
---DrawLine
function MDT:DrawLine(x, y, a, b, size, color, smooth, layer, layerSublevel, lineFactor, isOwn, objectIndex)
local line = getTexture()
if not layer then layer = objectDrawLayer end
line:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\Square_White")
line:SetVertexColor(color.r, color.g, color.b, color.a)
DrawLine(line, MDT.main_frame.mapPanelTile1, x, y, a, b, size, lineFactor and lineFactor or 1.1, "TOPLEFT")
line:SetDrawLayer(layer, layerSublevel)
line:Show()
line.isOwn = isOwn
line.objectIndex = objectIndex
line.coords = { x, y, a, b }
tinsert(activeTextures, line)
if smooth == true then
MDT:DrawCircle(x, y, size, color, layer, layerSublevel, isOwn, objectIndex)
end
end
---DrawTriangle
function MDT:DrawTriangle(x, y, rotation, size, color, layer, layerSublevel, isOwn, objectIndex)
local triangle = getTexture()
if not layer then layer = objectDrawLayer end
triangle:SetTexture("Interface\\AddOns\\MythicDungeonTools\\Textures\\triangle")
triangle:SetVertexColor(color.r, color.g, color.b, color.a)
triangle:Show()
triangle:SetWidth(size)
triangle:SetHeight(size)
triangle:SetRotation(rotation + pi)
triangle:ClearAllPoints()
triangle:SetPoint("CENTER", MDT.main_frame.mapPanelTile1, "TOPLEFT", x, y)
triangle:SetDrawLayer(layer, layerSublevel)
triangle.isOwn = isOwn
triangle.objectIndex = objectIndex
tinsert(activeTextures, triangle)
end
local noteEditbox
--store text in nobj
local function updateNoteObjText(text, note)
local currentPreset = MDT:GetCurrentPreset()
currentPreset.objects[note.objectIndex].d[5] = text
if MDT.liveSessionActive then MDT:LiveSession_SendNoteCommand("text", note.objectIndex, text) end
end
local function deleteNoteObj(note)
local currentPreset = MDT:GetCurrentPreset()
tremove(currentPreset.objects, note.objectIndex)
if MDT.liveSessionActive then MDT:LiveSession_SendNoteCommand("delete", note.objectIndex, "0") end
MDT:DrawAllPresetObjects()
end
local function makeNoteEditbox()
local editbox = AceGUI:Create("SimpleGroup")
editbox:SetWidth(240)
editbox:SetHeight(120)
editbox.frame:SetFrameStrata("HIGH")
editbox.frame:SetFrameLevel(50)
if not editbox.frame.SetBackdrop then
Mixin(editbox.frame, BackdropTemplateMixin)
end
editbox.frame:SetBackdropColor(unpack(MDT.BackdropColor))
editbox:SetLayout("Flow")
editbox.multiBox = AceGUI:Create("MultiLineEditBox")
editbox.multiBox:SetLabel(L["Note Text:"])
editbox.multiBox:SetCallback("OnEnterPressed", function(widget, callbackName, text)
for note, _ in pairs(notePoolCollection.pools.QuestPinTemplate.activeObjects) do
if note.noteIdx == editbox.noteIdx then
note.tooltipText = text
updateNoteObjText(text, note)
break
end
end
editbox.frame:Hide()
end)
editbox.multiBox:SetWidth(240)
editbox.multiBox:SetHeight(120)
editbox.multiBox.label:Hide()
--[[ hiding the scrollbar messes up the whole editbox
editbox.multiBox.scrollBar:Hide()
editbox.multiBox.scrollBar:ClearAllPoints()
editbox.multiBox.scrollBar:SetPoint("BOTTOM", editbox.multiBox.button, "TOP", 0, 16)
editbox.multiBox.scrollBar.ScrollUpButton:SetPoint("BOTTOM", editbox.multiBox.scrollBar, "TOP",0,3)
]]
editbox.frame:Hide()
editbox:AddChild(editbox.multiBox)
MDT:FixAceGUIShowHide(editbox, nil, nil, true)
editbox.frame:SetScript("OnShow", function()
hooksecurefunc(MDT, "MouseDownHook", function() editbox.frame:Hide() end)
hooksecurefunc(MDT, "ZoomMap", function() editbox.frame:Hide() end)
end)
return editbox
end
local noteDropDown = CreateFrame("frame", "MDTNoteDropDown", nil, "UIDropDownMenuTemplate")
local currentNote
local noteMenu = {}
do
tinsert(noteMenu, {
text = L["Edit"],
notCheckable = 1,
func = function()
currentNote:OpenEditBox()
end
})
tinsert(noteMenu, {
text = " ",
notClickable = 1,
notCheckable = 1,
func = nil
})
tinsert(noteMenu, {
text = L["Delete"],
notCheckable = 1,
func = function()
deleteNoteObj(currentNote)
end
})
tinsert(noteMenu, {
text = " ",
notClickable = 1,
notCheckable = 1,
func = nil
})
tinsert(noteMenu, {
text = L["Close"],
notCheckable = 1,
func = function()
noteDropDown:Hide()
end
})
end
---DrawNote
function MDT:DrawNote(x, y, text, objectIndex)
if not notePoolCollection then
notePoolCollection = CreateFramePoolCollection()
notePoolCollection:CreatePool("Button", MDT.main_frame.mapPanelFrame, "QuestPinTemplate")
end
local scale = MDT:GetScale()
--setup
local note = notePoolCollection:Acquire("QuestPinTemplate")
note.noteIdx = notePoolCollection.pools.QuestPinTemplate.numActiveObjects
note.objectIndex = objectIndex
note:ClearAllPoints()
note:SetPoint("CENTER", MDT.main_frame.mapPanelTile1, "TOPLEFT", x, y)
note:SetSize(12 * scale, 12 * scale)
note.NormalTexture:SetSize(15 * scale, 15 * scale)
note.PushedTexture:SetSize(15 * scale, 15 * scale)
note.HighlightTexture:SetSize(15 * scale, 15 * scale)
note.Display.Icon:SetSize(16 * scale, 16 * scale)
note.NormalTexture:SetTexture("Interface/WorldMap/UI-QuestPoi-NumberIcons")
note.PushedTexture:SetTexture("Interface/WorldMap/UI-QuestPoi-NumberIcons")
note.HighlightTexture:SetTexture("Interface/WorldMap/UI-QuestPoi-NumberIcons")
note.Display.Icon:SetTexture("Interface/WorldMap/UI-QuestPoi-NumberIcons")
note.NormalTexture:SetTexCoord(0.500, 0.625, 0.375, 0.5)
note.PushedTexture:SetTexCoord(0.375, 0.500, 0.375, 0.5)
note.HighlightTexture:SetTexCoord(0.625, 0.750, 0.375, 0.5)
note.Display.Icon:SetTexCoord(QuestPOI_CalculateNumericTexCoords(note.noteIdx, QUEST_POI_COLOR_BLACK))
note.Display.Icon:Show()
note.tooltipText = text or ""
note:RegisterForClicks("AnyUp")
--click
function note:OpenEditBox()
if not noteEditbox then noteEditbox = makeNoteEditbox() end
if noteEditbox.frame:IsShown() and noteEditbox.noteIdx == note.noteIdx then
noteEditbox.frame:Hide()
else
noteEditbox.noteIdx = note.noteIdx
noteEditbox:ClearAllPoints()
noteEditbox.frame:SetPoint("TOPLEFT", note, "TOPRIGHT")
noteEditbox.frame:Show()
noteEditbox.multiBox:SetText(note.tooltipText)
noteEditbox.multiBox.button:Enable()
end
end
note:SetScript("OnClick", function(self, button, down)
if button == "LeftButton" then
CloseDropDownMenus()
self:OpenEditBox()
elseif button == "RightButton" then
currentNote = note
EasyMenu(noteMenu, noteDropDown, "cursor", 0, -15, "MENU")
if noteEditbox and noteEditbox.frame:IsShown() then
noteEditbox.frame:Hide()
end
end
end)
note:SetScript("OnEnter", function()
GameTooltip:SetOwner(UIParent, "ANCHOR_CURSOR")
GameTooltip:AddLine(note.tooltipText, 1, 1, 1, 1)
GameTooltip:Show()
end)
note:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
note:Show()
end