changeset 49:fd3dd12f96ce

Handle text generation modules being LoadOnDemand. lib-st widget to v5 to fix handling multiple live ST instances.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Sun, 29 Jan 2012 03:38:30 +0000
parents 22db12e97313
children 973d7396e0bf
files AceGUIWidget-lib-st.lua core.lua gui.lua
diffstat 3 files changed, 113 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/AceGUIWidget-lib-st.lua	Sat Jan 28 23:36:23 2012 +0000
+++ b/AceGUIWidget-lib-st.lua	Sun Jan 29 03:38:30 2012 +0000
@@ -23,6 +23,7 @@
 Version 2 reshuffle to follow new AceGUI widget coding style
 Version 3 add .tail_offset, defaulting to same absolute value as .head_offset
 Version 4 restore original frame methods, as fortold by ancient prophecy
+Version 5 don't bogart the widget object
 -farmbuyer
 -------------------------------------------------------------------------------]]
 local Type, Version = "lib-st", 4
@@ -76,22 +77,22 @@
 	if not st.frame then
 		error"lib-st instance has no '.frame' field... wtf did you pass to this function?"
 	end
-	if st.frame.obj and (st.frame.obj ~= self) then
-		error"lib-st instance already has an '.obj' field from a different widget, cannot use with AceGUI!"
-	end
+	--if st.frame.obj and (st.frame.obj ~= self) then
+	--	error"lib-st instance already has an '.obj' field from a different widget, cannot use with AceGUI!"
+	--end
 	self.st = st
 	if not st.head then
-		error"lib-st instance has no '.head' field, must use either ScrollingTable:CreateST or this widget's CreatST first"
+		error"lib-st instance has no '.head' field, must use either ScrollingTable:CreateST or this widget's CreateST first"
 	end
 	self.frame = st.frame   -- gutsy, but looks doable
 
 	-- Possibly have already wrapped this ST in a previous widget, careful.
-	if st.frame.obj ~= self then
+	--if st.frame.obj ~= self then
 		self.frame.customSetPoint = rawget(self.frame,"SetPoint")
 		self.frame.realSetPoint = self.frame.SetPoint
 		self.frame.SetPoint = ShiftingSetPoint
 		self.frame.SetAllPoints = ShiftingSetAllPoints
-	end
+	--end
 
 	-- This needs the .frame field.  This also unconditionally creates .obj
 	-- inside that field and calls a SetScript on it as well.
--- a/core.lua	Sat Jan 28 23:36:23 2012 +0000
+++ b/core.lua	Sun Jan 29 03:38:30 2012 +0000
@@ -556,6 +556,8 @@
 	end)
 	_G.InterfaceOptions_AddCategory(bliz)
 
+	self:_scan_LOD_modules()
+
 	if self.debug.flow then self:Print"is in control-flow debug mode." end
 end
 --function addon:OnDisable() end
@@ -1103,6 +1105,21 @@
 	end
 end
 
+-- Check for plugins which haven't already been loaded, and add hooks for
+-- them.  Credit to DBM for the approach here.
+function addon:_scan_LOD_modules()
+	for i = 1, GetNumAddOns() do
+		if GetAddOnMetadata (i, "X-OuroLoot-Plugin")
+		   and IsAddOnLoadOnDemand(i)
+		   and not IsAddOnLoaded(i)
+		then
+			local folder, _, _, enabled, _, reason = GetAddOnInfo(i)
+			local tabtitle = GetAddOnMetadata (i, "X-OuroLoot-Plugin")
+			self:_gui_add_LOD_tab (tabtitle, folder, i, enabled, reason)
+		end
+	end
+end
+
 -- Adds indices to traverse the tables in a nice sorted order.
 do
 	local byindex, temp = {}, {}
--- a/gui.lua	Sat Jan 28 23:36:23 2012 +0000
+++ b/gui.lua	Sun Jan 29 03:38:30 2012 +0000
@@ -56,6 +56,16 @@
 local _generate_text, _populate_text_specials
 local _tabtexts, _taborder -- filled out in gui block scope
 
+--[[
+This is a table of callback functions, each responsible for drawing a tab
+into the container passed in the first argument.  Special-purpose buttons
+can optionally be created (mkbutton) and added to the container in the second
+argument.
+]]
+local tabs_OnGroupSelected = {}
+local mkbutton
+local tabs_OnGroupSelected_func, tabs_generated_text_OGS
+
 -- Working around this bug:
 -- http://forums.wowace.com/showpost.php?p=295202&postcount=31
 do
@@ -142,6 +152,72 @@
 		if not f then return end
 		pcall (f, text_type, editbox, specials, mkb)
 	end
