comparison Devian.lua @ 13:080dfa4990fb

necessary abstractions for running multiple console buffers in place message prefix can act as a channel selector when tagged in savedvars more frame vars defined in the XML XML parentKey names organized
author Nenue
date Sat, 19 Dec 2015 07:59:12 -0500
parents 65fcb81f4e0a
children 5254d1ba6013
comparison
equal deleted inserted replaced
12:0f91c3679c01 13:080dfa4990fb
2 -- Created: 11/30/2015 7:46 AM 2 -- Created: 11/30/2015 7:46 AM
3 if not LibStub then 3 if not LibStub then
4 print('Something has happened...') 4 print('Something has happened...')
5 end 5 end
6 Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0") 6 Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0")
7 local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@'
7 local D = _G.Devian 8 local D = _G.Devian
8 local STATE_LOW, STATE_HIGH = 1, 2 9 local STATE_LOW, STATE_HIGH = 1, 2
9 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() 10 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName()
10 local DEVIAN_FRAME = DevianConsole 11 local DEVIAN_FRAME = 'DevianConsole'
11 local cherry = false
12 local print = function(...) 12 local print = function(...)
13 _G.print('DVN', ...) 13 _G.print('Dvn', ...)
14 end 14 end
15 local db 15 local db
16 16 local defaults = {
17 17 ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}},
18 function D:SavePos(x,y) 18 ['tags'] = {},
19 db.y = (DEVIAN_FRAME:GetTop() - GetScreenHeight()) 19 ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}},
20 db.x = DEVIAN_FRAME:GetLeft() 20 current_channel = 1,
21 db.width = DEVIAN_FRAME:GetWidth() 21 console = true,
22 if not DEVIAN_FRAME.minimized then 22 dnd_status = true,
23 db.height = DEVIAN_FRAME:GetHeight() 23 dnd_message = "Debugging. Your messages may get eaten.",
24 end 24 font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]],
25 25 fontsize = 13,
26 print(db.y) 26 fontoutline = 'NONE',
27 DEVIAN_FRAME:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) 27 }
28 end 28
29 29
30 local ScanAddOnList = function(args) 30 local function ScanAddOnList(cmd, ...)
31 local list_state 31 local list_state
32 32
33 local mode = tonumber(args:match('^%d$')) 33 local mode = tonumber(cmd:match("%d"))
34 34
35 print('ScanAddOnList(', mode, ')') 35
36 print('Starting Addons scan. arg=', mode)
36 if mode == nil then 37 if mode == nil then
37 list_state = db.enabled and STATE_LOW or STATE_HIGH 38 list_state = db.enabled and STATE_LOW or STATE_HIGH
38 db.enabled = (db.enabled == false) and true or false 39 db.enabled = (db.enabled == false) and true or false
39 print(list_state, db.enabled) 40 print(list_state, db.enabled)
40 41
41 if list_state == STATE_LOW then 42 if list_state == STATE_LOW then
42 BNSetDND(true)
43 end 43 end
44 44
45 else 45 else
46 if mode > 2 then 46 if mode > 2 then
47 print('ScanAddOnList(',mode,'): Something has happened.') 47 print('Something has happened.')
48 return 48 return
49 end 49 end
50 list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH 50 list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH
51 51
52 if not db.chat_size then
53 db.chat_size = {}
54 end
55 if mode == STATE_LOW or mode == STATE_HIGH then
56 db.chat_size[list_state] = ChatFrame1:GetHeight()
57 end
58 52
59 end 53 end
60 local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state] 54 local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state]
61 55
62 local playername = UnitName("player") 56 local playername = UnitName("player")
67 61
68 if mode == STATE_LOW or mode == STATE_HIGH then 62 if mode == STATE_LOW or mode == STATE_HIGH then
69 char_list[name] = enableState 63 char_list[name] = enableState
70 global_list[name] = globalState 64 global_list[name] = globalState
71 else 65 else
66 if char_list[name] or global_list[name] then
72 67
73 if char_list[name] ~= 0 and global_list[name] ~= 0 then 68 if char_list[name] ~= 0 and global_list[name] ~= 0 then
74 local value = false 69 local value = false
75 if char_list[name] == 2 and global_list[name] == 1 then 70 if char_list[name] == 2 and global_list[name] == 1 then
76 value = UnitName("player") 71 value = UnitName("player")
85 value = UnitName("player") 80 value = UnitName("player")
86 end 81 end
87 print('DisableAddOn(', i, ',', value,')') 82 print('DisableAddOn(', i, ',', value,')')
88 DisableAddOn(i,value) 83 DisableAddOn(i,value)
89 end 84 end
85 end
90 86
91 end 87 end
92 end 88 end
93 89
94 if mode == nil then 90 if mode == nil then
99 else 95 else
100 D:Print('Standard AddOn list saved.') 96 D:Print('Standard AddOn list saved.')
101 end 97 end
102 end 98 end
103 99
104 -- Debug info 100
105 local function CreateMessenger() 101 local function Console_MinMax(self)
106 if db.console == true and db.enabled == false then 102 if self.minimized then
107 DEVIAN_FRAME:Show() 103 self:Maximize()
108 end 104 else
109 105 self:Minimize()
110 106 end
111 local f = DEVIAN_FRAME 107 end
112 --[[ 108
113 f.backdrop = f:CreateTexture('backdrop', 'BACKGROUND') 109 local function Console_Minimize(self)
114 f.backdrop:SetTexture(1,1,1,1) 110 self:SetHeight(20)
115 f.backdrop:SetGradient('HORIZONTAL', 0.2, 0.2, 0.2, 1, 1, 1) 111 self:SetMaxResize(GetScreenWidth(),20)
116 f.backdrop:SetBlendMode('MOD') 112 self.minimized = true
117 f.backdrop:SetAllPoints(f) 113 return self.out:Hide()
118 f:AddMessage('init a thing') 114 end
119 115
120 f:EnableMouseWheel(true) 116 local function Console_Maximize(self)
121 f:EnableKeyboard(true) 117 local db = db.channels[self.index]
122 f:SetScript('OnMouseWheel', function (self, delta) 118 self:SetHeight(db.height)
123 end) 119 self:SetMaxResize(GetScreenWidth(),GetScreenHeight())
124 120 self.minimized = nil
125 f:ScrollToBottom() 121 self.grip:SetTexture(0.5,0.5,0.5)
126 f:SetMaxLines(500) 122 return self.out:Show()
127 --]] 123 end
128 f.console:SetInsertMode('BOTTOM') 124
129 f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) 125
130 f:SetSize(db.width, db.height) 126 local function Console_Save(self)
127 local db = db.channels[self.index]
128 db.y = (self:GetTop() - GetScreenHeight())
129 db.x = self:GetLeft()
130 db.width = self:GetWidth()
131 if not self.minimized then
132 db.height = self:GetHeight()
133 db.minimized = nil
134 else
135 db.minimized = true
136 end
137 if self:IsVisible() then
138 db.enabled = true
139 else
140 db.enabled = nil
141 end
142 self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y)
143 end
144
145
146 local function Console_Toggle(input)
147 local key = input:gmatch("[%a%d]")
148 local search
149 if key and D.sig[key] then
150 search = {D.sig[key]}
151 elseif D.console[key] then
152 search = {D.console[key]}
153 else
154 search = D.console
155 end
156
157 for _, c in ipairs(search) do
158 if c:IsVisible() then
159 c:Hide()
160 else
161 c:Show()
162 c:Maximize()
163 end
164 c:Save()
165 end
166 end
167
168 --
169 --
170 -- Construct a console frame
171 local function CreateConsole(i, vars)
172 local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME)
173 f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.channels[i].x, db.channels[i].y)
174 f:SetSize(vars.width, vars.height)
131 f:Lower() 175 f:Lower()
132 176 f.out:SetFont(db.font, db.fontsize, db.fontoutline)
133 f.console:SetFading(false) 177 f.Save = Console_Save
134 f.console:SetTimeVisible(2147483647) 178 f.Minimize = Console_Minimize
135 f.console:SetFont(db.font, db.fontsize, db.fontoutline) 179 f.Maximize = Console_Maximize
136 --f:SetJustifyH('LEFT') 180 f.MinMax = Console_MinMax
137 181 f.Toggle = D.Console_Toggle
138 182 f.name = vars.name
139 D.debug_init = true 183 f.index = i
140 end 184
141 function D:ToggleMinMax() 185 if db.channels[i].enabled then
142 if DEVIAN_FRAME.minimized then 186 f:Show()
143 self:Maximize() 187 end
144 else 188 if db.channels[i].minimized then
145 self:Minimize() 189 f:Minimize()
146 end 190 end
147 end 191
148 function D:Minimize() 192 return f
149 DEVIAN_FRAME:SetHeight(20) 193 end
150 DEVIAN_FRAME.minimized = true 194
151 DEVIAN_FRAME:SetMaxResize(GetScreenWidth(),20) 195 --
152 return DEVIAN_FRAME.console:Hide() 196 --
153 end 197 -- Send a message somewhere
154 function D:Maximize()
155 DEVIAN_FRAME:SetHeight(db.height)
156 DEVIAN_FRAME.minimized = nil
157 DEVIAN_FRAME:SetMaxResize(GetScreenWidth(),GetScreenHeight())
158 return DEVIAN_FRAME.console:Show()
159 end
160
161 local prefix_cache = {}
162 local function Message(prefix, ...) 198 local function Message(prefix, ...)
163 if prefix == nil then 199 if prefix == nil then
164 oldprint('Tried to print nothing.') 200 prefix = 1
165 return 201 end
166 end 202
203 local channel
204 local byName = true
205 if D.sig[prefix] then
206 channel = D.sig[prefix]
207 elseif D.console[prefix] then
208 channel = D.console[prefix]
209 byName = nil
210 else
211 channel = D.console[1]
212 end
213
214
167 215
168 -- color me timbers 216 -- color me timbers
169 local pcolor 217 local pcolor
170 if db.tags[prefix] then 218 if D.tags[prefix] then
171 pcolor = db.tags[prefix] 219 pcolor = db.tags[prefix]
172 elseif not prefix_cache[prefix] then 220 elseif byName then
173 local c = {0, 0, 0 } 221 local c = {0, 0, 0 }
174 local max = string.len(prefix) 222 local max = string.len(prefix)
175 for i = 1, max, 3 do 223 for i = 1, max, 3 do
176 for k, v in ipairs(c) do 224 for k, v in ipairs(c) do
177 local j = i + (k - 1) 225 local j = i + (k - 1)
184 c[k] = 0 232 c[k] = 0
185 elseif c[k] > 127 then 233 elseif c[k] > 127 then
186 c[k] = 255 234 c[k] = 255
187 end 235 end
188 end 236 end
189 prefix_cache[prefix] = string.format('%02X%02X%02X', unpack(c)) 237 D.tags[prefix] = string.format('%02X%02X%02X', unpack(c))
190 end 238 end
191 239
192 local buffer = {'|cFF'.. prefix_cache[prefix]..prefix ..'|r'} 240 local buffer = {'|cFF'.. D.tags[prefix]..prefix ..'|r'}
193 for i = 1, select('#',...) do 241 for i = 1, select('#',...) do
194 local var = select(i, ...) 242 local var = select(i, ...)
195 243
196 if type(var) == 'table' then 244 if type(var) == 'table' then
197 var = '<table>' 245 var = '<table>'
203 var = 'nil' 251 var = 'nil'
204 end 252 end
205 253
206 table.insert(buffer, var) 254 table.insert(buffer, var)
207 end 255 end
208 DEVIAN_FRAME.console:AddMessage(table.concat(buffer, ' ')) 256 channel.out:AddMessage(table.concat(buffer, ' '))
209 table.wipe(buffer) 257 table.wipe(buffer)
210 end 258 end
211 259
212 function D:OnEnable() 260 function D:OnEnable()
261 -- commands
262 local cmdlist = {
263 ['dvn'] = ScanAddOnList,
264 ['devian'] = ScanAddOnList,
265 ['dvc'] = Console_Toggle,
266 }
267 for cmd, func in pairs(cmdlist) do
268 self:RegisterChatCommand(cmd, func, true)
269 end
270
213 if db.enabled == true then 271 if db.enabled == true then
214 D:Print('Standard AddOn list active. Type /dvn to switch to development mode.') 272 D:Print('Standard AddOn list active. Type /dvn to switch to development mode.')
215 else 273 else
216 D:Print('Development AddOn list active. Type /dvn to revert to regular operation.') 274 D:Print('Development AddOn list active. Type /dvn to revert to regular operation.')
217 end 275 end
276
218 end 277 end
219 278
220 279
221 function D:OnInitialize() 280 function D:OnInitialize()
281 -- emergency button
282 self:RegisterChatCommand("cleandvn", function(args)
283 DevianDB = nil
284 ReloadUI()
285 end)
286
287 -- savedvars
288 local cherry = false
222 if not _G.DevianDB then 289 if not _G.DevianDB then
223 _G.DevianDB = { 290 _G.DevianDB = defaults
224 ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}, 291 cherry = "Type /dvnsave to snapshot your current UI"
225 ['tags'] = {},
226 console = true,
227 dnd_status = true,
228 dnd_message = "Debugging. Your messages may get eaten.",
229 x = 100,
230 y = 800,
231 height = 500,
232 width = 600,
233 font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]],
234 fontsize = 13,
235 fontoutline = 'NONE',
236 }
237 cherry = "This is probably the first time, so:\n /dvn 2 to save your regular addon list\n /dvn 1 to save your development addon list\n /dvn to switch between the two\n /dvc to toggle print() frame"
238 end 292 end
239 db = _G.DevianDB 293 db = _G.DevianDB
240 294
241 print(PLAYER_REALM)
242 if not db[PLAYER_REALM] then 295 if not db[PLAYER_REALM] then
243 db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}} 296 db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}
244 if not cherry then 297 if not cherry then
245 cherry = "This character didn't have an AddOn table." 298 cherry = "This character didn't have an AddOn table."
246 end 299 end
247 end 300 end
248 301
249 -- inform the user if we have a virgin data table 302 -- copy tags
303 self.tags = {}
304 for n, c in pairs(db.tags) do
305 self.tags[n] = c
306 end
250 if cherry then 307 if cherry then
251 D:Print(cherry) 308 D:Print(cherry)
252 end 309 end
253
254 -- replace print handler and make the original available in global if possible
255
256 CreateMessenger()
257 D.oldprint = getprinthandler() 310 D.oldprint = getprinthandler()
258 if not _G.oldprint then 311 if not _G.oldprint then
259 _G.oldprint = D.oldprint 312 _G.oldprint = D.oldprint
260 end 313 end
314
315 self.console = {}
316 self.sig = {}
317 for i, cinfo in ipairs(db.channels) do
318 self.console[i] = CreateConsole(i, cinfo)
319 self.sig[cinfo.signature] = self.console[i]
320 end
261 setprinthandler(Message) 321 setprinthandler(Message)
262 self:RegisterChatCommand("dvn", ScanAddOnList) 322 print(MAJOR, MINOR)
263 self:RegisterChatCommand("dvc", function(args) 323 end
264 db.console = (not db.console) and true or nil
265 if db.console then
266 DEVIAN_FRAME:Show()
267 D:Maximize()
268 else
269 DEVIAN_FRAME:Hide()
270 end
271 end)
272
273 print('Master! I am here.')
274 end