Mercurial > wow > devian
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 |