+
+	-- LOD tab has been clicked on.
+	local function _handle_LOD (tabs_container,specials,tabtitle)
+		local what = _tabtexts[tabtitle]
+		local addon_index = what.LOD
+		local loaded_at = what.loaded_at
+		local real_nip = next_insertion_position
+		local function LOAD()
+			_tabtexts[tabtitle] = nil
+			tremove (_taborder, loaded_at)
+			next_insertion_position = loaded_at
+			local loaded, whynot = LoadAddOn(addon_index)
+			if loaded then
+				addon:Print(tabtitle, "loaded.")
+			else
+				what.disabled = true
+				_tabtexts[tabtitle] = what -- restore this for mouseovers
+				addon:Print("%s could not load (game client reason was '%s').", tabtitle, whynot)
+				DisableAddOn(addon_index)
+			end
+			next_insertion_position = real_nip
+			dirty_tabs = true
+			addon:BuildMainDisplay()
+		end
+		addon.display:Hide()
+		if what.LOD_enabled then
+			-- totally loadable, go for it
+			LOAD()
+		else
+			-- was disabled at addons menu
+			StaticPopupDialogs["OUROL_LOD_DISABLED"] = flib.StaticPopup{
+				text = tabtitle.." was disabled at the character loading screen.  Do you want to enable it?",
+				button1 = YES,
+				button2 = NO,
+				OnAccept = function()
+					EnableAddOn(addon_index)
+					LOAD()
+				end,
+				OnCancel = function()
+					addon:BuildMainDisplay()
+				end,
+				OnHide = function()
+					StaticPopupDialogs["OUROL_LOD_DISABLED"] = nil
+				end,
+			}
+			StaticPopup_Show("OUROL_LOD_DISABLED")
+		end
+	end
+
+	-- Add a clickable tab that brings the real module in.  Since gui_init has
+	-- already been called, we flag the dirty bit and let the main building
+	-- routine handle it like any other plugin.
+	function addon:_gui_add_LOD_tab (tabtitle, folder, addon_index, enabled_p, why_not)
+		_tabtexts[tabtitle] = {
+			title = tabtitle,
+			desc = ("'%s' is not loaded yet.  Click the tab to load it now."):format(folder),
+			LOD = addon_index,
+			LOD_enabled = enabled_p,
+			LOD_why_not = why_not,
+			loaded_at = next_insertion_position,
+		}
+		tabs_OnGroupSelected[tabtitle] = _handle_LOD
+		tinsert (_taborder, next_insertion_position, tabtitle)
+		next_insertion_position = next_insertion_position + 1
+		dirty_tabs = true
+	end
 end
 
 --[[
@@ -347,16 +423,6 @@
 _taborder = { "eoi", "hist", "help", "opt" }
 --else _taborder = { "eoi", "help", "opt" } end
 
---[[
-This is a table of callback functions, each responsible for drawing a tab
-into the container passed in the first argument.  Special-purpose buttons
-can optionally be created (mkbutton) and added to the container in the second
-argument.
-]]
-local tabs_OnGroupSelected = {}
-local mkbutton
-local tabs_OnGroupSelected_func, tabs_generated_text_OGS
-
 function addon:gui_init (loot_pointer)
 	g_loot = loot_pointer
 	g_generated = nil
@@ -367,11 +433,15 @@
 	-- If we won't have enough tabs to trigger this on its own, pad out the tab
 	-- titles (not looking quite as nice, ah well) to force it to trigger.
 	local fmtstr = #_taborder > 6 and "%s" or "   %s   "
-	for _,v in ipairs(_taborder) do
-		tinsert (tabgroup_tabs, {value=v, text=fmtstr:format(_tabtexts[v].title)})
+	for i,name in ipairs(_taborder) do
+		tabgroup_tabs[i] = {
+			value = name,
+			text = fmtstr:format(_tabtexts[name].title),
+			disabled = _tabtexts[name].disabled,
+		}
 		-- By default, tabs are editboxes with generated text
-		if not tabs_OnGroupSelected[v] then
-			tabs_OnGroupSelected[v] = tabs_generated_text_OGS
+		if not tabs_OnGroupSelected[name] then
+			tabs_OnGroupSelected[name] = tabs_generated_text_OGS
 		end
 	end
 	dirty_tabs = nil
@@ -2000,7 +2070,11 @@
 	local tabs = GUI:Create("TabGroup")
 	tabs:SetLayout("Flow")
 	tabs.alignoffset = 25
-	tabs.titletext:SetFontObject(GameFontNormalSmall) -- XXX
+	local titletext_orig_fo = tabs.titletext:GetFontObject()
+	tabs.titletext:SetFontObject(GameFontNormalSmall)
+	tabs:SetCallback("OnRelease", function(_tabs)
+		tabs.titletext:SetFontObject(titletext_orig_fo)
+	end)
 	do
 		self.sender_list.sort()
 		tabs.titletext:SetFormattedText("Received broadcast data from %d |4player:players;.",