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() if self.liveSessionActive then self:LiveSession_SendCommand("undo") end 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() if self.liveSessionActive then self:LiveSession_SendCommand("redo") end 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