├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── release.yml ├── .gitignore ├── GUI ├── BarEditTab.lua ├── BarEditTab_BarStatesPanel.lua ├── BarEditTab_BarVisibilityPanel.lua ├── BarEditTab_GeneralConfigPanel.lua ├── ButtonEditTab.lua ├── ButtonStatusEditTab.lua ├── IconSelectorPanel.lua ├── InterfacePanel.lua ├── MainWindow.lua ├── Neuron-GUI.xml └── RegisteredGUIData.lua ├── Images ├── AdjustOptionLeft-Down.tga ├── AdjustOptionLeft-Highlight.tga ├── AdjustOptionLeft-Up.tga ├── AdjustOptionRight-Down.tga ├── AdjustOptionRight-Highlight.tga ├── AdjustOptionRight-Up.tga ├── BarFill_Carpaint_1.tga ├── BarFill_Carpaint_2.tga ├── BarFill_Contrast_1.tga ├── BarFill_Contrast_2.tga ├── BarFill_Default_1.tga ├── BarFill_Default_2.tga ├── BarFill_Gel_1.tga ├── BarFill_Gel_2.tga ├── BarFill_Glassed_1.tga ├── BarFill_Glassed_2.tga ├── BarFill_Soft_1.tga ├── BarFill_Soft_2.tga ├── BarFill_Velvet_1.tga ├── BarFill_Velvet_2.tga ├── Border_Dialog.tga ├── CastingBar_Spark_1.tga ├── CastingBar_Spark_2.tga ├── CheckButtonHilight.tga ├── MirageUI_LatencyMicroButton_Frame.tga ├── MirageUI_LatencyMicroButton_FramePushed.tga ├── MirageUI_LatencyMicroButton_Overlay.tga ├── RoundCheck.tga ├── RoundCheckBox.tga ├── RoundCheckGreen.tga ├── UI-CHARACTER-ACTIVETAB.tga ├── UI-CHARACTER-INACTIVETAB.tga ├── UI-Character-Tab-RealHighlight.tga ├── UI-Common-MouseHilight.tga ├── UI-Panel-Button-Disabled-Down.tga ├── UI-Panel-Button-Disabled.tga ├── UI-Panel-Button-Down.tga ├── UI-Panel-Button-Highlight.tga ├── UI-Panel-Button-Up.tga ├── UI-Panel-ExpandButton-Disabled.tga ├── UI-Panel-ExpandButton-Down.tga ├── UI-Panel-ExpandButton-Up.tga ├── UI-Panel-MinimizeButton-Down.tga ├── UI-Panel-MinimizeButton-Highlight.tga ├── UI-Panel-MinimizeButton-Up.tga ├── UI-Panel-Tab-Background.tga ├── UI-Quickslot2.tga ├── UI-QuickslotGray.tga ├── UI-RotationRight-Button-Down.tga ├── UI-RotationRight-Button-Up.tga ├── UI-Tooltip-Border-Tab.tga ├── UI-Tooltip-Border.tga ├── UpIndicator.tga ├── cast_glow.tga ├── flyout.tga ├── globe_black.tga ├── honeycomb_small.tga ├── new_vehicle_exit.tga └── static_icon.tga ├── LICENSE ├── Libs ├── AceAddon-3.0 │ ├── AceAddon-3.0.lua │ └── AceAddon-3.0.xml ├── AceBucket-3.0 │ ├── AceBucket-3.0.lua │ └── AceBucket-3.0.xml ├── AceComm-3.0 │ ├── AceComm-3.0.lua │ ├── AceComm-3.0.xml │ └── ChatThrottleLib.lua ├── AceConfig-3.0 │ ├── AceConfig-3.0.lua │ ├── AceConfig-3.0.xml │ ├── AceConfigCmd-3.0 │ │ ├── AceConfigCmd-3.0.lua │ │ └── AceConfigCmd-3.0.xml │ ├── AceConfigDialog-3.0 │ │ ├── AceConfigDialog-3.0.lua │ │ └── AceConfigDialog-3.0.xml │ └── AceConfigRegistry-3.0 │ │ ├── AceConfigRegistry-3.0.lua │ │ └── AceConfigRegistry-3.0.xml ├── AceConsole-3.0 │ ├── AceConsole-3.0.lua │ └── AceConsole-3.0.xml ├── AceDB-3.0 │ ├── AceDB-3.0.lua │ └── AceDB-3.0.xml ├── AceDBOptions-3.0 │ ├── AceDBOptions-3.0.lua │ └── AceDBOptions-3.0.xml ├── AceEvent-3.0 │ ├── AceEvent-3.0.lua │ └── AceEvent-3.0.xml ├── AceGUI-3.0 │ ├── AceGUI-3.0.lua │ ├── AceGUI-3.0.xml │ └── widgets │ │ ├── AceGUIContainer-BlizOptionsGroup.lua │ │ ├── AceGUIContainer-DropDownGroup.lua │ │ ├── AceGUIContainer-Frame.lua │ │ ├── AceGUIContainer-InlineGroup.lua │ │ ├── AceGUIContainer-ScrollFrame.lua │ │ ├── AceGUIContainer-SimpleGroup.lua │ │ ├── AceGUIContainer-TabGroup.lua │ │ ├── AceGUIContainer-TreeGroup.lua │ │ ├── AceGUIContainer-Window.lua │ │ ├── AceGUIWidget-Button.lua │ │ ├── AceGUIWidget-CheckBox.lua │ │ ├── AceGUIWidget-ColorPicker.lua │ │ ├── AceGUIWidget-DropDown-Items.lua │ │ ├── AceGUIWidget-DropDown.lua │ │ ├── AceGUIWidget-EditBox.lua │ │ ├── AceGUIWidget-Heading.lua │ │ ├── AceGUIWidget-Icon.lua │ │ ├── AceGUIWidget-InteractiveLabel.lua │ │ ├── AceGUIWidget-Keybinding.lua │ │ ├── AceGUIWidget-Label.lua │ │ ├── AceGUIWidget-MultiLineEditBox.lua │ │ └── AceGUIWidget-Slider.lua ├── AceHook-3.0 │ ├── AceHook-3.0.lua │ └── AceHook-3.0.xml ├── AceLocale-3.0 │ ├── AceLocale-3.0.lua │ └── AceLocale-3.0.xml ├── AceSerializer-3.0 │ ├── AceSerializer-3.0.lua │ └── AceSerializer-3.0.xml ├── AceTab-3.0 │ ├── AceTab-3.0.lua │ └── AceTab-3.0.xml ├── AceTimer-3.0 │ ├── AceTimer-3.0.lua │ └── AceTimer-3.0.xml ├── CallbackHandler-1.0 │ ├── CallbackHandler-1.0.lua │ └── CallbackHandler-1.0.xml ├── LibDBIcon-1.0 │ ├── LibDBIcon-1.0.lua │ └── lib.xml ├── LibDeflate │ ├── LICENSE.txt │ ├── LibDeflate.lua │ ├── LibDeflate.toc │ ├── LibStub │ │ ├── LibStub.lua │ │ ├── LibStub.toc │ │ └── tests │ │ │ ├── test.lua │ │ │ ├── test2.lua │ │ │ ├── test3.lua │ │ │ └── test4.lua │ ├── README.md │ ├── changelog.md │ ├── docs │ │ ├── README.md │ │ ├── benchmark.md │ │ ├── config.ld │ │ ├── examples │ │ │ └── example.lua.html │ │ ├── index.html │ │ ├── ldoc.css │ │ ├── source │ │ │ └── LibDeflate.lua.html │ │ └── topics │ │ │ ├── benchmark.md.html │ │ │ ├── changelog.md.html │ │ │ └── readme.md.html │ ├── examples │ │ └── example.lua │ ├── lib.xml │ └── libdeflate-1.0.2-1.rockspec ├── LibDualSpec-1.0 │ ├── CHANGES.txt │ ├── LibDualSpec-1.0.lua │ ├── LibDualSpec-1.0.toc │ ├── LibDualSpec-1.0_Wrath.toc │ └── LibStub.lua ├── LibStub │ └── LibStub.lua ├── embeds.xml └── libdatabroker-1.1 │ ├── Changelog-libdatabroker-1-1-v1.1.4.txt │ ├── LibDataBroker-1.1.lua │ └── README.textile ├── Localizations ├── Neuron_Localizations.xml ├── Neuron_X-deDE.lua ├── Neuron_X-enUS.lua ├── Neuron_X-esES.lua ├── Neuron_X-esMX.lua ├── Neuron_X-frFR.lua ├── Neuron_X-itIT.lua ├── Neuron_X-koKR.lua ├── Neuron_X-ptBR.lua ├── Neuron_X-ruRU.lua ├── Neuron_X-zhCN.lua └── Neuron_X-zhTW.lua ├── Neuron-Console.lua ├── Neuron-DB-Defaults.lua ├── Neuron-Default-Profile.lua ├── Neuron-DisableBlizzardUI.lua ├── Neuron-MinimapIcon.lua ├── Neuron-RegisteredBarData.lua ├── Neuron-Startup.lua ├── Neuron-States.lua ├── Neuron.lua ├── Neuron.toc ├── Objects ├── ActionButton.lua ├── ActionButton_DragAndDrop.lua ├── ActionButton_Flyout.lua ├── BagButton.lua ├── Bar.lua ├── Bar_SnapTo.lua ├── Button.lua ├── CastButton.lua ├── ExitButton.lua ├── ExpButton.lua ├── ExtraButton.lua ├── MenuButton.lua ├── MirrorButton.lua ├── PetButton.lua ├── RepButton.lua ├── StatusButton.lua └── ZoneAbilityButton.lua ├── Overlay ├── BarEditor.lua ├── ButtonBinder.lua └── ButtonEditor.lua ├── README.md ├── Utilities ├── Array.lua ├── DB-Fixer.lua └── Spec.lua ├── XML ├── NeuronActionButtonTemplate.xml ├── NeuronAnchorButtonTemplate.xml ├── NeuronBarTemplate.xml ├── NeuronOverlayFrameTemplate.xml ├── NeuronStatusBarTemplate.xml └── NeuronZoneAbilityButtonTemplate.xml └── pkgmeta.yaml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [brittyazel] 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: brittyazel 7 | 8 | --- 9 | *When reporting, please verify the issue with only **this** addon enabled and no others unless explicitly reporting an incompatibility between this addon an another. Likewise, please fill in the below information to the best of your ability — this information helps us a great deal.* 10 | 11 | ## Issue description: 12 | *A clear and concise description of what the issue is (i.e. what went wrong and what should have happened).* 13 | 14 | ## How to reproduce: 15 | *E.g., Steps to reproduce the behavior...* 16 | 1. *Go to '....'* 17 | 2. *Click on '....'* 18 | 3. *Scroll down to '....'* 19 | 4. *See error* 20 | 21 | ## Technical info: 22 | - **Addon Version:** *[e.g., 1.2.1]* 23 | - **Client:** *[e.g., Retail, Classic, PTR, or Beta]* 24 | - **Client Patch Version:** *[e.g., 9.0.1]* 25 | 26 | ## Additional context: 27 | *Add any other context about the problem here.* 28 | 29 | ## Screenshots: 30 | *If applicable, add screenshots to help explain your problem.* 31 | 32 | ## Lua error log: 33 | *Attach the Lua error log here (please use code tags)* 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: brittyazel 7 | 8 | --- 9 | 10 | ## Is your feature request related to a problem? Please describe: 11 | *A clear and concise description detailing the problem. E.g., "I'm always frustrated when [...]"* 12 | 13 | ## Describe the solution you'd like to see implemented: 14 | *A clear and concise description of what solution or behavior you would like to see implemented.* 15 | 16 | ## Describe alternatives you've considered: 17 | *A clear and concise description of any alternative solutions or features you've considered, such as supplementing a different mod that contains the feature in question.* 18 | 19 | ## Additional context: 20 | *Add any other context, screenshots, sketches, etc about the feature request here. A picture is worth 1000 words.* 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # description of this workflow, can be anything you want 2 | name: Package and release 3 | 4 | # we need to let GitHub know _when_ we want to release, typically only when we create a new tag. 5 | # this will target only tags, and not all pushes to the master branch. 6 | # this part can be heavily customized to your liking, like targeting only tags that match a certain word, 7 | # other branches or even pullrequests. 8 | on: 9 | push: 10 | tags: 11 | - '**' 12 | 13 | # a workflow is built up as jobs, and within these jobs are steps 14 | jobs: 15 | 16 | # "release" is a job, you can name it anything you want 17 | release: 18 | 19 | # we can run our steps on pretty much anything, but the "ubuntu-latest" image is a safe bet 20 | runs-on: ubuntu-latest 21 | 22 | # specify the environment variables used by the packager, matching the secrets from the project on GitHub 23 | env: 24 | CF_API_KEY: ${{ secrets.CF_API_KEY }} 25 | WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }} 26 | WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }} 27 | GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }} # "GITHUB_TOKEN" is a secret always provided to the workflow 28 | # for your own token, the name cannot start with "GITHUB_" 29 | 30 | # "steps" holds a list of all the steps needed to package and release our AddOn 31 | steps: 32 | 33 | # we first have to clone the AddOn project, this is a required step 34 | - name: Clone project 35 | uses: actions/checkout@v3 36 | with: 37 | fetch-depth: 0 # gets git history for changelogs 38 | 39 | # once cloned, we just run the GitHub Action for the packager project 40 | - name: Package and release 41 | uses: BigWigsMods/packager@v2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .idea 3 | .libcache 4 | .luarc.json 5 | Libs 6 | dist 7 | -------------------------------------------------------------------------------- /GUI/BarEditTab_BarStatesPanel.lua: -------------------------------------------------------------------------------- 1 | -- Neuron is a World of Warcraft® user interface addon. 2 | -- Copyright (c) 2017-2023 Britt W. Yazel 3 | -- Copyright (c) 2006-2014 Connor H. Chenoweth 4 | -- This code is licensed under the MIT license (see LICENSE for details) 5 | 6 | local _, addonTable = ... 7 | local Neuron = addonTable.Neuron 8 | 9 | local NeuronGUI = Neuron.NeuronGUI 10 | 11 | local L = LibStub("AceLocale-3.0"):GetLocale("Neuron") 12 | local AceGUI = LibStub("AceGUI-3.0") 13 | local Array = addonTable.utilities.Array 14 | 15 | 16 | ---@return Frame @a dropdown widget 17 | local function actionPrimaryBarKindOptions() 18 | local barKinds = 19 | Array.map( 20 | function(state) return state[1] end, 21 | Array.fromIterator(pairs(Neuron.MANAGED_HOME_STATES))) 22 | local currentKind = Array.foldl( 23 | function (kind, candidate) 24 | return Neuron.currentBar.data[candidate] and candidate or kind 25 | end, 26 | "none", 27 | barKinds 28 | ) 29 | local kindList = Array.foldl( 30 | function (list, kind) 31 | list[kind] = Neuron.MANAGED_HOME_STATES[kind].localizedName 32 | return list 33 | end, 34 | {none = L["None"]}, 35 | barKinds 36 | ) 37 | 38 | local barKindDropdown = AceGUI:Create("Dropdown") 39 | barKindDropdown:SetLabel(L["Home State"]) 40 | barKindDropdown:SetList(kindList) 41 | barKindDropdown:SetFullWidth(false) 42 | barKindDropdown:SetFullHeight(false) 43 | barKindDropdown:SetValue(currentKind) 44 | barKindDropdown:SetCallback("OnValueChanged", function(_, _, key) 45 | if key == "none" then 46 | for _,kind in ipairs(barKinds) do 47 | Neuron.currentBar:SetState(kind, true, false) 48 | end 49 | else 50 | Neuron.currentBar:SetState(key, true, true) 51 | end 52 | end) 53 | 54 | return barKindDropdown 55 | end 56 | 57 | ---@return Frame @a group containing checkboxes 58 | local function actionSecondaryStateOptions() 59 | local stateList = 60 | Array.map( 61 | function(state) return state[1] end, 62 | Array.fromIterator(pairs(Neuron.MANAGED_SECONDARY_STATES))) 63 | 64 | --Might want to add some checks for states like stealth for classes that 65 | --don't have stealth. But for now it doesn't break anything to have it show 66 | --generically 67 | if Neuron.class == "ROGUE" then 68 | stateList = Array.filter(function (state) return state ~= "stealth" end, stateList) 69 | end 70 | 71 | local secondaryStatesContainer = AceGUI:Create("SimpleGroup") 72 | secondaryStatesContainer:SetFullWidth(true) 73 | secondaryStatesContainer:SetLayout("Flow") 74 | 75 | for _,state in ipairs(stateList) do 76 | local checkbox = AceGUI:Create("CheckBox") 77 | checkbox:SetLabel(Neuron.MANAGED_SECONDARY_STATES[state].localizedName) 78 | checkbox:SetValue(Neuron.currentBar.data[state]) 79 | checkbox:SetCallback("OnValueChanged", function(_,_,value) 80 | Neuron.currentBar:SetState(state, true, value) 81 | end) 82 | secondaryStatesContainer:AddChild(checkbox) 83 | end 84 | 85 | return secondaryStatesContainer 86 | end 87 | 88 | ---@param tabFrame Frame 89 | function NeuronGUI:BarStatesPanel(tabFrame) 90 | -- weird stuff happens if we don't wrap this in a group 91 | -- like dropdowns showing at the bottom of the screen and stuff 92 | local settingContainer = AceGUI:Create("SimpleGroup") 93 | settingContainer:SetFullWidth(true) 94 | settingContainer:SetLayout("Flow") 95 | 96 | settingContainer:AddChild(actionPrimaryBarKindOptions()) 97 | settingContainer:AddChild(actionSecondaryStateOptions()) 98 | 99 | tabFrame:AddChild(settingContainer) 100 | end 101 | -------------------------------------------------------------------------------- /GUI/BarEditTab_BarVisibilityPanel.lua: -------------------------------------------------------------------------------- 1 | -- Neuron is a World of Warcraft® user interface addon. 2 | -- Copyright (c) 2017-2023 Britt W. Yazel 3 | -- Copyright (c) 2006-2014 Connor H. Chenoweth 4 | -- This code is licensed under the MIT license (see LICENSE for details) 5 | 6 | local _, addonTable = ... 7 | local Neuron = addonTable.Neuron 8 | 9 | local NeuronGUI = Neuron.NeuronGUI 10 | 11 | local L = LibStub("AceLocale-3.0"):GetLocale("Neuron") 12 | local AceGUI = LibStub("AceGUI-3.0") 13 | 14 | local Array = addonTable.utilities.Array 15 | 16 | local function barVisibilityOptions() 17 | local stateList = 18 | Array.map( 19 | function (state) 20 | return state[1] 21 | end, 22 | Array.fromIterator(pairs(Neuron.VISIBILITY_STATES))) 23 | if Neuron.class == 'ROGUE' then 24 | stateList = Array.filter( 25 | function (state) 26 | return state ~= 'stealth0' and state ~= 'stealth1' 27 | end, 28 | stateList 29 | ) 30 | end 31 | 32 | local visibilityStatesContainer = AceGUI:Create("SimpleGroup") 33 | visibilityStatesContainer:SetFullWidth(true) 34 | visibilityStatesContainer:SetLayout("Flow") 35 | 36 | for _,state in ipairs(stateList) do 37 | local checkbox = AceGUI:Create("CheckBox") 38 | checkbox:SetLabel(Neuron.VISIBILITY_STATES[state]) 39 | checkbox:SetValue(not Neuron.currentBar.data.hidestates:find(state)) 40 | checkbox:SetCallback("OnValueChanged", function(_,_,value) 41 | Neuron.currentBar:SetVisibility(state, value) 42 | end) 43 | visibilityStatesContainer:AddChild(checkbox) 44 | end 45 | 46 | return visibilityStatesContainer 47 | end 48 | function NeuronGUI:BarVisibilityPanel(tabFrame) 49 | -- weird stuff happens if we don't wrap this in a group 50 | -- like dropdowns showing at the bottom of the screen and stuff 51 | local settingContainer = AceGUI:Create("SimpleGroup") 52 | settingContainer:SetFullWidth(true) 53 | settingContainer:SetLayout("Flow") 54 | 55 | 56 | --sometimes the apply button doesn't appear 57 | --so far it doesn't seem to happen when it is in 58 | --it's own group :-/ 59 | local reloadButtonContainer = AceGUI:Create("SimpleGroup") 60 | reloadButtonContainer:SetFullWidth(true) 61 | reloadButtonContainer:SetLayout("Flow") 62 | 63 | --visibility status doesn't apply properly 64 | --so just suggest a ui reload with this apply button 65 | local reloadButton = AceGUI:Create("Button") 66 | reloadButton:SetText(L["Apply"]) 67 | reloadButton:SetCallback("OnClick", ReloadUI) 68 | reloadButtonContainer:AddChild(reloadButton) 69 | 70 | settingContainer:AddChild(barVisibilityOptions()) 71 | settingContainer:AddChild(reloadButtonContainer) 72 | tabFrame:AddChild(settingContainer) 73 | end 74 | -------------------------------------------------------------------------------- /GUI/IconSelectorPanel.lua: -------------------------------------------------------------------------------- 1 | -- Neuron is a World of Warcraft® user interface addon. 2 | -- Copyright (c) 2017-2023 Britt W. Yazel 3 | -- Copyright (c) 2006-2014 Connor H. Chenoweth 4 | -- This code is licensed under the MIT license (see LICENSE for details) 5 | 6 | local _, addonTable = ... 7 | local Neuron = addonTable.Neuron 8 | 9 | local NeuronGUI = Neuron.NeuronGUI 10 | 11 | local L = LibStub("AceLocale-3.0"):GetLocale("Neuron") 12 | local AceGUI = LibStub("AceGUI-3.0") 13 | 14 | local iconSelector 15 | local iconList = {} 16 | 17 | local MAX_ICONS_PER_PAGE = 120 18 | local curIconPage = 1 19 | 20 | ----------------------------------------------------------------------------- 21 | --------------------------Icon Selector-------------------------------------- 22 | ----------------------------------------------------------------------------- 23 | 24 | function NeuronGUI:IconFrame_OnClick() 25 | NeuronGUI:CreateIconSelector() 26 | end 27 | 28 | function NeuronGUI:CreateIconSelector() 29 | iconSelector = AceGUI:Create("Frame") 30 | iconSelector:SetTitle("Select an icon") 31 | iconSelector:SetCallback("OnClose", function() iconSelector:Release() end) 32 | iconSelector:SetWidth(610) 33 | iconSelector:SetHeight(500) 34 | iconSelector:EnableResize(true) 35 | if iconSelector.frame.SetResizeBounds then -- WoW 10.0 36 | iconSelector.frame:SetResizeBounds(610,450) 37 | else 38 | iconSelector.frame:SetMinResize(610,450) 39 | end 40 | iconSelector:SetLayout("Flow") -- important! 41 | 42 | NeuronGUI:GenerateIconList() 43 | 44 | NeuronGUI:CreateIconSelectorInternals() 45 | 46 | end 47 | 48 | function NeuronGUI:RefreshIconSelector() 49 | iconSelector:ReleaseChildren() 50 | NeuronGUI:CreateIconSelectorInternals() 51 | end 52 | 53 | function NeuronGUI:CreateIconSelectorInternals() 54 | 55 | -------------------------------------------------- 56 | ------------------- Pagination ------------------- 57 | -------------------------------------------------- 58 | 59 | --container group for pagination 60 | local paginationContainer = AceGUI:Create("SimpleGroup") 61 | paginationContainer:SetLayout("Flow") -- important! 62 | paginationContainer:SetFullWidth(true) 63 | paginationContainer:SetHeight(80) 64 | iconSelector:AddChild(paginationContainer) 65 | 66 | --back button 67 | local backButton = AceGUI:Create("Button") 68 | backButton:SetRelativeWidth(0.15) 69 | backButton:SetText("Previous") 70 | backButton:SetCallback("OnClick", function() 71 | if curIconPage > 1 then 72 | curIconPage = curIconPage-1 73 | end 74 | NeuronGUI:RefreshIconSelector() 75 | end) 76 | --disable button if we are on th first page 77 | if curIconPage > 1 then 78 | backButton:SetDisabled(false) 79 | else 80 | backButton:SetDisabled(true) 81 | end 82 | paginationContainer:AddChild(backButton) 83 | 84 | --pagination slider 85 | local paginationSlider = AceGUI:Create("Slider") 86 | paginationSlider:SetRelativeWidth(0.68) 87 | paginationSlider:SetSliderValues(1,ceil(#iconList/MAX_ICONS_PER_PAGE),1) 88 | paginationSlider:SetLabel("Page") 89 | paginationSlider:SetValue(curIconPage) 90 | paginationSlider:SetCallback("OnValueChanged", function(self) 91 | curIconPage = self:GetValue() 92 | NeuronGUI:RefreshIconSelector() 93 | end) 94 | paginationContainer:AddChild(paginationSlider) 95 | 96 | --forward button 97 | local forwardButton = AceGUI:Create("Button") 98 | forwardButton:SetRelativeWidth(0.15) 99 | forwardButton:SetText("Next") 100 | forwardButton:SetCallback("OnClick",function() 101 | if curIconPage < ceil(#iconList/MAX_ICONS_PER_PAGE) then 102 | curIconPage = curIconPage + 1 103 | end 104 | NeuronGUI:RefreshIconSelector() 105 | end) 106 | --disable button if we are on the last page 107 | if curIconPage < ceil(#iconList/MAX_ICONS_PER_PAGE) then 108 | forwardButton:SetDisabled(false) 109 | else 110 | forwardButton:SetDisabled(true) 111 | end 112 | paginationContainer:AddChild(forwardButton) 113 | 114 | -------------------------------------------------- 115 | --------------- Icon Scroll Frame ---------------- 116 | -------------------------------------------------- 117 | local scrollContainer = AceGUI:Create("SimpleGroup") -- "InlineGroup" is also good 118 | scrollContainer:SetLayout("Fill") -- important! 119 | scrollContainer:SetFullWidth(true) 120 | scrollContainer:SetFullHeight(true) 121 | iconSelector:AddChild(scrollContainer) 122 | 123 | local iconScroll = AceGUI:Create("ScrollFrame") 124 | iconScroll:SetLayout("Flow") -- probably? 125 | scrollContainer:AddChild(iconScroll) 126 | 127 | --this is temporary. We need to populate a list of icons here 128 | 129 | local start = (curIconPage*MAX_ICONS_PER_PAGE)-(MAX_ICONS_PER_PAGE-1) 130 | local stop = (curIconPage*MAX_ICONS_PER_PAGE) 131 | 132 | for i=start,stop do 133 | local iconFrame=AceGUI:Create("Icon") 134 | iconFrame:SetImage(iconList[i]) 135 | iconFrame:SetImageSize(40,40) 136 | iconFrame:SetWidth(50) 137 | iconFrame:SetCallback("OnClick", function() 138 | Neuron.currentButton:SetMacroIcon(iconList[i]) 139 | Neuron.currentButton:UpdateIcon() 140 | NeuronGUI:RefreshIconPreview() 141 | end) 142 | iconScroll:AddChild(iconFrame) 143 | end 144 | end 145 | 146 | ----------------------------------------------------------- 147 | ----------------------------------------------------------- 148 | 149 | function NeuronGUI:GenerateIconList() 150 | wipe(iconList) 151 | --we need a quick function to check if a table contains a value already 152 | local function tContains(table, item) 153 | local index = 1; 154 | while table[index] do 155 | if item == table[index] then 156 | return 1; 157 | end 158 | index = index + 1; 159 | end 160 | return nil; 161 | end 162 | 163 | for _,v in pairs(Neuron.spellCache) do 164 | if v.icon and not tContains(iconList, v.icon) then 165 | table.insert(iconList, v.icon) 166 | end 167 | end 168 | 169 | for _,v in pairs(Neuron.itemCache) do 170 | if v.icon and not tContains(iconList, v.icon) then 171 | table.insert(iconList, v.icon) 172 | end 173 | end 174 | 175 | GetLooseMacroIcons( iconList ); 176 | GetLooseMacroItemIcons( iconList ); 177 | GetMacroIcons( iconList ); 178 | GetMacroItemIcons( iconList ); 179 | end -------------------------------------------------------------------------------- /GUI/InterfacePanel.lua: -------------------------------------------------------------------------------- 1 | -- Neuron is a World of Warcraft® user interface addon. 2 | -- Copyright (c) 2017-2023 Britt W. Yazel 3 | -- Copyright (c) 2006-2014 Connor H. Chenoweth 4 | -- This code is licensed under the MIT license (see LICENSE for details) 5 | 6 | local addonName, addonTable = ... 7 | local Neuron = addonTable.Neuron 8 | 9 | local NeuronGUI = Neuron.NeuronGUI 10 | 11 | local L = LibStub("AceLocale-3.0"):GetLocale("Neuron") 12 | 13 | ----------------------------------------------------------------------------- 14 | --------------------------Interface Menu------------------------------------- 15 | ----------------------------------------------------------------------------- 16 | -- This is the file that manages this addons main configuration screen 17 | -- this is not the file the manages bars and buttons 18 | -- 19 | -- each fooOptions function sets up a separate configuration panel 20 | -- these panels are then loaded via NeuronGUI:LoadInterfaceOptions 21 | 22 | local function profileOptions() 23 | local options = LibStub("AceDBOptions-3.0"):GetOptionsTable(Neuron.db) 24 | 25 | --enhance the database object with per spec profile features 26 | if Neuron.isWoWRetail or Neuron.isWoWWrathClassic then 27 | local LibDualSpec = LibStub('LibDualSpec-1.0') 28 | LibDualSpec:EnhanceDatabase(Neuron.db, addonName) 29 | LibDualSpec:EnhanceOptions(options, Neuron.db) -- enhance the profiles config panel with per spec profile features 30 | end 31 | return options 32 | end 33 | 34 | local function experimentalOptions() 35 | return { 36 | name = L["Experimental"], 37 | desc = L["Experimental Options"], 38 | type = "group", 39 | order = 1001, 40 | args = { 41 | 42 | Header = { 43 | order = 1, 44 | name = L["Experimental Options"], 45 | type = "header", 46 | }, 47 | 48 | Warning = { 49 | order = 2, 50 | type = "description", 51 | name = DIM_RED_FONT_COLOR:WrapTextInColorCode(L["Experimental_Options_Warning"]), 52 | fontSize = "large", 53 | }, 54 | importexport={ 55 | name = L["Profile"].." "..L["Import"].."/"..L["Export"], 56 | type = "group", 57 | order = 1, 58 | args={ 59 | 60 | Header = { 61 | order = 1, 62 | name = L["Profile"].." "..L["Import"].."/"..L["Export"], 63 | type = "header", 64 | }, 65 | 66 | Instructions = { 67 | order = 2, 68 | name = L["ImportExport_Desc"], 69 | type = "description", 70 | fontSize = "medium", 71 | }, 72 | 73 | TextBox = { 74 | order = 3, 75 | name = L["Import or Export the current profile:"], 76 | desc = DIM_RED_FONT_COLOR:WrapTextInColorCode(L["ImportExport_WarningDesc"]), 77 | type = "input", 78 | multiline = 22, 79 | confirm = function() return L["ImportWarning"] end, 80 | validate = false, 81 | set = function(self, input) Neuron:SetSerializedAndCompressedProfile(input) end, 82 | get = function() return Neuron:GetSerializedAndCompressedProfile() end, 83 | width = "full", 84 | }, 85 | }, 86 | }, 87 | }, 88 | } 89 | end 90 | 91 | local function guiOptions() 92 | local DB = Neuron.db.profile 93 | local changes = CopyTable(DB.blizzBars) 94 | local args = { 95 | RevertButton = { 96 | order = 3, 97 | name = L["Revert"], 98 | type = "execute", 99 | width = "half", 100 | disabled = function() 101 | return tCompare(DB.blizzBars, changes) 102 | end, 103 | func = function() 104 | changes = CopyTable(DB.blizzBars) 105 | end 106 | }, 107 | ApplyButton = { 108 | order = 4, 109 | name = L["Apply"], 110 | desc = L["ReloadUI"], 111 | type = "execute", 112 | confirm = true, 113 | width = "half", 114 | disabled = function() 115 | return tCompare(DB.blizzBars, changes) 116 | end, 117 | func = function() 118 | Neuron:ToggleBlizzUI(changes) 119 | ReloadUI() 120 | end 121 | }, 122 | } 123 | for bar, _ in pairs(changes) do 124 | args[bar] = { 125 | order = 2, 126 | name = Neuron.registeredBarData[bar].barLabel, 127 | desc = L["Shows / Hides the Default Blizzard UI"], 128 | type = "toggle", 129 | set = function(_, value) 130 | changes[bar] = value 131 | end, 132 | get = function() 133 | return changes[bar] 134 | end, 135 | width = "full", 136 | } 137 | end 138 | 139 | args.NeuronMinimapButton = { 140 | order = 0, 141 | name = L["Display Minimap Button"], 142 | desc = L["Toggles the minimap button."], 143 | type = "toggle", 144 | set = function() Neuron:Minimap_ToggleIcon() end, 145 | get = function() return not DB.NeuronIcon.hide end, 146 | width = "full" 147 | } 148 | args.NeuronOverrides = { 149 | name = L["Display the Blizzard UI"], 150 | desc = L["Shows / Hides the Default Blizzard UI"], 151 | type = "header", 152 | order = 1, 153 | } 154 | return { 155 | name = L["Options"], 156 | type = "group", 157 | order = 0, 158 | args=args 159 | } 160 | end 161 | 162 | local function mainOptions() 163 | return { 164 | name = "Neuron", 165 | type = 'group', 166 | args = { 167 | }, 168 | } 169 | end 170 | 171 | ---This is the main entry point 172 | function NeuronGUI:LoadInterfaceOptions() 173 | -- local mainPanel = mainOptions() 174 | local mainPanel = guiOptions() 175 | local subPanels = {profileOptions(), experimentalOptions()} 176 | 177 | -- set up the top level panel 178 | LibStub("AceConfigRegistry-3.0"):ValidateOptionsTable(mainPanel, addonName) 179 | LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName, mainPanel) 180 | LibStub("AceConfigDialog-3.0"):AddToBlizOptions(addonName, addonName) 181 | 182 | -- set up the tree of child panels 183 | for _,options in ipairs(subPanels) do 184 | LibStub("AceConfigRegistry-3.0"):ValidateOptionsTable(options, addonName) 185 | LibStub("AceConfig-3.0"):RegisterOptionsTable(addonName..'-'..options.name, options) 186 | LibStub("AceConfigDialog-3.0"):AddToBlizOptions(addonName..'-'..options.name,options.name, addonName) 187 | end 188 | end 189 | -------------------------------------------------------------------------------- /GUI/MainWindow.lua: -------------------------------------------------------------------------------- 1 | -- Neuron is a World of Warcraft® user interface addon. 2 | -- Copyright (c) 2017-2023 Britt W. Yazel 3 | -- Copyright (c) 2006-2014 Connor H. Chenoweth 4 | -- This code is licensed under the MIT license (see LICENSE for details) 5 | 6 | local _, addonTable = ... 7 | local Neuron = addonTable.Neuron 8 | 9 | Neuron.NeuronGUI = Neuron.NeuronGUI or {} 10 | local NeuronGUI = Neuron.NeuronGUI 11 | 12 | local L = LibStub("AceLocale-3.0"):GetLocale("Neuron") 13 | local AceGUI = LibStub("AceGUI-3.0") 14 | 15 | local Array = addonTable.utilities.Array 16 | 17 | local currentTab = "bar" --remember which tab we were using between refreshes 18 | 19 | ----------------------------------------------------------------------------- 20 | --------------------------Main Window---------------------------------------- 21 | ----------------------------------------------------------------------------- 22 | 23 | function NeuronGUI:RefreshEditor(defaultTab) 24 | addonTable.NeuronEditor:ReleaseChildren() 25 | 26 | if defaultTab then 27 | currentTab = defaultTab 28 | end 29 | 30 | --re-add all the stuff to the editor window 31 | NeuronGUI:PopulateEditorWindow() 32 | 33 | if Neuron.currentBar then 34 | addonTable.NeuronEditor:SetStatusText("|cffffd200" .. Neuron.currentBar:GetBarName().."|cFFFFFFFF is currently selected. Left-click a different bar to change your selection.") 35 | else 36 | addonTable.NeuronEditor:SetStatusText("|cFFFFFFFFWelcome to the Neuron editor, please select a bar to begin") 37 | end 38 | end 39 | 40 | 41 | function NeuronGUI:CreateEditor(defaultTab) 42 | addonTable.NeuronEditor = AceGUI:Create("Frame") --add it to our base addon table to reference later 43 | 44 | addonTable.NeuronEditor:SetTitle("Neuron Editor") 45 | addonTable.NeuronEditor:EnableResize(true) 46 | if addonTable.NeuronEditor.frame.SetResizeBounds then -- WoW 10.0 47 | addonTable.NeuronEditor.frame:SetResizeBounds(760,600) 48 | else 49 | addonTable.NeuronEditor.frame:SetMinResize(760,600) 50 | end 51 | -- assuming that 720p is a reasonable minimum target for what people will be using 52 | addonTable.NeuronEditor:SetWidth("760") 53 | addonTable.NeuronEditor:SetHeight(GetScreenHeight() > 850 and "850" or "700") 54 | if Neuron.currentBar then 55 | addonTable.NeuronEditor:SetStatusText("|cffffd200" .. Neuron.currentBar:GetBarName().."|cFFFFFFFF is currently selected. Left-click a different bar to change your selection.") 56 | else 57 | addonTable.NeuronEditor:SetStatusText("|cFFFFFFFFWelcome to the Neuron editor, please select a bar to begin") 58 | end 59 | addonTable.NeuronEditor:SetCallback("OnClose", function() NeuronGUI:DestroyEditor() end) 60 | addonTable.NeuronEditor:SetLayout("Fill") 61 | 62 | -- make the thing closable with escape 63 | _G.NeuronEditorMainFrame = addonTable.NeuronEditor 64 | tinsert(UISpecialFrames, "NeuronEditorMainFrame") 65 | 66 | if defaultTab then 67 | currentTab = defaultTab 68 | end 69 | --add all the stuff to the editor window 70 | NeuronGUI:PopulateEditorWindow() 71 | end 72 | 73 | function NeuronGUI:DestroyEditor() 74 | if addonTable.NeuronEditor then 75 | AceGUI:Release(addonTable.NeuronEditor) 76 | addonTable.NeuronEditor = nil 77 | end 78 | 79 | Neuron:ToggleBarEditMode() 80 | Neuron:ToggleButtonEditMode() 81 | end 82 | 83 | function NeuronGUI:PopulateEditorWindow() 84 | local tabs ={{text="Bar Settings", value="bar"}} 85 | if Neuron.currentBar.barType == "ActionBar" then 86 | -- only action bars have editable buttons 87 | table.insert(tabs, {text=L["Configure Buttons"], value="button"}) 88 | elseif Neuron.currentBar.barType == "XPBar" then 89 | table.insert(tabs, {text=L["Configure Appearance"], value="status"}) 90 | elseif Neuron.currentBar.barType == "RepBar" then 91 | table.insert(tabs, {text=L["Configure Appearance"], value="status"}) 92 | elseif Neuron.currentBar.barType == "CastBar" then 93 | table.insert(tabs, {text=L["Configure Appearance"], value="status"}) 94 | elseif Neuron.currentBar.barType == "MirrorBar" then 95 | table.insert(tabs, {text=L["Configure Appearance"], value="status"}) 96 | end 97 | 98 | -- make sure that we switch to the bar tab 99 | -- when selecting a bar without the current tab 100 | currentTab = Array.foldl( 101 | function(current, candidate) 102 | return candidate.value == currentTab and currentTab or current 103 | end, 104 | "bar", 105 | tabs 106 | ) 107 | 108 | --Tab group that will contain all of our settings to configure 109 | local tabFrame = AceGUI:Create("TabGroup") 110 | tabFrame:SetLayout("Flow") 111 | tabFrame:SetTabs(tabs) 112 | tabFrame:SetCallback("OnGroupSelected", function(frame, _, value) NeuronGUI:SelectTab(frame, _, value) end) 113 | addonTable.NeuronEditor:AddChild(tabFrame) 114 | tabFrame:SelectTab(currentTab) 115 | end 116 | 117 | 118 | function NeuronGUI:SelectTab(tabFrame, _, value) 119 | tabFrame:ReleaseChildren() 120 | if value == "bar" then 121 | NeuronGUI:BarEditPanel(tabFrame) 122 | elseif value == "button" then 123 | -- whenever we change a button, RefreshEditor is called upstream 124 | -- so we don't need to keep track of updating currentButton here 125 | NeuronGUI:ButtonsEditPanel(tabFrame) 126 | elseif value == "status" then 127 | NeuronGUI:ButtonStatusEditPanel(tabFrame) 128 | else 129 | return -- if we get here we forgot to add a tab! 130 | end 131 | currentTab = value 132 | end 133 | -------------------------------------------------------------------------------- /GUI/Neuron-GUI.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 8 | 9 |