Quantcast

* Added basic configuration panel that allows you disable/enable plugins. Requires reload and may not work properly.

James Whitehead II [02-08-09 - 00:40]
* Added basic configuration panel that allows you disable/enable plugins.  Requires reload and may not work properly.
* Added support for AddonLoader delayed loading
Filename
Libs/tekKonfigAboutPanel.lua
Libs/tekKonfigScroll.lua
NinjaPanel.lua
NinjaPanel.toc
diff --git a/Libs/tekKonfigAboutPanel.lua b/Libs/tekKonfigAboutPanel.lua
new file mode 100644
index 0000000..98022b4
--- /dev/null
+++ b/Libs/tekKonfigAboutPanel.lua
@@ -0,0 +1,115 @@
+
+local lib, oldminor = LibStub:NewLibrary("tekKonfig-AboutPanel", 5)
+if not lib then return end
+
+
+function lib.new(parent, addonname)
+	local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
+	frame.name, frame.parent, frame.addonname = parent and "About" or addonname, parent, addonname
+	frame:Hide()
+	frame:SetScript("OnShow", lib.OnShow)
+	InterfaceOptions_AddCategory(frame)
+	return frame
+end
+
+
+local editbox = CreateFrame('EditBox', nil, UIParent)
+editbox:Hide()
+editbox:SetAutoFocus(true)
+editbox:SetHeight(32)
+editbox:SetFontObject('GameFontHighlightSmall')
+lib.editbox = editbox
+
+local left = editbox:CreateTexture(nil, "BACKGROUND")
+left:SetWidth(8) left:SetHeight(20)
+left:SetPoint("LEFT", -5, 0)
+left:SetTexture("Interface\\Common\\Common-Input-Border")
+left:SetTexCoord(0, 0.0625, 0, 0.625)
+
+local right = editbox:CreateTexture(nil, "BACKGROUND")
+right:SetWidth(8) right:SetHeight(20)
+right:SetPoint("RIGHT", 0, 0)
+right:SetTexture("Interface\\Common\\Common-Input-Border")
+right:SetTexCoord(0.9375, 1, 0, 0.625)
+
+local center = editbox:CreateTexture(nil, "BACKGROUND")
+center:SetHeight(20)
+center:SetPoint("RIGHT", right, "LEFT", 0, 0)
+center:SetPoint("LEFT", left, "RIGHT", 0, 0)
+center:SetTexture("Interface\\Common\\Common-Input-Border")
+center:SetTexCoord(0.0625, 0.9375, 0, 0.625)
+
+editbox:SetScript("OnEscapePressed", editbox.ClearFocus)
+editbox:SetScript("OnEnterPressed", editbox.ClearFocus)
+editbox:SetScript("OnEditFocusLost", editbox.Hide)
+editbox:SetScript("OnEditFocusGained", editbox.HighlightText)
+editbox:SetScript("OnTextChanged", function(self)
+	self:SetText(self:GetParent().val)
+	self:HighlightText()
+end)
+
+
+function lib.OpenEditbox(self)
+	editbox:SetText(self.val)
+	editbox:SetParent(self)
+	editbox:SetPoint("LEFT", self)
+	editbox:SetPoint("RIGHT", self)
+	editbox:Show()
+end
+
+
+local fields = {"Version", "Author", "X-Category", "X-License", "X-Email", "X-Website", "X-Credits"}
+local haseditbox = {["Version"] = true, ["X-Website"] = true, ["X-Email"] = true}
+local function HideTooltip() GameTooltip:Hide() end
+local function ShowTooltip(self)
+	GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
+	GameTooltip:SetText("Click and press Ctrl-C to copy")
+end
+function lib.OnShow(frame)
+	local notes = GetAddOnMetadata(frame.addonname, "Notes")
+
+	local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
+	title:SetPoint("TOPLEFT", 16, -16)
+	title:SetText((frame.parent or frame.addonname).." - About")
+
+	local subtitle = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	subtitle:SetHeight(32)
+	subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
+	subtitle:SetPoint("RIGHT", parent, -32, 0)
+	subtitle:SetNonSpaceWrap(true)
+	subtitle:SetJustifyH("LEFT")
+	subtitle:SetJustifyV("TOP")
+	subtitle:SetText(notes)
+
+	local anchor
+	for _,field in pairs(fields) do
+		local val = GetAddOnMetadata(frame.addonname, field)
+		if val then
+			local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
+			title:SetWidth(75)
+			if not anchor then title:SetPoint("TOPLEFT", subtitle, "BOTTOMLEFT", -2, -8)
+			else title:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, -6) end
+			title:SetJustifyH("RIGHT")
+			title:SetText(field:gsub("X%-", ""))
+
+			local detail = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+			detail:SetPoint("LEFT", title, "RIGHT", 4, 0)
+			detail:SetPoint("RIGHT", -16, 0)
+			detail:SetJustifyH("LEFT")
+			detail:SetText((haseditbox[field] and "|cff9999ff" or "").. val)
+
+			if haseditbox[field] then
+				local button = CreateFrame("Button", nil, frame)
+				button:SetAllPoints(detail)
+				button.val = val
+				button:SetScript("OnClick", lib.OpenEditbox)
+				button:SetScript("OnEnter", ShowTooltip)
+				button:SetScript("OnLeave", HideTooltip)
+			end
+
+			anchor = title
+		end
+	end
+
+	frame:SetScript("OnShow", nil)
+end
diff --git a/Libs/tekKonfigScroll.lua b/Libs/tekKonfigScroll.lua
new file mode 100644
index 0000000..18ad71a
--- /dev/null
+++ b/Libs/tekKonfigScroll.lua
@@ -0,0 +1,80 @@
+
+local lib, oldminor = LibStub:NewLibrary("tekKonfig-Scroll", 2)
+if not lib then return end
+
+lib.bg = {
+	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+	tile = true,
+	tileSize = 16,
+	edgeSize = 12,
+	insets = { left = 0, right = 0, top = 5, bottom = 5 }
+}
+
+-- Creates a scrollbar
+-- Parent is required, offset and step are optional
+function lib.new(parent, offset, step)
+	local f = CreateFrame("Slider", nil, parent)
+	f:SetWidth(16)
+
+	f:SetPoint("TOPRIGHT", 0 - (offset or 0), -16 - (offset or 0))
+	f:SetPoint("BOTTOMRIGHT", 0 - (offset or 0), 16 + (offset or 0))
+
+	local up = CreateFrame("Button", nil, f)
+	up:SetPoint("BOTTOM", f, "TOP")
+	up:SetWidth(16) up:SetHeight(16)
+	up:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Up")
+	up:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Down")
+	up:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Disabled")
+	up:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollUpButton-Highlight")
+
+	up:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	up:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	up:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	up:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	up:GetHighlightTexture():SetBlendMode("ADD")
+
+	up:SetScript("OnClick", function(self)
+		local parent = self:GetParent()
+		parent:SetValue(parent:GetValue() - (step or parent:GetHeight()/2))
+		PlaySound("UChatScrollButton")
+	end)
+
+	local down = CreateFrame("Button", nil, f)
+	down:SetPoint("TOP", f, "BOTTOM")
+	down:SetWidth(16) down:SetHeight(16)
+	down:SetNormalTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up")
+	down:SetPushedTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Down")
+	down:SetDisabledTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Disabled")
+	down:SetHighlightTexture("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Highlight")
+
+	down:GetNormalTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	down:GetPushedTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	down:GetDisabledTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	down:GetHighlightTexture():SetTexCoord(1/4, 3/4, 1/4, 3/4)
+	down:GetHighlightTexture():SetBlendMode("ADD")
+
+	down:SetScript("OnClick", function(self)
+		local parent = self:GetParent()
+		parent:SetValue(parent:GetValue() + (step or parent:GetHeight()/2))
+		PlaySound("UChatScrollButton")
+	end)
+
+	f:SetThumbTexture("Interface\\Buttons\\UI-ScrollBar-Knob")
+	local thumb = f:GetThumbTexture()
+	thumb:SetWidth(16) thumb:SetHeight(24)
+	thumb:SetTexCoord(1/4, 3/4, 1/8, 7/8)
+
+	f:SetScript("OnValueChanged", function(self, value)
+		local min, max = self:GetMinMaxValues()
+		if value == min then up:Disable() else up:Enable() end
+		if value == max then down:Disable() else down:Enable() end
+	end)
+
+	local border = CreateFrame("Frame", nil, f)
+	border:SetPoint("TOPLEFT", up, -5, 5)
+	border:SetPoint("BOTTOMRIGHT", down, 5, -3)
+	border:SetBackdrop(lib.bg)
+	border:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b, 0.5)
+
+	return f, up, down, border
+end
diff --git a/NinjaPanel.lua b/NinjaPanel.lua
index e570c11..b83eb9a 100644
--- a/NinjaPanel.lua
+++ b/NinjaPanel.lua
@@ -1,4 +1,4 @@
-NinjaPanel = {panels = {}, plugins = {}}
+NinjaPanel = {panels = {}, plugins = {}, pluginNames = {}}

 -- Import Data Broker and bail if we can't find it for some reason
 local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
