Quantcast

Deal with custom widgets with the same name as a default widget.

Scott Sibley [09-14-10 - 04:36]
Deal with custom widgets with the same name as a default widget.
Filename
Modules/Bars.lua
Modules/Histograms.lua
Modules/Text.lua
Modules/UnitTooltip.lua
diff --git a/Modules/Bars.lua b/Modules/Bars.lua
index f32a386..1cadc53 100644
--- a/Modules/Bars.lua
+++ b/Modules/Bars.lua
@@ -83,7 +83,7 @@ return UnitMana(unit)
 ]],
 		min = "return 0",
 		max = "return UnitManaMax('mouseover')",
-		color1 = [[
+		color1 = [[
 return PowerColor(nil, unit)
 ]],
 		height = 6,
@@ -92,7 +92,7 @@ return PowerColor(nil, unit)
 		enabled = true,
 		layer = 1
 	},
-
+

 }

@@ -102,23 +102,27 @@ local defaults = {
 	}
 }

-local options = {
+local options = {}
+local optionsDefaults = {
 	add = {
 		name = "Add Bar",
 		desc = "Add a bar",
 		type = "input",
 		set = function(info, v)
-			mod.db.profile.bars[v] = {
+			local widget = {
+				name = v,
 				type = "bar",
 				min = "return 0",
 				max = "return 100",
 				height = 6,
 				point = {"BOTTOMLEFT", "GameTooltip", "TOPLEFT"},
 				texture = LSM:GetDefault("statusbar"),
-				expression = ""
+				expression = "",
+				custom = true
 			}
+			tinsert(mod.db.profile.bars, widget)
 			StarTip:RebuildOpts()
-			createBars()
+			mod:ClearBars()
 		end,
 		order = 5
 	},
@@ -126,31 +130,25 @@ local options = {
 		name = "Restore Defaults",
 		desc = "Restore Defaults",
 		type = "execute",
-		func = function()
-			mod.db.profile.bars = copy(defaultWidgets);
-			StarTip:RebuildOpts()
-			StarTip:Print("Bug: You'll have to reload your UI to see the change in the bars list. I'm not sure why.")
+		func = function()
+			mod.db.profile.bars = copy(defaultWidgets);
+			StarTip:RebuildOpts()
 		end,
 		order = 6
 	},
-	bars = {
-		name = "Bars",
-		type = "group",
-		args = {}
-	},
 }

 function updateBar(widget, bar)
 	bar:SetValue(widget.val1 * 100)
-
+
 	local r, g, b = 0, 0, 1
-
+
 	if widget.color1 and widget.bar1 then
 		r, g, b = widget.color1.res1, widget.color1.res2, widget.color1.res3
 	elseif widget.color2 and widget.color2.is_valid then
 		r, g, b = widget.color2.res1, widget.color2.res2, widget.color2.res3
 	end
-
+
 	if type(r) == "number" then
 		bar:SetStatusBarColor(r, g, b)
 	else
@@ -160,22 +158,18 @@ end

 local textureDict = {}

-function mod:CreateBars()
-	createBars()
-end
-
 local new, del
 do
 	local pool = {}
 	function new()
 		local bar = next(pool)
-
+
 		if bar then
 			pool[bar] = nil
 		else
 			bar = CreateFrame("StatusBar", nil, GameTooltip)
 		end
-
+
 		return bar
 	end
 	function del(bar)
@@ -184,14 +178,14 @@ do
 end

 local defaultPoint = {"BOTTOMLEFT", "GameTooltip", "TOPLEFT"}
-
+
 local strataNameList = {
 	"BACKGROUND", "LOW", "MEDIUM", "HIGH", "DIALOG", "FULLSCREEN", "FULLSCREEN_DIALOG", "TOOLTIP"
 }

 local strataLocaleList = {"Background", "Low", "Medium", "High", "Dialog", "Fullscreen", "Fullscreen Dialog", "Tooltip"}

-function clearBar(obj)
+local function clearBar(obj)
 	obj = mod.bars and mod.bars[obj]
 	if not obj then return end
 	del(obj.bar)
@@ -202,16 +196,23 @@ function clearBar(obj)
 	end
 end

-function createBars()
+function mod:ClearBars()
+	for k, v in pairs(mod.bars) do
+		clearBar(v)
+	end
+	wipe(mod.bars)
+end
+
+local function createBars()
 	if type(mod.bars) ~= "table" then mod.bars = {} end
-
+
 	for k, v in pairs(self.db.profile.bars) do
-		if v.enabled then
-
+		if v.enabled and not v.deleted then
+
 			local widget = mod.bars[v]
 			if not widget then
 				local bar = new()
-				widget = mod.bars[v] or WidgetBar:New(mod.core, v.name, v, v.row or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateBar, bar)
+				widget = mod.bars[v] or WidgetBar:New(mod.core, v.name, v, v.row or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateBar, bar)
 				bar:SetStatusBarTexture(LSM:Fetch("statusbar", v.texture1))
 				bar:ClearAllPoints()
 				local arg1, arg2, arg3, arg4, arg5 = unpack(v.point)
@@ -231,7 +232,7 @@ function createBars()
 				widget.bar1 = true
 				widget.bar = bar
 				mod.bars[v] = widget
-
+
 				if v.expression2 then
 					bar = new()
 					widget = WidgetBar:New(mod.core, v.name, v, v.row or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateBar, bar)
@@ -263,23 +264,27 @@ function createBars()
 	end
 end

+function mod:CreateBars()
+	createBars()
+end
+
 function mod:OnInitialize()
 	self.db = StarTip.db:RegisterNamespace(self:GetName(), defaults)
-
+
 	if not self.db.profile.bars then
 		self.db.profile.bars = {}
 	end
-
+
 	for k in pairs(self.db.profile.bars) do
 		if type(k) == "string" then
 			wipe(self.db.profile.bars)
 			break
 		end
 	end
-
+
 	for k, v in pairs(defaultWidgets) do
 		for j, vv in ipairs(self.db.profile.bars) do
-			if v.name == vv.name then
+			if v.name == vv.name and not vv.custom then
 				for k, val in pairs(v) do
 					if v[k] ~= vv[k] and not vv[k.."Dirty"] then
 						vv[k] = v[k]
@@ -295,16 +300,17 @@ function mod:OnInitialize()
 			self.db.profile.bars[k] = copy(v)
 		end
 	end
-
-	self.core = LibCore:New(mod, environment, "StarTip.Bars", {["StarTip.Bars"] = {}}, nil, StarTip.db.profile.errorLevel)
-
-	StarTip:SetOptionsDisabled(options, true)

+	self.core = LibCore:New(mod, environment, "StarTip.Bars", {["StarTip.Bars"] = {}}, nil, StarTip.db.profile.errorLevel)
+
+	StarTip:SetOptionsDisabled(options, true)
+
+	self.bars = {}
 end

 function mod:OnEnable()
 	if not self.bars then self.bars = {} end
-
+
 	for k, bar in pairs(self.bars) do
 		bar.bar:Hide()
 	end
@@ -393,9 +399,14 @@ end

 function mod:RebuildOpts()
 	local defaults = WidgetBar.defaults
-
+
+	wipe(options)
+	for k, v in pairs(optionsDefaults) do
+		options[k] = v
+	end
+
 	for i, db in ipairs(self.db.profile.bars) do
-		options.bars.args[db.name:gsub(" ", "_")] = {
+		options[db.name:gsub(" ", "_")] = {
 			name = db.name,
 			type="group",
 			order = i,
@@ -408,8 +419,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.enabled = v
 						db["enabledDirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 1
 				},
@@ -419,11 +429,10 @@ function mod:RebuildOpts()
 					type = "input",
 					pattern = "%d",
 					get = function() return tostring(db.height or defaults.height) end,
-					set = function(info, v)
-						db.height = tonumber(v);
+					set = function(info, v)
+						db.height = tonumber(v);
 						db["heightDirty"] = true
-						clearBar(db)
-						createBars();
+						self:ClearBars()
 					end,
 					order = 2
 				},
@@ -433,11 +442,10 @@ function mod:RebuildOpts()
 					type = "input",
 					pattern = "%d",
 					get = function() return tostring(db.update or defaults.update) end,
-					set = function(info, v)
-						db.update = tonumber(v);
-						db["updateDirty"] = true
-						clearBar(db)
-						createBars()
+					set = function(info, v)
+						db.update = tonumber(v);
+						db["updateDirty"] = true
+						self:ClearBars()
 					end,
 					order = 3
 				},
@@ -446,7 +454,7 @@ function mod:RebuildOpts()
 					type = "select",
 					values = WidgetBar.directionList,
 					get = function() return db.direction or defaults.direction end,
-					set = function(info, v) db.direction = v; createBars() end,
+					set = function(info, v) db.direction = v;  end,
 					order = 4
 				},
 				style = {
@@ -454,7 +462,7 @@ function mod:RebuildOpts()
 					type = "select",
 					values = WidgetBar.styleList,
 					get = function() return db.style or defaults.style end,
-					set = function(info, v) db.style = v; createBars() end,
+					set = function(info, v) db.style = v;  end,
 					order = 5
 				},]]
 				texture1 = {
@@ -467,9 +475,8 @@ function mod:RebuildOpts()
 					end,
 					set = function(info, v)
 						db.texture1 = LSM:List("statusbar")[v]
-						db["texture1Dirty"] = true
-						clearBar(db)
-						createBars()
+						db["texture1Dirty"] = true
+						self:ClearBars()
 					end,
 					order = 4
 				},
