Mercurial > wow > buffalo2
diff Config.lua @ 0:3dbcad2b387d
initial push
author | Nenue |
---|---|
date | Wed, 30 Mar 2016 02:24:56 -0400 |
parents | |
children | 66b927b46776 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Config.lua Wed Mar 30 02:24:56 2016 -0400 @@ -0,0 +1,388 @@ +--- All the control GUI stuff, including chat command functions +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ +-- Created: 3/12/2016 12:49 AM +local B, _G = select(2,...).frame, _G +local M = B:RegisterModule("Options") +local tostring, tonumber, floor, format = tostring, tonumber, floor, string.format +local unpack, select, pairs, ipairs, type, wipe = unpack, select, pairs, ipairs, type, table.wipe +local CreateFrame, IsControlKeyDown = _G.CreateFrame, _G.IsControlKeyDown +local max = math.max +local OpacitySliderFrame, ColorPickerFrame = _G.OpacitySliderFrame, _G.ColorPickerFrame +local print = B.print('Cfgl') +local function round(number, decimals) + if floor(number) == number then + return ('%d'):format(number) + end + + return (("%%.%df"):format(decimals)):format(number) +end + +--- STATE VARIABLES +local configInit +--- Dummies for addon table upvalues +local configFrames = {} -- actual frame objects +local displays = B.displays -- anchor objects dummy + + +--- Returns a value retreival function and the current value stored in config +-- @paramsig value, previousValue = configInteger(key) +-- @param key Name of the config field being represented. +local defaultGroup = 'BuffButton' +local configInteger = function(group, key) + return function(self ,display) + return floor(tonumber(self:GetValue()) + 0.5) + end, (B.Conf[group ..key] or B.Conf[defaultGroup..key]) +end +local configPercent = function(group, key) + return function(self, display) + local value = self:GetValue() + if display then + return tostring(floor(value*100+0.5))..' %' + else + return floor((value*100+0.5))/100 + end + end, (B.Conf[group ..key] or B.Conf[defaultGroup..key]) +end +local configColor = function(group, key) + -- table for config, color value list for text + return function(self, display) + if display then + return "|cFFFF4444" .. round(self.rgba[1], 1) .. "|r, |cFF44FF44" .. round(self.rgba[2], 1) .. "|r, |cFF4488FF" .. + round(self.rgba[3], 1) .. "|r, " .. round(self.rgba[4], 1) + else + return self.rgba + end + end, (B.Conf[group ..key] or B.Conf[defaultGroup..key]) +end +local configCheck = function(group, key) + return function(self) return self:GetChecked() end, B.Conf[group ..key] or B.Conf[defaultGroup..key] +end +-- initializes the corresponding type of config field +local frameTypeConv = { + Color = 'Button', + Font = 'Frame', +} +local configTypeParams = { + Slider = function(frame, optionInfo) + frame:SetMinMaxValues(optionInfo[5], optionInfo[6]) + frame:SetValueStep(optionInfo[7]) + frame:SetStepsPerPage(optionInfo[8]) + print(frame.OptName, '\n {', optionInfo[5], optionInfo[6], optionInfo[7], optionInfo[8], '}') + end, + CheckButton = function(frame, optionInfo) + frame.SetValue = function(self, ...) + self:SetChecked(...) + B.Conf[self.OptName] = self:GetChecked() + print(self.OptTab) + B.UpdateAll() + end + frame:SetScript("OnClick",function(self) + B.Conf[self.OptName] = self:GetChecked() + print(B.Conf[self.OptName], self:GetChecked()) + B.UpdateAll() + end) + end, + Color = function(frame, optionInfo) + frame.rgba = { frame.current:GetVertexColor() } + local colorPickerCallback = function(restore) + local newR, newG, newB, newA + if restore then + newR, newG, newB, newA = unpack(restore) + else + newA, newR, newG, newB = OpacitySliderFrame:GetValue(), ColorPickerFrame:GetColorRGB() + print('not cancel', newA, newR, newB, newG) + end + frame:SetValue({newR, newG, newB, newA}) + B.UpdateBuffs(frame.OptTab) + end + frame:SetScript("OnClick", function(self) + print('got a click') + local r, g, b, a = frame.current:GetVertexColor() + ColorPickerFrame:SetColorRGB(r, g, b) + ColorPickerFrame.hasOpacity = (a ~= nil) + ColorPickerFrame.opacity = a + ColorPickerFrame.previousValues = {r,g,b,a} + ColorPickerFrame.func, ColorPickerFrame.opacityFunc, ColorPickerFrame.cancelFunc = + colorPickerCallback, colorPickerCallback,colorPickerCallback + ColorPickerFrame:Hide() + ColorPickerFrame:Show() + end) + frame.SetValue = function(self, rgba) + print(rgba) + frame.rgba = rgba + B.Conf[self.OptName] = rgba + frame.current:SetVertexColor(unpack(rgba)) + frame.fieldvalue:SetText(frame.OptValue(frame, true)) + end + end +} +--- configDialog +-- @usage tinsert(configDialog, {prefix, row, [...] }) +-- Each top level member defines a group of config value handlers, structured as an iterative table where the +-- first member is a key prefix, the second member is an integer row value, and all following members are treated +-- as a widget resource, defined initially as a complete sub-table, which can be re-used further down by passing +-- the string literal widget suffix. +-- widget table: ... {'suffix', 'description', valueCallback, 'template', [widget parameters]} +-- widget copy: ... 'suffix', ... +local configDialog = { + {'BuffButton', 1, + + {'Max', 'Max', configInteger, 'Slider', + 1, _G.BUFF_MAX_DISPLAY, 1, 1}, -- valueMin, valueMax, valueStep, stepsPerPage + {'PerRow', 'Per Row', configInteger, 'Slider', + 1, _G.BUFF_MAX_DISPLAY, 1, 1}, -- valueMin, valueMax, valueStep, stepsPerPage, + {'Size', 'Icon Size', configInteger, 'Slider', + 1, 256, 1, 1}, + {'Spacing', 'Icon Spacing', configInteger, 'Slider', + 1, 50, 1, 1}, + {'DurationSize', 'Duration Text Height', configInteger, 'Slider', + 1, 72, 1, 1}, + {'Zoom', 'Icon Zoom', configInteger, 'Slider', + 0, 100, 1, 1}, + {'Border', 'Border', configInteger, 'Slider', + 1, 16, 1, 1}, + {'Color', 'Default Border', configColor, 'Color'}, + {'RaidColor', 'RaidBuff Border', configColor, 'Color'}, + {'PlayerColor', 'Player Buffs', configColor, 'Color'}, + {'BossColor', 'Encounter Buffs', configColor, 'Color'}, + {'ShowSelfCast', 'Show name for self-casts', configCheck, 'CheckButton'} + }, + { 'DebuffButton', 1, + {'Max', 'Max', configInteger, 'Slider', + 1, _G.DEBUFF_MAX_DISPLAY, 1, 1 } + , + {'PerRow', 'Per Row', configInteger, 'Slider', + 1, _G.DEBUFF_MAX_DISPLAY, 1, 1 }, + 'Size', 'Spacing', 'DurationSize', 'Zoom', 'Border', + 'Color', 'RaidColor', 'PlayerColor', 'BossColor', + }, + { 'TempEnchant', 1, + {'Max', 'Max', configInteger, 'Slider', + 1, _G.NUM_TEMP_ENCHANT_FRAMES, 1, 1 }, + {'PerRow', 'Per Row', configInteger, 'Slider', + 1, _G.NUM_TEMP_ENCHANT_FRAMES, 1, 1}, + 'Size', 'Spacing', 'DurationSize', 'Zoom', 'Border', + 'Color', 'RaidColor', 'PlayerColor', 'BossColor', + }, + { 'ConsolidatedBuff', 2, + {'Position', 'Slot Position', configInteger, 'Slider', + 1, _G.BUFF_MAX_DISPLAY, 1, 1 } + + }, + { 'ConsolidatedBuff', 2, + 'Size' + }, + { 'Raid', 3, + {'ShowMissing', 'Verbose missing raid buffs', configCheck, 'CheckButton'} + } +} + + + + +local configFrame +local optionTemplates = {} +local configPadding, configSpacing = 3, 3 + +--- Walks the structure table to generate a pretty config panel +local InitConfig = function() + configInit = true + local configWidth = B:GetWidth() + local optionWidth = (configWidth - configPadding) / 3 - configSpacing + local configHeight = 0 + local bottom_extent = 0 + local clusterHeight = 0 + local clusterOffset = 0 + local lastCluster + local cluster = 1 + local col = 0 + for t, taboptions in ipairs(configDialog) do + local group = taboptions[1] + cluster = taboptions[2] + col = col + 1 + + + if not configFrames[t] then + configFrames[t] = {} + end + + + if cluster ~= lastCluster then + configHeight = configHeight + clusterHeight + print('|cFFFF8800## new cluster|r, advancing offset from', clusterOffset, 'to', clusterOffset + clusterHeight) + clusterOffset = clusterOffset + clusterHeight + col = 1 + clusterHeight = 0 + lastCluster = cluster + end + + print('processing tab', group) + local row = 0 + for i = 3, #taboptions do + row = row + 1 + local optionInfo = taboptions[i] + if type(optionInfo) == 'string' then + optionInfo = optionTemplates[optionInfo] + end + local key, fieldname, valueFuncGenerator, configType = unpack(optionInfo) + + if not optionTemplates[key] then + optionTemplates[key] = optionInfo + end + + local fullkey = group .. key + print(fullkey, fieldname) + + if not configFrames[t][row] then + print('building frame', t, group, row) + local frameTemplate = 'VeneerConfig'..configType + local frameType = frameTypeConv[configType] or configType + configFrames[t][row] = CreateFrame(frameType, fullkey, B, frameTemplate) + local f = configFrames[t][row] + f.OptKey = key + f.OptTab = group + f.OptName = fullkey + local valueFunc, initialValue = valueFuncGenerator(group, key) + print(' value getter', fullkey,'->', valueFunc,initialValue) + configTypeParams[configType](f, optionInfo) + f.OptValue = valueFunc + + --- Enclosing these to + -- a) make the panel easy to bring up externally + -- b) limit gameplay risk from config frame errors + -- c) milk the iterator scope for all its worth + f.OnChange = function(self) + + -- holding control; mirror this setting in other categories + if IsControlKeyDown() and not (configInit) then + configInit = true + for optTab, opts in pairs(configFrames) do + for _, opt in ipairs(opts) do + if opt.OptKey == key then + if optTab ~= group then + print('mapping to', optTab, opt.OptKey) + opt:SetValue(self:GetValue()) + end + + end + end + end + configInit = nil + end + local newValue = valueFunc(self) + if newValue ~= B.Conf[fullkey] then + print(newValue, fullkey) + f.fieldvalue:SetText(valueFunc(self, true)) + B.Conf[fullkey] = valueFunc(self) + -- prepare to update + wipe(B.drawn[f.OptTab]) + B.UpdateBuffs(self.OptTab) + B.UpdateConfigLayers() + end + + end + + f:SetValue(initialValue) + local yBuffer = configPadding + if f.fieldname then + f.fieldname:SetText(fieldname) + yBuffer = yBuffer + f.fieldname:GetHeight() + end + if f.fieldvalue then + f.fieldvalue:SetText(f:OptValue(true)) + end + + local point, relative, x, y = 'TOPLEFT', 'BOTTOMLEFT', 0, -3 + + local base + if (row == 1) then + bottom_extent = 0 + base = B.header + x = (col-1) * (optionWidth+configSpacing) + y = -configPadding + else + base = configFrames[t][row-1] + end + + print('|cFFFF0088'..cluster..'|r |cFF00FF00'.. row..'|r', col, base:GetName(), x, y - clusterOffset) + + if frameType ~= 'CheckButton' then + f:SetWidth(optionWidth) + end + + f:SetPoint(point, base, relative, x, y-yBuffer-clusterOffset) + --print('creating', frameType, fieldname) + f:Show() + + bottom_extent = bottom_extent + f:GetHeight() + yBuffer + configSpacing + + + + clusterHeight = max(clusterHeight, bottom_extent) + --print('y', floor(yBuffer+0.5), 'f:H', floor(f:GetHeight()+0.5), 'hTally', floor(bottom_extent+0.5), 'hMax', floor(configHeight+0.5)) + end + end + end + + -- grab the last cluster + if lastCluster == cluster then + print('|cFF00FF00##scooping up last cluster info') + configHeight = configHeight + clusterHeight + end + + if not B.configFramesCreated then + B.configFramesCreated = true + B:SetHeight(B.header:GetStringHeight() + configSpacing*3 + configHeight) + end + if configInit then configInit = nil end +end + +M.Command = function(enable, editbox) + displays = B.displays + if type(enable) == 'boolean' then + B.Conf.ConfigMode = enable + else + B.Conf.ConfigMode = (B.Conf.ConfigMode == false) and true or false + end + + print('/BUFF', B.Conf.ConfigMode, type(B.Conf.ConfigMode)) + if B.Conf.ConfigMode then + if not B.configFramesCreated then + InitConfig() + end + print('Veneer config') + B:Show() + else + B:Hide() + end + B.UpdateAll() + B.UpdateConfigLayers() +end + +B.Close = function () + M.Command() +end + +B.ToggleGuides = function(_, self) + B.Conf.GuidesMode = (not B.Conf.GuidesMode) + if B.Conf.GuidesMode then + self:GetNormalTexture():SetTexture(0.94, 0.21, 0.21, 1) + else + self:GetNormalTexture():SetTexture(0, 0, 0, 1) + end + + B.UpdateConfigLayers() +end + +M.OnEnable = function() + M.Command(B.Conf.ConfigMode) +end + +M.OnInitialize = function() + DEFAULT_CHAT_FRAME:AddMessage("|cFF22D822Veneer|r") + SLASH_BUFFALO1, SLASH_BUFFALO2 = "/buffalo", "/buff" + SlashCmdList.BUFFALO = M.Command + +end \ No newline at end of file