You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
14 KiB

local Plater = _G.Plater
local addonName, platerInternal = ...
local detailsFramework = DetailsFramework
local GetErrorHandler = platerInternal.GetErrorHandler
local _
--create a namespace for plugins
platerInternal.Plugins = {}
--a table to store plugins installed
platerInternal.Plugins.Installed = {}
--store the plugin.Frame
platerInternal.Plugins.OptionFrames = {}
--used to save on profile.plugin_data
platerInternal.Plugins.DataPrototype = {
enabled = true,
}
--the frame from Plater Options Panel
local pluginFrameOptions
function platerInternal.Plugins.GetPluginList()
return platerInternal.Plugins.Installed
end
function platerInternal.Plugins.GetPluginAreaFrame()
return pluginFrameOptions
end
function platerInternal.Plugins.GetPluginObjectByPluginUniqueName(pluginUniqueName)
local allPluginsInstalled = platerInternal.Plugins.GetPluginList()
for i = 1, #allPluginsInstalled do
local pluginObject = allPluginsInstalled[i]
if (pluginObject.UniqueName == pluginUniqueName) then
return pluginObject
end
end
end
function platerInternal.Plugins.GetPluginFrameByPluginUniqueName(pluginUniqueName)
local pluginObject = platerInternal.Plugins.GetPluginObjectByPluginUniqueName(pluginUniqueName)
return pluginObject.Frame
end
do
--[[
the state of 'Plater.db.profile.plugins_data[pluginUniqueName].enabled' is already set when the functions below are called
]]
--called after the plugin was installed
--the Plater.InstallPlugin() call does not check if the plugin is enabled or not
--this has to be done on this function
function platerInternal.Plugins.PluginInstalled(pluginUniqueName)
if (Plater.db.profile.plugins_data[pluginUniqueName].enabled) then
platerInternal.Plugins.PluginEnabled(pluginUniqueName)
else
platerInternal.Plugins.PluginDisabled(pluginUniqueName)
end
end
--called after the plugin is installed or by user interaction on the enabled checkbox from the plugin panel
function platerInternal.Plugins.PluginEnabled(pluginUniqueName)
local pluginObject = platerInternal.Plugins.GetPluginObjectByPluginUniqueName(pluginUniqueName)
if (pluginObject) then
if (pluginObject.OnEnable) then
xpcall(pluginObject.OnEnable, GetErrorHandler("Plater plugin enabled error for '" .. (pluginUniqueName or "ERROR: NO NAME").. "':"), pluginUniqueName)
end
else
error("Plater Plugins OnEnabled(): couldn't find plugin object for: " .. (pluginUniqueName or "-plugin name is nil"))
end
end
--called after the plugin is disabled by the user from the enabled checkbox on plugin panel
function platerInternal.Plugins.PluginDisabled(pluginUniqueName)
local pluginObject = platerInternal.Plugins.GetPluginObjectByPluginUniqueName(pluginUniqueName)
if (pluginObject) then
if (pluginObject.OnDisable) then
xpcall(pluginObject.OnDisable, GetErrorHandler("Plater plugin disabled error for '" .. (pluginUniqueName or "ERROR: NO NAME").. "':"), pluginUniqueName)
end
else
error("Plater Plugins OnDisable(): couldn't find plugin object for: " .. (pluginUniqueName or "-plugin name is nil"))
end
end
end
--install plugin on main plater object
function Plater.InstallPlugin(pluginObject, silent)
assert(type(pluginObject) == "table", "Use: Plater.InstallPlugin(pluginObject)")
assert(type(pluginObject.OnEnable) == "function", "pluginObject require a function on pluginObject['OnEnable'], this function is call when the plugin is enabled from the plugins menu (or after installed).")
assert(type(pluginObject.OnDisable) == "function", "pluginObject require a function on pluginObject['OnDisable'], this function is call when the plugin is disabled from the plugins menu.")
assert(type(pluginObject.Frame) == "table" and pluginObject.Frame:GetObjectType() == "Frame", "pluginObject require pluginObject['Frame'], this frame attaches into the plugins tab on Plater to show the plugin options.")
assert(type(pluginObject.Name) == "string" and pluginObject.Name:len() >= 4, "pluginObject require pluginObject['Name'], this is a localized name which is shown in the plugin tab on Plater.")
assert(type(pluginObject.UniqueName) == "string" and pluginObject.Name:len() >= 8, "pluginObject require pluginObject['UniqueName'], this is the internal name to compare if the plugin is already installed and to save enable/disabled state.")
if (platerInternal.Plugins.Installed[pluginObject.UniqueName]) then
if (not silent) then
error("Plater.InstallPlugin(): this plugin is already installed.")
end
return
end
if (not pluginObject.Icon or (type(pluginObject.Icon) ~= "number" and type(pluginObject.Icon) ~= "string")) then
pluginObject.Icon = [[Interface\ICONS\INV_Misc_QuestionMark]]
end
local pluginData = Plater.db.profile.plugins_data[pluginObject.UniqueName]
if (not pluginData) then
--create the plugin data if absent
pluginData = DetailsFramework.table.copy({}, platerInternal.Plugins.DataPrototype)
Plater.db.profile.plugins_data[pluginObject.UniqueName] = pluginData
end
--copy new values from the prototype into the plugin data
DetailsFramework.table.deploy(pluginData, platerInternal.Plugins.DataPrototype)
--saving as an indexed table to make it easy to sort by name
platerInternal.Plugins.Installed[#platerInternal.Plugins.Installed+1] = pluginObject
table.sort(platerInternal.Plugins.Installed, function(t1, t2)
return t1.Name < t2.Name
end)
platerInternal.Plugins.OptionFrames[#platerInternal.Plugins.OptionFrames+1] = pluginObject.Frame
local pluginsFrame = PlaterOptionsPanelContainerPluginsFrame
if (pluginsFrame) then
if (pluginsFrame:IsShown()) then
pluginsFrame.PluginsScrollBox:Refresh()
end
end
platerInternal.Plugins.PluginInstalled(pluginObject.UniqueName)
return true
end
function platerInternal.Plugins.CreatePluginsOptionsTab(pluginsFrame)
--_G.PlaterOptionsPanelContainerPluginsFrame
local scrollbox_size = {200, 475}
local scrollBoxHeight = scrollbox_size[2]
local scrollbox_line_height = 28.7
local scrollbox_lines = floor(scrollBoxHeight / scrollbox_line_height)
local scrollbox_line_backdrop_color = {0, 0, 0, 0.5}
local scrollbox_line_backdrop_color_selected = {.6, .6, .1, 0.7}
pluginFrameOptions = pluginsFrame
pluginsFrame.OnShowCallback = function(self)
self.PluginsScrollBox:SetData(platerInternal.Plugins.GetPluginList())
self.PluginsScrollBox:Refresh()
end
pluginsFrame:SetScript("OnShow", pluginsFrame.OnShowCallback)
pluginsFrame:SetScript("OnHide", function(self)
return "smile face"
end)
--store the UniqueName of the current plugin selected
local currentPluginSelected = false
local f = PlaterOptionsPanelFrame
local mainFrame = PlaterOptionsPanelContainer
local hideAllPluginOptionsFrame = function()
for i = 1, #platerInternal.Plugins.OptionFrames do
platerInternal.Plugins.OptionFrames[i]:Hide()
end
end
local showOptionsFrameForPlugin = function(pluginUniqueName)
local pluginFrame = platerInternal.Plugins.GetPluginFrameByPluginUniqueName(pluginUniqueName)
pluginFrame:SetParent(PlaterOptionsPanelContainerPluginsFramePluginOptionsArea)
pluginFrame:SetAllPoints(PlaterOptionsPanelContainerPluginsFramePluginOptionsArea)
pluginFrame:Show()
end
local checkBoxCallback = function(checkBox)
local pluginObject = platerInternal.Plugins.GetPluginObjectByPluginUniqueName(checkBox.pluginUniqueName)
Plater.db.profile.plugins_data[pluginObject.UniqueName].enabled = not Plater.db.profile.plugins_data[pluginObject.UniqueName].enabled
if (Plater.db.profile.plugins_data[pluginObject.UniqueName].enabled) then
--user enabled the plugin
platerInternal.Plugins.PluginEnabled(checkBox.pluginUniqueName)
else
--use disabled the plugin
platerInternal.Plugins.PluginDisabled(checkBox.pluginUniqueName)
end
end
--set points
local startX = 10
local startY = platerInternal.optionsYStart --menu and settings panel
local startYGeneralSettings = -150
function pluginsFrame.RefreshPluginSelectScrollBox(self, data, offset, totalLines) --~refresh
--update the scroll
for i = 1, totalLines do
local index = i + offset
local pluginObject = data[index]
if (pluginObject) then
--update the line
local line = self:GetLine(i)
line:UpdateLine(pluginObject)
if (pluginObject.UniqueName == currentPluginSelected) then
line:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
else
line:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
end
end
end
end
function pluginsFrame.OnEnterScrollSelectionLine(self)
self:SetBackdropColor(.3, .3, .3, .6)
end
function pluginsFrame.OnLeaveScrollSelectionLine(self)
--check if the hover overed button is the current plugin being edited
if (currentPluginSelected == self.pluginUniqueName) then
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
else
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color))
end
end
function pluginsFrame.OnClickScrollSelectionLine(self) --~õnclick ~onclick
local pluginUniqueName = self.pluginUniqueName
if (pluginUniqueName) then
--open options to plugin
hideAllPluginOptionsFrame()
showOptionsFrameForPlugin(pluginUniqueName)
currentPluginSelected = pluginUniqueName
pluginsFrame.PluginsScrollBox:Refresh()
end
end
--update a single line in the scroll list
function pluginsFrame.UpdateScrollLine(line, pluginObject) --~updateline
line.Icon:SetTexture(pluginObject.Icon)
line.Icon:SetTexCoord(.1, .9, .1, .9)
line.PluginName:SetText(pluginObject.Name)
line.pluginUniqueName = pluginObject.UniqueName
local isEnabled = Plater.db.profile.plugins_data[pluginObject.UniqueName].enabled
line.EnabledCheckbox:SetValue(isEnabled)
line.EnabledCheckbox.pluginUniqueName = pluginObject.UniqueName
end
--scrollbox to select the plugin to edit its options
local pluginsLabel = detailsFramework:CreateLabel(pluginsFrame, "Select a Plugin:", detailsFramework:GetTemplate("font", "ORANGE_FONT_TEMPLATE"))
pluginsLabel:SetPoint("topleft", pluginsFrame, "topleft", startX, startY)
local pluginSelectScrollBox = detailsFramework:CreateScrollBox(pluginsFrame, "$parentScrollBox", pluginsFrame.RefreshPluginSelectScrollBox, {}, 200, scrollBoxHeight, scrollbox_lines, scrollbox_line_height) --~scroll
pluginSelectScrollBox:SetPoint("topleft", pluginsLabel.widget, "bottomleft", 0, -2)
detailsFramework:ReskinSlider(pluginSelectScrollBox)
pluginsFrame.PluginsScrollBox = pluginSelectScrollBox
local gapBetweenScrollBoxAndOptionsPanel = 30
local pluginOptionsArea = CreateFrame("frame", "$parentPluginOptionsArea", pluginsFrame)
pluginOptionsArea:SetPoint("topleft", pluginSelectScrollBox, "topright", gapBetweenScrollBoxAndOptionsPanel, 0)
pluginOptionsArea:SetPoint("bottomleft", pluginSelectScrollBox, "bottomright", gapBetweenScrollBoxAndOptionsPanel, 0)
detailsFramework:ApplyStandardBackdrop(pluginOptionsArea)
pluginOptionsArea:SetWidth(838)
local createNewLineFunc = function(self, index)
--create a new line
local line = CreateFrame("button", "$parentLine" .. index, self, BackdropTemplateMixin and "BackdropTemplate")
--set its parameters
line:SetPoint("topleft", self, "topleft", 1, -((index-1) *(scrollbox_line_height+1)) - 1)
line:SetSize(scrollbox_size[1]-2, scrollbox_line_height)
line:RegisterForClicks("LeftButtonDown", "RightButtonDown")
line:SetScript("OnEnter", pluginsFrame.OnEnterScrollSelectionLine)
line:SetScript("OnLeave", pluginsFrame.OnLeaveScrollSelectionLine)
line:SetScript("OnClick", pluginsFrame.OnClickScrollSelectionLine)
detailsFramework:ApplyStandardBackdrop(line)
local icon = line:CreateTexture("$parentIcon", "overlay") --~create
icon:SetSize(scrollbox_line_height-4, scrollbox_line_height-4)
local pluginName = detailsFramework:CreateLabel(line, "", detailsFramework:GetTemplate("font", "PLATER_SCRIPTS_NAME"))
local enabledCheckBox = detailsFramework:CreateSwitch(line, checkBoxCallback, true, _, _, _, _, "EnabledCheckbox", "$parentEnabledToggle" .. index, _, _, _, nil, detailsFramework:GetTemplate ("switch", "OPTIONS_CHECKBOX_BRIGHT_TEMPLATE"))
enabledCheckBox:SetAsCheckBox()
--setup anchors
icon:SetPoint("left", line, "left", 2, 0)
pluginName:SetPoint("topleft", icon, "topright", 2, -2)
enabledCheckBox:SetPoint("right", line, "right", -2, 0)
line.Icon = icon
line.PluginName = pluginName
line.EnabledCheckbox = enabledCheckBox
line.UpdateLine = pluginsFrame.UpdateScrollLine
return line
end
--create the scrollbox lines
for i = 1, scrollbox_lines do
pluginSelectScrollBox:CreateLine(createNewLineFunc)
end
end
------------------------------------------------------------------------------------------
--create two test plugins
--[=[
C_Timer.After(1, function()
local plugin1 = {
Frame = CreateFrame("frame", "FrameName1"),
Name = "Test Plugin 1",
UniqueName = "TESTPLUGIN1",
Icon = [[Interface\ICONS\6BF_Explosive_Shard]],
OnEnable = function() print("plugin enabled")end,
OnDisable = function() print("plugin disabled")end,
}
Plater.InstallPlugin(plugin1, false)
local plugin2 = {
Frame = CreateFrame("frame", "MyPluginFrame", UIParent),
Name = "My Test Plugin",
UniqueName = "testplifdf 2",
Icon = [[Interface\ICONS\70_inscription_deck_dominion_3]],
OnEnable = function()end,
OnDisable = function()end,
}
Plater.InstallPlugin(plugin2)
end)
--]=]