@@ -45,6 +45,8 @@ eventFrame:SetScript("OnEvent", function(self, event, arg1, ...)
 			db.plugins["BottomTwo"].panel = "NinjaPanelBottom"
 			NinjaPanel:UpdatePanels()
 		end
+
+		ldb.RegisterCallback(NinjaPanel, "LibDataBroker_DataObjectCreated", "ScanForPlugins")
 	end
 end)

@@ -194,7 +196,11 @@ function NinjaPanel:ScanForPlugins()

 	local changed = false
 	for name,dataobj in ldb:DataObjectIterator() do
-		if not self:HasPlugin(name) and not self:PluginIsDisabled(name) then
+		if not self.pluginNames[name] then
+			self.pluginNames[name] = true
+			table.insert(self.pluginNames, name)
+		end
+		if not self:HasPlugin(name) and not self:PluginIsDisabled(name) then
 			if dataobj.type == "data source" or dataobj.text then
 				self:SpawnPlugin(name, dataobj, "data source")
 				changed = true
@@ -361,8 +367,6 @@ function NinjaPanel:HardAnchorPlugins()
 	end
 end

-ldb.RegisterCallback(NinjaPanel, "LibDataBroker_DataObjectCreated", "ScanForPlugins")
-
 function Panel_UpdateLayout(self)
 	local left, right = {}, {}