@@ -479,13 +486,13 @@ function mod:RebuildOpts()
 					type = "select",
 					values = LSM:List("statusbar"),
 					get = function()
-						return db.texture2 or db.texture1 or "Blizzard"
+						return db.texture2 or db.texture1 or "Blizzard"
 					end,
-					set = function(info, v)
-						db.texture2 = LSM:List("statusbar")[v]
-						db["texture2Dirty"] = true
-						clearBar(db)
-						createBars() end,
+					set = function(info, v)
+						db.texture2 = LSM:List("statusbar")[v]
+						db["texture2Dirty"] = true
+						self:ClearBars()
+						 end,
 					order = 5
 				},
 				strata = {
@@ -493,7 +500,7 @@ function mod:RebuildOpts()
 					type = "select",
 					values = strataLocaleList,
 					get = function() return db.strata end,
-					set = function(info, v) db.strata = v; clearBar(db) end,
+					set = function(info, v) db.strata = v; self:ClearBars() end,
 					order = 6
 				},
 				point = {
@@ -506,14 +513,14 @@ function mod:RebuildOpts()
 							type = "select",
 							values = anchors,
 							get = function() return anchorsDict[db.point[1] or 1] end,
-							set = function(info, v) db.point[1] = anchors[v]; clearBar(db) end,
+							set = function(info, v) db.point[1] = anchors[v]; self:ClearBars() end,
 							order = 1
 						},
 						relativeFrame = {
 							name = "Relative Frame",
 							type = "input",
 							get = function() return db.point[2] end,
-							set = function(info, v) db.point[2] = v; clearBar(db) end,
+							set = function(info, v) db.point[2] = v; self:ClearBars() end,
 							order = 2
 						},
 						relativePoint = {
@@ -521,7 +528,7 @@ function mod:RebuildOpts()
 							type = "select",
 							values = anchors,
 							get = function() return anchorsDict[db.point[3] or 1] end,
-							set = function(info, v) db.point[3] = anchors[v]; clearBar(db) end,
+							set = function(info, v) db.point[3] = anchors[v]; self:ClearBars() end,
 							order = 3
 						},
 						xOfs = {
@@ -529,7 +536,7 @@ function mod:RebuildOpts()
 							type = "input",
 							pattern = "%d",
 							get = function() return tostring(db.point[4] or 0) end,
-							set = function(info, v) db.point[4] = tonumber(anchors[v]); clearBar(db) end,
+							set = function(info, v) db.point[4] = tonumber(anchors[v]); self:ClearBars() end,
 							order = 4
 						},
 						yOfs = {
@@ -537,8 +544,8 @@ function mod:RebuildOpts()
 							type = "input",
 							pattern = "%d",
 							get = function() return tostring(db.point[5] or 0) end,
-							set = function(info, v) db.point[5] = tonumber(anchors[v]); clearBar(db) end,
-							order = 4
+							set = function(info, v) db.point[5] = tonumber(anchors[v]); self:ClearBars() end,
+							order = 4
 						}
 					},
 					order = 7
