Add ability to change the anchor point for a layout, and fix a few issues around this, eg dragging layouts.

Mere [06-26-13 - 18:31]
Add ability to change the anchor point for a layout, and fix a few issues around this, eg dragging layouts.
Filename
ConfigUI.lua
ConfigUI_Layouts.lua
HealingPanelLayout.lua
RaidManagement.lua
diff --git a/ConfigUI.lua b/ConfigUI.lua
index 00c2000..1297c16 100644
--- a/ConfigUI.lua
+++ b/ConfigUI.lua
@@ -21,7 +21,10 @@ end
 function MereHealingFrames.Config.UI:CreateConfigUI()
 	-- Ask the watchdog to be quiet:
 	Command.System.Watchdog.Quiet()
-
+
+    -- Create a tooltip
+    MereHealingFrames.Config.ToolTipControl = UI.CreateFrame("SimpleTooltip", "ToolTip",  MereHealingFrames.context)
+
 	self.Config_Window = UI.CreateFrame("SimpleWindow", "Config_Window", MereHealingFrames.context)
 	self.Config_Window:SetCloseButtonVisible(true)
 	self.Config_Window:SetTitle("Mere Healing Frames, " .. MereHealingFrames.fetchVersion())
diff --git a/ConfigUI_Layouts.lua b/ConfigUI_Layouts.lua
index 73677bc..d81363b 100644
--- a/ConfigUI_Layouts.lua
+++ b/ConfigUI_Layouts.lua
@@ -222,6 +222,34 @@ function MereHealingFrames.Config.UI.Layouts.RenameLayout(currentSetName, newSet
 end


+local AnchorPoints = {
+    "TOPLEFT",
+    "TOPCENTER",
+    "TOPRIGHT",
+    "CENTERLEFT",
+    "CENTER",
+    "CENTERRIGHT",
+    "BOTTOMLEFT",
+    "BOTTOMCENTER",
+    "BOTTOMRIGHT"
+}
+
+local AnchorPointsInternal = {
+    {"TOP", "LEFT"},
+    {"TOP", "CENTER"},
+    {"TOP", "RIGHT"},
+    {"CENTER", "LEFT"},
+    {"CENTER", "CENTER"},
+    {"CENTER", "RIGHT"},
+    {"BOTTOM", "LEFT"},
+    {"BOTTOM", "CENTER"},
+    {"BOTTOM", "RIGHT"},
+}
+
+local function anchorPointToolTipText(tooltip)
+    return "The Anchor Point is the point on the layout that is fixed to the screen, as it grows it grows from this point"
+end
+
 function MereHealingFrames.Config.UI.Layouts:CreateSizingTab()
 	local topOffsetY = 5
 	self.sizing = {}
@@ -234,8 +262,23 @@ function MereHealingFrames.Config.UI.Layouts:CreateSizingTab()
 		self.layoutValues[config.layoutName]:SetCallback(function (...) MereHealingFrames.Config.UI.Layouts.ChangeValue(self, ...) end)

 		topOffsetY = topOffsetY + 25
-	end
-	return self.sizing.Frame
+    end
+
+    self.sizing.anchorLabel = UI.CreateFrame("Text", "anchorLabel", self.sizing.Frame)
+    self.sizing.anchorLabel:SetText("Anchor Point")
+    self.sizing.anchorLabel:SetPoint("TOPLEFT", self.sizing.Frame, "TOPLEFT", 5, topOffsetY)
+
+    self.sizing.anchorDropDown = UI.CreateFrame("SimpleSelect", "energyFormattingDropdown", self.sizing.Frame)
+    self.sizing.anchorDropDown:SetItems(AnchorPoints, AnchorPointsInternal)
+    self.sizing.anchorDropDown:SetPoint("TOPLEFT", self.sizing.Frame, "TOPLEFT", 130, topOffsetY)
+    self.sizing.anchorDropDown:SetBorder(1, 1, 1, 1, 1)
+    self.sizing.anchorDropDown:ResizeToFit()
+
+    self.sizing.anchorDropDown.Event.ItemSelect = function (item, value, index) MereHealingFrames.Config.UI.Layouts.ChangeAnchorPoint(self, index[1], index[2]) end
+
+    MereHealingFrames.Config.ToolTipControl:InjectEvents(self.sizing.anchorLabel, anchorPointToolTipText)
+
+    return self.sizing.Frame
 end

 local FormattingTypesInternal = {
@@ -723,7 +766,9 @@ function MereHealingFrames.Config.UI.Layouts:ChangeLayoutSelection(item)
 	for key, slider in pairs(self.layoutValues) do
 		slider:SetCurrentValue(layout[key])
 	end
-
+
+    self.sizing.anchorDropDown:SetSelectedItem(layout.AnchorPoint, true)
+
 	for role, _ in pairs(roleFilterMappings) do
 		self.filterBoxes[role]:SetCurrentValue(layout.RoleFilter[role] or false)
 	end
@@ -804,6 +849,13 @@ function MereHealingFrames.Config.UI.Layouts:ChangeValue(key, newValue)
 	self.layout:RelayPanels()
 end

+function MereHealingFrames.Config.UI.Layouts:ChangeAnchorPoint(vertical, horizontal)
+    if not self.layout then return end
+    MereHealingFrames.Debug(2, "Changing Anchor Point to %s%s", vertical, horizontal)
+
+    self.layout:ChangeAnchorPoint(vertical,horizontal)
+end
+
 MereHealingFrames.Config.UI.Layout = {}
 function MereHealingFrames.Config.UI.Layout:new (frame, layoutName, layout)
 	local this = {}
diff --git a/HealingPanelLayout.lua b/HealingPanelLayout.lua
index 42ac543..f53dee0 100644
--- a/HealingPanelLayout.lua
+++ b/HealingPanelLayout.lua
@@ -240,8 +240,8 @@ function MereHealingFrames.HealingPanelLayout:Initialize (settings)
 	self.Frame = UI.CreateFrame("Frame", "LayoutBackFrame", MereHealingFrames.context)
 	self.Frame:SetSecureMode("restricted")

-	MereHealingFrames.Debug(1, "Loading panel %s, top left %d, %d", self.Name, self.TopLeftX, self.TopLeftY)
-	self.Frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", self.TopLeftX, self.TopLeftY)
+	MereHealingFrames.Debug(1, "Loading panel %s, AnchorPoint %s, position %d, %d", self.Name, self.AnchorPoint, self.TopLeftX, self.TopLeftY)
+	self.Frame:SetPoint(self.AnchorPoint, UIParent, "TOPLEFT", self.TopLeftX, self.TopLeftY)
 	self.Frame:SetBackgroundColor(MereHealingFrames.Colours.FetchRGBA("LayoutBackground"))

 	self.Frame:SetLayer(MereHealingFrames.Layers.CalculateLayer(self.LayoutOffset, "LayoutBase"))
@@ -829,25 +829,76 @@ end
 function MereHealingFrames.HealingPanelLayout:LeftDown(...)
 	if self.DragInfo then
 		self.DragInfo.dragging = true
-		self.DragInfo.offsetX = Inspect.Mouse().x - self.Frame:GetLeft()
-		self.DragInfo.offsetY = Inspect.Mouse().y - self.Frame:GetTop()
+		self.DragInfo.offsetX = Inspect.Mouse().x - self.TopLeftX
+		self.DragInfo.offsetY = Inspect.Mouse().y - self.TopLeftY
+        self.DragInfo.LastX = self.TopLeftX
+        self.DragInfo.LastY = self.TopLeftY
 	end
 end

 function MereHealingFrames.HealingPanelLayout:MouseMove(event, x, y)
 	if (self.DragInfo and self.DragInfo.dragging) then
-		local newX = math.max(x - self.DragInfo.offsetX, 0)
-		local newY = math.max(y - self.DragInfo.offsetY, 0)
+		local newX = x - self.DragInfo.offsetX
+		local newY = y - self.DragInfo.offsetY
+        self.DragInfo.LastX = newX
+        self.DragInfo.LastY = newY

-		self.Frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", newX, newY)
+		self.Frame:SetPoint(self.AnchorPoint, UIParent, "TOPLEFT", newX, newY)
 	end
 end

 function MereHealingFrames.HealingPanelLayout:LeftUp(...)
 	if self.DragInfo then
 		self.DragInfo.dragging = false
-		self.TopLeftX = self.Frame:GetLeft()
-		self.TopLeftY = self.Frame:GetTop()
+		self.TopLeftX = self.DragInfo.LastX
+		self.TopLeftY = self.DragInfo.LastY
 	end
 end
+
+
+-- anchor is two part
+-- horizontal is TOP, CENTER, BOTTOM
+-- vertical is LEFT, CENTER, RIGHT
+-- Note I did wonder about taking the standard names, but realised that they'd all be internal till here
+function MereHealingFrames.HealingPanelLayout:ChangeAnchorPoint(horizontalAnchor, verticalAnchor)
+
+    local left, top, right, bottom = self.Frame:GetBounds()
+    local newX, newY
+    if (horizontalAnchor == "TOP") then
+        newY = top
+    elseif (horizontalAnchor == "CENTER") then
+        newY = top + ((bottom - top) / 2)
+    elseif (horizontalAnchor == "BOTTOM") then
+        newY = bottom
+    else
+    -- invalid param!
+        return
+    end
+
+    if (verticalAnchor == "LEFT") then
+        newX = left
+    elseif(verticalAnchor == "CENTER") then
+        newX = left + ((right-left) / 2)
+    elseif(verticalAnchor == "RIGHT") then
+        newX = right
+    else
+        return
+    end
+
+    local newAnchorPoint = horizontalAnchor .. verticalAnchor
+    if (newAnchorPoint == "CENTERCENTER" ) then
+        newAnchorPoint = "CENTER"
+    end
+
+    MereHealingFrames.Debug(2, "Layout Anchor point changed from %s to %s, from %d,%d to %d,%d",
+        self.AnchorPoint, newAnchorPoint, self.TopLeftX, self.TopLeftY, newX, newY)
+
+    self.Frame:ClearPoint(self.AnchorPoint)
+
+    self.TopLeftX = newX
+    self.TopLeftY = newY
+    self.AnchorPoint = newAnchorPoint
+
+    self.Frame:SetPoint(self.AnchorPoint, UIParent, "TOPLEFT", self.TopLeftX, self.TopLeftY)
+end

diff --git a/RaidManagement.lua b/RaidManagement.lua
index e013308..d0d3799 100644
--- a/RaidManagement.lua
+++ b/RaidManagement.lua
@@ -544,7 +544,7 @@ function MereHealingFrames.RaidManagement.RemoveFakes()
 			-- it's a stray so bin it
 			binnedPlayers = true
 			for layoutName, layout in pairs(MereHealingFrames.Layouts) do
-				layout:GroupLeave(unitId, playerData.specifier, true)
+				layout:GroupLeave(unitId, playerData.specifier)
             end
             playerData:delete()
 		end