@@ -632,3 +636,187 @@ function Button_Tooltip_OnLeave(button)
 	tooltip:Hide()
 end

+--[[-------------------------------------------------------------------------
+-- Interface Options using tekConfig with Ampere's code example
+-------------------------------------------------------------------------]]--
+
+local frame = CreateFrame("Frame", nil, InterfaceOptionsFramePanelContainer)
+frame.name = "NinjaPanel"
+frame:Hide()
+frame:SetScript("OnShow", function(frame)
+	local function MakeButton(parent)
+		local button = CreateFrame("Button", nil, parent or frame)
+		button:SetWidth(80)
+		button:SetHeight(22)
+
+		button:SetHighlightFontObject(GameFontHighlightSmall)
+		button:SetNormalFontObject(GameFontNormalSmall)
+
+		button:SetNormalTexture("Interface\\Buttons\\UI-Panel-Button-Up")
+		button:SetPushedTexture("Interface\\Buttons\\UI-Panel-Button-Down")
+		button:SetHighlightTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")
+		button:SetDisabledTexture("Interface\\Buttons\\UI-Panel-Button-Disabled")
+		button:GetNormalTexture():SetTexCoord(0, 0.625, 0, 0.6875)
+		button:GetPushedTexture():SetTexCoord(0, 0.625, 0, 0.6875)
+		button:GetHighlightTexture():SetTexCoord(0, 0.625, 0, 0.6875)
+		button:GetDisabledTexture():SetTexCoord(0, 0.625, 0, 0.6875)
+		button:GetHighlightTexture():SetBlendMode("ADD")
+
+		return button
+	end
+
+	local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
+	title:SetPoint("TOPLEFT", 16, -16)
+	title:SetText("NinjaPanel Configuration")
+
+	local subtitle = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
+	--~ 	subtitle:SetHeight(32)
+	subtitle:SetHeight(35)
+	subtitle:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
+	subtitle:SetPoint("RIGHT", frame, -32, 0)
+	subtitle:SetNonSpaceWrap(true)
+	subtitle:SetJustifyH("LEFT")
+	subtitle:SetJustifyV("TOP")
+	--~ 	subtitle:SetMaxLines(3)
+	subtitle:SetText("This panel can be used to configure the NinjaPanel LDB display.")
+
+	local rows, anchor = {}
+	local EDGEGAP, ROWHEIGHT, ROWGAP, GAP = 16, 20, 2, 4
+
+	local function OnEnter(self)
+		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT")
+		GameTooltip:AddLine("Title", nil, nil, nil, true)
+		GameTooltip:AddLine("Info", 1, 1, 1, true)
+		GameTooltip:Show()
+	end
+	local function OnLeave() GameTooltip:Hide() end
+	local function OnClick(self)
+		local opts = NinjaPanelDB.plugins[self.name]
+		if opts.disabled then
+			opts.disabled = nil
+		else
+			opts.disabled = true
+		end
+		PlaySound(enabled and "igMainMenuOptionCheckBoxOff" or "igMainMenuOptionCheckBoxOn")
+		Refresh()
+	end
+	for i=1,math.floor((305-22)/(ROWHEIGHT + ROWGAP)) do
+		local row = CreateFrame("Button", nil, frame)
+		if not anchor then row:SetPoint("TOP", subtitle, "BOTTOM", 0, -16)
+		else row:SetPoint("TOP", anchor, "BOTTOM", 0, -ROWGAP) end
+		row:SetPoint("LEFT", EDGEGAP, 0)
+		row:SetPoint("RIGHT", -EDGEGAP*2-8, 0)
+		row:SetHeight(ROWHEIGHT)
+		anchor = row
+		rows[i] = row
+
+		local check = CreateFrame("CheckButton", nil, row)
+		check:SetWidth(ROWHEIGHT+4)
+		check:SetHeight(ROWHEIGHT+4)
+		check:SetPoint("LEFT")
+		check:SetNormalTexture("Interface\\Buttons\\UI-CheckBox-Up")
+		check:SetPushedTexture("Interface\\Buttons\\UI-CheckBox-Down")
+		check:SetHighlightTexture("Interface\\Buttons\\UI-CheckBox-Highlight")
+		check:SetDisabledCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check-Disabled")
+		check:SetCheckedTexture("Interface\\Buttons\\UI-CheckBox-Check")
+		check:SetScript("OnClick", OnClick)
+		row.check = check
+
+		local title = row:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
+		title:SetPoint("LEFT", check, "RIGHT", 4, 0)
+		row.title = title
+
+		local status = row:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
+		status:SetPoint("RIGHT", row, "RIGHT", -4, 0)
+		status:SetPoint("LEFT", title, "RIGHT")
+		status:SetJustifyH("RIGHT")
+		row.status = status
+
+		row:SetScript("OnEnter", OnEnter)
+		row:SetScript("OnLeave", OnLeave)
+	end
+
+	local statusColors = {
+		[true] = {0.1, 1.0, 0.1},
+		[false] = {1.0, 0.1, 0.1},
+	}
+
+	local offset = 0
+	Refresh = function()
+		if not frame:IsVisible() then return end
+
+		table.sort(NinjaPanel.pluginNames)
+
+		for i,row in ipairs(rows) do
+			if (i + offset) <= #NinjaPanel.pluginNames then
+				local name = NinjaPanel.pluginNames[i]
+				local entry = NinjaPanel.plugins[name]
+				local opts = NinjaPanelDB.plugins[name]
+				local enabled = not opts.disabled
+				local color = statusColors[enabled]
+
+				row.check:SetChecked(enabled)
+				row.title:SetText(name)
+				row.status:SetText(enabled and "Enabled" or "Disabled")
+				row.status:SetTextColor(unpack(color))
+				row.name = name
+				row.check.name = name
+				row:Show()
+			else
+				row:Hide()
+			end
+		end
+	end
+	frame:SetScript("OnEvent", Refresh)
+	frame:RegisterEvent("ADDON_LOADED")
+	frame:SetScript("OnShow", Refresh)
+	Refresh()
+
+	local scrollbar = LibStub("tekKonfig-Scroll").new(frame, nil, #rows/2)
+	scrollbar:ClearAllPoints()
+	scrollbar:SetPoint("TOP", rows[1], 0, -16)
+	scrollbar:SetPoint("BOTTOM", rows[#rows], 0, 16)
+	scrollbar:SetPoint("RIGHT", -16, 0)
+	scrollbar:SetMinMaxValues(0, math.max(0, #NinjaPanel.pluginNames))
+	scrollbar:SetValue(0)
+
+	local f = scrollbar:GetScript("OnValueChanged")
+	scrollbar:SetScript("OnValueChanged", function(self, value, ...)
+		offset = value
+		Refresh()
+		return f(self, value, ...)
+	end)
+
+	frame:EnableMouseWheel()
+	frame:SetScript("OnMouseWheel", function(self, val) scrollbar:SetValue(scrollbar:GetValue() - val*#rows/2) end)
+
+	local enableall = MakeButton()
+	enableall:SetPoint("BOTTOMLEFT", 16, 16)
+	enableall:SetText("Enable All")
+	enableall:SetScript("OnClick", EnableAllAddOns)
+
+	local disableall = MakeButton()
+	disableall:SetPoint("LEFT", enableall, "RIGHT", 4, 0)
+	disableall:SetText("Disable All")
+	disableall:SetScript("OnClick", DisableAllAddOns)
+
+	local reload = MakeButton()
+	reload:SetPoint("BOTTOMRIGHT", -16, 16)
+	reload:SetText("Refresh")
+	reload:SetScript("OnClick", ReloadUI)
+end)
+
+InterfaceOptions_AddCategory(frame)
+LibStub("tekKonfig-AboutPanel").new("NinjaPanel", "NinjaPanel")
+
+----------------------------------------
+--      Quicklaunch registration      --
+----------------------------------------
+
+local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("NinjaPanel-Launcher", {
+	type = "launcher",
+	icon = "Interface\\Icons\\Spell_Nature_StormReach",
+	OnClick = function() InterfaceOptionsFrame_OpenToCategory(frame) end,
+})
+
+
diff --git a/NinjaPanel.toc b/NinjaPanel.toc
index b43c0c7..70dba95 100644
--- a/NinjaPanel.toc
+++ b/NinjaPanel.toc
@@ -5,8 +5,13 @@
 ## Notes: A simple no-frills top panel for data broker feeds
 ## SavedVariables: NinjaPanelDB

+## LoadManagers: AddonLoader
+## X-LoadOn-Always: delayed
+
 Libs\LibStub.lua
 Libs\CallbackHandler-1.0.lua
 Libs\LibDataBroker-1.1.lua
 Libs\LibJostle-3.0.lua
+Libs\tekKonfigAboutPanel.lua
+Libs\tekKonfigScroll.lua
 NinjaPanel.lua