@@ -548,11 +555,10 @@ function mod:RebuildOpts()
 					desc = "Toggle whether to place the first bar on top",
 					type = "toggle",
 					get = function() return db.top end,
-					set = function(info, v)
-						db.top = v;
-						db["topDirty"] = true
-						clearBar(db)
-						createBars()
+					set = function(info, v)
+						db.top = v;
+						db["topDirty"] = true
+						self:ClearBars()
 					end,
 					order = 8
 				},
@@ -563,11 +569,10 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.expression end,
-					set = function(info, v)
-						db.expression = v;
+					set = function(info, v)
+						db.expression = v;
 						db["expressionDirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 9
 				},
@@ -578,11 +583,10 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.expression2 end,
-					set = function(info, v)
-						db.expression2 = v ;
-						db["expressionDirty"] = true
-						clearBar(db)
-						createBars()
+					set = function(info, v)
+						db.expression2 = v ;
+						db["expression2Dirty"] = true
+						self:ClearBars()
 					end,
 					order = 10
 				},
@@ -593,14 +597,13 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.min end,
-					set = function(info, v)
-						db.min = v;
+					set = function(info, v)
+						db.min = v;
 						db["minDirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 11
-
+
 				},
 				max = {
 					name = "Bar max expression",
@@ -609,11 +612,10 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.max end,
-					set = function(info, v)
-						db.max = v;
+					set = function(info, v)
+						db.max = v;
 						db["maxDirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 12
 				},
@@ -624,11 +626,10 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.color1 end,
-					set = function(info, v)
-						db.color1 = v;
+					set = function(info, v)
+						db.color1 = v;
 						db["color1Dirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 13
 				},
@@ -639,14 +640,32 @@ function mod:RebuildOpts()
 					multiline = true,
 					width = "full",
 					get = function() return db.color2 end,
-					set = function(info, v)
-						db.color2 = v;
+					set = function(info, v)
+						db.color2 = v;
 						db["color2Dirty"] = true
-						clearBar(db)
-						createBars()
+						self:ClearBars()
 					end,
 					order = 13
-				}
+				},
+				delete = {
+					name = "Delete",
+					type = "execute",
+					func = function()
+						local delete = true
+						for i, v in ipairs(defaultWidgets) do
+							if db.name == v.name then
+								db.deleted = true
+								delete = false
+							end
+						end
+						if delete then
+							self.db.profile.bars[i] = nil
+						end
+						self:ClearBars()
+						StarTip:RebuildOpts()
+					end,
+					order = 100
+				}
 			}
 		}
 	end
