├── fonts
└── Prototype.ttf
├── Bindings.xml
├── services
└── index.xml
├── app.xml
├── libs
├── AceAddon-3.0
│ └── AceAddon-3.0.xml
├── AceEvent-3.0
│ ├── AceEvent-3.0.xml
│ └── AceEvent-3.0.lua
├── AceLocale-3.0
│ ├── AceLocale-3.0.xml
│ └── AceLocale-3.0.lua
├── CallbackHandler-1.0
│ ├── CallbackHandler-1.0.xml
│ └── CallbackHandler-1.0.lua
├── AceConfig-3.0
│ ├── AceConfigCmd-3.0
│ │ └── AceConfigCmd-3.0.xml
│ ├── AceConfigDialog-3.0
│ │ └── AceConfigDialog-3.0.xml
│ ├── AceConfigRegistry-3.0
│ │ └── AceConfigRegistry-3.0.xml
│ ├── AceConfig-3.0.xml
│ └── AceConfig-3.0.lua
├── AceComm-3.0
│ ├── AceComm-3.0.xml
│ └── AceComm-3.0.lua
├── LibStub
│ └── LibStub.lua
└── AceGUI-3.0
│ ├── AceGUI-3.0.xml
│ └── widgets
│ ├── AceGUIContainer-SimpleGroup.lua
│ ├── AceGUIWidget-Heading.lua
│ ├── AceGUIWidget-InteractiveLabel.lua
│ ├── AceGUIWidget-Button.lua
│ ├── AceGUIContainer-InlineGroup.lua
│ ├── AceGUIContainer-BlizOptionsGroup.lua
│ ├── AceGUIWidget-Icon.lua
│ ├── AceGUIContainer-DropDownGroup.lua
│ ├── AceGUIWidget-Label.lua
│ ├── AceGUIWidget-ColorPicker.lua
│ ├── AceGUIContainer-ScrollFrame.lua
│ ├── AceGUIWidget-Keybinding.lua
│ ├── AceGUIWidget-EditBox.lua
│ ├── AceGUIWidget-CheckBox.lua
│ ├── AceGUIWidget-Slider.lua
│ ├── AceGUIContainer-Frame.lua
│ ├── AceGUIContainer-Window.lua
│ ├── AceGUIContainer-TabGroup.lua
│ └── AceGUIWidget-MultiLineEditBox.lua
├── DungeonWatchDog.toc
├── .github
└── workflows
│ └── release.yml
├── README.md
├── embeds.xml
├── components
├── init.lua
├── index.xml
├── ignore_all.lua
├── ignore_list.lua
├── share.lua
└── settings.lua
├── constants.lua
├── init.lua
├── utils.lua
├── locales
├── zhTW.lua
├── zhCN.lua
└── enUS.lua
└── app.lua
/fonts/Prototype.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/unix/DungeonWatchDog/HEAD/fonts/Prototype.ttf
--------------------------------------------------------------------------------
/Bindings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/services/index.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/libs/AceAddon-3.0/AceAddon-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceEvent-3.0/AceEvent-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceLocale-3.0/AceLocale-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/CallbackHandler-1.0/CallbackHandler-1.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceComm-3.0/AceComm-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/DungeonWatchDog.toc:
--------------------------------------------------------------------------------
1 | ## Interface: 90001
2 | ## Title: DungeonWatchDog
3 | ## Title-zhCN: 看门狗
4 | ## Notes: Ignore players in dungeon finder
5 | ## Notes-zhCN: 帮助您更优质的组建队伍
6 | ## Version: @project-version@
7 | ## SavedVariables: WATCHDOG_VARS
8 | ## SavedVariablesPerCharacter: WATCHDOG_DB
9 | ## LoadManagers: AddonLoader
10 | ## OptionalDeps: Ace3
11 | ## X-License: MIT/X
12 |
13 | embeds.xml
14 |
15 | init.lua
16 | constants.lua
17 |
18 | locales\enUS.lua
19 | locales\zhCN.lua
20 |
21 | app.xml
22 |
--------------------------------------------------------------------------------
/libs/AceConfig-3.0/AceConfig-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "**"
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | env:
12 | CF_API_KEY: ${{ secrets.CF_API_KEY }}
13 | GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
14 | steps:
15 | - name: Clone project
16 | uses: actions/checkout@v1
17 | with:
18 | fetch-depth: 5
19 |
20 | - name: Package and release
21 | uses: BigWigsMods/packager@master
22 | with:
23 | args: -p 303265
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Dungeon WatchDog
2 |
3 | A dungeon finder filter with World of Warcraft
4 |
5 | #### What can it help you ?
6 |
7 | - ignore a player in dungeon finder (or MeetingStone).
8 | - ignore all search results.
9 | - auto filtering of ad teams.
10 | - manage your ignore list.
11 | - export / import and share your ignore list.
12 |
13 | #### How do i use it ?
14 |
15 | 1. download addon in [curseforge](https://wow.curseforge.com/projects/dungeonwatchdog/files).
16 | 2. unzip and move addon folder to 'World of Warcraft\Interface\AddOns'
17 | 3. restart World of Warcraft.
18 |
--------------------------------------------------------------------------------
/embeds.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/components/init.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local Components = addon:NewModule('Components')
4 | local Settings = addon:GetModule('Settings')
5 | local IgnoreAll = addon:GetModule('IgnoreAll')
6 | local IgnoreList = addon:GetModule('IgnoreList')
7 |
8 | function Components:OnInitialize()
9 | self.refs = {
10 | ['Settings'] = Settings,
11 | ['IgnoreAll'] = IgnoreAll,
12 | ['IgnoreList'] = IgnoreList,
13 | }
14 | end
15 |
16 | function Components:get(name)
17 | if not self.refs[name] then return nil end
18 | return self.refs[name]
19 | end
20 |
--------------------------------------------------------------------------------
/components/index.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/constants.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local ADDON_VERSION = GetAddOnMetadata(..., 'Version')
3 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
4 | local Constants = addon:NewModule('Constants')
5 |
6 | local infos = {
7 | ADDON_BASE_NAME = ADDON_NAME,
8 | VERSION = ADDON_VERSION,
9 | EXPORT_PLANEL_FRAME = 'exportPanelFrame',
10 | KEYWORD_PLANEL_FRAME = 'keywordPanelFrame',
11 | DEFAULT_EXPORT_SEP = '0Z0',
12 | EXPORT_TYPE_COVER = 'cover',
13 | EXPORT_TYPE_MERGE = 'merge',
14 | PGF_NAME = 'PremadeGroupsFilter',
15 | ADDON_COMM_BASE = ADDON_NAME,
16 | ADDON_COMM_IGNORE_SHARE = 'WATCH_DOG_IG',
17 | ADDON_COMM_IGNORE_SHARE_ONCE = 'WATCH_DOG_IG_O',
18 | }
19 |
20 | function Constants:GetInfos()
21 | return infos
22 | end
23 |
--------------------------------------------------------------------------------
/init.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):NewAddon(ADDON_NAME, 'AceEvent-3.0')
3 | local Init = addon:NewModule('Init')
4 |
5 | function Init:getDefaultSettings()
6 | return {
7 | version = 7,
8 | players = {},
9 | defaultFilterToggle = true,
10 | versionMessageToggle = true,
11 | shareToggle = true,
12 | shareGuildToggle = true,
13 | shareLimit = 500,
14 | ignoreTimeLimit = 259200,
15 | }
16 | end
17 |
18 | function Init:vars()
19 | if not WATCHDOG_VARS then WATCHDOG_VARS = {} end
20 | if not _G then _G = {} end
21 | end
22 |
23 | function Init:DB()
24 | if not WATCHDOG_DB then WATCHDOG_DB = {} end
25 | local requireUpgrade = not WATCHDOG_DB.version or WATCHDOG_DB.version < self.DEFAULT_SETTINGS.version
26 | for k, v in pairs(self.DEFAULT_SETTINGS) do
27 | -- mandatory upgrade, do not modify ignore list
28 | if requireUpgrade then
29 | if k ~= 'players' then
30 | WATCHDOG_DB[k] = v
31 | end
32 | else
33 | if WATCHDOG_DB[k] == nil then
34 | WATCHDOG_DB[k] = v
35 | end
36 | end
37 | end
38 | if not WATCHDOG_DB.players then WATCHDOG_DB.players = {} end
39 | end
40 |
41 | function Init:OnInitialize()
42 | self.DEFAULT_SETTINGS = self:getDefaultSettings()
43 | self:vars()
44 | self:DB()
45 | end
46 |
47 |
48 |
--------------------------------------------------------------------------------
/libs/LibStub/LibStub.lua:
--------------------------------------------------------------------------------
1 | -- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
2 | -- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
3 | local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
4 | local LibStub = _G[LIBSTUB_MAJOR]
5 |
6 | if not LibStub or LibStub.minor < LIBSTUB_MINOR then
7 | LibStub = LibStub or {libs = {}, minors = {} }
8 | _G[LIBSTUB_MAJOR] = LibStub
9 | LibStub.minor = LIBSTUB_MINOR
10 |
11 | function LibStub:NewLibrary(major, minor)
12 | assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
13 | minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
14 |
15 | local oldminor = self.minors[major]
16 | if oldminor and oldminor >= minor then return nil end
17 | self.minors[major], self.libs[major] = minor, self.libs[major] or {}
18 | return self.libs[major], oldminor
19 | end
20 |
21 | function LibStub:GetLibrary(major, silent)
22 | if not self.libs[major] and not silent then
23 | error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
24 | end
25 | return self.libs[major], self.minors[major]
26 | end
27 |
28 | function LibStub:IterateLibraries() return pairs(self.libs) end
29 | setmetatable(LibStub, { __call = LibStub.GetLibrary })
30 | end
31 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/AceGUI-3.0.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/utils.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
4 | local Utils = addon:NewModule('Utils')
5 |
6 | function Utils:OnInitialize()
7 | self.name = UnitName('player')..'-'..GetRealmName()
8 | end
9 |
10 | function Utils:isNilOrZero(...)
11 | local is = true
12 | for k, v in pairs({...}) do
13 | if v ~= nil and v ~= 0 then
14 | is = false
15 | end
16 | end
17 | return is
18 | end
19 |
20 | function Utils:notEmptyStr(...)
21 | local notEmpty = true
22 | for k, str in pairs({...}) do
23 | if not str or str == '' then
24 | notEmpty = false
25 | end
26 | end
27 | return notEmpty
28 | end
29 |
30 | function Utils:encode(s)
31 | local next = string.gsub(s, '([^%w%.%- ])', function(c)
32 | return string.format('%%%02X', string.byte(c))
33 | end)
34 | return string.gsub(next, ' ', '+')
35 | end
36 |
37 | function Utils:decode(s)
38 | local next = string.gsub(s, '%%(%x%x)', function(h)
39 | return string.char(tonumber(h, 16))
40 | end)
41 | return next
42 | end
43 |
44 | function Utils:split(str, reps)
45 | local next = {}
46 | string.gsub(str, '[^'..reps..']+', function(w)
47 | table.insert(next,w)
48 | end)
49 | return next
50 | end
51 |
52 | function Utils:tableLength(t)
53 | if not t then return 0 end
54 | local count = 0
55 | for _, _ in pairs(t) do
56 | count = count + 1
57 | end
58 | return count
59 | end
60 |
61 | function Utils:encodeCommMessages(messages, version)
62 | version = not version and 1
63 | return self.name..'_NEND_'..version..'_VEND_'..messages
64 | end
65 |
66 | function Utils:decodeCommMessages(messages)
67 | local name, version, content = string.match(messages, '(.+)_NEND_(.+)_VEND_(.+)')
68 | return name, version, content
69 | end
70 |
71 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | SimpleGroup Container
3 | Simple container widget that just groups widgets.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "SimpleGroup", 20
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Methods
18 | -------------------------------------------------------------------------------]]
19 | local methods = {
20 | ["OnAcquire"] = function(self)
21 | self:SetWidth(300)
22 | self:SetHeight(100)
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["LayoutFinished"] = function(self, width, height)
28 | if self.noAutoHeight then return end
29 | self:SetHeight(height or 0)
30 | end,
31 |
32 | ["OnWidthSet"] = function(self, width)
33 | local content = self.content
34 | content:SetWidth(width)
35 | content.width = width
36 | end,
37 |
38 | ["OnHeightSet"] = function(self, height)
39 | local content = self.content
40 | content:SetHeight(height)
41 | content.height = height
42 | end
43 | }
44 |
45 | --[[-----------------------------------------------------------------------------
46 | Constructor
47 | -------------------------------------------------------------------------------]]
48 | local function Constructor()
49 | local frame = CreateFrame("Frame", nil, UIParent)
50 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
51 |
52 | --Container Support
53 | local content = CreateFrame("Frame", nil, frame)
54 | content:SetPoint("TOPLEFT")
55 | content:SetPoint("BOTTOMRIGHT")
56 |
57 | local widget = {
58 | frame = frame,
59 | content = content,
60 | type = Type
61 | }
62 | for method, func in pairs(methods) do
63 | widget[method] = func
64 | end
65 |
66 | return AceGUI:RegisterAsContainer(widget)
67 | end
68 |
69 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
70 |
--------------------------------------------------------------------------------
/libs/AceConfig-3.0/AceConfig-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceConfig-3.0 wrapper library.
2 | -- Provides an API to register an options table with the config registry,
3 | -- as well as associate it with a slash command.
4 | -- @class file
5 | -- @name AceConfig-3.0
6 | -- @release $Id: AceConfig-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $
7 |
8 | --[[
9 | AceConfig-3.0
10 |
11 | Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
12 |
13 | ]]
14 |
15 | local cfgreg = LibStub("AceConfigRegistry-3.0")
16 | local cfgcmd = LibStub("AceConfigCmd-3.0")
17 |
18 | local MAJOR, MINOR = "AceConfig-3.0", 3
19 | local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
20 |
21 | if not AceConfig then return end
22 |
23 | --TODO: local cfgdlg = LibStub("AceConfigDialog-3.0", true)
24 | --TODO: local cfgdrp = LibStub("AceConfigDropdown-3.0", true)
25 |
26 | -- Lua APIs
27 | local pcall, error, type, pairs = pcall, error, type, pairs
28 |
29 | -- -------------------------------------------------------------------
30 | -- :RegisterOptionsTable(appName, options, slashcmd, persist)
31 | --
32 | -- - appName - (string) application name
33 | -- - options - table or function ref, see AceConfigRegistry
34 | -- - slashcmd - slash command (string) or table with commands, or nil to NOT create a slash command
35 |
36 | --- Register a option table with the AceConfig registry.
37 | -- You can supply a slash command (or a table of slash commands) to register with AceConfigCmd directly.
38 | -- @paramsig appName, options [, slashcmd]
39 | -- @param appName The application name for the config table.
40 | -- @param options The option table (or a function to generate one on demand). http://www.wowace.com/addons/ace3/pages/ace-config-3-0-options-tables/
41 | -- @param slashcmd A slash command to register for the option table, or a table of slash commands.
42 | -- @usage
43 | -- local AceConfig = LibStub("AceConfig-3.0")
44 | -- AceConfig:RegisterOptionsTable("MyAddon", myOptions, {"/myslash", "/my"})
45 | function AceConfig:RegisterOptionsTable(appName, options, slashcmd)
46 | local ok,msg = pcall(cfgreg.RegisterOptionsTable, self, appName, options)
47 | if not ok then error(msg, 2) end
48 |
49 | if slashcmd then
50 | if type(slashcmd) == "table" then
51 | for _,cmd in pairs(slashcmd) do
52 | cfgcmd:CreateChatCommand(cmd, appName)
53 | end
54 | else
55 | cfgcmd:CreateChatCommand(slashcmd, appName)
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Heading Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Heading", 20
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Methods
16 | -------------------------------------------------------------------------------]]
17 | local methods = {
18 | ["OnAcquire"] = function(self)
19 | self:SetText()
20 | self:SetFullWidth()
21 | self:SetHeight(18)
22 | end,
23 |
24 | -- ["OnRelease"] = nil,
25 |
26 | ["SetText"] = function(self, text)
27 | self.label:SetText(text or "")
28 | if text and text ~= "" then
29 | self.left:SetPoint("RIGHT", self.label, "LEFT", -5, 0)
30 | self.right:Show()
31 | else
32 | self.left:SetPoint("RIGHT", -3, 0)
33 | self.right:Hide()
34 | end
35 | end
36 | }
37 |
38 | --[[-----------------------------------------------------------------------------
39 | Constructor
40 | -------------------------------------------------------------------------------]]
41 | local function Constructor()
42 | local frame = CreateFrame("Frame", nil, UIParent)
43 | frame:Hide()
44 |
45 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontNormal")
46 | label:SetPoint("TOP")
47 | label:SetPoint("BOTTOM")
48 | label:SetJustifyH("CENTER")
49 |
50 | local left = frame:CreateTexture(nil, "BACKGROUND")
51 | left:SetHeight(8)
52 | left:SetPoint("LEFT", 3, 0)
53 | left:SetPoint("RIGHT", label, "LEFT", -5, 0)
54 | left:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
55 | left:SetTexCoord(0.81, 0.94, 0.5, 1)
56 |
57 | local right = frame:CreateTexture(nil, "BACKGROUND")
58 | right:SetHeight(8)
59 | right:SetPoint("RIGHT", -3, 0)
60 | right:SetPoint("LEFT", label, "RIGHT", 5, 0)
61 | right:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
62 | right:SetTexCoord(0.81, 0.94, 0.5, 1)
63 |
64 | local widget = {
65 | label = label,
66 | left = left,
67 | right = right,
68 | frame = frame,
69 | type = Type
70 | }
71 | for method, func in pairs(methods) do
72 | widget[method] = func
73 | end
74 |
75 | return AceGUI:RegisterAsWidget(widget)
76 | end
77 |
78 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
79 |
--------------------------------------------------------------------------------
/components/ignore_all.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
4 | local IgnoreAll = addon:NewModule('IgnoreAll')
5 | local infos = addon:GetModule('Constants'):GetInfos()
6 | local Utils = addon:GetModule('Utils')
7 | local Actions = addon:GetModule('Actions')
8 |
9 | function IgnoreAll:OnInitialize()
10 | local panel = LFGListFrame.SearchPanel
11 | local btn = CreateFrame('Button', nil, panel, 'UIPanelButtonTemplate')
12 | local showTooltip = function(title, desc)
13 | GameTooltip:SetOwner(btn, 'ANCHOR_NONE')
14 | GameTooltip:SetPoint('BOTTOMLEFT', btn, 'TOPRIGHT', 0, 0)
15 | GameTooltip:AddLine(title)
16 | GameTooltip:Show()
17 | end
18 | local hideTooltip = function()
19 | GameTooltip:SetText(' ')
20 | GameTooltip:Hide()
21 | end
22 |
23 | btn:SetPoint('TOPRIGHT', panel, 'TOPRIGHT', -50, -27)
24 | btn:SetSize(50, 27)
25 | btn:SetText(L.IGNORE_ALL_BTN_TEXT)
26 | btn:SetNormalFontObject('GameFontNormal')
27 | btn:SetHighlightFontObject('GameFontHighlight')
28 |
29 | btn:SetScript('OnClick', function() self:showConfirm() end)
30 | btn:SetScript('OnEnter', function()
31 | showTooltip(L.IGNORE_ALL_BTN_TOOLTIP_TITLE)
32 | end)
33 | btn:SetScript('OnLeave', function() hideTooltip() end)
34 | btn:SetScript('OnShow', function()
35 | local _, _, _, loadable = GetAddOnInfo(infos.PGF_NAME)
36 | if loadable then
37 | btn:SetPoint('TOPRIGHT', panel, 'TOPRIGHT', -102, -27)
38 | end
39 | end)
40 |
41 | StaticPopupDialogs['WATCH_DOG_IGNORE_ALL_CONFIRM'] = {
42 | text = L.IGNORE_ALL_CONFIRM_TEXT,
43 | button1 = OKAY,
44 | button2 = NO,
45 | hideOnEscape = true,
46 | timeout = 0,
47 | exclusive = true,
48 | showAlert = true,
49 | OnAccept = function(s) self:banAllPlayers() end,
50 | OnCancel = function(s) self:hideConfirm() end,
51 | }
52 | end
53 |
54 | function IgnoreAll:banAllPlayers()
55 | Actions:banAllPlayers()
56 | local Components = addon:GetModule('Components', true)
57 | if Components then
58 | Components:get('IgnoreList'):updateWhenOpened()
59 | end
60 | collectgarbage('collect')
61 | end
62 |
63 | function IgnoreAll:showConfirm()
64 | PlaySound(SOUNDKIT.IG_MAINMENU_OPEN)
65 | StaticPopup_Show('WATCH_DOG_IGNORE_ALL_CONFIRM')
66 | end
67 |
68 | function IgnoreAll:hideConfirm()
69 | PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE)
70 | StaticPopup_Hide('WATCH_DOG_IGNORE_ALL_CONFIRM')
71 | end
72 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InteractiveLabel Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "InteractiveLabel", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs = select, pairs
10 |
11 | --[[-----------------------------------------------------------------------------
12 | Scripts
13 | -------------------------------------------------------------------------------]]
14 | local function Control_OnEnter(frame)
15 | frame.obj:Fire("OnEnter")
16 | end
17 |
18 | local function Control_OnLeave(frame)
19 | frame.obj:Fire("OnLeave")
20 | end
21 |
22 | local function Label_OnClick(frame, button)
23 | frame.obj:Fire("OnClick", button)
24 | AceGUI:ClearFocus()
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Methods
29 | -------------------------------------------------------------------------------]]
30 | local methods = {
31 | ["OnAcquire"] = function(self)
32 | self:LabelOnAcquire()
33 | self:SetHighlight()
34 | self:SetHighlightTexCoord()
35 | self:SetDisabled(false)
36 | end,
37 |
38 | -- ["OnRelease"] = nil,
39 |
40 | ["SetHighlight"] = function(self, ...)
41 | self.highlight:SetTexture(...)
42 | end,
43 |
44 | ["SetHighlightTexCoord"] = function(self, ...)
45 | local c = select("#", ...)
46 | if c == 4 or c == 8 then
47 | self.highlight:SetTexCoord(...)
48 | else
49 | self.highlight:SetTexCoord(0, 1, 0, 1)
50 | end
51 | end,
52 |
53 | ["SetDisabled"] = function(self,disabled)
54 | self.disabled = disabled
55 | if disabled then
56 | self.frame:EnableMouse(false)
57 | self.label:SetTextColor(0.5, 0.5, 0.5)
58 | else
59 | self.frame:EnableMouse(true)
60 | self.label:SetTextColor(1, 1, 1)
61 | end
62 | end
63 | }
64 |
65 | --[[-----------------------------------------------------------------------------
66 | Constructor
67 | -------------------------------------------------------------------------------]]
68 | local function Constructor()
69 | -- create a Label type that we will hijack
70 | local label = AceGUI:Create("Label")
71 |
72 | local frame = label.frame
73 | frame:EnableMouse(true)
74 | frame:SetScript("OnEnter", Control_OnEnter)
75 | frame:SetScript("OnLeave", Control_OnLeave)
76 | frame:SetScript("OnMouseDown", Label_OnClick)
77 |
78 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
79 | highlight:SetTexture(nil)
80 | highlight:SetAllPoints()
81 | highlight:SetBlendMode("ADD")
82 |
83 | label.highlight = highlight
84 | label.type = Type
85 | label.LabelOnAcquire = label.OnAcquire
86 | for method, func in pairs(methods) do
87 | label[method] = func
88 | end
89 |
90 | return label
91 | end
92 |
93 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
94 |
95 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Button Widget
3 | Graphical Button.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Button", 24
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local _G = _G
14 | local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Scripts
18 | -------------------------------------------------------------------------------]]
19 | local function Button_OnClick(frame, ...)
20 | AceGUI:ClearFocus()
21 | PlaySound(852) -- SOUNDKIT.IG_MAINMENU_OPTION
22 | frame.obj:Fire("OnClick", ...)
23 | end
24 |
25 | local function Control_OnEnter(frame)
26 | frame.obj:Fire("OnEnter")
27 | end
28 |
29 | local function Control_OnLeave(frame)
30 | frame.obj:Fire("OnLeave")
31 | end
32 |
33 | --[[-----------------------------------------------------------------------------
34 | Methods
35 | -------------------------------------------------------------------------------]]
36 | local methods = {
37 | ["OnAcquire"] = function(self)
38 | -- restore default values
39 | self:SetHeight(24)
40 | self:SetWidth(200)
41 | self:SetDisabled(false)
42 | self:SetAutoWidth(false)
43 | self:SetText()
44 | end,
45 |
46 | -- ["OnRelease"] = nil,
47 |
48 | ["SetText"] = function(self, text)
49 | self.text:SetText(text)
50 | if self.autoWidth then
51 | self:SetWidth(self.text:GetStringWidth() + 30)
52 | end
53 | end,
54 |
55 | ["SetAutoWidth"] = function(self, autoWidth)
56 | self.autoWidth = autoWidth
57 | if self.autoWidth then
58 | self:SetWidth(self.text:GetStringWidth() + 30)
59 | end
60 | end,
61 |
62 | ["SetDisabled"] = function(self, disabled)
63 | self.disabled = disabled
64 | if disabled then
65 | self.frame:Disable()
66 | else
67 | self.frame:Enable()
68 | end
69 | end
70 | }
71 |
72 | --[[-----------------------------------------------------------------------------
73 | Constructor
74 | -------------------------------------------------------------------------------]]
75 | local function Constructor()
76 | local name = "AceGUI30Button" .. AceGUI:GetNextWidgetNum(Type)
77 | local frame = CreateFrame("Button", name, UIParent, "UIPanelButtonTemplate")
78 | frame:Hide()
79 |
80 | frame:EnableMouse(true)
81 | frame:SetScript("OnClick", Button_OnClick)
82 | frame:SetScript("OnEnter", Control_OnEnter)
83 | frame:SetScript("OnLeave", Control_OnLeave)
84 |
85 | local text = frame:GetFontString()
86 | text:ClearAllPoints()
87 | text:SetPoint("TOPLEFT", 15, -1)
88 | text:SetPoint("BOTTOMRIGHT", -15, 1)
89 | text:SetJustifyV("MIDDLE")
90 |
91 | local widget = {
92 | text = text,
93 | frame = frame,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsWidget(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | InlineGroup Container
3 | Simple container widget that creates a visible "box" with an optional title.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "InlineGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Methods
17 | -------------------------------------------------------------------------------]]
18 | local methods = {
19 | ["OnAcquire"] = function(self)
20 | self:SetWidth(300)
21 | self:SetHeight(100)
22 | self:SetTitle("")
23 | end,
24 |
25 | -- ["OnRelease"] = nil,
26 |
27 | ["SetTitle"] = function(self,title)
28 | self.titletext:SetText(title)
29 | end,
30 |
31 |
32 | ["LayoutFinished"] = function(self, width, height)
33 | if self.noAutoHeight then return end
34 | self:SetHeight((height or 0) + 40)
35 | end,
36 |
37 | ["OnWidthSet"] = function(self, width)
38 | local content = self.content
39 | local contentwidth = width - 20
40 | if contentwidth < 0 then
41 | contentwidth = 0
42 | end
43 | content:SetWidth(contentwidth)
44 | content.width = contentwidth
45 | end,
46 |
47 | ["OnHeightSet"] = function(self, height)
48 | local content = self.content
49 | local contentheight = height - 20
50 | if contentheight < 0 then
51 | contentheight = 0
52 | end
53 | content:SetHeight(contentheight)
54 | content.height = contentheight
55 | end
56 | }
57 |
58 | --[[-----------------------------------------------------------------------------
59 | Constructor
60 | -------------------------------------------------------------------------------]]
61 | local PaneBackdrop = {
62 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
63 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
64 | tile = true, tileSize = 16, edgeSize = 16,
65 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
66 | }
67 |
68 | local function Constructor()
69 | local frame = CreateFrame("Frame", nil, UIParent)
70 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
71 |
72 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
73 | titletext:SetPoint("TOPLEFT", 14, 0)
74 | titletext:SetPoint("TOPRIGHT", -14, 0)
75 | titletext:SetJustifyH("LEFT")
76 | titletext:SetHeight(18)
77 |
78 | local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
79 | border:SetPoint("TOPLEFT", 0, -17)
80 | border:SetPoint("BOTTOMRIGHT", -1, 3)
81 | border:SetBackdrop(PaneBackdrop)
82 | border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
83 | border:SetBackdropBorderColor(0.4, 0.4, 0.4)
84 |
85 | --Container Support
86 | local content = CreateFrame("Frame", nil, border)
87 | content:SetPoint("TOPLEFT", 10, -10)
88 | content:SetPoint("BOTTOMRIGHT", -10, 10)
89 |
90 | local widget = {
91 | frame = frame,
92 | content = content,
93 | titletext = titletext,
94 | type = Type
95 | }
96 | for method, func in pairs(methods) do
97 | widget[method] = func
98 | end
99 |
100 | return AceGUI:RegisterAsContainer(widget)
101 | end
102 |
103 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
104 |
--------------------------------------------------------------------------------
/locales/zhTW.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):NewLocale(ADDON_NAME, 'zhTW', false)
4 | if not L then return end
5 |
6 | L['ADDON_SHOW_NAME'] = '看門狗'
7 | L['SEARCH_MENU_TEXT'] = '屏蔽此玩家'
8 | L['SEARCH_MENU_TOOLIP_TITLE'] = '屏蔽玩家'
9 | L['SEARCH_MENU_TOOLIP_TEXT'] = '屏蔽後將無法看到此玩家組建的隊伍,可以在面板中取消屏蔽。(在聊天窗口鍵入 “/wd” 瞭解更多信息)'
10 | L['NOT_FOUND_PLAYER_NAME'] = '未找到玩家'
11 | L['NOT_FOUND_PLAYER_NAME_FROM_BANNEDS'] = '未知'
12 | L['VERSION_EXPIRED'] = '版本已過期,請及時更新'
13 | L['WELCOME_MESSAGE'] = '感謝您的使用,您可以在地下城尋找器中右鍵點擊詳細條目來屏蔽指定的玩家。在聊天窗口鍵入 “/wd” 瞭解更多命令。'
14 | L['BANNED_LIST_TITLE'] = '屏蔽列表'
15 | L['BANNED_LIST_CLOSE'] = '關閉'
16 | L['BANNED_LIST_CANCEL'] = '取消屏蔽'
17 | L['BANNED_LIST_COUNT'] = '共計: '
18 |
19 | L['BANNED_LIST_EXPORT_BTN'] = '導入/導出'
20 | L['BANNED_LIST_EXPORT_BTN_TIPS_TITLE'] = '導入/導出'
21 | L['BANNED_LIST_EXPORT_BTN_TIPS_DESC'] = '導入或導出屏蔽列表,你可以選擇覆蓋亦或合併現有的屏蔽名單。'
22 | L['ACTION_BAN_MESSAGE'] = '已經加入屏蔽名單'
23 | L['ACTION_UNBAN_MESSAGE'] = '已經被移除屏蔽'
24 | L['EXPORT_TEXT_EMPTY'] = '沒有找到玩家'
25 | L['EXPORT_TEXT_ERROR'] = '錯誤的配置字符'
26 | L['EXPORT_TITLE_TEXT'] = '導入/導出'
27 | L['EXPORT_COVER_BTN_TEXT'] = '導入并覆蓋'
28 | L['EXPORT_MERGE_BTN_TEXT'] = '導入並合併'
29 | L['EXPORT_CLOSE_BTN_TEXT'] = '关闭'
30 | L['EXPORT_SUCCESS'] = '導入完畢,共計 %s 個玩家'
31 | L['EXPORT_TIPS_WITH_TYPE_COVER'] = '導入數據正在覆蓋原屏蔽列表'
32 | L['SLASH_TIPS_SHOW'] = '展示控制面板'
33 | L['SLASH_TIPS_EXPORT'] = '展示導入與導出面板'
34 | L['SLASH_TIPS_CLEAR'] = '清空屏蔽列表 (取消所有屏蔽)'
35 | L['SLASH_TIPS_VERSION'] = '查看程式版本'
36 | L['CLEAR_BAN_LIST_SUCCESS'] = '已清除屏蔽列表,取消所有屏蔽'
37 | L['CLEAR_BAN_LIST_TIME_SUCCESS'] = '已清除失效玩家,共計 %s 個'
38 | L['IGNORE_ALL_NOT_FOUND_PLAYER'] = '搜索結果中沒有合適的玩家'
39 | L['IGNORE_ALL_COMPLETED'] = '已屏蔽 %s 个玩家'
40 | L['IGNORE_ALL_BTN_TEXT'] = '忽略'
41 | L['IGNORE_ALL_BTN_TOOLTIP_TITLE'] = '屏蔽所有的搜索結果'
42 | L['IGNORE_ALL_CONFIRM_TEXT'] = '看門狗: 這樣做會屏蔽當前搜索結果的所有玩家,你確定嗎?'
43 |
44 | L['MEETINGSTONE_APPLY_TEXT'] = '申請加入'
45 | L['MEETINGSTONE_IGNORE_TITLE'] = '屏蔽 [看門狗]'
46 | L['MEETINGSTONE_IGNORE_TOOLTIP_TITLE'] = '屏蔽此玩家'
47 | L['MEETINGSTONE_IGNORE_TOOLTIP_DESC'] = '屏蔽後將無法看到此玩家組建的隊伍,可以在面板中取消屏蔽。(在聊天窗口鍵入 “/wd” 瞭解更多信息)'
48 |
49 |
50 | L['SETTINGS_PORTAL_NAME'] = '全局'
51 | L['SETTINGS_PORTAL_HEADER'] = '全局'
52 | L['SETTINGS_PORTAL_DESC'] = '\n全局設定\n\n'
53 | L['SETTINGS_PORTAL_TOGGLE1'] = '啓用默認過濾'
54 | L['SETTINGS_PORTAL_TOGGLE2'] = '有新版本時提示我'
55 | L['SETTINGS_PORTAL_SHARE_COUNT'] = '\n\n\n最近共享: '
56 | L['SETTINGS_PORTAL_STATUS_ALL'] = '\n屏蔽列表總數: '
57 | L['SETTINGS_PORTAL_VERSION'] = '\n當前版本: v'
58 | L['SETTINGS_IGNORE_LIST_NAME'] = '屏蔽列表'
59 | L['SETTINGS_IGNORE_LIST_HEADER'] = '屏蔽列表'
60 | L['SETTINGS_IGNORE_LIST_DESC'] = '\n點擊打開屏蔽列表查看詳情。\n\n'
61 | L['SETTINGS_IGNORE_LIST_BTN1'] = '顯示屏蔽列表'
62 | L['SETTINGS_EXPORT_NAME'] = '導入/導出'
63 | L['SETTINGS_EXPORT_HEADER'] = '導入/導出'
64 | L['SETTINGS_EXPORT_DESC'] = '\n你可以通過導出功能與他人分享你的屏蔽列表,同時也能導入一段屏蔽字符串。\n\n導入一段字符串會覆蓋你原有的屏蔽列表。\n'
65 | L['SETTINGS_EXPORT_BTN1'] = '生成導出字符串'
66 | L['SETTINGS_EXPORT_INPUT'] = '導出字符串'
67 | L['SETTINGS_CLEAR_NAME'] = '清理列表'
68 | L['SETTINGS_CLEAR_HEADER'] = '清理列表'
69 | L['SETTINGS_CLEAR_DESC'] = '\n這會清除所有的屏蔽列表,並且不可恢復。\n'
70 | L['SETTINGS_CLEAR_BTN1'] = '立即清理所有'
71 | L['SETTINGS_CLEAR_TIME_DESC'] = '\n\n\n清理屏蔽列表內近期無活動的玩家 (失效玩家)\n'
72 | L['SETTINGS_CLEAR_TIME_BTN1'] = '清理失效玩家'
73 | L['SETTINGS_CLEAR_CONFIR'] = '這樣做會清空屏蔽列表,並且無法恢復,你確定仍舊要這樣做嗎?'
74 | L['SETTINGS_SHARE_NAME'] = '共享'
75 | L['SETTINGS_SHARE_HEADER'] = '共享'
76 | L['SETTINGS_SHARE_DESC'] = '\n看門狗會自動與你的所有好友共享屏蔽列表。\n\n注意: 當你的屏蔽列表數量高於 %s 時,將不會再自動共享數據,除非你及時清理它們\n\n'
77 | L['SETTINGS_SHARE_TOGGLE'] = '自動共享'
78 | L['SETTINGS_SHARE_GUILD_TOGGLE'] = '與公會成員共享'
79 |
80 | L['SHARE_IGNORE_LIMIT'] = '您的自動共享已停止,因爲屏蔽列表數量超過了 %s,請及時清理。'
81 |
--------------------------------------------------------------------------------
/locales/zhCN.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):NewLocale(ADDON_NAME, 'zhCN', false)
4 | if not L then return end
5 |
6 | L['ADDON_SHOW_NAME'] = '看门狗'
7 | L['SEARCH_MENU_TEXT'] = '屏蔽该玩家'
8 | L['SEARCH_MENU_TOOLIP_TITLE'] = '屏蔽玩家'
9 | L['SEARCH_MENU_TOOLIP_TEXT'] = '屏蔽后将无法看到该玩家组建的队伍,可以在控制面板的屏蔽列表中取消。(聊天栏输入 "/wd" 了解更多命令)'
10 | L['NOT_FOUND_PLAYER_NAME'] = '未找到玩家'
11 | L['NOT_FOUND_PLAYER_NAME_FROM_BANNEDS'] = '未知'
12 | L['VERSION_EXPIRED'] = '当前版本已过期,请及时更新'
13 | L['WELCOME_MESSAGE'] = '感谢您的使用。您可以在地下城寻找器中右键点击详细条目来屏蔽指定玩家。在聊天栏输入 "/wd" 了解更多命令。'
14 | L['BANNED_LIST_TITLE'] = '屏蔽列表'
15 | L['BANNED_LIST_CLOSE'] = '关闭'
16 | L['BANNED_LIST_CANCEL'] = '取消屏蔽'
17 | L['BANNED_LIST_COUNT'] = '共计: '
18 |
19 | L['BANNED_LIST_EXPORT_BTN'] = '导入/导出'
20 | L['BANNED_LIST_EXPORT_BTN_TIPS_TITLE'] = '导入/导出'
21 | L['BANNED_LIST_EXPORT_BTN_TIPS_DESC'] = '导入或导出屏蔽列表,可以选择覆盖或合并现有的屏蔽名单。'
22 | L['ACTION_BAN_MESSAGE'] = '已经加入屏蔽名单'
23 | L['ACTION_UNBAN_MESSAGE'] = '已经被移除屏蔽'
24 | L['EXPORT_TEXT_EMPTY'] = '没有找到玩家'
25 | L['EXPORT_TEXT_ERROR'] = '错误的配置字符串'
26 | L['EXPORT_TITLE_TEXT'] = '导入/导出'
27 | L['EXPORT_COVER_BTN_TEXT'] = '导入并覆盖'
28 | L['EXPORT_MERGE_BTN_TEXT'] = '导入并合并'
29 | L['EXPORT_CLOSE_BTN_TEXT'] = '关闭'
30 | L['EXPORT_SUCCESS'] = '导入完毕,共计 %s 个玩家'
31 | L['EXPORT_TIPS_WITH_TYPE_COVER'] = '导入数据正在覆盖原屏蔽列表'
32 | L['SLASH_TIPS_SHOW'] = '展示控制面板'
33 | L['SLASH_TIPS_EXPORT'] = '展示导入与导出面板'
34 | L['SLASH_TIPS_CLEAR'] = '清空屏蔽列表 (取消所有屏蔽)'
35 | L['SLASH_TIPS_VERSION'] = '查看插件版本'
36 | L['CLEAR_BAN_LIST_SUCCESS'] = '已清除屏蔽列表,取消所有屏蔽'
37 | L['CLEAR_BAN_LIST_TIME_SUCCESS'] = '已清除失效玩家,共计 %s 个'
38 | L['IGNORE_ALL_NOT_FOUND_PLAYER'] = '搜索结果中没有合适的玩家'
39 | L['IGNORE_ALL_COMPLETED'] = '已屏蔽 %s 个玩家'
40 | L['IGNORE_ALL_BTN_TEXT'] = '忽略'
41 | L['IGNORE_ALL_BTN_TOOLTIP_TITLE'] = '屏蔽所有的搜索结果'
42 | L['IGNORE_ALL_CONFIRM_TEXT'] = '看门狗: 这样做会屏蔽当前搜索结果的所有玩家,你确定吗?'
43 |
44 | L['MEETINGSTONE_APPLY_TEXT'] = '申请加入'
45 | L['MEETINGSTONE_IGNORE_TITLE'] = '屏蔽 [看门狗]'
46 | L['MEETINGSTONE_IGNORE_TOOLTIP_TITLE'] = '屏蔽此玩家'
47 | L['MEETINGSTONE_IGNORE_TOOLTIP_DESC'] = '屏蔽后将无法看到该玩家组建的队伍,可以在控制面板的屏蔽列表中取消。(聊天栏输入 "/wd" 了解更多命令)'
48 |
49 |
50 | L['SETTINGS_PORTAL_NAME'] = '全局'
51 | L['SETTINGS_PORTAL_HEADER'] = '全局'
52 | L['SETTINGS_PORTAL_DESC'] = '\n全局设置\n\n'
53 | L['SETTINGS_PORTAL_TOGGLE1'] = '启用默认过滤'
54 | L['SETTINGS_PORTAL_TOGGLE2'] = '有新版本时提示我'
55 | L['SETTINGS_PORTAL_SHARE_COUNT'] = '\n\n\n最近共享: '
56 | L['SETTINGS_PORTAL_STATUS_ALL'] = '\n屏蔽列表总数: '
57 | L['SETTINGS_PORTAL_VERSION'] = '\n当前版本: v'
58 | L['SETTINGS_IGNORE_LIST_NAME'] = '屏蔽列表'
59 | L['SETTINGS_IGNORE_LIST_HEADER'] = '屏蔽列表'
60 | L['SETTINGS_IGNORE_LIST_DESC'] = '\n点击打开屏蔽列表查看详情。\n\n'
61 | L['SETTINGS_IGNORE_LIST_BTN1'] = '显示屏蔽列表'
62 | L['SETTINGS_EXPORT_NAME'] = '导入/导出'
63 | L['SETTINGS_EXPORT_HEADER'] = '导入/导出'
64 | L['SETTINGS_EXPORT_DESC'] = '\n你可以通过导出功能与他人分享你的屏蔽列表,同时也能导入一段屏蔽字符串。\n\n导入一段字符会覆盖你原有的屏蔽列表。\n'
65 | L['SETTINGS_EXPORT_BTN1'] = '生成导出字符串'
66 | L['SETTINGS_EXPORT_INPUT'] = '导出字符串'
67 | L['SETTINGS_CLEAR_NAME'] = '清理列表'
68 | L['SETTINGS_CLEAR_HEADER'] = '清理列表'
69 | L['SETTINGS_CLEAR_DESC'] = '\n这会清除所有的屏蔽列表,并且不可恢复。\n'
70 | L['SETTINGS_CLEAR_BTN1'] = '立即清理所有'
71 | L['SETTINGS_CLEAR_TIME_DESC'] = '\n\n\n清理列表内近期未活动的玩家 (失效玩家)\n'
72 | L['SETTINGS_CLEAR_TIME_BTN1'] = '清理失效玩家'
73 | L['SETTINGS_CLEAR_CONFIR'] = '这样做会清空屏蔽列表,并且无法恢复,你确定仍旧要这样做吗?'
74 | L['SETTINGS_SHARE_NAME'] = '共享'
75 | L['SETTINGS_SHARE_HEADER'] = '共享'
76 | L['SETTINGS_SHARE_DESC'] = '\n看门狗会自动与你的所有好友共享屏蔽列表。\n\n注意: 当你的屏蔽列表数量高于 %s 时,将不会再自动共享数据,除非你及时清理它们\n\n'
77 | L['SETTINGS_SHARE_TOGGLE'] = '自动共享'
78 | L['SETTINGS_SHARE_GUILD_TOGGLE'] = '与公会成员共享'
79 |
80 | L['SHARE_IGNORE_LIMIT'] = '您的自动共享已停止,因为屏蔽列表数量超过了 %s,请及时清理。'
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
3 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
4 | local AceComm = LibStub('AceComm-3.0')
5 | local infos = addon:GetModule('Constants'):GetInfos()
6 | local Actions = addon:GetModule('Actions')
7 | local Share = addon:GetModule('Share')
8 | local pairs = pairs
9 |
10 | local replaceSearchResult = function()
11 | local _searchCopy = C_LFGList.GetSearchResults
12 | local limitLevel = Actions:findLimitItemLevel()
13 | local defaultFilterToggle = WATCHDOG_DB.defaultFilterToggle
14 |
15 | C_LFGList.GetSearchResults = function()
16 | local _, searchResults = _searchCopy()
17 | local players, lastSearchPlayers = {}, {}
18 | local passed, lastPlayer, count, lastCount = nil, nil, 0, 0
19 |
20 | for _, id in pairs(searchResults) do
21 | if id then
22 | passed, lastPlayer = Actions:checkListInfo(id, limitLevel, defaultFilterToggle)
23 | if passed then
24 | count = count + 1
25 | players[count] = id
26 | end
27 | if lastPlayer then
28 | lastCount = lastCount + 1
29 | lastSearchPlayers[lastCount] = lastPlayer
30 | end
31 | passed, lastPlayer = nil, nil
32 | end
33 | end
34 |
35 | -- record the results of the previous search
36 | WATCHDOG_VARS.LAST_SEARCH_RESULTS = lastSearchPlayers
37 | lastSearchPlayers, searchResults, count, lastCount = nil, nil, nil, nil
38 | return count, players
39 | end
40 | end
41 |
42 | local findLastFuncPosition = function(list)
43 | local t
44 | for i = 1, #list do
45 | local item = list[i]
46 | if item ~= nil and item.text ~= nil and item.text == L.SEARCH_MENU_TEXT then
47 | t = i
48 | end
49 | end
50 | return t
51 | end
52 |
53 | local replaceNativeUtilWithMenu = function()
54 | local _menuCopy = LFGListUtil_GetSearchEntryMenu
55 | LFGListUtil_GetSearchEntryMenu = function(id)
56 | local list = _menuCopy(id)
57 | local setPosition = #list
58 | local lastPosition = findLastFuncPosition(list)
59 | if lastPosition ~= nil then
60 | setPosition = lastPosition
61 | table.remove(list, lastPosition)
62 | end
63 | table.insert(list, setPosition, {
64 | text = L.SEARCH_MENU_TEXT,
65 | func = function()
66 | Actions:banPlayerWithID(id)
67 | local Components = addon:GetModule('Components', true)
68 | if Components then
69 | local IgnoreList = Components:get('IgnoreList')
70 | IgnoreList:updateWhenOpened()
71 | end
72 | Components = nil
73 | end,
74 | notCheckable = true,
75 | disabled = nil,
76 | tooltipOnButton = 1,
77 | tooltipTitle = L.SEARCH_MENU_TOOLIP_TITLE,
78 | tooltipText = L.SEARCH_MENU_TOOLIP_TEXT,
79 | })
80 | return list
81 | end
82 | end
83 |
84 | function addon:OnInitialize()
85 | local f = CreateFrame('Frame')
86 | f:RegisterEvent('ADDON_LOADED')
87 | f:RegisterEvent('PLAYER_LOGIN')
88 | f:SetScript('OnEvent', function (s, event, name)
89 | if event == 'PLAYER_LOGIN' then
90 | Share:init()
91 | f:UnregisterEvent('ADDON_LOADED')
92 | return f:UnregisterEvent('PLAYER_LOGIN')
93 | end
94 | if event ~= 'ADDON_LOADED' then return end
95 | if name ~= 'MeetingStone' then return end
96 | if LibStub('AceAddon-3.0'):GetAddon('MeetingStone', true) then
97 | Actions:meetingStoneMixin()
98 | end
99 | end)
100 | end
101 |
102 | function addon:OnEnable()
103 | Actions:initSlash()
104 | Actions:sendVersionMessage()
105 | Actions:initAddonMessage()
106 |
107 | replaceNativeUtilWithMenu()
108 | replaceSearchResult()
109 | end
110 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | BlizOptionsGroup Container
3 | Simple container widget for the integration of AceGUI into the Blizzard Interface Options
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "BlizOptionsGroup", 21
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 |
19 | local function OnShow(frame)
20 | frame.obj:Fire("OnShow")
21 | end
22 |
23 | local function OnHide(frame)
24 | frame.obj:Fire("OnHide")
25 | end
26 |
27 | --[[-----------------------------------------------------------------------------
28 | Support functions
29 | -------------------------------------------------------------------------------]]
30 |
31 | local function okay(frame)
32 | frame.obj:Fire("okay")
33 | end
34 |
35 | local function cancel(frame)
36 | frame.obj:Fire("cancel")
37 | end
38 |
39 | local function default(frame)
40 | frame.obj:Fire("default")
41 | end
42 |
43 | local function refresh(frame)
44 | frame.obj:Fire("refresh")
45 | end
46 |
47 | --[[-----------------------------------------------------------------------------
48 | Methods
49 | -------------------------------------------------------------------------------]]
50 |
51 | local methods = {
52 | ["OnAcquire"] = function(self)
53 | self:SetName()
54 | self:SetTitle()
55 | end,
56 |
57 | -- ["OnRelease"] = nil,
58 |
59 | ["OnWidthSet"] = function(self, width)
60 | local content = self.content
61 | local contentwidth = width - 63
62 | if contentwidth < 0 then
63 | contentwidth = 0
64 | end
65 | content:SetWidth(contentwidth)
66 | content.width = contentwidth
67 | end,
68 |
69 | ["OnHeightSet"] = function(self, height)
70 | local content = self.content
71 | local contentheight = height - 26
72 | if contentheight < 0 then
73 | contentheight = 0
74 | end
75 | content:SetHeight(contentheight)
76 | content.height = contentheight
77 | end,
78 |
79 | ["SetName"] = function(self, name, parent)
80 | self.frame.name = name
81 | self.frame.parent = parent
82 | end,
83 |
84 | ["SetTitle"] = function(self, title)
85 | local content = self.content
86 | content:ClearAllPoints()
87 | if not title or title == "" then
88 | content:SetPoint("TOPLEFT", 10, -10)
89 | self.label:SetText("")
90 | else
91 | content:SetPoint("TOPLEFT", 10, -40)
92 | self.label:SetText(title)
93 | end
94 | content:SetPoint("BOTTOMRIGHT", -10, 10)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local function Constructor()
102 | local frame = CreateFrame("Frame")
103 | frame:Hide()
104 |
105 | -- support functions for the Blizzard Interface Options
106 | frame.okay = okay
107 | frame.cancel = cancel
108 | frame.default = default
109 | frame.refresh = refresh
110 |
111 | frame:SetScript("OnHide", OnHide)
112 | frame:SetScript("OnShow", OnShow)
113 |
114 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
115 | label:SetPoint("TOPLEFT", 10, -15)
116 | label:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", 10, -45)
117 | label:SetJustifyH("LEFT")
118 | label:SetJustifyV("TOP")
119 |
120 | --Container Support
121 | local content = CreateFrame("Frame", nil, frame)
122 | content:SetPoint("TOPLEFT", 10, -10)
123 | content:SetPoint("BOTTOMRIGHT", -10, 10)
124 |
125 | local widget = {
126 | label = label,
127 | frame = frame,
128 | content = content,
129 | type = Type
130 | }
131 | for method, func in pairs(methods) do
132 | widget[method] = func
133 | end
134 |
135 | return AceGUI:RegisterAsContainer(widget)
136 | end
137 |
138 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
139 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Icon Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Icon", 21
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs, print = select, pairs, print
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | --[[-----------------------------------------------------------------------------
15 | Scripts
16 | -------------------------------------------------------------------------------]]
17 | local function Control_OnEnter(frame)
18 | frame.obj:Fire("OnEnter")
19 | end
20 |
21 | local function Control_OnLeave(frame)
22 | frame.obj:Fire("OnLeave")
23 | end
24 |
25 | local function Button_OnClick(frame, button)
26 | frame.obj:Fire("OnClick", button)
27 | AceGUI:ClearFocus()
28 | end
29 |
30 | --[[-----------------------------------------------------------------------------
31 | Methods
32 | -------------------------------------------------------------------------------]]
33 | local methods = {
34 | ["OnAcquire"] = function(self)
35 | self:SetHeight(110)
36 | self:SetWidth(110)
37 | self:SetLabel()
38 | self:SetImage(nil)
39 | self:SetImageSize(64, 64)
40 | self:SetDisabled(false)
41 | end,
42 |
43 | -- ["OnRelease"] = nil,
44 |
45 | ["SetLabel"] = function(self, text)
46 | if text and text ~= "" then
47 | self.label:Show()
48 | self.label:SetText(text)
49 | self:SetHeight(self.image:GetHeight() + 25)
50 | else
51 | self.label:Hide()
52 | self:SetHeight(self.image:GetHeight() + 10)
53 | end
54 | end,
55 |
56 | ["SetImage"] = function(self, path, ...)
57 | local image = self.image
58 | image:SetTexture(path)
59 |
60 | if image:GetTexture() then
61 | local n = select("#", ...)
62 | if n == 4 or n == 8 then
63 | image:SetTexCoord(...)
64 | else
65 | image:SetTexCoord(0, 1, 0, 1)
66 | end
67 | end
68 | end,
69 |
70 | ["SetImageSize"] = function(self, width, height)
71 | self.image:SetWidth(width)
72 | self.image:SetHeight(height)
73 | --self.frame:SetWidth(width + 30)
74 | if self.label:IsShown() then
75 | self:SetHeight(height + 25)
76 | else
77 | self:SetHeight(height + 10)
78 | end
79 | end,
80 |
81 | ["SetDisabled"] = function(self, disabled)
82 | self.disabled = disabled
83 | if disabled then
84 | self.frame:Disable()
85 | self.label:SetTextColor(0.5, 0.5, 0.5)
86 | self.image:SetVertexColor(0.5, 0.5, 0.5, 0.5)
87 | else
88 | self.frame:Enable()
89 | self.label:SetTextColor(1, 1, 1)
90 | self.image:SetVertexColor(1, 1, 1, 1)
91 | end
92 | end
93 | }
94 |
95 | --[[-----------------------------------------------------------------------------
96 | Constructor
97 | -------------------------------------------------------------------------------]]
98 | local function Constructor()
99 | local frame = CreateFrame("Button", nil, UIParent)
100 | frame:Hide()
101 |
102 | frame:EnableMouse(true)
103 | frame:SetScript("OnEnter", Control_OnEnter)
104 | frame:SetScript("OnLeave", Control_OnLeave)
105 | frame:SetScript("OnClick", Button_OnClick)
106 |
107 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlight")
108 | label:SetPoint("BOTTOMLEFT")
109 | label:SetPoint("BOTTOMRIGHT")
110 | label:SetJustifyH("CENTER")
111 | label:SetJustifyV("TOP")
112 | label:SetHeight(18)
113 |
114 | local image = frame:CreateTexture(nil, "BACKGROUND")
115 | image:SetWidth(64)
116 | image:SetHeight(64)
117 | image:SetPoint("TOP", 0, -5)
118 |
119 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
120 | highlight:SetAllPoints(image)
121 | highlight:SetTexture(136580) -- Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight
122 | highlight:SetTexCoord(0, 1, 0.23, 0.77)
123 | highlight:SetBlendMode("ADD")
124 |
125 | local widget = {
126 | label = label,
127 | image = image,
128 | frame = frame,
129 | type = Type
130 | }
131 | for method, func in pairs(methods) do
132 | widget[method] = func
133 | end
134 |
135 | widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
136 |
137 | return AceGUI:RegisterAsWidget(widget)
138 | end
139 |
140 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
141 |
--------------------------------------------------------------------------------
/locales/enUS.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):NewLocale(ADDON_NAME, 'enUS', true)
4 |
5 |
6 | L['ADDON_SHOW_NAME'] = 'DUNGEON WATCH DOG'
7 | L['SEARCH_MENU_TEXT'] = 'ignore player'
8 | L['SEARCH_MENU_TOOLIP_TITLE'] = 'Ignore the player'
9 | L['SEARCH_MENU_TOOLIP_TEXT'] = 'After ignoring, you will not see any team from this player.'
10 | L['NOT_FOUND_PLAYER_NAME'] = 'Not found player name'
11 | L['NOT_FOUND_PLAYER_NAME_FROM_BANNEDS'] = 'Unknown'
12 | L['VERSION_EXPIRED'] = 'current version expired'
13 | L['WELCOME_MESSAGE'] = 'Thank you for using, you can click the right button in the Dungeon Finder Panel to ignore the player. Input “/wd” in chat bar to learn more commands.'
14 | L['BANNED_LIST_TITLE'] = 'Ignore list'
15 | L['BANNED_LIST_CANCEL'] = 'Cancel Ignore'
16 | L['BANNED_LIST_COUNT'] = 'Count: '
17 |
18 | L['BANNED_LIST_EXPORT_BTN'] = 'Import/Export'
19 | L['BANNED_LIST_EXPORT_BTN_TIPS_TITLE'] = 'Import / Export'
20 | L['BANNED_LIST_EXPORT_BTN_TIPS_DESC'] = 'Import / Export ignore list,you can choose to overwrite or merge existing ignored list.'
21 | L['ACTION_BAN_MESSAGE'] = 'has been ignored'
22 | L['ACTION_UNBAN_MESSAGE'] = 'has been removed from ignore list'
23 | L['EXPORT_TEXT_EMPTY'] = 'no player found'
24 | L['EXPORT_TEXT_ERROR'] = 'error setting string'
25 | L['EXPORT_SUCCESS'] = 'Import has finished, a total of %s players'
26 | L['EXPORT_TIPS_WITH_TYPE_COVER'] = 'Importing data is overriding the original ignore list.'
27 | L['EXPORT_TITLE_TEXT'] = 'Import / Export'
28 | L['EXPORT_COVER_BTN_TEXT'] = 'Cover import'
29 | L['EXPORT_MERGE_BTN_TEXT'] = 'Merge import'
30 | L['EXPORT_CLOSE_BTN_TEXT'] = 'Close'
31 | L['SLASH_TIPS_SHOW'] = 'show control panel'
32 | L['SLASH_TIPS_EXPORT'] = 'show export panel'
33 | L['SLASH_TIPS_CLEAR'] = 'clear all ignore lists'
34 | L['SLASH_TIPS_VERSION'] = 'show addon version'
35 | L['CLEAR_BAN_LIST_SUCCESS'] = 'all ignore lists have been cleared'
36 | L['CLEAR_BAN_LIST_TIME_SUCCESS'] = 'cleared expired player,a total of %s players'
37 | L['IGNORE_ALL_NOT_FOUND_PLAYER'] = 'no player found in search results'
38 | L['IGNORE_ALL_COMPLETED'] = '%s players have been ignored'
39 | L['IGNORE_ALL_BTN_TEXT'] = 'Ignore'
40 | L['IGNORE_ALL_BTN_TOOLTIP_TITLE'] = 'ignore all search results'
41 | L['IGNORE_ALL_CONFIRM_TEXT'] = 'WatchDog: This will ignore all players of the current search results. Are you sure ?'
42 |
43 | L['MEETINGSTONE_APPLY_TEXT'] = 'APPLY'
44 | L['MEETINGSTONE_IGNORE_TITLE'] = 'IGNORE [WATCH_DOG]'
45 | L['MEETINGSTONE_IGNORE_TOOLTIP_TITLE'] = 'Ignore this player'
46 | L['MEETINGSTONE_IGNORE_TOOLTIP_DESC'] = 'After ignoring, you will not see any team from this player.'
47 |
48 |
49 | L['SETTINGS_PORTAL_NAME'] = 'Global'
50 | L['SETTINGS_PORTAL_HEADER'] = 'Global'
51 | L['SETTINGS_PORTAL_DESC'] = '\nGlobal Settings\n\n'
52 | L['SETTINGS_PORTAL_TOGGLE1'] = 'Enable default filter'
53 | L['SETTINGS_PORTAL_TOGGLE2'] = 'Remind me when version updated'
54 | L['SETTINGS_PORTAL_SHARE_COUNT'] = '\n\n\nRecently shared: '
55 | L['SETTINGS_PORTAL_STATUS_ALL'] = '\nIgnore list count: '
56 | L['SETTINGS_PORTAL_VERSION'] = '\nCurrent version: v'
57 | L['SETTINGS_IGNORE_LIST_NAME'] = 'Ignore list'
58 | L['SETTINGS_IGNORE_LIST_HEADER'] = 'Ignore list'
59 | L['SETTINGS_IGNORE_LIST_DESC'] = '\nClick to open the ignore list to see details.\n\n'
60 | L['SETTINGS_IGNORE_LIST_BTN1'] = 'Show ignore list'
61 | L['SETTINGS_EXPORT_NAME'] = 'Improt/Export'
62 | L['SETTINGS_EXPORT_HEADER'] = 'Improt / Export'
63 | L['SETTINGS_EXPORT_DESC'] = '\nYou can share your list with others by Export, and you can also import a string.\n\nImporting a string will cover your ignore list.\n'
64 | L['SETTINGS_EXPORT_BTN1'] = 'Generate export string'
65 | L['SETTINGS_EXPORT_INPUT'] = 'Export string'
66 | L['SETTINGS_CLEAR_NAME'] = 'Clean up'
67 | L['SETTINGS_CLEAR_HEADER'] = 'Clean up'
68 | L['SETTINGS_CLEAR_DESC'] = '\nThis clears all ignore lists and is not recoverable.\n'
69 | L['SETTINGS_CLEAR_BTN1'] = 'Clear up all'
70 | L['SETTINGS_CLEAR_TIME_DESC'] = '\n\n\nClean up the recent inactive players in the ignore list (expired players)\n'
71 | L['SETTINGS_CLEAR_TIME_BTN1'] = 'Clean up expired players'
72 | L['SETTINGS_CLEAR_CONFIR'] = 'This operation will empty ignore list and cannot be resumed. Are you sure you want to do that?'
73 | L['SETTINGS_SHARE_NAME'] = 'Share'
74 | L['SETTINGS_SHARE_HEADER'] = 'Share'
75 | L['SETTINGS_SHARE_DESC'] = '\nWatchdog will automatically share the ignore list with your friends.\n\nTips: Data will not be shared when your ignore list is above %s, unless you clean them up in time.\n\n'
76 | L['SETTINGS_SHARE_TOGGLE'] = 'Auto share'
77 | L['SETTINGS_SHARE_GUILD_TOGGLE'] = 'Share with guild members'
78 |
79 | L['SHARE_IGNORE_LIMIT'] = 'Your automatic sharing has stopped, because the number of ignored lists exceeds %s, please clear up in time.'
80 |
81 |
--------------------------------------------------------------------------------
/components/ignore_list.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
4 | local IgnoreList = addon:NewModule('IgnoreList')
5 | local infos = addon:GetModule('Constants'):GetInfos()
6 | local Utils = addon:GetModule('Utils')
7 | local Actions = addon:GetModule('Actions')
8 | local AceGUI = LibStub('AceGUI-3.0')
9 |
10 | function IgnoreList:OnInitialize()
11 | self.len = 0
12 | self.scrollValue = 0
13 | self.lastSearchText = ''
14 | self.dropdown = CreateFrame('Frame', 'TouchDogDropMenu', nil, 'UIDropDownMenuTemplate')
15 | self.options = {
16 | {
17 | text = ' ',
18 | isTitle = true,
19 | notCheckable = true,
20 | },
21 | {
22 | text = L.BANNED_LIST_CANCEL,
23 | notCheckable = true,
24 | arg1 = nil,
25 | func = function(_, name)
26 | Actions:unbanPlayerWithName(name)
27 | -- self:updateScrollValue()
28 | self:updatePlayersWithKeyWord('')
29 | -- self:updateScrollPosition()
30 |
31 | if self.lastSearchText then
32 | self:updatePlayersWithKeyWord(self.lastSearchText)
33 | end
34 | end,
35 | },
36 | {
37 | text = CANCEL,
38 | notCheckable = true,
39 | },
40 | }
41 | end
42 |
43 | function IgnoreList:initOptions(name)
44 | local options = self.options
45 | options[1].text = name
46 | options[2].arg1 = name
47 | return options
48 | end
49 |
50 | function IgnoreList:initItem(name)
51 | local s, dropdown = self, self.dropdown
52 | local label = AceGUI:Create('InteractiveLabel')
53 | label:SetText(' '..name)
54 | label:SetColor(0.871, 0.777, 0.3)
55 | label:SetHeight(25)
56 | label.label:SetHeight(25)
57 | label:SetJustifyV('CENTER')
58 | label:SetCallback('OnEnter', function (self)
59 | self:SetColor(0.5, 0.5, 0.07)
60 | end)
61 | label:SetCallback('OnLeave', function (self)
62 | self:SetColor(0.871, 0.777, 0.3)
63 | end)
64 | label:SetCallback('OnClick', function (s, e, btn)
65 | if btn ~= 'RightButton' then return end
66 | EasyMenu(self:initOptions(name), dropdown, s.frame, 170, 5, 'MENU')
67 | end)
68 | return label
69 | end
70 |
71 | function IgnoreList:updatePlayerCount(len)
72 | self.frame:SetStatusText(L.BANNED_LIST_COUNT..len)
73 | self.len = len
74 | end
75 |
76 | function IgnoreList:update(players)
77 | self.scrollContainer:ReleaseChildren()
78 | self.scroll = nil
79 | local scroll = AceGUI:Create('ScrollFrame')
80 | scroll:SetLayout('Flow')
81 |
82 | for name, player in pairs(players) do
83 | if name then
84 | scroll:AddChild(self:initItem(name))
85 | end
86 | end
87 | self.scroll = scroll
88 | self.scrollContainer:AddChild(scroll)
89 | end
90 |
91 | function IgnoreList:render()
92 | self.frame = AceGUI:Create('Frame')
93 | local f = self.frame
94 | f:Hide()
95 | f:ReleaseChildren()
96 | f:SetTitle(L.BANNED_LIST_TITLE)
97 | f:SetLayout('Flow')
98 | f:SetWidth(260)
99 | f:SetHeight(460)
100 | f:EnableResize(false)
101 | local search = AceGUI:Create('EditBox')
102 | search:SetFullWidth(true)
103 | search:SetCallback('OnEnterPressed', function (s, e, text)
104 | self.lastSearchText = text
105 | self:updatePlayersWithKeyWord(text)
106 | end)
107 | f:AddChild(search)
108 | self.scrollContainer = AceGUI:Create('SimpleGroup')
109 | self.scrollContainer:SetFullWidth(true)
110 | self.scrollContainer:SetFullHeight(true)
111 | self.scrollContainer:SetLayout('Fill')
112 | f:Show()
113 | f:AddChild(self.scrollContainer)
114 | end
115 |
116 | function IgnoreList:open()
117 | self:render()
118 | self:updatePlayersWithKeyWord('')
119 | end
120 |
121 | function IgnoreList:updatePlayersWithKeyWord(text)
122 | local players, result, count = WATCHDOG_DB.players, {}, 0
123 | for name, player in pairs(players) do
124 | if name and string.find(name, text) then
125 | result[name] = player
126 | count = count + 1
127 | end
128 | end
129 | PlaySound(SOUNDKIT.IG_MAINMENU_OPEN)
130 | self:updatePlayerCount(count)
131 | return self:update(result)
132 | end
133 |
134 | function IgnoreList:updateScrollValue()
135 | if self.scroll then
136 | self.scrollValue = self.scroll.scrollbar:GetValue()
137 | end
138 | end
139 |
140 | function IgnoreList:updateScrollPosition()
141 | if self.scrollValue and self.scroll then
142 | self.scroll:SetScroll(self.scrollValue)
143 | end
144 | end
145 |
146 | function IgnoreList:updateWhenOpened()
147 | if self.frame and self.frame:IsShown() then
148 | self:updatePlayersWithKeyWord(self.lastSearchText)
149 | end
150 | end
151 |
--------------------------------------------------------------------------------
/libs/AceEvent-3.0/AceEvent-3.0.lua:
--------------------------------------------------------------------------------
1 | --- AceEvent-3.0 provides event registration and secure dispatching.
2 | -- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
3 | -- CallbackHandler, and dispatches all game events or addon message to the registrees.
4 | --
5 | -- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceEvent itself.\\
8 | -- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceEvent.
10 | -- @class file
11 | -- @name AceEvent-3.0
12 | -- @release $Id: AceEvent-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $
13 | local CallbackHandler = LibStub("CallbackHandler-1.0")
14 |
15 | local MAJOR, MINOR = "AceEvent-3.0", 4
16 | local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
17 |
18 | if not AceEvent then return end
19 |
20 | -- Lua APIs
21 | local pairs = pairs
22 |
23 | AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
24 | AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
25 |
26 | -- APIs and registry for blizzard events, using CallbackHandler lib
27 | if not AceEvent.events then
28 | AceEvent.events = CallbackHandler:New(AceEvent,
29 | "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
30 | end
31 |
32 | function AceEvent.events:OnUsed(target, eventname)
33 | AceEvent.frame:RegisterEvent(eventname)
34 | end
35 |
36 | function AceEvent.events:OnUnused(target, eventname)
37 | AceEvent.frame:UnregisterEvent(eventname)
38 | end
39 |
40 |
41 | -- APIs and registry for IPC messages, using CallbackHandler lib
42 | if not AceEvent.messages then
43 | AceEvent.messages = CallbackHandler:New(AceEvent,
44 | "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
45 | )
46 | AceEvent.SendMessage = AceEvent.messages.Fire
47 | end
48 |
49 | --- embedding and embed handling
50 | local mixins = {
51 | "RegisterEvent", "UnregisterEvent",
52 | "RegisterMessage", "UnregisterMessage",
53 | "SendMessage",
54 | "UnregisterAllEvents", "UnregisterAllMessages",
55 | }
56 |
57 | --- Register for a Blizzard Event.
58 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
59 | -- Any arguments to the event will be passed on after that.
60 | -- @name AceEvent:RegisterEvent
61 | -- @class function
62 | -- @paramsig event[, callback [, arg]]
63 | -- @param event The event to register for
64 | -- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
65 | -- @param arg An optional argument to pass to the callback function
66 |
67 | --- Unregister an event.
68 | -- @name AceEvent:UnregisterEvent
69 | -- @class function
70 | -- @paramsig event
71 | -- @param event The event to unregister
72 |
73 | --- Register for a custom AceEvent-internal message.
74 | -- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
75 | -- Any arguments to the event will be passed on after that.
76 | -- @name AceEvent:RegisterMessage
77 | -- @class function
78 | -- @paramsig message[, callback [, arg]]
79 | -- @param message The message to register for
80 | -- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
81 | -- @param arg An optional argument to pass to the callback function
82 |
83 | --- Unregister a message
84 | -- @name AceEvent:UnregisterMessage
85 | -- @class function
86 | -- @paramsig message
87 | -- @param message The message to unregister
88 |
89 | --- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
90 | -- @name AceEvent:SendMessage
91 | -- @class function
92 | -- @paramsig message, ...
93 | -- @param message The message to send
94 | -- @param ... Any arguments to the message
95 |
96 |
97 | -- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
98 | -- @param target target object to embed AceEvent in
99 | function AceEvent:Embed(target)
100 | for k, v in pairs(mixins) do
101 | target[v] = self[v]
102 | end
103 | self.embeds[target] = true
104 | return target
105 | end
106 |
107 | -- AceEvent:OnEmbedDisable( target )
108 | -- target (object) - target object that is being disabled
109 | --
110 | -- Unregister all events messages etc when the target disables.
111 | -- this method should be called by the target manually or by an addon framework
112 | function AceEvent:OnEmbedDisable(target)
113 | target:UnregisterAllEvents()
114 | target:UnregisterAllMessages()
115 | end
116 |
117 | -- Script to fire blizzard events into the event listeners
118 | local events = AceEvent.events
119 | AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
120 | events:Fire(event, ...)
121 | end)
122 |
123 | --- Finally: upgrade our old embeds
124 | for target, v in pairs(AceEvent.embeds) do
125 | AceEvent:Embed(target)
126 | end
127 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | DropdownGroup Container
3 | Container controlled by a dropdown on the top.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "DropdownGroup", 22
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local assert, pairs, type = assert, pairs, type
11 |
12 | -- WoW APIs
13 | local CreateFrame = CreateFrame
14 |
15 | --[[-----------------------------------------------------------------------------
16 | Scripts
17 | -------------------------------------------------------------------------------]]
18 | local function SelectedGroup(self, event, value)
19 | local group = self.parentgroup
20 | local status = group.status or group.localstatus
21 | status.selected = value
22 | self.parentgroup:Fire("OnGroupSelected", value)
23 | end
24 |
25 | --[[-----------------------------------------------------------------------------
26 | Methods
27 | -------------------------------------------------------------------------------]]
28 | local methods = {
29 | ["OnAcquire"] = function(self)
30 | self.dropdown:SetText("")
31 | self:SetDropdownWidth(200)
32 | self:SetTitle("")
33 | end,
34 |
35 | ["OnRelease"] = function(self)
36 | self.dropdown.list = nil
37 | self.status = nil
38 | for k in pairs(self.localstatus) do
39 | self.localstatus[k] = nil
40 | end
41 | end,
42 |
43 | ["SetTitle"] = function(self, title)
44 | self.titletext:SetText(title)
45 | self.dropdown.frame:ClearAllPoints()
46 | if title and title ~= "" then
47 | self.dropdown.frame:SetPoint("TOPRIGHT", -2, 0)
48 | else
49 | self.dropdown.frame:SetPoint("TOPLEFT", -1, 0)
50 | end
51 | end,
52 |
53 | ["SetGroupList"] = function(self,list,order)
54 | self.dropdown:SetList(list,order)
55 | end,
56 |
57 | ["SetStatusTable"] = function(self, status)
58 | assert(type(status) == "table")
59 | self.status = status
60 | end,
61 |
62 | ["SetGroup"] = function(self,group)
63 | self.dropdown:SetValue(group)
64 | local status = self.status or self.localstatus
65 | status.selected = group
66 | self:Fire("OnGroupSelected", group)
67 | end,
68 |
69 | ["OnWidthSet"] = function(self, width)
70 | local content = self.content
71 | local contentwidth = width - 26
72 | if contentwidth < 0 then
73 | contentwidth = 0
74 | end
75 | content:SetWidth(contentwidth)
76 | content.width = contentwidth
77 | end,
78 |
79 | ["OnHeightSet"] = function(self, height)
80 | local content = self.content
81 | local contentheight = height - 63
82 | if contentheight < 0 then
83 | contentheight = 0
84 | end
85 | content:SetHeight(contentheight)
86 | content.height = contentheight
87 | end,
88 |
89 | ["LayoutFinished"] = function(self, width, height)
90 | self:SetHeight((height or 0) + 63)
91 | end,
92 |
93 | ["SetDropdownWidth"] = function(self, width)
94 | self.dropdown:SetWidth(width)
95 | end
96 | }
97 |
98 | --[[-----------------------------------------------------------------------------
99 | Constructor
100 | -------------------------------------------------------------------------------]]
101 | local PaneBackdrop = {
102 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
103 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
104 | tile = true, tileSize = 16, edgeSize = 16,
105 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
106 | }
107 |
108 | local function Constructor()
109 | local frame = CreateFrame("Frame")
110 | frame:SetHeight(100)
111 | frame:SetWidth(100)
112 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
113 |
114 | local titletext = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
115 | titletext:SetPoint("TOPLEFT", 4, -5)
116 | titletext:SetPoint("TOPRIGHT", -4, -5)
117 | titletext:SetJustifyH("LEFT")
118 | titletext:SetHeight(18)
119 |
120 | local dropdown = AceGUI:Create("Dropdown")
121 | dropdown.frame:SetParent(frame)
122 | dropdown.frame:SetFrameLevel(dropdown.frame:GetFrameLevel() + 2)
123 | dropdown:SetCallback("OnValueChanged", SelectedGroup)
124 | dropdown.frame:SetPoint("TOPLEFT", -1, 0)
125 | dropdown.frame:Show()
126 | dropdown:SetLabel("")
127 |
128 | local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
129 | border:SetPoint("TOPLEFT", 0, -26)
130 | border:SetPoint("BOTTOMRIGHT", 0, 3)
131 | border:SetBackdrop(PaneBackdrop)
132 | border:SetBackdropColor(0.1,0.1,0.1,0.5)
133 | border:SetBackdropBorderColor(0.4,0.4,0.4)
134 |
135 | --Container Support
136 | local content = CreateFrame("Frame", nil, border)
137 | content:SetPoint("TOPLEFT", 10, -10)
138 | content:SetPoint("BOTTOMRIGHT", -10, 10)
139 |
140 | local widget = {
141 | frame = frame,
142 | localstatus = {},
143 | titletext = titletext,
144 | dropdown = dropdown,
145 | border = border,
146 | content = content,
147 | type = Type
148 | }
149 | for method, func in pairs(methods) do
150 | widget[method] = func
151 | end
152 | dropdown.parentgroup = widget
153 |
154 | return AceGUI:RegisterAsContainer(widget)
155 | end
156 |
157 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
158 |
--------------------------------------------------------------------------------
/components/share.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local AceComm = LibStub('AceComm-3.0')
4 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
5 | local Share = addon:NewModule('Share', 'AceEvent-3.0')
6 | local infos = addon:GetModule('Constants'):GetInfos()
7 | local Utils = addon:GetModule('Utils')
8 | local Actions = addon:GetModule('Actions')
9 |
10 |
11 | function Share:OnInitialize()
12 | self:RegisterMessage('NETWORKS_CONNECTION_CREATION', 'OnConnectionCreation')
13 |
14 | ChatFrame_AddMessageEventFilter('CHAT_MSG_SYSTEM', function(_, _, msg)
15 | if self:isUnkownMessage(msg) then return true end
16 | return false
17 | end)
18 | end
19 |
20 | function Share:init()
21 | if not WATCHDOG_DB.shareToggle then return end
22 |
23 | self.friends = {}
24 | self.BNCount = 0
25 | self.socialCount = 0
26 | self.shareCount = 0
27 | self.ignoreCount = Utils:tableLength(WATCHDOG_DB.players)
28 | self.faction = UnitFactionGroup('player')
29 |
30 | self:checkIgnoreCount()
31 | self:updateBNCount()
32 | self:updateBNNames()
33 | self:updateSocialNames()
34 | if WATCHDOG_DB.shareGuildToggle then
35 | self:sendIgnoreListToGuild()
36 | end
37 | end
38 |
39 | function Share:checkIgnoreCount()
40 | if not WATCHDOG_DB.shareToggle then return end
41 | if self.ignoreCount < WATCHDOG_DB.shareLimit then return end
42 | Actions:log(string.format(L.SHARE_IGNORE_LIMIT, WATCHDOG_DB.shareLimit))
43 | end
44 |
45 | function Share:updateBNCount()
46 | self.BNCount = BNGetNumFriends()
47 | self.socialCount = C_FriendList.GetNumOnlineFriends()
48 | end
49 |
50 | function Share:updateBNNames()
51 | local updateHandle = function(friend)
52 | if friend[3] ~= 'WoW' then return end
53 | if friend[6] ~= self.faction then return end
54 |
55 | -- sometimes there are deplays in BN, name and realm must be checked.
56 | if Utils:notEmptyStr(friend[2], friend[4]) then
57 | local name = friend[2]..'-'..friend[4]
58 |
59 | -- update only once.
60 | if not self.friends[name] then
61 | self:sendIgnoreList(name)
62 | self.friends[name] = 1
63 | end
64 | end
65 | end
66 |
67 | local accounts = 0
68 | for i = 1, self.BNCount do
69 | accounts = C_BattleNet.GetFriendNumGameAccounts(i)
70 | if accounts and accounts ~= 0 then
71 | for k = 1, accounts do
72 | updateHandle({ C_BattleNet.GetFriendGameAccountInfo(i, k) })
73 | end
74 | end
75 | accounts = 0
76 | end
77 | end
78 |
79 | function Share:updateSocialNames()
80 | local realm = '-'..GetRealmName()
81 |
82 | for i = 1, self.socialCount do
83 | local name, _, _, _, isOnline = C_FriendList.GetFriendInfo(i)
84 | if isOnline and Utils:notEmptyStr(name) then
85 | local full = name..realm
86 | if Utils:notEmptyStr(full) and not self.friends[full] then
87 | self:sendIgnoreList(full)
88 | self.friends[full] = 1
89 | end
90 | end
91 | end
92 | end
93 |
94 | function Share:sendIgnoreList(name, once)
95 | if not WATCHDOG_DB.shareToggle then return end
96 | if self.ignoreCount > WATCHDOG_DB.shareLimit then return end
97 | if self:isUnkownPlayer(name) then return end
98 |
99 | local str = (once and Actions:ExportSettings()) or ''
100 | local type = (once and infos.ADDON_COMM_IGNORE_SHARE_ONCE) or infos.ADDON_COMM_IGNORE_SHARE
101 | if not Utils:notEmptyStr(str) then str = infos.DEFAULT_EXPORT_SEP end
102 | AceComm:SendCommMessage(type, Utils:encodeCommMessages(str), 'WHISPER', name)
103 | end
104 |
105 | function Share:sendIgnoreListToGuild()
106 | if not WATCHDOG_DB.shareToggle then return end
107 | if not WATCHDOG_DB.shareGuildToggle then return end
108 | if self.ignoreCount > WATCHDOG_DB.shareLimit then return end
109 | AceComm:SendCommMessage(infos.ADDON_COMM_IGNORE_SHARE, Utils:encodeCommMessages(infos.DEFAULT_EXPORT_SEP), 'GUILD')
110 | end
111 |
112 | function Share:OnConnectionCreation(e, text, once)
113 | if not WATCHDOG_DB.shareToggle then return end
114 | if self.ignoreCount > WATCHDOG_DB.shareLimit then return end
115 | local name, version, content = Utils:decodeCommMessages(text)
116 | if self:isUnkownPlayer(name) then return end
117 |
118 | Actions:importSettings(content, true)
119 | self:updateShareCount()
120 |
121 | if not once then
122 | self:sendIgnoreList(name, true)
123 | end
124 | end
125 |
126 | function Share:updateShareCount()
127 | self.shareCount = self.shareCount + 1
128 | end
129 |
130 | function Share:getShareCount()
131 | return self.shareCount or 0
132 | end
133 |
134 | function Share:isUnkownPlayer(name)
135 | if not name or name == '' then return true end
136 | if string.find(name, '未知') then return true end
137 | if string.find(name, 'Unkown') then return true end
138 | if not self.username then
139 | self.username = UnitName('player')
140 | end
141 | if string.find(name, self.username) then return true end
142 | return false
143 | end
144 |
145 | function Share:isUnkownMessage(msg)
146 | if not msg or msg == '' then return false end
147 | if string.find(msg, '未找到名') then return true end
148 | if string.find(msg, 'No player named') then return true end
149 | return false
150 | end
151 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Label Widget
3 | Displays text and optionally an icon.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Label", 27
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local max, select, pairs = math.max, select, pairs
11 |
12 | -- WoW APIs
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
16 | -- List them here for Mikk's FindGlobals script
17 | -- GLOBALS: GameFontHighlightSmall
18 |
19 | --[[-----------------------------------------------------------------------------
20 | Support functions
21 | -------------------------------------------------------------------------------]]
22 |
23 | local function UpdateImageAnchor(self)
24 | if self.resizing then return end
25 | local frame = self.frame
26 | local width = frame.width or frame:GetWidth() or 0
27 | local image = self.image
28 | local label = self.label
29 | local height
30 |
31 | label:ClearAllPoints()
32 | image:ClearAllPoints()
33 |
34 | if self.imageshown then
35 | local imagewidth = image:GetWidth()
36 | if (width - imagewidth) < 200 or (label:GetText() or "") == "" then
37 | -- image goes on top centered when less than 200 width for the text, or if there is no text
38 | image:SetPoint("TOP")
39 | label:SetPoint("TOP", image, "BOTTOM")
40 | label:SetPoint("LEFT")
41 | label:SetWidth(width)
42 | height = image:GetHeight() + label:GetStringHeight()
43 | else
44 | -- image on the left
45 | image:SetPoint("TOPLEFT")
46 | if image:GetHeight() > label:GetStringHeight() then
47 | label:SetPoint("LEFT", image, "RIGHT", 4, 0)
48 | else
49 | label:SetPoint("TOPLEFT", image, "TOPRIGHT", 4, 0)
50 | end
51 | label:SetWidth(width - imagewidth - 4)
52 | height = max(image:GetHeight(), label:GetStringHeight())
53 | end
54 | else
55 | -- no image shown
56 | label:SetPoint("TOPLEFT")
57 | label:SetWidth(width)
58 | height = label:GetStringHeight()
59 | end
60 |
61 | -- avoid zero-height labels, since they can used as spacers
62 | if not height or height == 0 then
63 | height = 1
64 | end
65 |
66 | self.resizing = true
67 | frame:SetHeight(height)
68 | frame.height = height
69 | self.resizing = nil
70 | end
71 |
72 | --[[-----------------------------------------------------------------------------
73 | Methods
74 | -------------------------------------------------------------------------------]]
75 | local methods = {
76 | ["OnAcquire"] = function(self)
77 | -- set the flag to stop constant size updates
78 | self.resizing = true
79 | -- height is set dynamically by the text and image size
80 | self:SetWidth(200)
81 | self:SetText()
82 | self:SetImage(nil)
83 | self:SetImageSize(16, 16)
84 | self:SetColor()
85 | self:SetFontObject()
86 | self:SetJustifyH("LEFT")
87 | self:SetJustifyV("TOP")
88 |
89 | -- reset the flag
90 | self.resizing = nil
91 | -- run the update explicitly
92 | UpdateImageAnchor(self)
93 | end,
94 |
95 | -- ["OnRelease"] = nil,
96 |
97 | ["OnWidthSet"] = function(self, width)
98 | UpdateImageAnchor(self)
99 | end,
100 |
101 | ["SetText"] = function(self, text)
102 | self.label:SetText(text)
103 | UpdateImageAnchor(self)
104 | end,
105 |
106 | ["SetColor"] = function(self, r, g, b)
107 | if not (r and g and b) then
108 | r, g, b = 1, 1, 1
109 | end
110 | self.label:SetVertexColor(r, g, b)
111 | end,
112 |
113 | ["SetImage"] = function(self, path, ...)
114 | local image = self.image
115 | image:SetTexture(path)
116 |
117 | if image:GetTexture() then
118 | self.imageshown = true
119 | local n = select("#", ...)
120 | if n == 4 or n == 8 then
121 | image:SetTexCoord(...)
122 | else
123 | image:SetTexCoord(0, 1, 0, 1)
124 | end
125 | else
126 | self.imageshown = nil
127 | end
128 | UpdateImageAnchor(self)
129 | end,
130 |
131 | ["SetFont"] = function(self, font, height, flags)
132 | self.label:SetFont(font, height, flags)
133 | UpdateImageAnchor(self)
134 | end,
135 |
136 | ["SetFontObject"] = function(self, font)
137 | self:SetFont((font or GameFontHighlightSmall):GetFont())
138 | end,
139 |
140 | ["SetImageSize"] = function(self, width, height)
141 | self.image:SetWidth(width)
142 | self.image:SetHeight(height)
143 | UpdateImageAnchor(self)
144 | end,
145 |
146 | ["SetJustifyH"] = function(self, justifyH)
147 | self.label:SetJustifyH(justifyH)
148 | end,
149 |
150 | ["SetJustifyV"] = function(self, justifyV)
151 | self.label:SetJustifyV(justifyV)
152 | end,
153 | }
154 |
155 | --[[-----------------------------------------------------------------------------
156 | Constructor
157 | -------------------------------------------------------------------------------]]
158 | local function Constructor()
159 | local frame = CreateFrame("Frame", nil, UIParent)
160 | frame:Hide()
161 |
162 | local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
163 | local image = frame:CreateTexture(nil, "BACKGROUND")
164 |
165 | -- create widget
166 | local widget = {
167 | label = label,
168 | image = image,
169 | frame = frame,
170 | type = Type
171 | }
172 | for method, func in pairs(methods) do
173 | widget[method] = func
174 | end
175 |
176 | return AceGUI:RegisterAsWidget(widget)
177 | end
178 |
179 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
180 |
--------------------------------------------------------------------------------
/libs/AceLocale-3.0/AceLocale-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
2 | -- @class file
3 | -- @name AceLocale-3.0
4 | -- @release $Id: AceLocale-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $
5 | local MAJOR,MINOR = "AceLocale-3.0", 6
6 |
7 | local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
8 |
9 | if not AceLocale then return end -- no upgrade needed
10 |
11 | -- Lua APIs
12 | local assert, tostring, error = assert, tostring, error
13 | local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
14 |
15 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
16 | -- List them here for Mikk's FindGlobals script
17 | -- GLOBALS: GAME_LOCALE, geterrorhandler
18 |
19 | local gameLocale = GetLocale()
20 | if gameLocale == "enGB" then
21 | gameLocale = "enUS"
22 | end
23 |
24 | AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
25 | AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
26 |
27 | -- This metatable is used on all tables returned from GetLocale
28 | local readmeta = {
29 | __index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
30 | rawset(self, key, key) -- only need to see the warning once, really
31 | geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
32 | return key
33 | end
34 | }
35 |
36 | -- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
37 | local readmetasilent = {
38 | __index = function(self, key) -- requesting totally unknown entries: return key
39 | rawset(self, key, key) -- only need to invoke this function once
40 | return key
41 | end
42 | }
43 |
44 | -- Remember the locale table being registered right now (it gets set by :NewLocale())
45 | -- NOTE: Do never try to register 2 locale tables at once and mix their definition.
46 | local registering
47 |
48 | -- local assert false function
49 | local assertfalse = function() assert(false) end
50 |
51 | -- This metatable proxy is used when registering nondefault locales
52 | local writeproxy = setmetatable({}, {
53 | __newindex = function(self, key, value)
54 | rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
55 | end,
56 | __index = assertfalse
57 | })
58 |
59 | -- This metatable proxy is used when registering the default locale.
60 | -- It refuses to overwrite existing values
61 | -- Reason 1: Allows loading locales in any order
62 | -- Reason 2: If 2 modules have the same string, but only the first one to be
63 | -- loaded has a translation for the current locale, the translation
64 | -- doesn't get overwritten.
65 | --
66 | local writedefaultproxy = setmetatable({}, {
67 | __newindex = function(self, key, value)
68 | if not rawget(registering, key) then
69 | rawset(registering, key, value == true and key or value)
70 | end
71 | end,
72 | __index = assertfalse
73 | })
74 |
75 | --- Register a new locale (or extend an existing one) for the specified application.
76 | -- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
77 | -- game locale.
78 | -- @paramsig application, locale[, isDefault[, silent]]
79 | -- @param application Unique name of addon / module
80 | -- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
81 | -- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
82 | -- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
83 | -- @usage
84 | -- -- enUS.lua
85 | -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
86 | -- L["string1"] = true
87 | --
88 | -- -- deDE.lua
89 | -- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
90 | -- if not L then return end
91 | -- L["string1"] = "Zeichenkette1"
92 | -- @return Locale Table to add localizations to, or nil if the current locale is not required.
93 | function AceLocale:NewLocale(application, locale, isDefault, silent)
94 |
95 | -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
96 | local gameLocale = GAME_LOCALE or gameLocale
97 |
98 | local app = AceLocale.apps[application]
99 |
100 | if silent and app and getmetatable(app) ~= readmetasilent then
101 | geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
102 | end
103 |
104 | if not app then
105 | if silent=="raw" then
106 | app = {}
107 | else
108 | app = setmetatable({}, silent and readmetasilent or readmeta)
109 | end
110 | AceLocale.apps[application] = app
111 | AceLocale.appnames[app] = application
112 | end
113 |
114 | if locale ~= gameLocale and not isDefault then
115 | return -- nop, we don't need these translations
116 | end
117 |
118 | registering = app -- remember globally for writeproxy and writedefaultproxy
119 |
120 | if isDefault then
121 | return writedefaultproxy
122 | end
123 |
124 | return writeproxy
125 | end
126 |
127 | --- Returns localizations for the current locale (or default locale if translations are missing).
128 | -- Errors if nothing is registered (spank developer, not just a missing translation)
129 | -- @param application Unique name of addon / module
130 | -- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
131 | -- @return The locale table for the current language.
132 | function AceLocale:GetLocale(application, silent)
133 | if not silent and not AceLocale.apps[application] then
134 | error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
135 | end
136 | return AceLocale.apps[application]
137 | end
138 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ColorPicker Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "ColorPicker", 25
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs = pairs
10 |
11 | -- WoW APIs
12 | local CreateFrame, UIParent = CreateFrame, UIParent
13 |
14 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
15 | -- List them here for Mikk's FindGlobals script
16 | -- GLOBALS: ColorPickerFrame, OpacitySliderFrame
17 |
18 | --[[-----------------------------------------------------------------------------
19 | Support functions
20 | -------------------------------------------------------------------------------]]
21 | local function ColorCallback(self, r, g, b, a, isAlpha)
22 | if not self.HasAlpha then
23 | a = 1
24 | end
25 | self:SetColor(r, g, b, a)
26 | if ColorPickerFrame:IsVisible() then
27 | --colorpicker is still open
28 | self:Fire("OnValueChanged", r, g, b, a)
29 | else
30 | --colorpicker is closed, color callback is first, ignore it,
31 | --alpha callback is the final call after it closes so confirm now
32 | if isAlpha then
33 | self:Fire("OnValueConfirmed", r, g, b, a)
34 | end
35 | end
36 | end
37 |
38 | --[[-----------------------------------------------------------------------------
39 | Scripts
40 | -------------------------------------------------------------------------------]]
41 | local function Control_OnEnter(frame)
42 | frame.obj:Fire("OnEnter")
43 | end
44 |
45 | local function Control_OnLeave(frame)
46 | frame.obj:Fire("OnLeave")
47 | end
48 |
49 | local function ColorSwatch_OnClick(frame)
50 | ColorPickerFrame:Hide()
51 | local self = frame.obj
52 | if not self.disabled then
53 | ColorPickerFrame:SetFrameStrata("FULLSCREEN_DIALOG")
54 | ColorPickerFrame:SetFrameLevel(frame:GetFrameLevel() + 10)
55 | ColorPickerFrame:SetClampedToScreen(true)
56 |
57 | ColorPickerFrame.func = function()
58 | local r, g, b = ColorPickerFrame:GetColorRGB()
59 | local a = 1 - OpacitySliderFrame:GetValue()
60 | ColorCallback(self, r, g, b, a)
61 | end
62 |
63 | ColorPickerFrame.hasOpacity = self.HasAlpha
64 | ColorPickerFrame.opacityFunc = function()
65 | local r, g, b = ColorPickerFrame:GetColorRGB()
66 | local a = 1 - OpacitySliderFrame:GetValue()
67 | ColorCallback(self, r, g, b, a, true)
68 | end
69 |
70 | local r, g, b, a = self.r, self.g, self.b, self.a
71 | if self.HasAlpha then
72 | ColorPickerFrame.opacity = 1 - (a or 0)
73 | end
74 | ColorPickerFrame:SetColorRGB(r, g, b)
75 |
76 | ColorPickerFrame.cancelFunc = function()
77 | ColorCallback(self, r, g, b, a, true)
78 | end
79 |
80 | ColorPickerFrame:Show()
81 | end
82 | AceGUI:ClearFocus()
83 | end
84 |
85 | --[[-----------------------------------------------------------------------------
86 | Methods
87 | -------------------------------------------------------------------------------]]
88 | local methods = {
89 | ["OnAcquire"] = function(self)
90 | self:SetHeight(24)
91 | self:SetWidth(200)
92 | self:SetHasAlpha(false)
93 | self:SetColor(0, 0, 0, 1)
94 | self:SetDisabled(nil)
95 | self:SetLabel(nil)
96 | end,
97 |
98 | -- ["OnRelease"] = nil,
99 |
100 | ["SetLabel"] = function(self, text)
101 | self.text:SetText(text)
102 | end,
103 |
104 | ["SetColor"] = function(self, r, g, b, a)
105 | self.r = r
106 | self.g = g
107 | self.b = b
108 | self.a = a or 1
109 | self.colorSwatch:SetVertexColor(r, g, b, a)
110 | end,
111 |
112 | ["SetHasAlpha"] = function(self, HasAlpha)
113 | self.HasAlpha = HasAlpha
114 | end,
115 |
116 | ["SetDisabled"] = function(self, disabled)
117 | self.disabled = disabled
118 | if self.disabled then
119 | self.frame:Disable()
120 | self.text:SetTextColor(0.5, 0.5, 0.5)
121 | else
122 | self.frame:Enable()
123 | self.text:SetTextColor(1, 1, 1)
124 | end
125 | end
126 | }
127 |
128 | --[[-----------------------------------------------------------------------------
129 | Constructor
130 | -------------------------------------------------------------------------------]]
131 | local function Constructor()
132 | local frame = CreateFrame("Button", nil, UIParent)
133 | frame:Hide()
134 |
135 | frame:EnableMouse(true)
136 | frame:SetScript("OnEnter", Control_OnEnter)
137 | frame:SetScript("OnLeave", Control_OnLeave)
138 | frame:SetScript("OnClick", ColorSwatch_OnClick)
139 |
140 | local colorSwatch = frame:CreateTexture(nil, "OVERLAY")
141 | colorSwatch:SetWidth(19)
142 | colorSwatch:SetHeight(19)
143 | colorSwatch:SetTexture(130939) -- Interface\\ChatFrame\\ChatFrameColorSwatch
144 | colorSwatch:SetPoint("LEFT")
145 |
146 | local texture = frame:CreateTexture(nil, "BACKGROUND")
147 | colorSwatch.background = texture
148 | texture:SetWidth(16)
149 | texture:SetHeight(16)
150 | texture:SetColorTexture(1, 1, 1)
151 | texture:SetPoint("CENTER", colorSwatch)
152 | texture:Show()
153 |
154 | local checkers = frame:CreateTexture(nil, "BACKGROUND")
155 | colorSwatch.checkers = checkers
156 | checkers:SetWidth(14)
157 | checkers:SetHeight(14)
158 | checkers:SetTexture(188523) -- Tileset\\Generic\\Checkers
159 | checkers:SetTexCoord(.25, 0, 0.5, .25)
160 | checkers:SetDesaturated(true)
161 | checkers:SetVertexColor(1, 1, 1, 0.75)
162 | checkers:SetPoint("CENTER", colorSwatch)
163 | checkers:Show()
164 |
165 | local text = frame:CreateFontString(nil,"OVERLAY","GameFontHighlight")
166 | text:SetHeight(24)
167 | text:SetJustifyH("LEFT")
168 | text:SetTextColor(1, 1, 1)
169 | text:SetPoint("LEFT", colorSwatch, "RIGHT", 2, 0)
170 | text:SetPoint("RIGHT")
171 |
172 | --local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
173 | --highlight:SetTexture(136810) -- Interface\\QuestFrame\\UI-QuestTitleHighlight
174 | --highlight:SetBlendMode("ADD")
175 | --highlight:SetAllPoints(frame)
176 |
177 | local widget = {
178 | colorSwatch = colorSwatch,
179 | text = text,
180 | frame = frame,
181 | type = Type
182 | }
183 | for method, func in pairs(methods) do
184 | widget[method] = func
185 | end
186 |
187 | return AceGUI:RegisterAsWidget(widget)
188 | end
189 |
190 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
191 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | ScrollFrame Container
3 | Plain container that scrolls its content and doesn't grow in height.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "ScrollFrame", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs, assert, type = pairs, assert, type
11 | local min, max, floor = math.min, math.max, math.floor
12 |
13 | -- WoW APIs
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | --[[-----------------------------------------------------------------------------
17 | Support functions
18 | -------------------------------------------------------------------------------]]
19 | local function FixScrollOnUpdate(frame)
20 | frame:SetScript("OnUpdate", nil)
21 | frame.obj:FixScroll()
22 | end
23 |
24 | --[[-----------------------------------------------------------------------------
25 | Scripts
26 | -------------------------------------------------------------------------------]]
27 | local function ScrollFrame_OnMouseWheel(frame, value)
28 | frame.obj:MoveScroll(value)
29 | end
30 |
31 | local function ScrollFrame_OnSizeChanged(frame)
32 | frame:SetScript("OnUpdate", FixScrollOnUpdate)
33 | end
34 |
35 | local function ScrollBar_OnScrollValueChanged(frame, value)
36 | frame.obj:SetScroll(value)
37 | end
38 |
39 | --[[-----------------------------------------------------------------------------
40 | Methods
41 | -------------------------------------------------------------------------------]]
42 | local methods = {
43 | ["OnAcquire"] = function(self)
44 | self:SetScroll(0)
45 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
46 | end,
47 |
48 | ["OnRelease"] = function(self)
49 | self.status = nil
50 | for k in pairs(self.localstatus) do
51 | self.localstatus[k] = nil
52 | end
53 | self.scrollframe:SetPoint("BOTTOMRIGHT")
54 | self.scrollbar:Hide()
55 | self.scrollBarShown = nil
56 | self.content.height, self.content.width, self.content.original_width = nil, nil, nil
57 | end,
58 |
59 | ["SetScroll"] = function(self, value)
60 | local status = self.status or self.localstatus
61 | local viewheight = self.scrollframe:GetHeight()
62 | local height = self.content:GetHeight()
63 | local offset
64 |
65 | if viewheight > height then
66 | offset = 0
67 | else
68 | offset = floor((height - viewheight) / 1000.0 * value)
69 | end
70 | self.content:ClearAllPoints()
71 | self.content:SetPoint("TOPLEFT", 0, offset)
72 | self.content:SetPoint("TOPRIGHT", 0, offset)
73 | status.offset = offset
74 | status.scrollvalue = value
75 | end,
76 |
77 | ["MoveScroll"] = function(self, value)
78 | local status = self.status or self.localstatus
79 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
80 |
81 | if self.scrollBarShown then
82 | local diff = height - viewheight
83 | local delta = 1
84 | if value < 0 then
85 | delta = -1
86 | end
87 | self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
88 | end
89 | end,
90 |
91 | ["FixScroll"] = function(self)
92 | if self.updateLock then return end
93 | self.updateLock = true
94 | local status = self.status or self.localstatus
95 | local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
96 | local offset = status.offset or 0
97 | -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
98 | -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
99 | if viewheight < height + 2 then
100 | if self.scrollBarShown then
101 | self.scrollBarShown = nil
102 | self.scrollbar:Hide()
103 | self.scrollbar:SetValue(0)
104 | self.scrollframe:SetPoint("BOTTOMRIGHT")
105 | if self.content.original_width then
106 | self.content.width = self.content.original_width
107 | end
108 | self:DoLayout()
109 | end
110 | else
111 | if not self.scrollBarShown then
112 | self.scrollBarShown = true
113 | self.scrollbar:Show()
114 | self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
115 | if self.content.original_width then
116 | self.content.width = self.content.original_width - 20
117 | end
118 | self:DoLayout()
119 | end
120 | local value = (offset / (viewheight - height) * 1000)
121 | if value > 1000 then value = 1000 end
122 | self.scrollbar:SetValue(value)
123 | self:SetScroll(value)
124 | if value < 1000 then
125 | self.content:ClearAllPoints()
126 | self.content:SetPoint("TOPLEFT", 0, offset)
127 | self.content:SetPoint("TOPRIGHT", 0, offset)
128 | status.offset = offset
129 | end
130 | end
131 | self.updateLock = nil
132 | end,
133 |
134 | ["LayoutFinished"] = function(self, width, height)
135 | self.content:SetHeight(height or 0 + 20)
136 |
137 | -- update the scrollframe
138 | self:FixScroll()
139 |
140 | -- schedule another update when everything has "settled"
141 | self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
142 | end,
143 |
144 | ["SetStatusTable"] = function(self, status)
145 | assert(type(status) == "table")
146 | self.status = status
147 | if not status.scrollvalue then
148 | status.scrollvalue = 0
149 | end
150 | end,
151 |
152 | ["OnWidthSet"] = function(self, width)
153 | local content = self.content
154 | content.width = width - (self.scrollBarShown and 20 or 0)
155 | content.original_width = width
156 | end,
157 |
158 | ["OnHeightSet"] = function(self, height)
159 | local content = self.content
160 | content.height = height
161 | end
162 | }
163 | --[[-----------------------------------------------------------------------------
164 | Constructor
165 | -------------------------------------------------------------------------------]]
166 | local function Constructor()
167 | local frame = CreateFrame("Frame", nil, UIParent)
168 | local num = AceGUI:GetNextWidgetNum(Type)
169 |
170 | local scrollframe = CreateFrame("ScrollFrame", nil, frame)
171 | scrollframe:SetPoint("TOPLEFT")
172 | scrollframe:SetPoint("BOTTOMRIGHT")
173 | scrollframe:EnableMouseWheel(true)
174 | scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
175 | scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
176 |
177 | local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
178 | scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
179 | scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
180 | scrollbar:SetMinMaxValues(0, 1000)
181 | scrollbar:SetValueStep(1)
182 | scrollbar:SetValue(0)
183 | scrollbar:SetWidth(16)
184 | scrollbar:Hide()
185 | -- set the script as the last step, so it doesn't fire yet
186 | scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
187 |
188 | local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
189 | scrollbg:SetAllPoints(scrollbar)
190 | scrollbg:SetColorTexture(0, 0, 0, 0.4)
191 |
192 | --Container Support
193 | local content = CreateFrame("Frame", nil, scrollframe)
194 | content:SetPoint("TOPLEFT")
195 | content:SetPoint("TOPRIGHT")
196 | content:SetHeight(400)
197 | scrollframe:SetScrollChild(content)
198 |
199 | local widget = {
200 | localstatus = { scrollvalue = 0 },
201 | scrollframe = scrollframe,
202 | scrollbar = scrollbar,
203 | content = content,
204 | frame = frame,
205 | type = Type
206 | }
207 | for method, func in pairs(methods) do
208 | widget[method] = func
209 | end
210 | scrollframe.obj, scrollbar.obj = widget, widget
211 |
212 | return AceGUI:RegisterAsContainer(widget)
213 | end
214 |
215 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
216 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Keybinding Widget
3 | Set Keybindings in the Config UI.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Keybinding", 26
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs = pairs
11 |
12 | -- WoW APIs
13 | local IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown = IsShiftKeyDown, IsControlKeyDown, IsAltKeyDown
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
17 | -- List them here for Mikk's FindGlobals script
18 | -- GLOBALS: NOT_BOUND
19 |
20 | --[[-----------------------------------------------------------------------------
21 | Scripts
22 | -------------------------------------------------------------------------------]]
23 |
24 | local function Control_OnEnter(frame)
25 | frame.obj:Fire("OnEnter")
26 | end
27 |
28 | local function Control_OnLeave(frame)
29 | frame.obj:Fire("OnLeave")
30 | end
31 |
32 | local function Keybinding_OnClick(frame, button)
33 | if button == "LeftButton" or button == "RightButton" then
34 | local self = frame.obj
35 | if self.waitingForKey then
36 | frame:EnableKeyboard(false)
37 | frame:EnableMouseWheel(false)
38 | self.msgframe:Hide()
39 | frame:UnlockHighlight()
40 | self.waitingForKey = nil
41 | else
42 | frame:EnableKeyboard(true)
43 | frame:EnableMouseWheel(true)
44 | self.msgframe:Show()
45 | frame:LockHighlight()
46 | self.waitingForKey = true
47 | end
48 | end
49 | AceGUI:ClearFocus()
50 | end
51 |
52 | local ignoreKeys = {
53 | ["BUTTON1"] = true, ["BUTTON2"] = true,
54 | ["UNKNOWN"] = true,
55 | ["LSHIFT"] = true, ["LCTRL"] = true, ["LALT"] = true,
56 | ["RSHIFT"] = true, ["RCTRL"] = true, ["RALT"] = true,
57 | }
58 | local function Keybinding_OnKeyDown(frame, key)
59 | local self = frame.obj
60 | if self.waitingForKey then
61 | local keyPressed = key
62 | if keyPressed == "ESCAPE" then
63 | keyPressed = ""
64 | else
65 | if ignoreKeys[keyPressed] then return end
66 | if IsShiftKeyDown() then
67 | keyPressed = "SHIFT-"..keyPressed
68 | end
69 | if IsControlKeyDown() then
70 | keyPressed = "CTRL-"..keyPressed
71 | end
72 | if IsAltKeyDown() then
73 | keyPressed = "ALT-"..keyPressed
74 | end
75 | end
76 |
77 | frame:EnableKeyboard(false)
78 | frame:EnableMouseWheel(false)
79 | self.msgframe:Hide()
80 | frame:UnlockHighlight()
81 | self.waitingForKey = nil
82 |
83 | if not self.disabled then
84 | self:SetKey(keyPressed)
85 | self:Fire("OnKeyChanged", keyPressed)
86 | end
87 | end
88 | end
89 |
90 | local function Keybinding_OnMouseDown(frame, button)
91 | if button == "LeftButton" or button == "RightButton" then
92 | return
93 | elseif button == "MiddleButton" then
94 | button = "BUTTON3"
95 | elseif button == "Button4" then
96 | button = "BUTTON4"
97 | elseif button == "Button5" then
98 | button = "BUTTON5"
99 | end
100 | Keybinding_OnKeyDown(frame, button)
101 | end
102 |
103 | local function Keybinding_OnMouseWheel(frame, direction)
104 | local button
105 | if direction >= 0 then
106 | button = "MOUSEWHEELUP"
107 | else
108 | button = "MOUSEWHEELDOWN"
109 | end
110 | Keybinding_OnKeyDown(frame, button)
111 | end
112 |
113 | --[[-----------------------------------------------------------------------------
114 | Methods
115 | -------------------------------------------------------------------------------]]
116 | local methods = {
117 | ["OnAcquire"] = function(self)
118 | self:SetWidth(200)
119 | self:SetLabel("")
120 | self:SetKey("")
121 | self.waitingForKey = nil
122 | self.msgframe:Hide()
123 | self:SetDisabled(false)
124 | self.button:EnableKeyboard(false)
125 | self.button:EnableMouseWheel(false)
126 | end,
127 |
128 | -- ["OnRelease"] = nil,
129 |
130 | ["SetDisabled"] = function(self, disabled)
131 | self.disabled = disabled
132 | if disabled then
133 | self.button:Disable()
134 | self.label:SetTextColor(0.5,0.5,0.5)
135 | else
136 | self.button:Enable()
137 | self.label:SetTextColor(1,1,1)
138 | end
139 | end,
140 |
141 | ["SetKey"] = function(self, key)
142 | if (key or "") == "" then
143 | self.button:SetText(NOT_BOUND)
144 | self.button:SetNormalFontObject("GameFontNormal")
145 | else
146 | self.button:SetText(key)
147 | self.button:SetNormalFontObject("GameFontHighlight")
148 | end
149 | end,
150 |
151 | ["GetKey"] = function(self)
152 | local key = self.button:GetText()
153 | if key == NOT_BOUND then
154 | key = nil
155 | end
156 | return key
157 | end,
158 |
159 | ["SetLabel"] = function(self, label)
160 | self.label:SetText(label or "")
161 | if (label or "") == "" then
162 | self.alignoffset = nil
163 | self:SetHeight(24)
164 | else
165 | self.alignoffset = 30
166 | self:SetHeight(44)
167 | end
168 | end,
169 | }
170 |
171 | --[[-----------------------------------------------------------------------------
172 | Constructor
173 | -------------------------------------------------------------------------------]]
174 |
175 | local ControlBackdrop = {
176 | bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
177 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
178 | tile = true, tileSize = 16, edgeSize = 16,
179 | insets = { left = 3, right = 3, top = 3, bottom = 3 }
180 | }
181 |
182 | local function keybindingMsgFixWidth(frame)
183 | frame:SetWidth(frame.msg:GetWidth() + 10)
184 | frame:SetScript("OnUpdate", nil)
185 | end
186 |
187 | local function Constructor()
188 | local name = "AceGUI30KeybindingButton" .. AceGUI:GetNextWidgetNum(Type)
189 |
190 | local frame = CreateFrame("Frame", nil, UIParent)
191 | local button = CreateFrame("Button", name, frame, "UIPanelButtonTemplate")
192 |
193 | button:EnableMouse(true)
194 | button:EnableMouseWheel(false)
195 | button:RegisterForClicks("AnyDown")
196 | button:SetScript("OnEnter", Control_OnEnter)
197 | button:SetScript("OnLeave", Control_OnLeave)
198 | button:SetScript("OnClick", Keybinding_OnClick)
199 | button:SetScript("OnKeyDown", Keybinding_OnKeyDown)
200 | button:SetScript("OnMouseDown", Keybinding_OnMouseDown)
201 | button:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
202 | button:SetPoint("BOTTOMLEFT")
203 | button:SetPoint("BOTTOMRIGHT")
204 | button:SetHeight(24)
205 | button:EnableKeyboard(false)
206 |
207 | local text = button:GetFontString()
208 | text:SetPoint("LEFT", 7, 0)
209 | text:SetPoint("RIGHT", -7, 0)
210 |
211 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
212 | label:SetPoint("TOPLEFT")
213 | label:SetPoint("TOPRIGHT")
214 | label:SetJustifyH("CENTER")
215 | label:SetHeight(18)
216 |
217 | local msgframe = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
218 | msgframe:SetHeight(30)
219 | msgframe:SetBackdrop(ControlBackdrop)
220 | msgframe:SetBackdropColor(0,0,0)
221 | msgframe:SetFrameStrata("FULLSCREEN_DIALOG")
222 | msgframe:SetFrameLevel(1000)
223 | msgframe:SetToplevel(true)
224 |
225 | local msg = msgframe:CreateFontString(nil, "OVERLAY", "GameFontNormal")
226 | msg:SetText("Press a key to bind, ESC to clear the binding or click the button again to cancel.")
227 | msgframe.msg = msg
228 | msg:SetPoint("TOPLEFT", 5, -5)
229 | msgframe:SetScript("OnUpdate", keybindingMsgFixWidth)
230 | msgframe:SetPoint("BOTTOM", button, "TOP")
231 | msgframe:Hide()
232 |
233 | local widget = {
234 | button = button,
235 | label = label,
236 | msgframe = msgframe,
237 | frame = frame,
238 | alignoffset = 30,
239 | type = Type
240 | }
241 | for method, func in pairs(methods) do
242 | widget[method] = func
243 | end
244 | button.obj = widget
245 |
246 | return AceGUI:RegisterAsWidget(widget)
247 | end
248 |
249 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
250 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | EditBox Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "EditBox", 28
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local tostring, pairs = tostring, pairs
10 |
11 | -- WoW APIs
12 | local PlaySound = PlaySound
13 | local GetCursorInfo, ClearCursor, GetSpellInfo = GetCursorInfo, ClearCursor, GetSpellInfo
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 | local _G = _G
16 |
17 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
18 | -- List them here for Mikk's FindGlobals script
19 | -- GLOBALS: AceGUIEditBoxInsertLink, ChatFontNormal, OKAY
20 |
21 | --[[-----------------------------------------------------------------------------
22 | Support functions
23 | -------------------------------------------------------------------------------]]
24 | if not AceGUIEditBoxInsertLink then
25 | -- upgradeable hook
26 | hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIEditBoxInsertLink(...) end)
27 | end
28 |
29 | function _G.AceGUIEditBoxInsertLink(text)
30 | for i = 1, AceGUI:GetWidgetCount(Type) do
31 | local editbox = _G["AceGUI-3.0EditBox"..i]
32 | if editbox and editbox:IsVisible() and editbox:HasFocus() then
33 | editbox:Insert(text)
34 | return true
35 | end
36 | end
37 | end
38 |
39 | local function ShowButton(self)
40 | if not self.disablebutton then
41 | self.button:Show()
42 | self.editbox:SetTextInsets(0, 20, 3, 3)
43 | end
44 | end
45 |
46 | local function HideButton(self)
47 | self.button:Hide()
48 | self.editbox:SetTextInsets(0, 0, 3, 3)
49 | end
50 |
51 | --[[-----------------------------------------------------------------------------
52 | Scripts
53 | -------------------------------------------------------------------------------]]
54 | local function Control_OnEnter(frame)
55 | frame.obj:Fire("OnEnter")
56 | end
57 |
58 | local function Control_OnLeave(frame)
59 | frame.obj:Fire("OnLeave")
60 | end
61 |
62 | local function Frame_OnShowFocus(frame)
63 | frame.obj.editbox:SetFocus()
64 | frame:SetScript("OnShow", nil)
65 | end
66 |
67 | local function EditBox_OnEscapePressed(frame)
68 | AceGUI:ClearFocus()
69 | end
70 |
71 | local function EditBox_OnEnterPressed(frame)
72 | local self = frame.obj
73 | local value = frame:GetText()
74 | local cancel = self:Fire("OnEnterPressed", value)
75 | if not cancel then
76 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
77 | HideButton(self)
78 | end
79 | end
80 |
81 | local function EditBox_OnReceiveDrag(frame)
82 | local self = frame.obj
83 | local type, id, info = GetCursorInfo()
84 | local name
85 | if type == "item" then
86 | name = info
87 | elseif type == "spell" then
88 | name = GetSpellInfo(id, info)
89 | elseif type == "macro" then
90 | name = GetMacroInfo(id)
91 | end
92 | if name then
93 | self:SetText(name)
94 | self:Fire("OnEnterPressed", name)
95 | ClearCursor()
96 | HideButton(self)
97 | AceGUI:ClearFocus()
98 | end
99 | end
100 |
101 | local function EditBox_OnTextChanged(frame)
102 | local self = frame.obj
103 | local value = frame:GetText()
104 | if tostring(value) ~= tostring(self.lasttext) then
105 | self:Fire("OnTextChanged", value)
106 | self.lasttext = value
107 | ShowButton(self)
108 | end
109 | end
110 |
111 | local function EditBox_OnFocusGained(frame)
112 | AceGUI:SetFocus(frame.obj)
113 | end
114 |
115 | local function Button_OnClick(frame)
116 | local editbox = frame.obj.editbox
117 | editbox:ClearFocus()
118 | EditBox_OnEnterPressed(editbox)
119 | end
120 |
121 | --[[-----------------------------------------------------------------------------
122 | Methods
123 | -------------------------------------------------------------------------------]]
124 | local methods = {
125 | ["OnAcquire"] = function(self)
126 | -- height is controlled by SetLabel
127 | self:SetWidth(200)
128 | self:SetDisabled(false)
129 | self:SetLabel()
130 | self:SetText()
131 | self:DisableButton(false)
132 | self:SetMaxLetters(0)
133 | end,
134 |
135 | ["OnRelease"] = function(self)
136 | self:ClearFocus()
137 | end,
138 |
139 | ["SetDisabled"] = function(self, disabled)
140 | self.disabled = disabled
141 | if disabled then
142 | self.editbox:EnableMouse(false)
143 | self.editbox:ClearFocus()
144 | self.editbox:SetTextColor(0.5,0.5,0.5)
145 | self.label:SetTextColor(0.5,0.5,0.5)
146 | else
147 | self.editbox:EnableMouse(true)
148 | self.editbox:SetTextColor(1,1,1)
149 | self.label:SetTextColor(1,.82,0)
150 | end
151 | end,
152 |
153 | ["SetText"] = function(self, text)
154 | self.lasttext = text or ""
155 | self.editbox:SetText(text or "")
156 | self.editbox:SetCursorPosition(0)
157 | HideButton(self)
158 | end,
159 |
160 | ["GetText"] = function(self, text)
161 | return self.editbox:GetText()
162 | end,
163 |
164 | ["SetLabel"] = function(self, text)
165 | if text and text ~= "" then
166 | self.label:SetText(text)
167 | self.label:Show()
168 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,-18)
169 | self:SetHeight(44)
170 | self.alignoffset = 30
171 | else
172 | self.label:SetText("")
173 | self.label:Hide()
174 | self.editbox:SetPoint("TOPLEFT",self.frame,"TOPLEFT",7,0)
175 | self:SetHeight(26)
176 | self.alignoffset = 12
177 | end
178 | end,
179 |
180 | ["DisableButton"] = function(self, disabled)
181 | self.disablebutton = disabled
182 | if disabled then
183 | HideButton(self)
184 | end
185 | end,
186 |
187 | ["SetMaxLetters"] = function (self, num)
188 | self.editbox:SetMaxLetters(num or 0)
189 | end,
190 |
191 | ["ClearFocus"] = function(self)
192 | self.editbox:ClearFocus()
193 | self.frame:SetScript("OnShow", nil)
194 | end,
195 |
196 | ["SetFocus"] = function(self)
197 | self.editbox:SetFocus()
198 | if not self.frame:IsShown() then
199 | self.frame:SetScript("OnShow", Frame_OnShowFocus)
200 | end
201 | end,
202 |
203 | ["HighlightText"] = function(self, from, to)
204 | self.editbox:HighlightText(from, to)
205 | end
206 | }
207 |
208 | --[[-----------------------------------------------------------------------------
209 | Constructor
210 | -------------------------------------------------------------------------------]]
211 | local function Constructor()
212 | local num = AceGUI:GetNextWidgetNum(Type)
213 | local frame = CreateFrame("Frame", nil, UIParent)
214 | frame:Hide()
215 |
216 | local editbox = CreateFrame("EditBox", "AceGUI-3.0EditBox"..num, frame, "InputBoxTemplate")
217 | editbox:SetAutoFocus(false)
218 | editbox:SetFontObject(ChatFontNormal)
219 | editbox:SetScript("OnEnter", Control_OnEnter)
220 | editbox:SetScript("OnLeave", Control_OnLeave)
221 | editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
222 | editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
223 | editbox:SetScript("OnTextChanged", EditBox_OnTextChanged)
224 | editbox:SetScript("OnReceiveDrag", EditBox_OnReceiveDrag)
225 | editbox:SetScript("OnMouseDown", EditBox_OnReceiveDrag)
226 | editbox:SetScript("OnEditFocusGained", EditBox_OnFocusGained)
227 | editbox:SetTextInsets(0, 0, 3, 3)
228 | editbox:SetMaxLetters(256)
229 | editbox:SetPoint("BOTTOMLEFT", 6, 0)
230 | editbox:SetPoint("BOTTOMRIGHT")
231 | editbox:SetHeight(19)
232 |
233 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
234 | label:SetPoint("TOPLEFT", 0, -2)
235 | label:SetPoint("TOPRIGHT", 0, -2)
236 | label:SetJustifyH("LEFT")
237 | label:SetHeight(18)
238 |
239 | local button = CreateFrame("Button", nil, editbox, "UIPanelButtonTemplate")
240 | button:SetWidth(40)
241 | button:SetHeight(20)
242 | button:SetPoint("RIGHT", -2, 0)
243 | button:SetText(OKAY)
244 | button:SetScript("OnClick", Button_OnClick)
245 | button:Hide()
246 |
247 | local widget = {
248 | alignoffset = 30,
249 | editbox = editbox,
250 | label = label,
251 | button = button,
252 | frame = frame,
253 | type = Type
254 | }
255 | for method, func in pairs(methods) do
256 | widget[method] = func
257 | end
258 | editbox.obj, button.obj = widget, widget
259 |
260 | return AceGUI:RegisterAsWidget(widget)
261 | end
262 |
263 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
264 |
--------------------------------------------------------------------------------
/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:
--------------------------------------------------------------------------------
1 | --[[ $Id: CallbackHandler-1.0.lua 1186 2018-07-21 14:19:18Z nevcairiel $ ]]
2 | local MAJOR, MINOR = "CallbackHandler-1.0", 7
3 | local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
4 |
5 | if not CallbackHandler then return end -- No upgrade needed
6 |
7 | local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
8 |
9 | -- Lua APIs
10 | local tconcat = table.concat
11 | local assert, error, loadstring = assert, error, loadstring
12 | local setmetatable, rawset, rawget = setmetatable, rawset, rawget
13 | local next, select, pairs, type, tostring = next, select, pairs, type, tostring
14 |
15 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
16 | -- List them here for Mikk's FindGlobals script
17 | -- GLOBALS: geterrorhandler
18 |
19 | local xpcall = xpcall
20 |
21 | local function errorhandler(err)
22 | return geterrorhandler()(err)
23 | end
24 |
25 | local function Dispatch(handlers, ...)
26 | local index, method = next(handlers)
27 | if not method then return end
28 | repeat
29 | xpcall(method, errorhandler, ...)
30 | index, method = next(handlers, index)
31 | until not method
32 | end
33 |
34 | --------------------------------------------------------------------------
35 | -- CallbackHandler:New
36 | --
37 | -- target - target object to embed public APIs in
38 | -- RegisterName - name of the callback registration API, default "RegisterCallback"
39 | -- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
40 | -- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
41 |
42 | function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName)
43 |
44 | RegisterName = RegisterName or "RegisterCallback"
45 | UnregisterName = UnregisterName or "UnregisterCallback"
46 | if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
47 | UnregisterAllName = "UnregisterAllCallbacks"
48 | end
49 |
50 | -- we declare all objects and exported APIs inside this closure to quickly gain access
51 | -- to e.g. function names, the "target" parameter, etc
52 |
53 |
54 | -- Create the registry object
55 | local events = setmetatable({}, meta)
56 | local registry = { recurse=0, events=events }
57 |
58 | -- registry:Fire() - fires the given event/message into the registry
59 | function registry:Fire(eventname, ...)
60 | if not rawget(events, eventname) or not next(events[eventname]) then return end
61 | local oldrecurse = registry.recurse
62 | registry.recurse = oldrecurse + 1
63 |
64 | Dispatch(events[eventname], eventname, ...)
65 |
66 | registry.recurse = oldrecurse
67 |
68 | if registry.insertQueue and oldrecurse==0 then
69 | -- Something in one of our callbacks wanted to register more callbacks; they got queued
70 | for eventname,callbacks in pairs(registry.insertQueue) do
71 | local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
72 | for self,func in pairs(callbacks) do
73 | events[eventname][self] = func
74 | -- fire OnUsed callback?
75 | if first and registry.OnUsed then
76 | registry.OnUsed(registry, target, eventname)
77 | first = nil
78 | end
79 | end
80 | end
81 | registry.insertQueue = nil
82 | end
83 | end
84 |
85 | -- Registration of a callback, handles:
86 | -- self["method"], leads to self["method"](self, ...)
87 | -- self with function ref, leads to functionref(...)
88 | -- "addonId" (instead of self) with function ref, leads to functionref(...)
89 | -- all with an optional arg, which, if present, gets passed as first argument (after self if present)
90 | target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
91 | if type(eventname) ~= "string" then
92 | error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
93 | end
94 |
95 | method = method or eventname
96 |
97 | local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
98 |
99 | if type(method) ~= "string" and type(method) ~= "function" then
100 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
101 | end
102 |
103 | local regfunc
104 |
105 | if type(method) == "string" then
106 | -- self["method"] calling style
107 | if type(self) ~= "table" then
108 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
109 | elseif self==target then
110 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
111 | elseif type(self[method]) ~= "function" then
112 | error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
113 | end
114 |
115 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
116 | local arg=select(1,...)
117 | regfunc = function(...) self[method](self,arg,...) end
118 | else
119 | regfunc = function(...) self[method](self,...) end
120 | end
121 | else
122 | -- function ref with self=object or self="addonId" or self=thread
123 | if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
124 | error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
125 | end
126 |
127 | if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
128 | local arg=select(1,...)
129 | regfunc = function(...) method(arg,...) end
130 | else
131 | regfunc = method
132 | end
133 | end
134 |
135 |
136 | if events[eventname][self] or registry.recurse<1 then
137 | -- if registry.recurse<1 then
138 | -- we're overwriting an existing entry, or not currently recursing. just set it.
139 | events[eventname][self] = regfunc
140 | -- fire OnUsed callback?
141 | if registry.OnUsed and first then
142 | registry.OnUsed(registry, target, eventname)
143 | end
144 | else
145 | -- we're currently processing a callback in this registry, so delay the registration of this new entry!
146 | -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
147 | registry.insertQueue = registry.insertQueue or setmetatable({},meta)
148 | registry.insertQueue[eventname][self] = regfunc
149 | end
150 | end
151 |
152 | -- Unregister a callback
153 | target[UnregisterName] = function(self, eventname)
154 | if not self or self==target then
155 | error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
156 | end
157 | if type(eventname) ~= "string" then
158 | error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
159 | end
160 | if rawget(events, eventname) and events[eventname][self] then
161 | events[eventname][self] = nil
162 | -- Fire OnUnused callback?
163 | if registry.OnUnused and not next(events[eventname]) then
164 | registry.OnUnused(registry, target, eventname)
165 | end
166 | end
167 | if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
168 | registry.insertQueue[eventname][self] = nil
169 | end
170 | end
171 |
172 | -- OPTIONAL: Unregister all callbacks for given selfs/addonIds
173 | if UnregisterAllName then
174 | target[UnregisterAllName] = function(...)
175 | if select("#",...)<1 then
176 | error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
177 | end
178 | if select("#",...)==1 and ...==target then
179 | error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
180 | end
181 |
182 |
183 | for i=1,select("#",...) do
184 | local self = select(i,...)
185 | if registry.insertQueue then
186 | for eventname, callbacks in pairs(registry.insertQueue) do
187 | if callbacks[self] then
188 | callbacks[self] = nil
189 | end
190 | end
191 | end
192 | for eventname, callbacks in pairs(events) do
193 | if callbacks[self] then
194 | callbacks[self] = nil
195 | -- Fire OnUnused callback?
196 | if registry.OnUnused and not next(callbacks) then
197 | registry.OnUnused(registry, target, eventname)
198 | end
199 | end
200 | end
201 | end
202 | end
203 | end
204 |
205 | return registry
206 | end
207 |
208 |
209 | -- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
210 | -- try to upgrade old implicit embeds since the system is selfcontained and
211 | -- relies on closures to work.
212 |
213 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Checkbox Widget
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "CheckBox", 26
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local select, pairs = select, pairs
10 |
11 | -- WoW APIs
12 | local PlaySound = PlaySound
13 | local CreateFrame, UIParent = CreateFrame, UIParent
14 |
15 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
16 | -- List them here for Mikk's FindGlobals script
17 | -- GLOBALS: SetDesaturation, GameFontHighlight
18 |
19 | --[[-----------------------------------------------------------------------------
20 | Support functions
21 | -------------------------------------------------------------------------------]]
22 | local function AlignImage(self)
23 | local img = self.image:GetTexture()
24 | self.text:ClearAllPoints()
25 | if not img then
26 | self.text:SetPoint("LEFT", self.checkbg, "RIGHT")
27 | self.text:SetPoint("RIGHT")
28 | else
29 | self.text:SetPoint("LEFT", self.image, "RIGHT", 1, 0)
30 | self.text:SetPoint("RIGHT")
31 | end
32 | end
33 |
34 | --[[-----------------------------------------------------------------------------
35 | Scripts
36 | -------------------------------------------------------------------------------]]
37 | local function Control_OnEnter(frame)
38 | frame.obj:Fire("OnEnter")
39 | end
40 |
41 | local function Control_OnLeave(frame)
42 | frame.obj:Fire("OnLeave")
43 | end
44 |
45 | local function CheckBox_OnMouseDown(frame)
46 | local self = frame.obj
47 | if not self.disabled then
48 | if self.image:GetTexture() then
49 | self.text:SetPoint("LEFT", self.image,"RIGHT", 2, -1)
50 | else
51 | self.text:SetPoint("LEFT", self.checkbg, "RIGHT", 1, -1)
52 | end
53 | end
54 | AceGUI:ClearFocus()
55 | end
56 |
57 | local function CheckBox_OnMouseUp(frame)
58 | local self = frame.obj
59 | if not self.disabled then
60 | self:ToggleChecked()
61 |
62 | if self.checked then
63 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
64 | else -- for both nil and false (tristate)
65 | PlaySound(857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
66 | end
67 |
68 | self:Fire("OnValueChanged", self.checked)
69 | AlignImage(self)
70 | end
71 | end
72 |
73 | --[[-----------------------------------------------------------------------------
74 | Methods
75 | -------------------------------------------------------------------------------]]
76 | local methods = {
77 | ["OnAcquire"] = function(self)
78 | self:SetType()
79 | self:SetValue(false)
80 | self:SetTriState(nil)
81 | -- height is calculated from the width and required space for the description
82 | self:SetWidth(200)
83 | self:SetImage()
84 | self:SetDisabled(nil)
85 | self:SetDescription(nil)
86 | end,
87 |
88 | -- ["OnRelease"] = nil,
89 |
90 | ["OnWidthSet"] = function(self, width)
91 | if self.desc then
92 | self.desc:SetWidth(width - 30)
93 | if self.desc:GetText() and self.desc:GetText() ~= "" then
94 | self:SetHeight(28 + self.desc:GetStringHeight())
95 | end
96 | end
97 | end,
98 |
99 | ["SetDisabled"] = function(self, disabled)
100 | self.disabled = disabled
101 | if disabled then
102 | self.frame:Disable()
103 | self.text:SetTextColor(0.5, 0.5, 0.5)
104 | SetDesaturation(self.check, true)
105 | if self.desc then
106 | self.desc:SetTextColor(0.5, 0.5, 0.5)
107 | end
108 | else
109 | self.frame:Enable()
110 | self.text:SetTextColor(1, 1, 1)
111 | if self.tristate and self.checked == nil then
112 | SetDesaturation(self.check, true)
113 | else
114 | SetDesaturation(self.check, false)
115 | end
116 | if self.desc then
117 | self.desc:SetTextColor(1, 1, 1)
118 | end
119 | end
120 | end,
121 |
122 | ["SetValue"] = function(self, value)
123 | local check = self.check
124 | self.checked = value
125 | if value then
126 | SetDesaturation(check, false)
127 | check:Show()
128 | else
129 | --Nil is the unknown tristate value
130 | if self.tristate and value == nil then
131 | SetDesaturation(check, true)
132 | check:Show()
133 | else
134 | SetDesaturation(check, false)
135 | check:Hide()
136 | end
137 | end
138 | self:SetDisabled(self.disabled)
139 | end,
140 |
141 | ["GetValue"] = function(self)
142 | return self.checked
143 | end,
144 |
145 | ["SetTriState"] = function(self, enabled)
146 | self.tristate = enabled
147 | self:SetValue(self:GetValue())
148 | end,
149 |
150 | ["SetType"] = function(self, type)
151 | local checkbg = self.checkbg
152 | local check = self.check
153 | local highlight = self.highlight
154 |
155 | local size
156 | if type == "radio" then
157 | size = 16
158 | checkbg:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
159 | checkbg:SetTexCoord(0, 0.25, 0, 1)
160 | check:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
161 | check:SetTexCoord(0.25, 0.5, 0, 1)
162 | check:SetBlendMode("ADD")
163 | highlight:SetTexture(130843) -- Interface\\Buttons\\UI-RadioButton
164 | highlight:SetTexCoord(0.5, 0.75, 0, 1)
165 | else
166 | size = 24
167 | checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
168 | checkbg:SetTexCoord(0, 1, 0, 1)
169 | check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
170 | check:SetTexCoord(0, 1, 0, 1)
171 | check:SetBlendMode("BLEND")
172 | highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
173 | highlight:SetTexCoord(0, 1, 0, 1)
174 | end
175 | checkbg:SetHeight(size)
176 | checkbg:SetWidth(size)
177 | end,
178 |
179 | ["ToggleChecked"] = function(self)
180 | local value = self:GetValue()
181 | if self.tristate then
182 | --cycle in true, nil, false order
183 | if value then
184 | self:SetValue(nil)
185 | elseif value == nil then
186 | self:SetValue(false)
187 | else
188 | self:SetValue(true)
189 | end
190 | else
191 | self:SetValue(not self:GetValue())
192 | end
193 | end,
194 |
195 | ["SetLabel"] = function(self, label)
196 | self.text:SetText(label)
197 | end,
198 |
199 | ["SetDescription"] = function(self, desc)
200 | if desc then
201 | if not self.desc then
202 | local desc = self.frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
203 | desc:ClearAllPoints()
204 | desc:SetPoint("TOPLEFT", self.checkbg, "TOPRIGHT", 5, -21)
205 | desc:SetWidth(self.frame.width - 30)
206 | desc:SetPoint("RIGHT", self.frame, "RIGHT", -30, 0)
207 | desc:SetJustifyH("LEFT")
208 | desc:SetJustifyV("TOP")
209 | self.desc = desc
210 | end
211 | self.desc:Show()
212 | --self.text:SetFontObject(GameFontNormal)
213 | self.desc:SetText(desc)
214 | self:SetHeight(28 + self.desc:GetStringHeight())
215 | else
216 | if self.desc then
217 | self.desc:SetText("")
218 | self.desc:Hide()
219 | end
220 | --self.text:SetFontObject(GameFontHighlight)
221 | self:SetHeight(24)
222 | end
223 | end,
224 |
225 | ["SetImage"] = function(self, path, ...)
226 | local image = self.image
227 | image:SetTexture(path)
228 |
229 | if image:GetTexture() then
230 | local n = select("#", ...)
231 | if n == 4 or n == 8 then
232 | image:SetTexCoord(...)
233 | else
234 | image:SetTexCoord(0, 1, 0, 1)
235 | end
236 | end
237 | AlignImage(self)
238 | end
239 | }
240 |
241 | --[[-----------------------------------------------------------------------------
242 | Constructor
243 | -------------------------------------------------------------------------------]]
244 | local function Constructor()
245 | local frame = CreateFrame("Button", nil, UIParent)
246 | frame:Hide()
247 |
248 | frame:EnableMouse(true)
249 | frame:SetScript("OnEnter", Control_OnEnter)
250 | frame:SetScript("OnLeave", Control_OnLeave)
251 | frame:SetScript("OnMouseDown", CheckBox_OnMouseDown)
252 | frame:SetScript("OnMouseUp", CheckBox_OnMouseUp)
253 |
254 | local checkbg = frame:CreateTexture(nil, "ARTWORK")
255 | checkbg:SetWidth(24)
256 | checkbg:SetHeight(24)
257 | checkbg:SetPoint("TOPLEFT")
258 | checkbg:SetTexture(130755) -- Interface\\Buttons\\UI-CheckBox-Up
259 |
260 | local check = frame:CreateTexture(nil, "OVERLAY")
261 | check:SetAllPoints(checkbg)
262 | check:SetTexture(130751) -- Interface\\Buttons\\UI-CheckBox-Check
263 |
264 | local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
265 | text:SetJustifyH("LEFT")
266 | text:SetHeight(18)
267 | text:SetPoint("LEFT", checkbg, "RIGHT")
268 | text:SetPoint("RIGHT")
269 |
270 | local highlight = frame:CreateTexture(nil, "HIGHLIGHT")
271 | highlight:SetTexture(130753) -- Interface\\Buttons\\UI-CheckBox-Highlight
272 | highlight:SetBlendMode("ADD")
273 | highlight:SetAllPoints(checkbg)
274 |
275 | local image = frame:CreateTexture(nil, "OVERLAY")
276 | image:SetHeight(16)
277 | image:SetWidth(16)
278 | image:SetPoint("LEFT", checkbg, "RIGHT", 1, 0)
279 |
280 | local widget = {
281 | checkbg = checkbg,
282 | check = check,
283 | text = text,
284 | highlight = highlight,
285 | image = image,
286 | frame = frame,
287 | type = Type
288 | }
289 | for method, func in pairs(methods) do
290 | widget[method] = func
291 | end
292 |
293 | return AceGUI:RegisterAsWidget(widget)
294 | end
295 |
296 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
297 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Slider Widget
3 | Graphical Slider, like, for Range values.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "Slider", 23
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local min, max, floor = math.min, math.max, math.floor
11 | local tonumber, pairs = tonumber, pairs
12 |
13 | -- WoW APIs
14 | local PlaySound = PlaySound
15 | local CreateFrame, UIParent = CreateFrame, UIParent
16 |
17 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
18 | -- List them here for Mikk's FindGlobals script
19 | -- GLOBALS: GameFontHighlightSmall
20 |
21 | --[[-----------------------------------------------------------------------------
22 | Support functions
23 | -------------------------------------------------------------------------------]]
24 | local function UpdateText(self)
25 | local value = self.value or 0
26 | if self.ispercent then
27 | self.editbox:SetText(("%s%%"):format(floor(value * 1000 + 0.5) / 10))
28 | else
29 | self.editbox:SetText(floor(value * 100 + 0.5) / 100)
30 | end
31 | end
32 |
33 | local function UpdateLabels(self)
34 | local min, max = (self.min or 0), (self.max or 100)
35 | if self.ispercent then
36 | self.lowtext:SetFormattedText("%s%%", (min * 100))
37 | self.hightext:SetFormattedText("%s%%", (max * 100))
38 | else
39 | self.lowtext:SetText(min)
40 | self.hightext:SetText(max)
41 | end
42 | end
43 |
44 | --[[-----------------------------------------------------------------------------
45 | Scripts
46 | -------------------------------------------------------------------------------]]
47 | local function Control_OnEnter(frame)
48 | frame.obj:Fire("OnEnter")
49 | end
50 |
51 | local function Control_OnLeave(frame)
52 | frame.obj:Fire("OnLeave")
53 | end
54 |
55 | local function Frame_OnMouseDown(frame)
56 | frame.obj.slider:EnableMouseWheel(true)
57 | AceGUI:ClearFocus()
58 | end
59 |
60 | local function Slider_OnValueChanged(frame, newvalue)
61 | local self = frame.obj
62 | if not frame.setup then
63 | if self.step and self.step > 0 then
64 | local min_value = self.min or 0
65 | newvalue = floor((newvalue - min_value) / self.step + 0.5) * self.step + min_value
66 | end
67 | if newvalue ~= self.value and not self.disabled then
68 | self.value = newvalue
69 | self:Fire("OnValueChanged", newvalue)
70 | end
71 | if self.value then
72 | UpdateText(self)
73 | end
74 | end
75 | end
76 |
77 | local function Slider_OnMouseUp(frame)
78 | local self = frame.obj
79 | self:Fire("OnMouseUp", self.value)
80 | end
81 |
82 | local function Slider_OnMouseWheel(frame, v)
83 | local self = frame.obj
84 | if not self.disabled then
85 | local value = self.value
86 | if v > 0 then
87 | value = min(value + (self.step or 1), self.max)
88 | else
89 | value = max(value - (self.step or 1), self.min)
90 | end
91 | self.slider:SetValue(value)
92 | end
93 | end
94 |
95 | local function EditBox_OnEscapePressed(frame)
96 | frame:ClearFocus()
97 | end
98 |
99 | local function EditBox_OnEnterPressed(frame)
100 | local self = frame.obj
101 | local value = frame:GetText()
102 | if self.ispercent then
103 | value = value:gsub('%%', '')
104 | value = tonumber(value) / 100
105 | else
106 | value = tonumber(value)
107 | end
108 |
109 | if value then
110 | PlaySound(856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
111 | self.slider:SetValue(value)
112 | self:Fire("OnMouseUp", value)
113 | end
114 | end
115 |
116 | local function EditBox_OnEnter(frame)
117 | frame:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
118 | end
119 |
120 | local function EditBox_OnLeave(frame)
121 | frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
122 | end
123 |
124 | --[[-----------------------------------------------------------------------------
125 | Methods
126 | -------------------------------------------------------------------------------]]
127 | local methods = {
128 | ["OnAcquire"] = function(self)
129 | self:SetWidth(200)
130 | self:SetHeight(44)
131 | self:SetDisabled(false)
132 | self:SetIsPercent(nil)
133 | self:SetSliderValues(0,100,1)
134 | self:SetValue(0)
135 | self.slider:EnableMouseWheel(false)
136 | end,
137 |
138 | -- ["OnRelease"] = nil,
139 |
140 | ["SetDisabled"] = function(self, disabled)
141 | self.disabled = disabled
142 | if disabled then
143 | self.slider:EnableMouse(false)
144 | self.label:SetTextColor(.5, .5, .5)
145 | self.hightext:SetTextColor(.5, .5, .5)
146 | self.lowtext:SetTextColor(.5, .5, .5)
147 | --self.valuetext:SetTextColor(.5, .5, .5)
148 | self.editbox:SetTextColor(.5, .5, .5)
149 | self.editbox:EnableMouse(false)
150 | self.editbox:ClearFocus()
151 | else
152 | self.slider:EnableMouse(true)
153 | self.label:SetTextColor(1, .82, 0)
154 | self.hightext:SetTextColor(1, 1, 1)
155 | self.lowtext:SetTextColor(1, 1, 1)
156 | --self.valuetext:SetTextColor(1, 1, 1)
157 | self.editbox:SetTextColor(1, 1, 1)
158 | self.editbox:EnableMouse(true)
159 | end
160 | end,
161 |
162 | ["SetValue"] = function(self, value)
163 | self.slider.setup = true
164 | self.slider:SetValue(value)
165 | self.value = value
166 | UpdateText(self)
167 | self.slider.setup = nil
168 | end,
169 |
170 | ["GetValue"] = function(self)
171 | return self.value
172 | end,
173 |
174 | ["SetLabel"] = function(self, text)
175 | self.label:SetText(text)
176 | end,
177 |
178 | ["SetSliderValues"] = function(self, min, max, step)
179 | local frame = self.slider
180 | frame.setup = true
181 | self.min = min
182 | self.max = max
183 | self.step = step
184 | frame:SetMinMaxValues(min or 0,max or 100)
185 | UpdateLabels(self)
186 | frame:SetValueStep(step or 1)
187 | if self.value then
188 | frame:SetValue(self.value)
189 | end
190 | frame.setup = nil
191 | end,
192 |
193 | ["SetIsPercent"] = function(self, value)
194 | self.ispercent = value
195 | UpdateLabels(self)
196 | UpdateText(self)
197 | end
198 | }
199 |
200 | --[[-----------------------------------------------------------------------------
201 | Constructor
202 | -------------------------------------------------------------------------------]]
203 | local SliderBackdrop = {
204 | bgFile = "Interface\\Buttons\\UI-SliderBar-Background",
205 | edgeFile = "Interface\\Buttons\\UI-SliderBar-Border",
206 | tile = true, tileSize = 8, edgeSize = 8,
207 | insets = { left = 3, right = 3, top = 6, bottom = 6 }
208 | }
209 |
210 | local ManualBackdrop = {
211 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
212 | edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
213 | tile = true, edgeSize = 1, tileSize = 5,
214 | }
215 |
216 | local function Constructor()
217 | local frame = CreateFrame("Frame", nil, UIParent)
218 |
219 | frame:EnableMouse(true)
220 | frame:SetScript("OnMouseDown", Frame_OnMouseDown)
221 |
222 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
223 | label:SetPoint("TOPLEFT")
224 | label:SetPoint("TOPRIGHT")
225 | label:SetJustifyH("CENTER")
226 | label:SetHeight(15)
227 |
228 | local slider = CreateFrame("Slider", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
229 | slider:SetOrientation("HORIZONTAL")
230 | slider:SetHeight(15)
231 | slider:SetHitRectInsets(0, 0, -10, 0)
232 | slider:SetBackdrop(SliderBackdrop)
233 | slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Horizontal")
234 | slider:SetPoint("TOP", label, "BOTTOM")
235 | slider:SetPoint("LEFT", 3, 0)
236 | slider:SetPoint("RIGHT", -3, 0)
237 | slider:SetValue(0)
238 | slider:SetScript("OnValueChanged",Slider_OnValueChanged)
239 | slider:SetScript("OnEnter", Control_OnEnter)
240 | slider:SetScript("OnLeave", Control_OnLeave)
241 | slider:SetScript("OnMouseUp", Slider_OnMouseUp)
242 | slider:SetScript("OnMouseWheel", Slider_OnMouseWheel)
243 |
244 | local lowtext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
245 | lowtext:SetPoint("TOPLEFT", slider, "BOTTOMLEFT", 2, 3)
246 |
247 | local hightext = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
248 | hightext:SetPoint("TOPRIGHT", slider, "BOTTOMRIGHT", -2, 3)
249 |
250 | local editbox = CreateFrame("EditBox", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
251 | editbox:SetAutoFocus(false)
252 | editbox:SetFontObject(GameFontHighlightSmall)
253 | editbox:SetPoint("TOP", slider, "BOTTOM")
254 | editbox:SetHeight(14)
255 | editbox:SetWidth(70)
256 | editbox:SetJustifyH("CENTER")
257 | editbox:EnableMouse(true)
258 | editbox:SetBackdrop(ManualBackdrop)
259 | editbox:SetBackdropColor(0, 0, 0, 0.5)
260 | editbox:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
261 | editbox:SetScript("OnEnter", EditBox_OnEnter)
262 | editbox:SetScript("OnLeave", EditBox_OnLeave)
263 | editbox:SetScript("OnEnterPressed", EditBox_OnEnterPressed)
264 | editbox:SetScript("OnEscapePressed", EditBox_OnEscapePressed)
265 |
266 | local widget = {
267 | label = label,
268 | slider = slider,
269 | lowtext = lowtext,
270 | hightext = hightext,
271 | editbox = editbox,
272 | alignoffset = 25,
273 | frame = frame,
274 | type = Type
275 | }
276 | for method, func in pairs(methods) do
277 | widget[method] = func
278 | end
279 | slider.obj, editbox.obj = widget, widget
280 |
281 | return AceGUI:RegisterAsWidget(widget)
282 | end
283 |
284 | AceGUI:RegisterWidgetType(Type,Constructor,Version)
285 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | Frame Container
3 | -------------------------------------------------------------------------------]]
4 | local Type, Version = "Frame", 27
5 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
6 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
7 |
8 | -- Lua APIs
9 | local pairs, assert, type = pairs, assert, type
10 | local wipe = table.wipe
11 |
12 | -- WoW APIs
13 | local PlaySound = PlaySound
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 |
16 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
17 | -- List them here for Mikk's FindGlobals script
18 | -- GLOBALS: CLOSE
19 |
20 | --[[-----------------------------------------------------------------------------
21 | Scripts
22 | -------------------------------------------------------------------------------]]
23 | local function Button_OnClick(frame)
24 | PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
25 | frame.obj:Hide()
26 | end
27 |
28 | local function Frame_OnShow(frame)
29 | frame.obj:Fire("OnShow")
30 | end
31 |
32 | local function Frame_OnClose(frame)
33 | frame.obj:Fire("OnClose")
34 | end
35 |
36 | local function Frame_OnMouseDown(frame)
37 | AceGUI:ClearFocus()
38 | end
39 |
40 | local function Title_OnMouseDown(frame)
41 | frame:GetParent():StartMoving()
42 | AceGUI:ClearFocus()
43 | end
44 |
45 | local function MoverSizer_OnMouseUp(mover)
46 | local frame = mover:GetParent()
47 | frame:StopMovingOrSizing()
48 | local self = frame.obj
49 | local status = self.status or self.localstatus
50 | status.width = frame:GetWidth()
51 | status.height = frame:GetHeight()
52 | status.top = frame:GetTop()
53 | status.left = frame:GetLeft()
54 | end
55 |
56 | local function SizerSE_OnMouseDown(frame)
57 | frame:GetParent():StartSizing("BOTTOMRIGHT")
58 | AceGUI:ClearFocus()
59 | end
60 |
61 | local function SizerS_OnMouseDown(frame)
62 | frame:GetParent():StartSizing("BOTTOM")
63 | AceGUI:ClearFocus()
64 | end
65 |
66 | local function SizerE_OnMouseDown(frame)
67 | frame:GetParent():StartSizing("RIGHT")
68 | AceGUI:ClearFocus()
69 | end
70 |
71 | local function StatusBar_OnEnter(frame)
72 | frame.obj:Fire("OnEnterStatusBar")
73 | end
74 |
75 | local function StatusBar_OnLeave(frame)
76 | frame.obj:Fire("OnLeaveStatusBar")
77 | end
78 |
79 | --[[-----------------------------------------------------------------------------
80 | Methods
81 | -------------------------------------------------------------------------------]]
82 | local methods = {
83 | ["OnAcquire"] = function(self)
84 | self.frame:SetParent(UIParent)
85 | self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
86 | self:SetTitle()
87 | self:SetStatusText()
88 | self:ApplyStatus()
89 | self:Show()
90 | self:EnableResize(true)
91 | end,
92 |
93 | ["OnRelease"] = function(self)
94 | self.status = nil
95 | wipe(self.localstatus)
96 | end,
97 |
98 | ["OnWidthSet"] = function(self, width)
99 | local content = self.content
100 | local contentwidth = width - 34
101 | if contentwidth < 0 then
102 | contentwidth = 0
103 | end
104 | content:SetWidth(contentwidth)
105 | content.width = contentwidth
106 | end,
107 |
108 | ["OnHeightSet"] = function(self, height)
109 | local content = self.content
110 | local contentheight = height - 57
111 | if contentheight < 0 then
112 | contentheight = 0
113 | end
114 | content:SetHeight(contentheight)
115 | content.height = contentheight
116 | end,
117 |
118 | ["SetTitle"] = function(self, title)
119 | self.titletext:SetText(title)
120 | self.titlebg:SetWidth((self.titletext:GetWidth() or 0) + 10)
121 | end,
122 |
123 | ["SetStatusText"] = function(self, text)
124 | self.statustext:SetText(text)
125 | end,
126 |
127 | ["Hide"] = function(self)
128 | self.frame:Hide()
129 | end,
130 |
131 | ["Show"] = function(self)
132 | self.frame:Show()
133 | end,
134 |
135 | ["EnableResize"] = function(self, state)
136 | local func = state and "Show" or "Hide"
137 | self.sizer_se[func](self.sizer_se)
138 | self.sizer_s[func](self.sizer_s)
139 | self.sizer_e[func](self.sizer_e)
140 | end,
141 |
142 | -- called to set an external table to store status in
143 | ["SetStatusTable"] = function(self, status)
144 | assert(type(status) == "table")
145 | self.status = status
146 | self:ApplyStatus()
147 | end,
148 |
149 | ["ApplyStatus"] = function(self)
150 | local status = self.status or self.localstatus
151 | local frame = self.frame
152 | self:SetWidth(status.width or 700)
153 | self:SetHeight(status.height or 500)
154 | frame:ClearAllPoints()
155 | if status.top and status.left then
156 | frame:SetPoint("TOP", UIParent, "BOTTOM", 0, status.top)
157 | frame:SetPoint("LEFT", UIParent, "LEFT", status.left, 0)
158 | else
159 | frame:SetPoint("CENTER")
160 | end
161 | end
162 | }
163 |
164 | --[[-----------------------------------------------------------------------------
165 | Constructor
166 | -------------------------------------------------------------------------------]]
167 | local FrameBackdrop = {
168 | bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
169 | edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
170 | tile = true, tileSize = 32, edgeSize = 32,
171 | insets = { left = 8, right = 8, top = 8, bottom = 8 }
172 | }
173 |
174 | local PaneBackdrop = {
175 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
176 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
177 | tile = true, tileSize = 16, edgeSize = 16,
178 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
179 | }
180 |
181 | local function Constructor()
182 | local frame = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
183 | frame:Hide()
184 |
185 | frame:EnableMouse(true)
186 | frame:SetMovable(true)
187 | frame:SetResizable(true)
188 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
189 | frame:SetBackdrop(FrameBackdrop)
190 | frame:SetBackdropColor(0, 0, 0, 1)
191 | frame:SetMinResize(400, 200)
192 | frame:SetToplevel(true)
193 | frame:SetScript("OnShow", Frame_OnShow)
194 | frame:SetScript("OnHide", Frame_OnClose)
195 | frame:SetScript("OnMouseDown", Frame_OnMouseDown)
196 |
197 | local closebutton = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
198 | closebutton:SetScript("OnClick", Button_OnClick)
199 | closebutton:SetPoint("BOTTOMRIGHT", -27, 17)
200 | closebutton:SetHeight(20)
201 | closebutton:SetWidth(100)
202 | closebutton:SetText(CLOSE)
203 |
204 | local statusbg = CreateFrame("Button", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
205 | statusbg:SetPoint("BOTTOMLEFT", 15, 15)
206 | statusbg:SetPoint("BOTTOMRIGHT", -132, 15)
207 | statusbg:SetHeight(24)
208 | statusbg:SetBackdrop(PaneBackdrop)
209 | statusbg:SetBackdropColor(0.1,0.1,0.1)
210 | statusbg:SetBackdropBorderColor(0.4,0.4,0.4)
211 | statusbg:SetScript("OnEnter", StatusBar_OnEnter)
212 | statusbg:SetScript("OnLeave", StatusBar_OnLeave)
213 |
214 | local statustext = statusbg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
215 | statustext:SetPoint("TOPLEFT", 7, -2)
216 | statustext:SetPoint("BOTTOMRIGHT", -7, 2)
217 | statustext:SetHeight(20)
218 | statustext:SetJustifyH("LEFT")
219 | statustext:SetText("")
220 |
221 | local titlebg = frame:CreateTexture(nil, "OVERLAY")
222 | titlebg:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
223 | titlebg:SetTexCoord(0.31, 0.67, 0, 0.63)
224 | titlebg:SetPoint("TOP", 0, 12)
225 | titlebg:SetWidth(100)
226 | titlebg:SetHeight(40)
227 |
228 | local title = CreateFrame("Frame", nil, frame)
229 | title:EnableMouse(true)
230 | title:SetScript("OnMouseDown", Title_OnMouseDown)
231 | title:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
232 | title:SetAllPoints(titlebg)
233 |
234 | local titletext = title:CreateFontString(nil, "OVERLAY", "GameFontNormal")
235 | titletext:SetPoint("TOP", titlebg, "TOP", 0, -14)
236 |
237 | local titlebg_l = frame:CreateTexture(nil, "OVERLAY")
238 | titlebg_l:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
239 | titlebg_l:SetTexCoord(0.21, 0.31, 0, 0.63)
240 | titlebg_l:SetPoint("RIGHT", titlebg, "LEFT")
241 | titlebg_l:SetWidth(30)
242 | titlebg_l:SetHeight(40)
243 |
244 | local titlebg_r = frame:CreateTexture(nil, "OVERLAY")
245 | titlebg_r:SetTexture(131080) -- Interface\\DialogFrame\\UI-DialogBox-Header
246 | titlebg_r:SetTexCoord(0.67, 0.77, 0, 0.63)
247 | titlebg_r:SetPoint("LEFT", titlebg, "RIGHT")
248 | titlebg_r:SetWidth(30)
249 | titlebg_r:SetHeight(40)
250 |
251 | local sizer_se = CreateFrame("Frame", nil, frame)
252 | sizer_se:SetPoint("BOTTOMRIGHT")
253 | sizer_se:SetWidth(25)
254 | sizer_se:SetHeight(25)
255 | sizer_se:EnableMouse()
256 | sizer_se:SetScript("OnMouseDown",SizerSE_OnMouseDown)
257 | sizer_se:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
258 |
259 | local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
260 | line1:SetWidth(14)
261 | line1:SetHeight(14)
262 | line1:SetPoint("BOTTOMRIGHT", -8, 8)
263 | line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
264 | local x = 0.1 * 14/17
265 | line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
266 |
267 | local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
268 | line2:SetWidth(8)
269 | line2:SetHeight(8)
270 | line2:SetPoint("BOTTOMRIGHT", -8, 8)
271 | line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
272 | local x = 0.1 * 8/17
273 | line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
274 |
275 | local sizer_s = CreateFrame("Frame", nil, frame)
276 | sizer_s:SetPoint("BOTTOMRIGHT", -25, 0)
277 | sizer_s:SetPoint("BOTTOMLEFT")
278 | sizer_s:SetHeight(25)
279 | sizer_s:EnableMouse(true)
280 | sizer_s:SetScript("OnMouseDown", SizerS_OnMouseDown)
281 | sizer_s:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
282 |
283 | local sizer_e = CreateFrame("Frame", nil, frame)
284 | sizer_e:SetPoint("BOTTOMRIGHT", 0, 25)
285 | sizer_e:SetPoint("TOPRIGHT")
286 | sizer_e:SetWidth(25)
287 | sizer_e:EnableMouse(true)
288 | sizer_e:SetScript("OnMouseDown", SizerE_OnMouseDown)
289 | sizer_e:SetScript("OnMouseUp", MoverSizer_OnMouseUp)
290 |
291 | --Container Support
292 | local content = CreateFrame("Frame", nil, frame)
293 | content:SetPoint("TOPLEFT", 17, -27)
294 | content:SetPoint("BOTTOMRIGHT", -17, 40)
295 |
296 | local widget = {
297 | localstatus = {},
298 | titletext = titletext,
299 | statustext = statustext,
300 | titlebg = titlebg,
301 | sizer_se = sizer_se,
302 | sizer_s = sizer_s,
303 | sizer_e = sizer_e,
304 | content = content,
305 | frame = frame,
306 | type = Type
307 | }
308 | for method, func in pairs(methods) do
309 | widget[method] = func
310 | end
311 | closebutton.obj, statusbg.obj = widget, widget
312 |
313 | return AceGUI:RegisterAsContainer(widget)
314 | end
315 |
316 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
317 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua:
--------------------------------------------------------------------------------
1 | local AceGUI = LibStub("AceGUI-3.0")
2 |
3 | -- Lua APIs
4 | local pairs, assert, type = pairs, assert, type
5 |
6 | -- WoW APIs
7 | local PlaySound = PlaySound
8 | local CreateFrame, UIParent = CreateFrame, UIParent
9 |
10 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
11 | -- List them here for Mikk's FindGlobals script
12 | -- GLOBALS: GameFontNormal
13 |
14 | ----------------
15 | -- Main Frame --
16 | ----------------
17 | --[[
18 | Events :
19 | OnClose
20 |
21 | ]]
22 | do
23 | local Type = "Window"
24 | local Version = 6
25 |
26 | local function frameOnShow(this)
27 | this.obj:Fire("OnShow")
28 | end
29 |
30 | local function frameOnClose(this)
31 | this.obj:Fire("OnClose")
32 | end
33 |
34 | local function closeOnClick(this)
35 | PlaySound(799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
36 | this.obj:Hide()
37 | end
38 |
39 | local function frameOnMouseDown(this)
40 | AceGUI:ClearFocus()
41 | end
42 |
43 | local function titleOnMouseDown(this)
44 | this:GetParent():StartMoving()
45 | AceGUI:ClearFocus()
46 | end
47 |
48 | local function frameOnMouseUp(this)
49 | local frame = this:GetParent()
50 | frame:StopMovingOrSizing()
51 | local self = frame.obj
52 | local status = self.status or self.localstatus
53 | status.width = frame:GetWidth()
54 | status.height = frame:GetHeight()
55 | status.top = frame:GetTop()
56 | status.left = frame:GetLeft()
57 | end
58 |
59 | local function sizerseOnMouseDown(this)
60 | this:GetParent():StartSizing("BOTTOMRIGHT")
61 | AceGUI:ClearFocus()
62 | end
63 |
64 | local function sizersOnMouseDown(this)
65 | this:GetParent():StartSizing("BOTTOM")
66 | AceGUI:ClearFocus()
67 | end
68 |
69 | local function sizereOnMouseDown(this)
70 | this:GetParent():StartSizing("RIGHT")
71 | AceGUI:ClearFocus()
72 | end
73 |
74 | local function sizerOnMouseUp(this)
75 | this:GetParent():StopMovingOrSizing()
76 | end
77 |
78 | local function SetTitle(self,title)
79 | self.titletext:SetText(title)
80 | end
81 |
82 | local function SetStatusText(self,text)
83 | -- self.statustext:SetText(text)
84 | end
85 |
86 | local function Hide(self)
87 | self.frame:Hide()
88 | end
89 |
90 | local function Show(self)
91 | self.frame:Show()
92 | end
93 |
94 | local function OnAcquire(self)
95 | self.frame:SetParent(UIParent)
96 | self.frame:SetFrameStrata("FULLSCREEN_DIALOG")
97 | self:ApplyStatus()
98 | self:EnableResize(true)
99 | self:Show()
100 | end
101 |
102 | local function OnRelease(self)
103 | self.status = nil
104 | for k in pairs(self.localstatus) do
105 | self.localstatus[k] = nil
106 | end
107 | end
108 |
109 | -- called to set an external table to store status in
110 | local function SetStatusTable(self, status)
111 | assert(type(status) == "table")
112 | self.status = status
113 | self:ApplyStatus()
114 | end
115 |
116 | local function ApplyStatus(self)
117 | local status = self.status or self.localstatus
118 | local frame = self.frame
119 | self:SetWidth(status.width or 700)
120 | self:SetHeight(status.height or 500)
121 | if status.top and status.left then
122 | frame:SetPoint("TOP",UIParent,"BOTTOM",0,status.top)
123 | frame:SetPoint("LEFT",UIParent,"LEFT",status.left,0)
124 | else
125 | frame:SetPoint("CENTER",UIParent,"CENTER")
126 | end
127 | end
128 |
129 | local function OnWidthSet(self, width)
130 | local content = self.content
131 | local contentwidth = width - 34
132 | if contentwidth < 0 then
133 | contentwidth = 0
134 | end
135 | content:SetWidth(contentwidth)
136 | content.width = contentwidth
137 | end
138 |
139 |
140 | local function OnHeightSet(self, height)
141 | local content = self.content
142 | local contentheight = height - 57
143 | if contentheight < 0 then
144 | contentheight = 0
145 | end
146 | content:SetHeight(contentheight)
147 | content.height = contentheight
148 | end
149 |
150 | local function EnableResize(self, state)
151 | local func = state and "Show" or "Hide"
152 | self.sizer_se[func](self.sizer_se)
153 | self.sizer_s[func](self.sizer_s)
154 | self.sizer_e[func](self.sizer_e)
155 | end
156 |
157 | local function Constructor()
158 | local frame = CreateFrame("Frame",nil,UIParent)
159 | local self = {}
160 | self.type = "Window"
161 |
162 | self.Hide = Hide
163 | self.Show = Show
164 | self.SetTitle = SetTitle
165 | self.OnRelease = OnRelease
166 | self.OnAcquire = OnAcquire
167 | self.SetStatusText = SetStatusText
168 | self.SetStatusTable = SetStatusTable
169 | self.ApplyStatus = ApplyStatus
170 | self.OnWidthSet = OnWidthSet
171 | self.OnHeightSet = OnHeightSet
172 | self.EnableResize = EnableResize
173 |
174 | self.localstatus = {}
175 |
176 | self.frame = frame
177 | frame.obj = self
178 | frame:SetWidth(700)
179 | frame:SetHeight(500)
180 | frame:SetPoint("CENTER",UIParent,"CENTER",0,0)
181 | frame:EnableMouse()
182 | frame:SetMovable(true)
183 | frame:SetResizable(true)
184 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
185 | frame:SetScript("OnMouseDown", frameOnMouseDown)
186 |
187 | frame:SetScript("OnShow",frameOnShow)
188 | frame:SetScript("OnHide",frameOnClose)
189 | frame:SetMinResize(240,240)
190 | frame:SetToplevel(true)
191 |
192 | local titlebg = frame:CreateTexture(nil, "BACKGROUND")
193 | titlebg:SetTexture(251966) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Title-Background
194 | titlebg:SetPoint("TOPLEFT", 9, -6)
195 | titlebg:SetPoint("BOTTOMRIGHT", frame, "TOPRIGHT", -28, -24)
196 |
197 | local dialogbg = frame:CreateTexture(nil, "BACKGROUND")
198 | dialogbg:SetTexture(137056) -- Interface\\Tooltips\\UI-Tooltip-Background
199 | dialogbg:SetPoint("TOPLEFT", 8, -24)
200 | dialogbg:SetPoint("BOTTOMRIGHT", -6, 8)
201 | dialogbg:SetVertexColor(0, 0, 0, .75)
202 |
203 | local topleft = frame:CreateTexture(nil, "BORDER")
204 | topleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
205 | topleft:SetWidth(64)
206 | topleft:SetHeight(64)
207 | topleft:SetPoint("TOPLEFT")
208 | topleft:SetTexCoord(0.501953125, 0.625, 0, 1)
209 |
210 | local topright = frame:CreateTexture(nil, "BORDER")
211 | topright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
212 | topright:SetWidth(64)
213 | topright:SetHeight(64)
214 | topright:SetPoint("TOPRIGHT")
215 | topright:SetTexCoord(0.625, 0.75, 0, 1)
216 |
217 | local top = frame:CreateTexture(nil, "BORDER")
218 | top:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
219 | top:SetHeight(64)
220 | top:SetPoint("TOPLEFT", topleft, "TOPRIGHT")
221 | top:SetPoint("TOPRIGHT", topright, "TOPLEFT")
222 | top:SetTexCoord(0.25, 0.369140625, 0, 1)
223 |
224 | local bottomleft = frame:CreateTexture(nil, "BORDER")
225 | bottomleft:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
226 | bottomleft:SetWidth(64)
227 | bottomleft:SetHeight(64)
228 | bottomleft:SetPoint("BOTTOMLEFT")
229 | bottomleft:SetTexCoord(0.751953125, 0.875, 0, 1)
230 |
231 | local bottomright = frame:CreateTexture(nil, "BORDER")
232 | bottomright:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
233 | bottomright:SetWidth(64)
234 | bottomright:SetHeight(64)
235 | bottomright:SetPoint("BOTTOMRIGHT")
236 | bottomright:SetTexCoord(0.875, 1, 0, 1)
237 |
238 | local bottom = frame:CreateTexture(nil, "BORDER")
239 | bottom:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
240 | bottom:SetHeight(64)
241 | bottom:SetPoint("BOTTOMLEFT", bottomleft, "BOTTOMRIGHT")
242 | bottom:SetPoint("BOTTOMRIGHT", bottomright, "BOTTOMLEFT")
243 | bottom:SetTexCoord(0.376953125, 0.498046875, 0, 1)
244 |
245 | local left = frame:CreateTexture(nil, "BORDER")
246 | left:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
247 | left:SetWidth(64)
248 | left:SetPoint("TOPLEFT", topleft, "BOTTOMLEFT")
249 | left:SetPoint("BOTTOMLEFT", bottomleft, "TOPLEFT")
250 | left:SetTexCoord(0.001953125, 0.125, 0, 1)
251 |
252 | local right = frame:CreateTexture(nil, "BORDER")
253 | right:SetTexture(251963) -- Interface\\PaperDollInfoFrame\\UI-GearManager-Border
254 | right:SetWidth(64)
255 | right:SetPoint("TOPRIGHT", topright, "BOTTOMRIGHT")
256 | right:SetPoint("BOTTOMRIGHT", bottomright, "TOPRIGHT")
257 | right:SetTexCoord(0.1171875, 0.2421875, 0, 1)
258 |
259 | local close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
260 | close:SetPoint("TOPRIGHT", 2, 1)
261 | close:SetScript("OnClick", closeOnClick)
262 | self.closebutton = close
263 | close.obj = self
264 |
265 | local titletext = frame:CreateFontString(nil, "ARTWORK")
266 | titletext:SetFontObject(GameFontNormal)
267 | titletext:SetPoint("TOPLEFT", 12, -8)
268 | titletext:SetPoint("TOPRIGHT", -32, -8)
269 | self.titletext = titletext
270 |
271 | local title = CreateFrame("Button", nil, frame)
272 | title:SetPoint("TOPLEFT", titlebg)
273 | title:SetPoint("BOTTOMRIGHT", titlebg)
274 | title:EnableMouse()
275 | title:SetScript("OnMouseDown",titleOnMouseDown)
276 | title:SetScript("OnMouseUp", frameOnMouseUp)
277 | self.title = title
278 |
279 | local sizer_se = CreateFrame("Frame",nil,frame)
280 | sizer_se:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,0)
281 | sizer_se:SetWidth(25)
282 | sizer_se:SetHeight(25)
283 | sizer_se:EnableMouse()
284 | sizer_se:SetScript("OnMouseDown",sizerseOnMouseDown)
285 | sizer_se:SetScript("OnMouseUp", sizerOnMouseUp)
286 | self.sizer_se = sizer_se
287 |
288 | local line1 = sizer_se:CreateTexture(nil, "BACKGROUND")
289 | self.line1 = line1
290 | line1:SetWidth(14)
291 | line1:SetHeight(14)
292 | line1:SetPoint("BOTTOMRIGHT", -8, 8)
293 | line1:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
294 | local x = 0.1 * 14/17
295 | line1:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
296 |
297 | local line2 = sizer_se:CreateTexture(nil, "BACKGROUND")
298 | self.line2 = line2
299 | line2:SetWidth(8)
300 | line2:SetHeight(8)
301 | line2:SetPoint("BOTTOMRIGHT", -8, 8)
302 | line2:SetTexture(137057) -- Interface\\Tooltips\\UI-Tooltip-Border
303 | local x = 0.1 * 8/17
304 | line2:SetTexCoord(0.05 - x, 0.5, 0.05, 0.5 + x, 0.05, 0.5 - x, 0.5 + x, 0.5)
305 |
306 | local sizer_s = CreateFrame("Frame",nil,frame)
307 | sizer_s:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-25,0)
308 | sizer_s:SetPoint("BOTTOMLEFT",frame,"BOTTOMLEFT",0,0)
309 | sizer_s:SetHeight(25)
310 | sizer_s:EnableMouse()
311 | sizer_s:SetScript("OnMouseDown",sizersOnMouseDown)
312 | sizer_s:SetScript("OnMouseUp", sizerOnMouseUp)
313 | self.sizer_s = sizer_s
314 |
315 | local sizer_e = CreateFrame("Frame",nil,frame)
316 | sizer_e:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",0,25)
317 | sizer_e:SetPoint("TOPRIGHT",frame,"TOPRIGHT",0,0)
318 | sizer_e:SetWidth(25)
319 | sizer_e:EnableMouse()
320 | sizer_e:SetScript("OnMouseDown",sizereOnMouseDown)
321 | sizer_e:SetScript("OnMouseUp", sizerOnMouseUp)
322 | self.sizer_e = sizer_e
323 |
324 | --Container Support
325 | local content = CreateFrame("Frame",nil,frame)
326 | self.content = content
327 | content.obj = self
328 | content:SetPoint("TOPLEFT",frame,"TOPLEFT",12,-32)
329 | content:SetPoint("BOTTOMRIGHT",frame,"BOTTOMRIGHT",-12,13)
330 |
331 | AceGUI:RegisterAsContainer(self)
332 | return self
333 | end
334 |
335 | AceGUI:RegisterWidgetType(Type,Constructor,Version)
336 | end
337 |
--------------------------------------------------------------------------------
/components/settings.lua:
--------------------------------------------------------------------------------
1 | local ADDON_NAME = GetAddOnMetadata(..., 'Title')
2 | local addon = LibStub('AceAddon-3.0'):GetAddon(ADDON_NAME)
3 | local L = LibStub('AceLocale-3.0'):GetLocale(ADDON_NAME, false)
4 | local AceConfig, AceConfigDialog, AceGUI = LibStub('AceConfig-3.0'), LibStub('AceConfigDialog-3.0'), LibStub('AceGUI-3.0')
5 | local Settings = addon:NewModule('Settings')
6 | local infos = addon:GetModule('Constants'):GetInfos()
7 | local Utils = addon:GetModule('Utils')
8 | local Actions = addon:GetModule('Actions')
9 | local options = {}
10 |
11 | options = {
12 | type = 'group',
13 | args = {
14 | portalOptions = {
15 | name = L.SETTINGS_PORTAL_NAME,
16 | type = 'group',
17 | order = 1,
18 | args = {
19 | portalHander = {
20 | name = L.SETTINGS_PORTAL_HEADER,
21 | type = 'header',
22 | order = 1,
23 | },
24 | portalDesc = {
25 | name = L.SETTINGS_PORTAL_DESC,
26 | type = 'description',
27 | order = 2,
28 | },
29 | portalToggle1 = {
30 | name = L.SETTINGS_PORTAL_TOGGLE1,
31 | type = 'toggle',
32 | order = 3,
33 | width = '0.5',
34 | tristate = false,
35 | get = function (info)
36 | local count = Utils:tableLength(WATCHDOG_DB.players)
37 | local Share = addon:GetModule('Share', true)
38 | local shareCount = (Share and Share:getShareCount()) or 0
39 | info.options.args.portalOptions.args.portalStatusAll.name = L.SETTINGS_PORTAL_STATUS_ALL..count
40 | info.options.args.portalOptions.args.portalShareCount.name = L.SETTINGS_PORTAL_SHARE_COUNT..shareCount
41 | info.options.args.portalOptions.args.portalVersion.name = L.SETTINGS_PORTAL_VERSION..infos.VERSION
42 | info.options.args.shareOptions.args.shareDesc.name = string.format(L.SETTINGS_SHARE_DESC, WATCHDOG_DB.shareLimit)
43 | return (WATCHDOG_DB.defaultFilterToggle and true) or false
44 | end,
45 | set = function (info, t)
46 | WATCHDOG_DB.defaultFilterToggle = t
47 | end
48 | },
49 | portalSep = {
50 | name = ' ',
51 | type = 'description',
52 | order = 4,
53 | },
54 | portalToggle2 = {
55 | name = L.SETTINGS_PORTAL_TOGGLE2,
56 | type = 'toggle',
57 | order = 5,
58 | width = '0.5',
59 | tristate = false,
60 | get = function (info)
61 | return (WATCHDOG_DB.versionMessageToggle and true) or false
62 | end,
63 | set = function (info, t)
64 | WATCHDOG_DB.versionMessageToggle = t
65 | end
66 | },
67 | portalShareCount = {
68 | name = ' ',
69 | type = 'description',
70 | order = 6,
71 | },
72 | portalStatusAll = {
73 | name = ' ',
74 | type = 'description',
75 | order = 7,
76 | },
77 | portalVersion = {
78 | name = ' ',
79 | type = 'description',
80 | order = 8,
81 | },
82 | },
83 | },
84 | shareOptions = {
85 | name = L.SETTINGS_SHARE_NAME,
86 | type = 'group',
87 | order = 2,
88 | args = {
89 | shareHander = {
90 | name = L.SETTINGS_SHARE_HEADER,
91 | type = 'header',
92 | order = 1,
93 | },
94 | shareDesc = {
95 | name = ' ',
96 | type = 'description',
97 | order = 2,
98 | },
99 | shareToggle = {
100 | name = L.SETTINGS_SHARE_TOGGLE,
101 | type = 'toggle',
102 | order = 3,
103 | width = 'full',
104 | tristate = false,
105 | get = function (info)
106 | return (WATCHDOG_DB.shareToggle and true) or false
107 | end,
108 | set = function (info, t)
109 | WATCHDOG_DB.shareToggle = t
110 | end
111 | },
112 | shareGuildToggle = {
113 | name = L.SETTINGS_SHARE_GUILD_TOGGLE,
114 | type = 'toggle',
115 | order = 4,
116 | width = 'full',
117 | tristate = false,
118 | disabled = false,
119 | get = function (info)
120 | info.options.args.shareOptions.args.shareGuildToggle.disabled = not WATCHDOG_DB.shareToggle
121 | local t = WATCHDOG_DB.shareToggle and WATCHDOG_DB.shareGuildToggle
122 | return (t and true) or false
123 | end,
124 | set = function (info, t)
125 | WATCHDOG_DB.shareGuildToggle = t
126 | end
127 | },
128 | },
129 | },
130 | ignoreListOptions = {
131 | name = L.SETTINGS_IGNORE_LIST_NAME,
132 | type = 'group',
133 | order = 3,
134 | args = {
135 | ignoreListHander = {
136 | name = L.SETTINGS_IGNORE_LIST_HEADER,
137 | type = 'header',
138 | order = 1,
139 | },
140 | ignoreListDesc = {
141 | name = L.SETTINGS_IGNORE_LIST_DESC,
142 | type = 'description',
143 | order = 2,
144 | },
145 | ignoreListBtn1 = {
146 | name = L.SETTINGS_IGNORE_LIST_BTN1,
147 | descStyle = 'online',
148 | type = 'execute',
149 | width = '0.5',
150 | hidden = false,
151 | func = function (info)
152 | -- reset export string
153 | info.options.args.exportOptions.args.exportInput.get = function()
154 | return ''
155 | end
156 |
157 | local Components = addon:GetModule('Components', true)
158 | if not Components then return end
159 | Components:get('IgnoreList'):open()
160 | AceConfigDialog:Close(L.ADDON_SHOW_NAME)
161 | end
162 | },
163 | },
164 | },
165 | exportOptions={
166 | name = L.SETTINGS_EXPORT_NAME,
167 | type = 'group',
168 | order = 4,
169 | args = {
170 | exportHander = {
171 | name = L.SETTINGS_EXPORT_HEADER,
172 | type = 'header',
173 | order = 1,
174 | },
175 | exportDesc = {
176 | name = L.SETTINGS_EXPORT_DESC,
177 | type = 'description',
178 | order = 2,
179 | },
180 | exportBtn1 = {
181 | name = L.SETTINGS_EXPORT_BTN1,
182 | type = 'execute',
183 | width = '0.5',
184 | order = 4,
185 | func = function(info)
186 | info.options.args.exportOptions.args.exportInput.get = function()
187 | return Actions:ExportSettings()
188 | end
189 | end,
190 | },
191 | exportInput = {
192 | name = ' ',
193 | desc = L.SETTINGS_EXPORT_INPUT,
194 | type = 'input',
195 | width = 'full',
196 | order = 5,
197 | multiline = true,
198 | set = function(info, val)
199 | Actions:importSettings(val)
200 | end,
201 | },
202 | }
203 | },
204 | ignoreClearOptions = {
205 | name = L.SETTINGS_CLEAR_NAME,
206 | type = 'group',
207 | order = 10,
208 | args = {
209 | ignoreClearHander = {
210 | name = L.SETTINGS_CLEAR_HEADER,
211 | type = 'header',
212 | order = 1,
213 | },
214 | ignoreClearDesc = {
215 | name = L.SETTINGS_CLEAR_DESC,
216 | type = 'description',
217 | order = 2,
218 | },
219 | ignoreClearBtn1 = {
220 | name = L.SETTINGS_CLEAR_BTN1,
221 | type = 'execute',
222 | width = '0.5',
223 | order = 3,
224 | func = function()
225 | PlaySound(SOUNDKIT.IG_MAINMENU_OPEN)
226 | StaticPopup_Show('WATCH_DOG_CANCEL_ALL_CONFIRM')
227 | end
228 | },
229 | ignoreClearWithTimeDesc = {
230 | name = L.SETTINGS_CLEAR_TIME_DESC,
231 | type = 'description',
232 | order = 4,
233 | },
234 | ignoreClearWithTimeBtn1 = {
235 | name = L.SETTINGS_CLEAR_TIME_BTN1,
236 | type = 'execute',
237 | width = '0.5',
238 | order = 5,
239 | func = function()
240 | PlaySound(SOUNDKIT.IG_MAINMENU_OPEN)
241 | Actions:unbanPlayerWithTime(WATCHDOG_DB.ignoreTimeLimit)
242 | end
243 | },
244 | },
245 | },
246 | }
247 |
248 | }
249 |
250 | function Settings:OnInitialize()
251 | StaticPopupDialogs['WATCH_DOG_CANCEL_ALL_CONFIRM'] = {
252 | text = L.SETTINGS_CLEAR_CONFIR,
253 | button1 = OKAY,
254 | button2 = NO,
255 | hideOnEscape = true,
256 | timeout = 0,
257 | exclusive = true,
258 | showAlert = true,
259 | OnAccept = function(self)
260 | PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE)
261 | Actions:unbanAllplayers()
262 | end,
263 | OnCancel = function(self)
264 | PlaySound(SOUNDKIT.IG_MAINMENU_CLOSE)
265 | StaticPopup_Hide('WATCH_DOG_CANCEL_ALL_CONFIRM')
266 | end,
267 | }
268 |
269 | local AceFrame = AceGUI:Create('Frame')
270 | AceFrame:Hide()
271 | AceFrame:SetCallback('OnClose', function (w)
272 | AceGUI:Release(w)
273 | end)
274 | AceConfig:RegisterOptionsTable(L.ADDON_SHOW_NAME, options)
275 | AceFrame:SetTitle(L.ADDON_SHOW_NAME)
276 | AceFrame:SetStatusText(' ')
277 | AceFrame:SetLayout('Flow')
278 | AceFrame:Hide()
279 | AceConfigDialog:AddToBlizOptions(L.ADDON_SHOW_NAME, L.ADDON_SHOW_NAME)
280 | AceConfigDialog:SetDefaultSize(L.ADDON_SHOW_NAME, 600, 500)
281 | end
282 |
283 | function Settings:Open()
284 | AceConfigDialog:Open(L.ADDON_SHOW_NAME, AceFrame)
285 | end
286 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua:
--------------------------------------------------------------------------------
1 | --[[-----------------------------------------------------------------------------
2 | TabGroup Container
3 | Container that uses tabs on top to switch between groups.
4 | -------------------------------------------------------------------------------]]
5 | local Type, Version = "TabGroup", 37
6 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
7 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
8 |
9 | -- Lua APIs
10 | local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, wipe
11 |
12 | -- WoW APIs
13 | local PlaySound = PlaySound
14 | local CreateFrame, UIParent = CreateFrame, UIParent
15 | local _G = _G
16 |
17 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
18 | -- List them here for Mikk's FindGlobals script
19 | -- GLOBALS: PanelTemplates_TabResize, PanelTemplates_SetDisabledTabState, PanelTemplates_SelectTab, PanelTemplates_DeselectTab
20 |
21 | -- local upvalue storage used by BuildTabs
22 | local widths = {}
23 | local rowwidths = {}
24 | local rowends = {}
25 |
26 | --[[-----------------------------------------------------------------------------
27 | Support functions
28 | -------------------------------------------------------------------------------]]
29 | local function UpdateTabLook(frame)
30 | if frame.disabled then
31 | PanelTemplates_SetDisabledTabState(frame)
32 | elseif frame.selected then
33 | PanelTemplates_SelectTab(frame)
34 | else
35 | PanelTemplates_DeselectTab(frame)
36 | end
37 | end
38 |
39 | local function Tab_SetText(frame, text)
40 | frame:_SetText(text)
41 | local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
42 | PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
43 | end
44 |
45 | local function Tab_SetSelected(frame, selected)
46 | frame.selected = selected
47 | UpdateTabLook(frame)
48 | end
49 |
50 | local function Tab_SetDisabled(frame, disabled)
51 | frame.disabled = disabled
52 | UpdateTabLook(frame)
53 | end
54 |
55 | local function BuildTabsOnUpdate(frame)
56 | local self = frame.obj
57 | self:BuildTabs()
58 | frame:SetScript("OnUpdate", nil)
59 | end
60 |
61 | --[[-----------------------------------------------------------------------------
62 | Scripts
63 | -------------------------------------------------------------------------------]]
64 | local function Tab_OnClick(frame)
65 | if not (frame.selected or frame.disabled) then
66 | PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
67 | frame.obj:SelectTab(frame.value)
68 | end
69 | end
70 |
71 | local function Tab_OnEnter(frame)
72 | local self = frame.obj
73 | self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
74 | end
75 |
76 | local function Tab_OnLeave(frame)
77 | local self = frame.obj
78 | self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
79 | end
80 |
81 | local function Tab_OnShow(frame)
82 | _G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
83 | end
84 |
85 | --[[-----------------------------------------------------------------------------
86 | Methods
87 | -------------------------------------------------------------------------------]]
88 | local methods = {
89 | ["OnAcquire"] = function(self)
90 | self:SetTitle()
91 | end,
92 |
93 | ["OnRelease"] = function(self)
94 | self.status = nil
95 | for k in pairs(self.localstatus) do
96 | self.localstatus[k] = nil
97 | end
98 | self.tablist = nil
99 | for _, tab in pairs(self.tabs) do
100 | tab:Hide()
101 | end
102 | end,
103 |
104 | ["CreateTab"] = function(self, id)
105 | local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
106 | local tab = CreateFrame("Button", tabname, self.border, "OptionsFrameTabButtonTemplate")
107 | tab.obj = self
108 | tab.id = id
109 |
110 | tab.text = _G[tabname .. "Text"]
111 | tab.text:ClearAllPoints()
112 | tab.text:SetPoint("LEFT", 14, -3)
113 | tab.text:SetPoint("RIGHT", -12, -3)
114 |
115 | tab:SetScript("OnClick", Tab_OnClick)
116 | tab:SetScript("OnEnter", Tab_OnEnter)
117 | tab:SetScript("OnLeave", Tab_OnLeave)
118 | tab:SetScript("OnShow", Tab_OnShow)
119 |
120 | tab._SetText = tab.SetText
121 | tab.SetText = Tab_SetText
122 | tab.SetSelected = Tab_SetSelected
123 | tab.SetDisabled = Tab_SetDisabled
124 |
125 | return tab
126 | end,
127 |
128 | ["SetTitle"] = function(self, text)
129 | self.titletext:SetText(text or "")
130 | if text and text ~= "" then
131 | self.alignoffset = 25
132 | else
133 | self.alignoffset = 18
134 | end
135 | self:BuildTabs()
136 | end,
137 |
138 | ["SetStatusTable"] = function(self, status)
139 | assert(type(status) == "table")
140 | self.status = status
141 | end,
142 |
143 | ["SelectTab"] = function(self, value)
144 | local status = self.status or self.localstatus
145 | local found
146 | for i, v in ipairs(self.tabs) do
147 | if v.value == value then
148 | v:SetSelected(true)
149 | found = true
150 | else
151 | v:SetSelected(false)
152 | end
153 | end
154 | status.selected = value
155 | if found then
156 | self:Fire("OnGroupSelected",value)
157 | end
158 | end,
159 |
160 | ["SetTabs"] = function(self, tabs)
161 | self.tablist = tabs
162 | self:BuildTabs()
163 | end,
164 |
165 |
166 | ["BuildTabs"] = function(self)
167 | local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
168 | local tablist = self.tablist
169 | local tabs = self.tabs
170 |
171 | if not tablist then return end
172 |
173 | local width = self.frame.width or self.frame:GetWidth() or 0
174 |
175 | wipe(widths)
176 | wipe(rowwidths)
177 | wipe(rowends)
178 |
179 | --Place Text into tabs and get thier initial width
180 | for i, v in ipairs(tablist) do
181 | local tab = tabs[i]
182 | if not tab then
183 | tab = self:CreateTab(i)
184 | tabs[i] = tab
185 | end
186 |
187 | tab:Show()
188 | tab:SetText(v.text)
189 | tab:SetDisabled(v.disabled)
190 | tab.value = v.value
191 |
192 | widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
193 | end
194 |
195 | for i = (#tablist)+1, #tabs, 1 do
196 | tabs[i]:Hide()
197 | end
198 |
199 | --First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
200 | local numtabs = #tablist
201 | local numrows = 1
202 | local usedwidth = 0
203 |
204 | for i = 1, #tablist do
205 | --If this is not the first tab of a row and there isn't room for it
206 | if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
207 | rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
208 | rowends[numrows] = i - 1
209 | numrows = numrows + 1
210 | usedwidth = 0
211 | end
212 | usedwidth = usedwidth + widths[i]
213 | end
214 | rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
215 | rowends[numrows] = #tablist
216 |
217 | --Fix for single tabs being left on the last row, move a tab from the row above if applicable
218 | if numrows > 1 then
219 | --if the last row has only one tab
220 | if rowends[numrows-1] == numtabs-1 then
221 | --if there are more than 2 tabs in the 2nd last row
222 | if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
223 | --move 1 tab from the second last row to the last, if there is enough space
224 | if (rowwidths[numrows] + widths[numtabs-1]) <= width then
225 | rowends[numrows-1] = rowends[numrows-1] - 1
226 | rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
227 | rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
228 | end
229 | end
230 | end
231 | end
232 |
233 | --anchor the rows as defined and resize tabs to fill thier row
234 | local starttab = 1
235 | for row, endtab in ipairs(rowends) do
236 | local first = true
237 | for tabno = starttab, endtab do
238 | local tab = tabs[tabno]
239 | tab:ClearAllPoints()
240 | if first then
241 | tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
242 | first = false
243 | else
244 | tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
245 | end
246 | end
247 |
248 | -- equal padding for each tab to fill the available width,
249 | -- if the used space is above 75% already
250 | -- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
251 | -- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
252 | local padding = 0
253 | if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
254 | padding = (width - rowwidths[row]) / (endtab - starttab+1)
255 | end
256 |
257 | for i = starttab, endtab do
258 | PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
259 | end
260 | starttab = endtab + 1
261 | end
262 |
263 | self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
264 | self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
265 | end,
266 |
267 | ["OnWidthSet"] = function(self, width)
268 | local content = self.content
269 | local contentwidth = width - 60
270 | if contentwidth < 0 then
271 | contentwidth = 0
272 | end
273 | content:SetWidth(contentwidth)
274 | content.width = contentwidth
275 | self:BuildTabs(self)
276 | self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
277 | end,
278 |
279 | ["OnHeightSet"] = function(self, height)
280 | local content = self.content
281 | local contentheight = height - (self.borderoffset + 23)
282 | if contentheight < 0 then
283 | contentheight = 0
284 | end
285 | content:SetHeight(contentheight)
286 | content.height = contentheight
287 | end,
288 |
289 | ["LayoutFinished"] = function(self, width, height)
290 | if self.noAutoHeight then return end
291 | self:SetHeight((height or 0) + (self.borderoffset + 23))
292 | end
293 | }
294 |
295 | --[[-----------------------------------------------------------------------------
296 | Constructor
297 | -------------------------------------------------------------------------------]]
298 | local PaneBackdrop = {
299 | bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
300 | edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
301 | tile = true, tileSize = 16, edgeSize = 16,
302 | insets = { left = 3, right = 3, top = 5, bottom = 3 }
303 | }
304 |
305 | local function Constructor()
306 | local num = AceGUI:GetNextWidgetNum(Type)
307 | local frame = CreateFrame("Frame",nil,UIParent)
308 | frame:SetHeight(100)
309 | frame:SetWidth(100)
310 | frame:SetFrameStrata("FULLSCREEN_DIALOG")
311 |
312 | local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
313 | titletext:SetPoint("TOPLEFT", 14, 0)
314 | titletext:SetPoint("TOPRIGHT", -14, 0)
315 | titletext:SetJustifyH("LEFT")
316 | titletext:SetHeight(18)
317 | titletext:SetText("")
318 |
319 | local border = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
320 | border:SetPoint("TOPLEFT", 1, -27)
321 | border:SetPoint("BOTTOMRIGHT", -1, 3)
322 | border:SetBackdrop(PaneBackdrop)
323 | border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
324 | border:SetBackdropBorderColor(0.4, 0.4, 0.4)
325 |
326 | local content = CreateFrame("Frame", nil, border)
327 | content:SetPoint("TOPLEFT", 10, -7)
328 | content:SetPoint("BOTTOMRIGHT", -10, 7)
329 |
330 | local widget = {
331 | num = num,
332 | frame = frame,
333 | localstatus = {},
334 | alignoffset = 18,
335 | titletext = titletext,
336 | border = border,
337 | borderoffset = 27,
338 | tabs = {},
339 | content = content,
340 | type = Type
341 | }
342 | for method, func in pairs(methods) do
343 | widget[method] = func
344 | end
345 |
346 | return AceGUI:RegisterAsContainer(widget)
347 | end
348 |
349 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
350 |
--------------------------------------------------------------------------------
/libs/AceComm-3.0/AceComm-3.0.lua:
--------------------------------------------------------------------------------
1 | --- **AceComm-3.0** allows you to send messages of unlimited length over the addon comm channels.
2 | -- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
3 | -- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
4 | --
5 | -- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
6 | -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
7 | -- and can be accessed directly, without having to explicitly call AceComm itself.\\
8 | -- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
9 | -- make into AceComm.
10 | -- @class file
11 | -- @name AceComm-3.0
12 | -- @release $Id: AceComm-3.0.lua 1174 2018-05-14 17:29:49Z h.leppkes@gmail.com $
13 |
14 | --[[ AceComm-3.0
15 |
16 | TODO: Time out old data rotting around from dead senders? Not a HUGE deal since the number of possible sender names is somewhat limited.
17 |
18 | ]]
19 |
20 | local CallbackHandler = LibStub("CallbackHandler-1.0")
21 | local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
22 |
23 | local MAJOR, MINOR = "AceComm-3.0", 12
24 | local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
25 |
26 | if not AceComm then return end
27 |
28 | -- Lua APIs
29 | local type, next, pairs, tostring = type, next, pairs, tostring
30 | local strsub, strfind = string.sub, string.find
31 | local match = string.match
32 | local tinsert, tconcat = table.insert, table.concat
33 | local error, assert = error, assert
34 |
35 | -- WoW APIs
36 | local Ambiguate = Ambiguate
37 |
38 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
39 | -- List them here for Mikk's FindGlobals script
40 | -- GLOBALS: LibStub, DEFAULT_CHAT_FRAME, geterrorhandler, RegisterAddonMessagePrefix
41 |
42 | AceComm.embeds = AceComm.embeds or {}
43 |
44 | -- for my sanity and yours, let's give the message type bytes some names
45 | local MSG_MULTI_FIRST = "\001"
46 | local MSG_MULTI_NEXT = "\002"
47 | local MSG_MULTI_LAST = "\003"
48 | local MSG_ESCAPE = "\004"
49 |
50 | -- remove old structures (pre WoW 4.0)
51 | AceComm.multipart_origprefixes = nil
52 | AceComm.multipart_reassemblers = nil
53 |
54 | -- the multipart message spool: indexed by a combination of sender+distribution+
55 | AceComm.multipart_spool = AceComm.multipart_spool or {}
56 |
57 | --- Register for Addon Traffic on a specified prefix
58 | -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
59 | -- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
60 | function AceComm:RegisterComm(prefix, method)
61 | if method == nil then
62 | method = "OnCommReceived"
63 | end
64 |
65 | if #prefix > 16 then -- TODO: 15?
66 | error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
67 | end
68 | if C_ChatInfo then
69 | C_ChatInfo.RegisterAddonMessagePrefix(prefix)
70 | else
71 | RegisterAddonMessagePrefix(prefix)
72 | end
73 |
74 | return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
75 | end
76 |
77 | local warnedPrefix=false
78 |
79 | --- Send a message over the Addon Channel
80 | -- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
81 | -- @param text Data to send, nils (\000) not allowed. Any length.
82 | -- @param distribution Addon channel, e.g. "RAID", "GUILD", etc; see SendAddonMessage API
83 | -- @param target Destination for some distributions; see SendAddonMessage API
84 | -- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL".
85 | -- @param callbackFn OPTIONAL: callback function to be called as each chunk is sent. receives 3 args: the user supplied arg (see next), the number of bytes sent so far, and the number of bytes total to send.
86 | -- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified.
87 | function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callbackFn, callbackArg)
88 | prio = prio or "NORMAL" -- pasta's reference implementation had different prio for singlepart and multipart, but that's a very bad idea since that can easily lead to out-of-sequence delivery!
89 | if not( type(prefix)=="string" and
90 | type(text)=="string" and
91 | type(distribution)=="string" and
92 | (target==nil or type(target)=="string" or type(target)=="number") and
93 | (prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
94 | ) then
95 | error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
96 | end
97 |
98 | local textlen = #text
99 | local maxtextlen = 255 -- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
100 | local queueName = prefix..distribution..(target or "")
101 |
102 | local ctlCallback = nil
103 | if callbackFn then
104 | ctlCallback = function(sent)
105 | return callbackFn(callbackArg, sent, textlen)
106 | end
107 | end
108 |
109 | local forceMultipart
110 | if match(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
111 | -- we need to escape the first character with a \004
112 | if textlen+1 > maxtextlen then -- would we go over the size limit?
113 | forceMultipart = true -- just make it multipart, no escape problems then
114 | else
115 | text = "\004" .. text
116 | end
117 | end
118 |
119 | if not forceMultipart and textlen <= maxtextlen then
120 | -- fits all in one message
121 | CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
122 | else
123 | maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
124 |
125 | -- first part
126 | local chunk = strsub(text, 1, maxtextlen)
127 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
128 |
129 | -- continuation
130 | local pos = 1+maxtextlen
131 |
132 | while pos+maxtextlen <= textlen do
133 | chunk = strsub(text, pos, pos+maxtextlen-1)
134 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
135 | pos = pos + maxtextlen
136 | end
137 |
138 | -- final part
139 | chunk = strsub(text, pos)
140 | CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
141 | end
142 | end
143 |
144 |
145 | ----------------------------------------
146 | -- Message receiving
147 | ----------------------------------------
148 |
149 | do
150 | local compost = setmetatable({}, {__mode = "k"})
151 | local function new()
152 | local t = next(compost)
153 | if t then
154 | compost[t]=nil
155 | for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
156 | t[i]=nil
157 | end
158 | return t
159 | end
160 |
161 | return {}
162 | end
163 |
164 | local function lostdatawarning(prefix,sender,where)
165 | DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
166 | end
167 |
168 | function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
169 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
170 | local spool = AceComm.multipart_spool
171 |
172 | --[[
173 | if spool[key] then
174 | lostdatawarning(prefix,sender,"First")
175 | -- continue and overwrite
176 | end
177 | --]]
178 |
179 | spool[key] = message -- plain string for now
180 | end
181 |
182 | function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender)
183 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
184 | local spool = AceComm.multipart_spool
185 | local olddata = spool[key]
186 |
187 | if not olddata then
188 | --lostdatawarning(prefix,sender,"Next")
189 | return
190 | end
191 |
192 | if type(olddata)~="table" then
193 | -- ... but what we have is not a table. So make it one. (Pull a composted one if available)
194 | local t = new()
195 | t[1] = olddata -- add old data as first string
196 | t[2] = message -- and new message as second string
197 | spool[key] = t -- and put the table in the spool instead of the old string
198 | else
199 | tinsert(olddata, message)
200 | end
201 | end
202 |
203 | function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender)
204 | local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
205 | local spool = AceComm.multipart_spool
206 | local olddata = spool[key]
207 |
208 | if not olddata then
209 | --lostdatawarning(prefix,sender,"End")
210 | return
211 | end
212 |
213 | spool[key] = nil
214 |
215 | if type(olddata) == "table" then
216 | -- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
217 | tinsert(olddata, message)
218 | AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender)
219 | compost[olddata] = true
220 | else
221 | -- if we've only received a "first", the spooled data will still only be a string
222 | AceComm.callbacks:Fire(prefix, olddata..message, distribution, sender)
223 | end
224 | end
225 | end
226 |
227 |
228 |
229 |
230 |
231 |
232 | ----------------------------------------
233 | -- Embed CallbackHandler
234 | ----------------------------------------
235 |
236 | if not AceComm.callbacks then
237 | AceComm.callbacks = CallbackHandler:New(AceComm,
238 | "_RegisterComm",
239 | "UnregisterComm",
240 | "UnregisterAllComm")
241 | end
242 |
243 | AceComm.callbacks.OnUsed = nil
244 | AceComm.callbacks.OnUnused = nil
245 |
246 | local function OnEvent(self, event, prefix, message, distribution, sender)
247 | if event == "CHAT_MSG_ADDON" then
248 | sender = Ambiguate(sender, "none")
249 | local control, rest = match(message, "^([\001-\009])(.*)")
250 | if control then
251 | if control==MSG_MULTI_FIRST then
252 | AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
253 | elseif control==MSG_MULTI_NEXT then
254 | AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
255 | elseif control==MSG_MULTI_LAST then
256 | AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
257 | elseif control==MSG_ESCAPE then
258 | AceComm.callbacks:Fire(prefix, rest, distribution, sender)
259 | else
260 | -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
261 | end
262 | else
263 | -- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
264 | AceComm.callbacks:Fire(prefix, message, distribution, sender)
265 | end
266 | else
267 | assert(false, "Received "..tostring(event).." event?!")
268 | end
269 | end
270 |
271 | AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame")
272 | AceComm.frame:SetScript("OnEvent", OnEvent)
273 | AceComm.frame:UnregisterAllEvents()
274 | AceComm.frame:RegisterEvent("CHAT_MSG_ADDON")
275 |
276 |
277 | ----------------------------------------
278 | -- Base library stuff
279 | ----------------------------------------
280 |
281 | local mixins = {
282 | "RegisterComm",
283 | "UnregisterComm",
284 | "UnregisterAllComm",
285 | "SendCommMessage",
286 | }
287 |
288 | -- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:..
289 | -- @param target target object to embed AceComm-3.0 in
290 | function AceComm:Embed(target)
291 | for k, v in pairs(mixins) do
292 | target[v] = self[v]
293 | end
294 | self.embeds[target] = true
295 | return target
296 | end
297 |
298 | function AceComm:OnEmbedDisable(target)
299 | target:UnregisterAllComm()
300 | end
301 |
302 | -- Update embeds
303 | for target, v in pairs(AceComm.embeds) do
304 | AceComm:Embed(target)
305 | end
306 |
--------------------------------------------------------------------------------
/libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua:
--------------------------------------------------------------------------------
1 | local Type, Version = "MultiLineEditBox", 29
2 | local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
3 | if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
4 |
5 | -- Lua APIs
6 | local pairs = pairs
7 |
8 | -- WoW APIs
9 | local GetCursorInfo, GetSpellInfo, ClearCursor = GetCursorInfo, GetSpellInfo, ClearCursor
10 | local CreateFrame, UIParent = CreateFrame, UIParent
11 | local _G = _G
12 |
13 | -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
14 | -- List them here for Mikk's FindGlobals script
15 | -- GLOBALS: ACCEPT, ChatFontNormal
16 |
17 | --[[-----------------------------------------------------------------------------
18 | Support functions
19 | -------------------------------------------------------------------------------]]
20 |
21 | if not AceGUIMultiLineEditBoxInsertLink then
22 | -- upgradeable hook
23 | hooksecurefunc("ChatEdit_InsertLink", function(...) return _G.AceGUIMultiLineEditBoxInsertLink(...) end)
24 | end
25 |
26 | function _G.AceGUIMultiLineEditBoxInsertLink(text)
27 | for i = 1, AceGUI:GetWidgetCount(Type) do
28 | local editbox = _G[("MultiLineEditBox%uEdit"):format(i)]
29 | if editbox and editbox:IsVisible() and editbox:HasFocus() then
30 | editbox:Insert(text)
31 | return true
32 | end
33 | end
34 | end
35 |
36 |
37 | local function Layout(self)
38 | self:SetHeight(self.numlines * 14 + (self.disablebutton and 19 or 41) + self.labelHeight)
39 |
40 | if self.labelHeight == 0 then
41 | self.scrollBar:SetPoint("TOP", self.frame, "TOP", 0, -23)
42 | else
43 | self.scrollBar:SetPoint("TOP", self.label, "BOTTOM", 0, -19)
44 | end
45 |
46 | if self.disablebutton then
47 | self.scrollBar:SetPoint("BOTTOM", self.frame, "BOTTOM", 0, 21)
48 | self.scrollBG:SetPoint("BOTTOMLEFT", 0, 4)
49 | else
50 | self.scrollBar:SetPoint("BOTTOM", self.button, "TOP", 0, 18)
51 | self.scrollBG:SetPoint("BOTTOMLEFT", self.button, "TOPLEFT")
52 | end
53 | end
54 |
55 | --[[-----------------------------------------------------------------------------
56 | Scripts
57 | -------------------------------------------------------------------------------]]
58 | local function OnClick(self) -- Button
59 | self = self.obj
60 | self.editBox:ClearFocus()
61 | if not self:Fire("OnEnterPressed", self.editBox:GetText()) then
62 | self.button:Disable()
63 | end
64 | end
65 |
66 | local function OnCursorChanged(self, _, y, _, cursorHeight) -- EditBox
67 | self, y = self.obj.scrollFrame, -y
68 | local offset = self:GetVerticalScroll()
69 | if y < offset then
70 | self:SetVerticalScroll(y)
71 | else
72 | y = y + cursorHeight - self:GetHeight()
73 | if y > offset then
74 | self:SetVerticalScroll(y)
75 | end
76 | end
77 | end
78 |
79 | local function OnEditFocusLost(self) -- EditBox
80 | self:HighlightText(0, 0)
81 | self.obj:Fire("OnEditFocusLost")
82 | end
83 |
84 | local function OnEnter(self) -- EditBox / ScrollFrame
85 | self = self.obj
86 | if not self.entered then
87 | self.entered = true
88 | self:Fire("OnEnter")
89 | end
90 | end
91 |
92 | local function OnLeave(self) -- EditBox / ScrollFrame
93 | self = self.obj
94 | if self.entered then
95 | self.entered = nil
96 | self:Fire("OnLeave")
97 | end
98 | end
99 |
100 | local function OnMouseUp(self) -- ScrollFrame
101 | self = self.obj.editBox
102 | self:SetFocus()
103 | self:SetCursorPosition(self:GetNumLetters())
104 | end
105 |
106 | local function OnReceiveDrag(self) -- EditBox / ScrollFrame
107 | local type, id, info = GetCursorInfo()
108 | if type == "spell" then
109 | info = GetSpellInfo(id, info)
110 | elseif type ~= "item" then
111 | return
112 | end
113 | ClearCursor()
114 | self = self.obj
115 | local editBox = self.editBox
116 | if not editBox:HasFocus() then
117 | editBox:SetFocus()
118 | editBox:SetCursorPosition(editBox:GetNumLetters())
119 | end
120 | editBox:Insert(info)
121 | self.button:Enable()
122 | end
123 |
124 | local function OnSizeChanged(self, width, height) -- ScrollFrame
125 | self.obj.editBox:SetWidth(width)
126 | end
127 |
128 | local function OnTextChanged(self, userInput) -- EditBox
129 | if userInput then
130 | self = self.obj
131 | self:Fire("OnTextChanged", self.editBox:GetText())
132 | self.button:Enable()
133 | end
134 | end
135 |
136 | local function OnTextSet(self) -- EditBox
137 | self:HighlightText(0, 0)
138 | self:SetCursorPosition(self:GetNumLetters())
139 | self:SetCursorPosition(0)
140 | self.obj.button:Disable()
141 | end
142 |
143 | local function OnVerticalScroll(self, offset) -- ScrollFrame
144 | local editBox = self.obj.editBox
145 | editBox:SetHitRectInsets(0, 0, offset, editBox:GetHeight() - offset - self:GetHeight())
146 | end
147 |
148 | local function OnShowFocus(frame)
149 | frame.obj.editBox:SetFocus()
150 | frame:SetScript("OnShow", nil)
151 | end
152 |
153 | local function OnEditFocusGained(frame)
154 | AceGUI:SetFocus(frame.obj)
155 | frame.obj:Fire("OnEditFocusGained")
156 | end
157 |
158 | --[[-----------------------------------------------------------------------------
159 | Methods
160 | -------------------------------------------------------------------------------]]
161 | local methods = {
162 | ["OnAcquire"] = function(self)
163 | self.editBox:SetText("")
164 | self:SetDisabled(false)
165 | self:SetWidth(200)
166 | self:DisableButton(false)
167 | self:SetNumLines()
168 | self.entered = nil
169 | self:SetMaxLetters(0)
170 | end,
171 |
172 | ["OnRelease"] = function(self)
173 | self:ClearFocus()
174 | end,
175 |
176 | ["SetDisabled"] = function(self, disabled)
177 | local editBox = self.editBox
178 | if disabled then
179 | editBox:ClearFocus()
180 | editBox:EnableMouse(false)
181 | editBox:SetTextColor(0.5, 0.5, 0.5)
182 | self.label:SetTextColor(0.5, 0.5, 0.5)
183 | self.scrollFrame:EnableMouse(false)
184 | self.button:Disable()
185 | else
186 | editBox:EnableMouse(true)
187 | editBox:SetTextColor(1, 1, 1)
188 | self.label:SetTextColor(1, 0.82, 0)
189 | self.scrollFrame:EnableMouse(true)
190 | end
191 | end,
192 |
193 | ["SetLabel"] = function(self, text)
194 | if text and text ~= "" then
195 | self.label:SetText(text)
196 | if self.labelHeight ~= 10 then
197 | self.labelHeight = 10
198 | self.label:Show()
199 | end
200 | elseif self.labelHeight ~= 0 then
201 | self.labelHeight = 0
202 | self.label:Hide()
203 | end
204 | Layout(self)
205 | end,
206 |
207 | ["SetNumLines"] = function(self, value)
208 | if not value or value < 4 then
209 | value = 4
210 | end
211 | self.numlines = value
212 | Layout(self)
213 | end,
214 |
215 | ["SetText"] = function(self, text)
216 | self.editBox:SetText(text)
217 | end,
218 |
219 | ["GetText"] = function(self)
220 | return self.editBox:GetText()
221 | end,
222 |
223 | ["SetMaxLetters"] = function (self, num)
224 | self.editBox:SetMaxLetters(num or 0)
225 | end,
226 |
227 | ["DisableButton"] = function(self, disabled)
228 | self.disablebutton = disabled
229 | if disabled then
230 | self.button:Hide()
231 | else
232 | self.button:Show()
233 | end
234 | Layout(self)
235 | end,
236 |
237 | ["ClearFocus"] = function(self)
238 | self.editBox:ClearFocus()
239 | self.frame:SetScript("OnShow", nil)
240 | end,
241 |
242 | ["SetFocus"] = function(self)
243 | self.editBox:SetFocus()
244 | if not self.frame:IsShown() then
245 | self.frame:SetScript("OnShow", OnShowFocus)
246 | end
247 | end,
248 |
249 | ["HighlightText"] = function(self, from, to)
250 | self.editBox:HighlightText(from, to)
251 | end,
252 |
253 | ["GetCursorPosition"] = function(self)
254 | return self.editBox:GetCursorPosition()
255 | end,
256 |
257 | ["SetCursorPosition"] = function(self, ...)
258 | return self.editBox:SetCursorPosition(...)
259 | end,
260 |
261 |
262 | }
263 |
264 | --[[-----------------------------------------------------------------------------
265 | Constructor
266 | -------------------------------------------------------------------------------]]
267 | local backdrop = {
268 | bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
269 | edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
270 | insets = { left = 4, right = 3, top = 4, bottom = 3 }
271 | }
272 |
273 | local function Constructor()
274 | local frame = CreateFrame("Frame", nil, UIParent)
275 | frame:Hide()
276 |
277 | local widgetNum = AceGUI:GetNextWidgetNum(Type)
278 |
279 | local label = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
280 | label:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
281 | label:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
282 | label:SetJustifyH("LEFT")
283 | label:SetText(ACCEPT)
284 | label:SetHeight(10)
285 |
286 | local button = CreateFrame("Button", ("%s%dButton"):format(Type, widgetNum), frame, "UIPanelButtonTemplate")
287 | button:SetPoint("BOTTOMLEFT", 0, 4)
288 | button:SetHeight(22)
289 | button:SetWidth(label:GetStringWidth() + 24)
290 | button:SetText(ACCEPT)
291 | button:SetScript("OnClick", OnClick)
292 | button:Disable()
293 |
294 | local text = button:GetFontString()
295 | text:ClearAllPoints()
296 | text:SetPoint("TOPLEFT", button, "TOPLEFT", 5, -5)
297 | text:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -5, 1)
298 | text:SetJustifyV("MIDDLE")
299 |
300 | local scrollBG = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
301 | scrollBG:SetBackdrop(backdrop)
302 | scrollBG:SetBackdropColor(0, 0, 0)
303 | scrollBG:SetBackdropBorderColor(0.4, 0.4, 0.4)
304 |
305 | local scrollFrame = CreateFrame("ScrollFrame", ("%s%dScrollFrame"):format(Type, widgetNum), frame, "UIPanelScrollFrameTemplate")
306 |
307 | local scrollBar = _G[scrollFrame:GetName() .. "ScrollBar"]
308 | scrollBar:ClearAllPoints()
309 | scrollBar:SetPoint("TOP", label, "BOTTOM", 0, -19)
310 | scrollBar:SetPoint("BOTTOM", button, "TOP", 0, 18)
311 | scrollBar:SetPoint("RIGHT", frame, "RIGHT")
312 |
313 | scrollBG:SetPoint("TOPRIGHT", scrollBar, "TOPLEFT", 0, 19)
314 | scrollBG:SetPoint("BOTTOMLEFT", button, "TOPLEFT")
315 |
316 | scrollFrame:SetPoint("TOPLEFT", scrollBG, "TOPLEFT", 5, -6)
317 | scrollFrame:SetPoint("BOTTOMRIGHT", scrollBG, "BOTTOMRIGHT", -4, 4)
318 | scrollFrame:SetScript("OnEnter", OnEnter)
319 | scrollFrame:SetScript("OnLeave", OnLeave)
320 | scrollFrame:SetScript("OnMouseUp", OnMouseUp)
321 | scrollFrame:SetScript("OnReceiveDrag", OnReceiveDrag)
322 | scrollFrame:SetScript("OnSizeChanged", OnSizeChanged)
323 | scrollFrame:HookScript("OnVerticalScroll", OnVerticalScroll)
324 |
325 | local editBox = CreateFrame("EditBox", ("%s%dEdit"):format(Type, widgetNum), scrollFrame)
326 | editBox:SetAllPoints()
327 | editBox:SetFontObject(ChatFontNormal)
328 | editBox:SetMultiLine(true)
329 | editBox:EnableMouse(true)
330 | editBox:SetAutoFocus(false)
331 | editBox:SetCountInvisibleLetters(false)
332 | editBox:SetScript("OnCursorChanged", OnCursorChanged)
333 | editBox:SetScript("OnEditFocusLost", OnEditFocusLost)
334 | editBox:SetScript("OnEnter", OnEnter)
335 | editBox:SetScript("OnEscapePressed", editBox.ClearFocus)
336 | editBox:SetScript("OnLeave", OnLeave)
337 | editBox:SetScript("OnMouseDown", OnReceiveDrag)
338 | editBox:SetScript("OnReceiveDrag", OnReceiveDrag)
339 | editBox:SetScript("OnTextChanged", OnTextChanged)
340 | editBox:SetScript("OnTextSet", OnTextSet)
341 | editBox:SetScript("OnEditFocusGained", OnEditFocusGained)
342 |
343 |
344 | scrollFrame:SetScrollChild(editBox)
345 |
346 | local widget = {
347 | button = button,
348 | editBox = editBox,
349 | frame = frame,
350 | label = label,
351 | labelHeight = 10,
352 | numlines = 4,
353 | scrollBar = scrollBar,
354 | scrollBG = scrollBG,
355 | scrollFrame = scrollFrame,
356 | type = Type
357 | }
358 | for method, func in pairs(methods) do
359 | widget[method] = func
360 | end
361 | button.obj, editBox.obj, scrollFrame.obj = widget, widget, widget
362 |
363 | return AceGUI:RegisterAsWidget(widget)
364 | end
365 |
366 | AceGUI:RegisterWidgetType(Type, Constructor, Version)
367 |
--------------------------------------------------------------------------------