@@ -686,7 +705,7 @@ function mod:UpdateBar()
 		color.r, color.g, color.b = colorGradient(min/max)
 	elseif(UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) or not UnitIsConnected(unit)) then
 		color = health[1]
-	elseif UnitIsPlayer(unit) then
+	elseif UnitIsPlayer(unit) then
 		color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
 	else
 		color = StarTip.new()
@@ -697,7 +716,7 @@ function mod:UpdateBar()
 	StarTip.del(color)
 end
 ]]
--- Logic snagged from oUF
+-- Logic snagged from oUF
 --[[
 function mod:UpdateHealth()
 	local unit = "mouseover"
@@ -712,7 +731,7 @@ function mod:UpdateHealth()
 		color.r, color.g, color.b = colorGradient(min/max)
 	elseif(UnitIsTapped(unit) and not UnitIsTappedByPlayer(unit) or not UnitIsConnected(unit)) then
 		color = health[1]
-	elseif UnitIsPlayer(unit) then
+	elseif UnitIsPlayer(unit) then
 		color = RAID_CLASS_COLORS[select(2, UnitClass(unit))]
 	else
 		color = StarTip.new()
diff --git a/Modules/Histograms.lua b/Modules/Histograms.lua
index da10485..8e251b9 100644
--- a/Modules/Histograms.lua
+++ b/Modules/Histograms.lua
@@ -163,13 +163,15 @@ local defaults = {
 	}
 }

-local options = {
+local options = {}
+local optionsDefaults = {
 	add = {
 		name = "Add Histogram",
 		desc = "Add a histogram",
 		type = "input",
 		set = function(info, v)
-			mod.db.profile.histograms[v] = {
+			local widget = {
+				name = v,
 				type = "histogram",
 				min = "return 0",
 				max = "return 100",
@@ -179,10 +181,12 @@ local options = {
 				point = {"TOPLEFT", "GameTooltip", "BOTTOMLEFT", 0, -50},
 				texture = LSM:GetDefault("statusbar"),
 				expression = "return random(100)",
-				color = "return 0, 0, 1"
+				color = "return 0, 0, 1",
+				custom = true
 			}
+			tinsert(mod.db.profile.histograms, widget)
 			StarTip:RebuildOpts()
-			createHistograms()
+
 		end,
 		order = 5
 	},
@@ -193,15 +197,9 @@ local options = {
 		func = function()
 			mod.db.profile.histograms = copy(defaultWidgets);
 			StarTip:RebuildOpts()
-			StarTip:Print("Bug: You'll have to reload your UI to see the change in the histograms list. I'm not sure why.")
 		end,
 		order = 6
 	},
-	histograms = {
-		name = "Histograms",
-		type = "group",
-		args = {}
-	},
 }

 function updateHistogram(widget)
@@ -222,10 +220,6 @@ end

 local textureDict = {}

-function mod:CreateHistograms()
-	createHistograms()
-end
-
 local new, del
 do
 	local pool = {}
@@ -254,6 +248,13 @@ local function clearHistogram(obj)
 	obj:Del()
 end

+function mod:ClearHistograms()
+	for k, v in pairs(mod.histograms) do
+		clearHistogram(v)
+	end
+	wipe(mod.histograms)
+end
+
 local function createHistograms()
 	if type(mod.histograms) ~= "table" then mod.histograms = {} end
 	--[[for k, widget in pairs(mod.histograms) do
@@ -276,7 +277,7 @@ local function createHistograms()
 	end

 	for k, v in pairs(self.db.profile.histograms) do
-		if v.enabled then
+		if v.enabled and not v.deleted then
 			v.width = v.width or WidgetHistogram.defaults.width
 			local widget = mod.histograms[v]
 			local newWidget
@@ -322,15 +323,17 @@ local function createHistograms()
 	end
 end

+function mod:CreateHistograms()
+	createHistograms()
+end
+
 function mod:OnInitialize()
 	self.db = StarTip.db:RegisterNamespace(self:GetName(), defaults)

 	if not self.db.profile.histograms then
 		self.db.profile.histograms = {}
 	end
-
-	wipe(self.db.profile.histograms)
-
+
 	for k in pairs(self.db.profile.histograms) do
 		if type(k) == "string" then
 			wipe(self.db.profile.histograms)
@@ -340,7 +343,7 @@ function mod:OnInitialize()

 	for i, v in ipairs(defaultWidgets) do
 		for j, vv in ipairs(self.db.profile.histograms) do
-			if v.name == vv.name then
+			if v.name == vv.name and not vv.custom then
 				for k, val in pairs(v) do
 					if v[k] ~= vv[k] and not vv[k.."Dirty"] then
 						vv[k] = v[k]
@@ -363,6 +366,7 @@ function mod:OnInitialize()

 	StarTip:SetOptionsDisabled(options, true)

+	self.histograms = {}
 end

 function mod:OnEnable()
@@ -383,12 +387,6 @@ function mod:OnDisable()
 	StarTip:SetOptionsDisabled(options, true)
 end

---[[function mod:RebuildOpts()
-	for k, v in ipairs(self.db.profile.histograms) do
-		options.histograms.args[k] = WidgetHistogram:GetOptions(v)
-	end
-end]]
-
 function mod:GetOptions()
 	return options
 end
@@ -452,9 +450,13 @@ end

 function mod:RebuildOpts()
 	local defaults = WidgetHistogram.defaults
-
+	self:ClearHistograms()
+	wipe(options)
+	for k, v in pairs(optionsDefaults) do
+		options[k] = v
+	end
 	for i, db in ipairs(self.db.profile.histograms) do
-		options.histograms.args[db.name:gsub(" ", "_")] = {
+		options[db.name:gsub(" ", "_")] = {
 			name = db.name,
 			type="group",
 			order = i,
@@ -467,8 +469,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.enabled = v
 						db["enabledDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
 					end,
 					order = 1
 				},
@@ -481,8 +482,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.height = tonumber(v);
 						db["heightDirty"] = true
-						clearHistogram(db)
-						createHistograms();
+						self:ClearHistograms()
 					end,
 					order = 2
 				},
@@ -495,8 +495,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.width = tonumber(v)
 						db["widthDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
 					end,
 					order = 3
 				},
@@ -518,8 +517,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.update = tonumber(v);
 						db["updateDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
 					end,
 					order = 5
 				},
@@ -550,8 +548,7 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.texture = LSM:List("statusbar")[v]
 						db["textureDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
 					end,
 					order = 6
 				},
@@ -565,14 +562,14 @@ function mod:RebuildOpts()
 							type = "select",
 							values = anchors,
 							get = function() return anchorsDict[db.point[1] or 1] end,
-							set = function(info, v) db.point[1] = anchors[v];clearHistogram(db);createHistograms() end,
+							set = function(info, v) db.point[1] = anchors[v];self:ClearHistograms(); end,
 							order = 1
 						},
 						relativeFrame = {
 							name = "Relative Frame",
 							type = "input",
 							get = function() return db.point[2] end,
-							set = function(info, v) db.point[2] = v; clearHistogram(db); createHistograms() end,
+							set = function(info, v) db.point[2] = v; self:ClearHistograms();  end,
 							order = 2
 						},
 						relativePoint = {
@@ -580,7 +577,7 @@ function mod:RebuildOpts()
 							type = "select",
 							values = anchors,
 							get = function() return anchorsDict[db.point[3] or 1] end,
-							set = function(info, v) db.point[3] = anchors[v]; clearHistogram(db); createHistograms() end,
+							set = function(info, v) db.point[3] = anchors[v]; self:ClearHistograms();  end,
 							order = 3
 						},
 						xOfs = {
@@ -588,7 +585,7 @@ function mod:RebuildOpts()
 							type = "input",
 							pattern = "%d",
 							get = function() return tostring(db.point[4] or 0) end,
-							set = function(info, v) db.point[4] = tonumber(v); clearHistogram(db); createHistograms() end,
+							set = function(info, v) db.point[4] = tonumber(v); self:ClearHistograms();  end,
 							order = 4
 						},
 						yOfs = {
@@ -596,7 +593,7 @@ function mod:RebuildOpts()
 							type = "input",
 							pattern = "%d",
 							get = function() return tostring(db.point[5] or 0) end,
-							set = function(info, v) db.point[5] = tonumber(v); clearHistogram(db);createHistograms() end,
+							set = function(info, v) db.point[5] = tonumber(v); self:ClearHistograms(); end,
 							order = 4
 						}
 					},
@@ -620,8 +617,8 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.expression = v;
 						db["expressionDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
+
 					end,
 					order = 9
 				},
@@ -635,8 +632,8 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.min = v;
 						db["minDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
+
 					end,
 					order = 10

@@ -651,8 +648,8 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.max = v;
 						db["maxDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
+
 					end,
 					order = 11
 				},
@@ -666,8 +663,8 @@ function mod:RebuildOpts()
 					set = function(info, v)
 						db.color = v;
 						db["colorDirty"] = true
-						clearHistogram(db)
-						createHistograms()
+						self:ClearHistograms()
+
 					end,
 					order = 12
 				},
@@ -676,9 +673,18 @@ function mod:RebuildOpts()
 					desc = "Delete this widget",
 					type = "execute",
 					func = function()
-						self.db.profile.histograms[k] = nil
-						clearHistogram(db)
-						createHistograms()
+						local delete = true
+						for i, v in ipairs(defaultWidgets) do
+							if db.name == v.name then
+								db.deleted = true
+								delete = false
+							end
+						end
+						if delete then
+							self.db.profile.histograms[i] = nil
+						end
+						self:ClearHistograms()
+						StarTip:RebuildOpts()
 					end,
 					order = 13
 				}
diff --git a/Modules/Text.lua b/Modules/Text.lua
index 7a48e19..cd79a8f 100644
--- a/Modules/Text.lua
+++ b/Modules/Text.lua
@@ -188,23 +188,27 @@ local defaults = {
 	}
 }

-local options = {
+local options = {}
+local optionsDefaults = {
 	add = {
 		name = "Add Text",
 		desc = "Add a text widget",
 		type = "input",
 		set = function(info, v)
-			mod.db.profile.texts[v] = {
+			local widget = {
+				name = v,
 				type = "text",
 				min = "return 0",
 				max = "return 100",
 				height = 6,
 				point = {"BOTTOMLEFT", "GameTooltip", "TOPLEFT"},
 				texture = LSM:GetDefault("statustext"),
-				expression = ""
+				expression = "",
+				custom = true
 			}
+			tinsert(mod.db.profile.texts, widget)
 			StarTip:RebuildOpts()
-			createTexts()
+			mod:ClearTexts()
 		end,
 		order = 5
 	},
@@ -215,15 +219,9 @@ local options = {
 		func = function()
 			mod.db.profile.texts = copy(defaultWidgets);
 			StarTip:RebuildOpts()
-			StarTip:Print("Bug: You'll have to reload your UI to see the change in the texts list. I'm not sure why.")
 		end,
 		order = 6
 	},
-	texts = {
-		name = "Texts",
-		type = "group",
-		args = {}
-	},
 }

 function updateText(widget)
@@ -275,6 +273,20 @@ local strataNameList = {

 local strataLocaleList = {"Background", "Low", "Medium", "High", "Dialog", "Fullscreen", "Fullscreen Dialog", "Tooltip"}

+local function clearText(obj)
+	local widget = mod.texts[obj]
+	if not widget then return end
+	widget:Del()
+	del(widget.text)
+end
+
+function mod:ClearTexts()
+	for k, v in pairs(mod.texts) do
+		clearText(v)
+	end
+	wipe(mod.texts)
+end
+
 function createTexts()
 	if type(mod.texts) ~= "table" then mod.texts = {} end
 	--[[for k, v in pairs(mod.texts) do
@@ -283,12 +295,11 @@ function createTexts()
 		del(v.text)
 	end]]
 	local appearance = StarTip:GetModule("Appearance")
-	for k, v in pairs(self.db.profile.texts) do
-		if v.enabled then
+	for i, v in ipairs(self.db.profile.texts) do
+		if v.enabled and not v.deleted then
 			local text = new(v.cols or WidgetText.defaults.cols)
-			local cfg = copy(v)
-			cfg.unit = StarTip.unit
-			local widget = mod.texts[v] or WidgetText:New(mod.core, v.name, cfg, v.row or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateText)
+			local widget = mod.texts[v] or WidgetText:New(mod.core, v.name, v, v.row or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateText)
+			widget.config.unit = StarTip.unit
 			text:ClearAllPoints()
 			text:SetParent(v.parent)
 			local arg1, arg2, arg3, arg4, arg5 = unpack(v.point)
@@ -318,7 +329,7 @@ function mod:OnInitialize()

 	for i, v in ipairs(defaultWidgets) do
 		for j, vv in ipairs(self.db.profile.texts) do
-			if v.name == vv.name then
+			if v.name == vv.name and not vv.custom then
 				for k, val in pairs(v) do
 					if v[k] ~= vv[k] and not vv[k.."Dirty"] then
 						vv[k] = v[k]
@@ -339,6 +350,7 @@ function mod:OnInitialize()

 	StarTip:SetOptionsDisabled(options, true)

+	self.texts = {}
 end

 function mod:OnEnable()
@@ -415,14 +427,39 @@ end

 function mod:RebuildOpts()
 	local defaults = WidgetText.defaults
+	self:ClearTexts()
+
+	wipe(options)
+	for k, v in pairs(optionsDefaults) do
+		options[k] = v
+	end

 	for i, db in ipairs(self.db.profile.texts) do
-		options.texts.args[db.name:gsub(" ", "_")] = {
+		options[db.name:gsub(" ", "_")] = {
 			name = db.name,
 			type="group",
 			order = i,
 			args=WidgetText:GetOptions(StarTip, db)
 		}
+		options[db.name:gsub(" ", "_")].args.delete = {
+			name = "Delete",
+			type = "execute",
+			func = function()
+				local delete = true
+				for i, v in ipairs(defaultWidgets) do
+					if db.name == v.name then
+						db.deleted = true
+						delete = false
+					end
+				end
+				if delete then
+					self.db.profile.texts[i] = nil
+				end
+				self:ClearTexts()
+				StarTip:RebuildOpts()
+			end,
+			order = 100
+		}
 	end
 end

diff --git a/Modules/UnitTooltip.lua b/Modules/UnitTooltip.lua
index f253294..0e494db 100644
--- a/Modules/UnitTooltip.lua
+++ b/Modules/UnitTooltip.lua
@@ -71,7 +71,7 @@ end

 local function copy(src, dst)
 	if type(src) ~= "table" then return nil end
-	if type(dst) ~= "table" then dst = StarTip.new() end
+	if type(dst) ~= "table" then dst = {} end
 	for k, v in pairs(src) do
 		if type(v) == "table" then
 			v = copy(v)
@@ -428,16 +428,19 @@ function mod:UPDATE_FACTION()
     end
 end

-local fontStringsToDraw = {}
-local function updateFontString(widget, fontString)
-	fontStringsToDraw[widget] = true
+local widgetsToDraw = {}
+local function updateWidget(widget)
+	widgetsToDraw[widget] = true
+	if mod.db.profile.refreshRate == 0 then
+		draw()
+	end
 end

 do
 	local fontsList = LSM:List("font")
 	local widget, fontString
 	function draw()
-		for widget in pairs(fontStringsToDraw) do
+		for widget in pairs(widgetsToDraw) do
 			if not widget.fontString then break end
 			local fontString = widget.fontString
 			fontString:SetText(widget.buffer)
@@ -460,7 +463,7 @@ do
 				end
 			end
 		end
-		table.wipe(fontStringsToDraw)
+		table.wipe(widgetsToDraw)
 	end
 end

@@ -502,11 +505,7 @@ function mod:CreateLines()
 							v.config.value = v.left
 							local tmp = v.update
 							if not v.leftUpdating then v.update = 0 end
-							if mod.db.profile.refreshRate == 0 then
-								v.config.update = 0
-								v.config.scroll = 0
-							end
-							v.leftObj = v.leftObj or WidgetText:New(mod.core, v.name .. "left", v.config, 0, 0, v.layer or 0, StarTip.db.profile.errorLevel, updateFontString)
+							v.leftObj = v.leftObj or WidgetText:New(mod.core, v.name .. "left", copy(v.config), 0, 0, v.layer or 0, StarTip.db.profile.errorLevel, updateWidget)
 							v.update = tmp
 						end

@@ -515,31 +514,23 @@ function mod:CreateLines()
 							v.config.value = v.right
 							local tmp = v.update
 							if not v.rightUpdating then v.update = 0 end
-							if mod.db.profile.refreshRate == 0 then
-								v.config.update = 0
-								v.config.scroll = 0
-							end
-							v.rightObj = v.rightObj or WidgetText:New(mod.core, v.name .. "right", v.config, 0, 0, v.layer or 0, StarTip.db.profile.errorLevel, updateFontString)
+							v.rightObj = v.rightObj or WidgetText:New(mod.core, v.name .. "right", copy(v.config), 0, 0, v.layer or 0, StarTip.db.profile.errorLevel, updateWidget)
 							v.update = tmp
 						end
 						v.leftObj.fontString = mod.leftLines[lineNum]
-						fontStringsToDraw[v.leftObj] = true
+						widgetsToDraw[v.leftObj] = true
 						v.rightObj.fontString = mod.rightLines[lineNum]
-						fontStringsToDraw[v.rightObj] = true
+						widgetsToDraw[v.rightObj] = true
                     else
 						GameTooltip:AddLine(' ', mod.db.profile.color.r, mod.db.profile.color.g, mod.db.profile.color.b)

 						v.config.value = v.left
 						local tmp = v.update
 						if not v.leftUpdating then v.update = 0 end
-						if mod.db.profile.refreshRate == 0 then
-							v.config.update = 0
-							v.config.scroll = 0
-						end
-						v.leftObj = v.leftObj or WidgetText:New(mod.core, v.name, v.config, 0, 0, 0, StarTip.db.profile.errorLevel, updateFontString)
+						v.leftObj = v.leftObj or WidgetText:New(mod.core, v.name, copy(v.config), 0, 0, 0, StarTip.db.profile.errorLevel, updateWidget)
 						v.update = tmp
 						v.leftObj.fontString = mod.leftLines[lineNum]
-						fontStringsToDraw[v.leftObj] = true
+						widgetsToDraw[v.leftObj] = true
                     end
 					if v.rightObj then
 						if mod.db.profile.refreshRate == 0 then
@@ -565,7 +556,6 @@ function mod:CreateLines()

         end
         --mod.NUM_LINES = lineNum
-	draw()
 	GameTooltip:Show()
     end})
 end