diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/RangeReticle.lua b/RangeReticle.lua index 3b934e4..6a941a0 100755 --- a/RangeReticle.lua +++ b/RangeReticle.lua @@ -1,5 +1,5 @@ -- Load the addon menu library -local LAM = LibStub("LibAddonMenu-1.0") +local LAM = LibStub("LibAddonMenu-2.0") local db local hostileOORColorHex, hostileIRColorHex, hostileIMRColorHex local alliesOORColorHex, alliesIRColorHex, alliesIMRColorHex @@ -126,347 +126,625 @@ local function AddonSetup() previousDimensionsX = 10000 previousDimensionsY = 10000 -end - + SLASH_COMMANDS["/rret"] = CommandHandler +end -- Create the settings in the control panel local function CreateSettings() - local panel = LAM:CreateControlPanel("RANGE_RETICLE_SETTINGS", "Range Reticle") - - LAM:AddHeader(panel, "Range_Reticle_Settings_Hostile_Header", "Hostile") - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Name_Enabled", "Show Name", "If enabled, the target name is shown above the reticle", - function() return db.hostileNameEnabled end, --getFunc - function() --setFunc - db.hostileNameEnabled = not db.hostileNameEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Level_Enabled", "Show Level", "If enabled, the target level is shown above the reticle", - function() return db.hostileLevelEnabled end, --getFunc - function() --setFunc - db.hostileLevelEnabled = not db.hostileLevelEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Range_Enabled", "Show Range", "If enabled, the target range is shown at the top-right of the reticle", - function() return db.hostileRangeEnabled end, --getFunc - function() --setFunc - db.hostileRangeEnabled = not db.hostileRangeEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Difficulty_Enabled", "Show Target Difficulty", "If enabled, the target difficulty is shown as *'s above the reticle", - function() return db.hostileDifficultyEnabled end, --getFunc - function() --setFunc - db.hostileDifficultyEnabled = not db.hostileDifficultyEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Reticle_Coloring_Enabled", "Colorize Reticle", "If enabled, the color of the target reticle is colorized to reflect range status", - function() return db.hostileReticleColoringEnabled end, --getFunc - function() --setFunc - db.hostileReticleColoringEnabled = not db.hostileReticleColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_Range_Coloring_Enabled", "Colorize Range", "If enabled, the color of the target range is colorized to reflect range status", - function() return db.hostileRangeColoringEnabled end, --getFunc - function() --setFunc - db.hostileRangeColoringEnabled = not db.hostileRangeColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_NameLevel_Coloring_Enabled", "Colorize Name and Level", "If enabled, the color of the name and level is colorized to reflect range status", - function() return db.hostileNameLevelColoringEnabled end, --getFunc - function() --setFunc - db.hostileNameLevelColoringEnabled = not db.hostileNameLevelColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_OOR_Enabled", "Out Of Range", "If enabled, the reticle color will change when the target is out of range", - function() return db.hostileOutOfRangeEnabled end, --getFunc - function() --setFunc - db.hostileOutOfRangeEnabled = not db.hostileOutOfRangeEnabled - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Hostile_OOR_Color", "Out Of Range Color", "The reticle color when the target is out of range", - function() return db.hostileOORColor.r, db.hostileOORColor.g, db.hostileOORColor.b end, - function(r,g,b,a) - db.hostileOORColor.r = r - db.hostileOORColor.g = g - db.hostileOORColor.b = b - hostileOORColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_IR_Enabled", "In Range", "If enabled, the reticle color will change when the target is in range", - function() return db.hostileInRangeEnabled end, --getFunc - function() --setFunc - db.hostileInRangeEnabled = not db.hostileInRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Hostile_IR_Distance", "In Range Distance", "Set the distance that determines when a target is in range", 0, 60, 1, - function() return db.hostileInRangeDistance end, - function(value) - db.hostileInRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Hostile_IR_Color", "In Range Color", "The reticle color when the target is in range", - function() return db.hostileIRColor.r, db.hostileIRColor.g, db.hostileIRColor.b end, - function(r,g,b,a) - db.hostileIRColor.r = r - db.hostileIRColor.g = g - db.hostileIRColor.b = b - hostileIRColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Hostile_IMR_Enabled", "In Melee Range", "If enabled, the reticle color will change when the target is in melee range", - function() return db.hostileInMeleeRangeEnabled end, --getFunc - function() --setFunc - db.hostileInMeleeRangeEnabled = not db.hostileInMeleeRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Hostile_IMR_Distance", "In Melee Range Distance", "Set the distance that determines when a target is in melee range", 0, 60, 1, - function() return db.hostileInMeleeRangeDistance end, - function(value) - db.hostileInMeleeRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Hostile_IMR_Color", "In Melee Range Color", "The reticle color when the target is in melee range", - function() return db.hostileIMRColor.r, db.hostileIMRColor.g, db.hostileIMRColor.b end, - function(r,g,b,a) - db.hostileIMRColor.r = r - db.hostileIMRColor.g = g - db.hostileIMRColor.b = b - hostileIMRColorHex = RGBPercToHex(r,g,b) - end) - - LAM:AddHeader(panel, "Range_Reticle_Settings_Allies_Header", "Allies") - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_Name_Enabled", "Show Name", "If enabled, the target name is shown above the reticle", - function() return db.alliesNameEnabled end, --getFunc - function() --setFunc - db.alliesNameEnabled = not db.alliesNameEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_Level_Enabled", "Show Level", "If enabled, the target level is shown above the reticle", - function() return db.alliesLevelEnabled end, --getFunc - function() --setFunc - db.alliesLevelEnabled = not db.alliesLevelEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_Range_Enabled", "Show Range", "If enabled, the target range is shown at the top-right of the reticle", - function() return db.alliesRangeEnabled end, --getFunc - function() --setFunc - db.alliesRangeEnabled = not db.alliesRangeEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_Reticle_Coloring_Enabled", "Colorize Reticle", "If enabled, the color of the target reticle is colorized to reflect range status", - function() return db.alliesReticleColoringEnabled end, --getFunc - function() --setFunc - db.alliesReticleColoringEnabled = not db.alliesReticleColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_Range_Coloring_Enabled", "Colorize Range", "If enabled, the color of the target range is colorized to reflect range status", - function() return db.alliesRangeColoringEnabled end, --getFunc - function() --setFunc - db.alliesRangeColoringEnabled = not db.alliesRangeColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_NameLevel_Coloring_Enabled", "Colorize Name and Level", "If enabled, the color of the name and level is colorized to reflect range status", - function() return db.alliesNameLevelColoringEnabled end, --getFunc - function() --setFunc - db.alliesNameLevelColoringEnabled = not db.alliesNameLevelColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_OOR_Enabled", "Out Of Range", "If enabled, the reticle color will change when the target is out of range", - function() return db.alliesOutOfRangeEnabled end, --getFunc - function() --setFunc - db.alliesOutOfRangeEnabled = not db.alliesOutOfRangeEnabled - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Allies_OOR_Color", "Out Of Range Color", "The reticle color when the target is out of range", - function() return db.alliesOORColor.r, db.alliesOORColor.g, db.alliesOORColor.b end, - function(r,g,b,a) - db.alliesOORColor.r = r - db.alliesOORColor.g = g - db.alliesOORColor.b = b - alliesOORColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_IR_Enabled", "In Range", "If enabled, the reticle color will change when the target is in range", - function() return db.alliesInRangeEnabled end, --getFunc - function() --setFunc - db.alliesInRangeEnabled = not db.alliesInRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Allies_IR_Distance", "In Range Distance", "Set the distance that determines when a target is in range", 0, 60, 1, - function() return db.alliesInRangeDistance end, - function(value) - db.alliesInRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Allies_IR_Color", "In Range Color", "The reticle color when the target is in range", - function() return db.alliesIRColor.r, db.alliesIRColor.g, db.alliesIRColor.b end, - function(r,g,b,a) - db.alliesIRColor.r = r - db.alliesIRColor.g = g - db.alliesIRColor.b = b - alliesIRColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Allies_IMR_Enabled", "In Melee Range", "If enabled, the reticle color will change when the target is in melee range", - function() return db.alliesInMeleeRangeEnabled end, --getFunc - function() --setFunc - db.alliesInMeleeRangeEnabled = not db.alliesInMeleeRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Allies_IMR_Distance", "In Melee Range Distance", "Set the distance that determines when a target is in melee range", 0, 60, 1, - function() return db.alliesInMeleeRangeDistance end, - function(value) - db.alliesInMeleeRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Allies_IMR_Color", "In Melee Range Color", "The reticle color when the target is in melee range", - function() return db.alliesIMRColor.r, db.alliesIMRColor.g, db.alliesIMRColor.b end, - function(r,g,b,a) - db.alliesIMRColor.r = r - db.alliesIMRColor.g = g - db.alliesIMRColor.b = b - alliesIMRColorHex = RGBPercToHex(r,g,b) - end) - - LAM:AddHeader(panel, "Range_Reticle_Settings_Neutral_Header", "Neutral") - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Name_Enabled", "Show Name", "If enabled, the target name is shown above the reticle", - function() return db.neutralNameEnabled end, --getFunc - function() --setFunc - db.neutralNameEnabled = not db.neutralNameEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Level_Enabled", "Show Level", "If enabled, the target level is shown above the reticle", - function() return db.neutralLevelEnabled end, --getFunc - function() --setFunc - db.neutralLevelEnabled = not db.neutralLevelEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Range_Enabled", "Show Range", "If enabled, the target range is shown at the top-right of the reticle", - function() return db.neutralRangeEnabled end, --getFunc - function() --setFunc - db.neutralRangeEnabled = not db.neutralRangeEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Difficulty_Enabled", "Show Target Difficulty", "If enabled, the target difficulty is shown as *'s above the reticle", - function() return db.neutralDifficultyEnabled end, --getFunc - function() --setFunc - db.neutralDifficultyEnabled = not db.neutralDifficultyEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Reticle_Coloring_Enabled", "Colorize Reticle", "If enabled, the color of the target reticle is colorized to reflect range status", - function() return db.neutralReticleColoringEnabled end, --getFunc - function() --setFunc - db.neutralReticleColoringEnabled = not db.neutralReticleColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_Range_Coloring_Enabled", "Colorize Range", "If enabled, the color of the target range is colorized to reflect range status", - function() return db.neutralRangeColoringEnabled end, --getFunc - function() --setFunc - db.neutralRangeColoringEnabled = not db.neutralRangeColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_NameLevel_Coloring_Enabled", "Colorize Name and Level", "If enabled, the color of the name and level is colorized to reflect range status", - function() return db.neutralNameLevelColoringEnabled end, --getFunc - function() --setFunc - db.neutralNameLevelColoringEnabled = not db.neutralNameLevelColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_OOR_Enabled", "Out Of Range", "If enabled, the reticle color will change when the target is out of range", - function() return db.neutralOutOfRangeEnabled end, --getFunc - function() --setFunc - db.neutralOutOfRangeEnabled = not db.neutralOutOfRangeEnabled - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Neutral_OOR_Color", "Out Of Range Color", "The reticle color when the target is out of range", - function() return db.neutralOORColor.r, db.neutralOORColor.g, db.neutralOORColor.b end, - function(r,g,b,a) - db.neutralOORColor.r = r - db.neutralOORColor.g = g - db.neutralOORColor.b = b - neutralOORColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_IR_Enabled", "In Range", "If enabled, the reticle color will change when the target is in range", - function() return db.neutralInRangeEnabled end, --getFunc - function() --setFunc - db.neutralInRangeEnabled = not db.neutralInRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Neutral_IR_Distance", "In Range Distance", "Set the distance that determines when a target is in range", 0, 60, 1, - function() return db.neutralInRangeDistance end, - function(value) - db.neutralInRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Neutral_IR_Color", "In Range Color", "The reticle color when the target is in range", - function() return db.neutralIRColor.r, db.neutralIRColor.g, db.neutralIRColor.b end, - function(r,g,b,a) - db.neutralIRColor.r = r - db.neutralIRColor.g = g - db.neutralIRColor.b = b - neutralIRColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_Neutral_IMR_Enabled", "In Melee Range", "If enabled, the reticle color will change when the target is in melee range", - function() return db.neutralInMeleeRangeEnabled end, --getFunc - function() --setFunc - db.neutralInMeleeRangeEnabled = not db.neutralInMeleeRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_Neutral_IMR_Distance", "In Melee Range Distance", "Set the distance that determines when a target is in melee range", 0, 60, 1, - function() return db.neutralInMeleeRangeDistance end, - function(value) - db.neutralInMeleeRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_Neutral_IMR_Color", "In Melee Range Color", "The reticle color when the target is in melee range", - function() return db.neutralIMRColor.r, db.neutralIMRColor.g, db.neutralIMRColor.b end, - function(r,g,b,a) - db.neutralIMRColor.r = r - db.neutralIMRColor.g = g - db.neutralIMRColor.b = b - neutralIMRColorHex = RGBPercToHex(r,g,b) - end) - - LAM:AddHeader(panel, "Range_Reticle_Settings_NPCs_Header", "NPCs") - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_Name_Enabled", "Show Name", "If enabled, the target name is shown above the reticle", - function() return db.npcsNameEnabled end, --getFunc - function() --setFunc - db.npcsNameEnabled = not db.npcsNameEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_Level_Enabled", "Show Level", "If enabled, the target level is shown above the reticle", - function() return db.npcsLevelEnabled end, --getFunc - function() --setFunc - db.npcsLevelEnabled = not db.npcsLevelEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_Range_Enabled", "Show Range", "If enabled, the target range is shown at the top-right of the reticle", - function() return db.npcsRangeEnabled end, --getFunc - function() --setFunc - db.npcsRangeEnabled = not db.npcsRangeEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_Reticle_Coloring_Enabled", "Colorize Reticle", "If enabled, the color of the target reticle is colorized to reflect range status", - function() return db.npcsReticleColoringEnabled end, --getFunc - function() --setFunc - db.npcsReticleColoringEnabled = not db.npcsReticleColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_Range_Coloring_Enabled", "Colorize Range", "If enabled, the color of the target range is colorized to reflect range status", - function() return db.npcsRangeColoringEnabled end, --getFunc - function() --setFunc - db.npcsRangeColoringEnabled = not db.npcsRangeColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_NameLevel_Coloring_Enabled", "Colorize Name and Level", "If enabled, the color of the name and level is colorized to reflect range status", - function() return db.npcsNameLevelColoringEnabled end, --getFunc - function() --setFunc - db.npcsNameLevelColoringEnabled = not db.npcsNameLevelColoringEnabled - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_OOR_Enabled", "Out Of Range", "If enabled, the reticle color will change when the target is out of range", - function() return db.npcsOutOfRangeEnabled end, --getFunc - function() --setFunc - db.npcsOutOfRangeEnabled = not db.npcsOutOfRangeEnabled - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_NPCs_OOR_Color", "Out Of Range Color", "The reticle color when the target is out of range", - function() return db.npcsOORColor.r, db.npcsOORColor.g, db.npcsOORColor.b end, - function(r,g,b,a) - db.npcsOORColor.r = r - db.npcsOORColor.g = g - db.npcsOORColor.b = b - npcsOORColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_IR_Enabled", "In Range", "If enabled, the reticle color will change when the target is in range", - function() return db.npcsInRangeEnabled end, --getFunc - function() --setFunc - db.npcsInRangeEnabled = not db.npcsInRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_NPCs_IR_Distance", "In Range Distance", "Set the distance that determines when a target is in range", 0, 60, 1, - function() return db.npcsInRangeDistance end, - function(value) - db.npcsInRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_NPCs_IR_Color", "In Range Color", "The reticle color when the target is in range", - function() return db.npcsIRColor.r, db.npcsIRColor.g, db.npcsIRColor.b end, - function(r,g,b,a) - db.npcsIRColor.r = r - db.npcsIRColor.g = g - db.npcsIRColor.b = b - npcsIRColorHex = RGBPercToHex(r,g,b) - end) - LAM:AddCheckbox(panel, "Range_Reticle_Settings_NPCs_IMR_Enabled", "In Melee Range", "If enabled, the reticle color will change when the target is in melee range", - function() return db.npcsInMeleeRangeEnabled end, --getFunc - function() --setFunc - db.npcsInMeleeRangeEnabled = not db.npcsInMeleeRangeEnabled - end) - LAM:AddSlider(panel, "Range_Reticle_Settings_NPCs_IMR_Distance", "In Melee Range Distance", "Set the distance that determines when a target is in melee range", 0, 60, 1, - function() return db.npcsInMeleeRangeDistance end, - function(value) - db.npcsInMeleeRangeDistance = value - end) - LAM:AddColorPicker(panel, "Range_Reticle_Settings_NPCs_IMR_Color", "In Melee Range Color", "The reticle color when the target is in melee range", - function() return db.npcsIMRColor.r, db.npcsIMRColor.g, db.npcsIMRColor.b end, - function(r,g,b,a) - db.npcsIMRColor.r = r - db.npcsIMRColor.g = g - db.npcsIMRColor.b = b - npcsIMRColorHex = RGBPercToHex(r,g,b) - end) + local panelData = { + type = "panel", + name = "RangeReticle", + displayName = "RangeReticle", + author = "Adein", + version = "0.6", + slashCommand = "/rret", --(optional) will register a keybind to open to this panel + registerForRefresh = true, --boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown) + registerForDefaults = true, --boolean (optional) (will set all options controls back to default values) + } + + local optionsTable = { + [1] = { + type = "header", + name = "Range Reticle Settings", + width = "full", --or "half" (optional) + }, + [2] = { + type = "submenu", + name = "Hostile Targets", + tooltip = "Settings for hostile targets", --(optional) + controls = { + [1] = { + type = "checkbox", + name = "Show Name", + tooltip = "If enabled, the target name is shown above the reticle", + getFunc = function() return db.hostileNameEnabled end, + setFunc = function() db.hostileNameEnabled = not db.hostileNameEnabled end, + width = "half", --or "half" (optional) + }, + [2] = { + type = "checkbox", + name = "Show Level", + tooltip = "If enabled, the target level is shown above the reticle", + getFunc = function() return db.hostileLevelEnabled end, + setFunc = function() db.hostileLevelEnabled = not db.hostileLevelEnabled end, + width = "half", --or "half" (optional) + }, + [3] = { + type = "checkbox", + name = "Show Range", + tooltip = "If enabled, the target range is shown at the top-right of the reticle", + getFunc = function() return db.hostileRangeEnabled end, + setFunc = function() db.hostileRangeEnabled = not db.hostileRangeEnabled end, + width = "half", --or "half" (optional) + }, + [4] = { + type = "checkbox", + name = "Show Target Difficulty", + tooltip = "If enabled, the target difficulty is shown as *'s above the reticle", + getFunc = function() return db.hostileDifficultyEnabled end, + setFunc = function() db.hostileDifficultyEnabled = not db.hostileDifficultyEnabled end, + width = "half", --or "half" (optional) + }, + [5] = { + type = "checkbox", + name = "Colorize Reticle", + tooltip = "If enabled, the color of the target reticle is colorized to reflect range status", + getFunc = function() return db.hostileReticleColoringEnabled end, + setFunc = function() db.hostileReticleColoringEnabled = not db.hostileReticleColoringEnabled end, + width = "half", --or "half" (optional) + }, + [6] = { + type = "checkbox", + name = "Colorize Range", + tooltip = "If enabled, the color of the target range is colorized to reflect range status", + getFunc = function() return db.hostileRangeColoringEnabled end, + setFunc = function() db.hostileRangeColoringEnabled = not db.hostileRangeColoringEnabled end, + width = "half", --or "half" (optional) + }, + [7] = { + type = "checkbox", + name = "Colorize Name and Level", + tooltip = "If enabled, the color of the name and level is colorized to reflect range status", + getFunc = function() return db.hostileNameLevelColoringEnabled end, + setFunc = function() db.hostileNameLevelColoringEnabled = not db.hostileNameLevelColoringEnabled end, + width = "half", --or "half" (optional) + }, + [8] = { + type = "checkbox", + name = "Out Of Range", + tooltip = "If enabled, the reticle color will change when the target is out of range", + getFunc = function() return db.hostileOutOfRangeEnabled end, + setFunc = function() db.hostileOutOfRangeEnabled = not db.hostileOutOfRangeEnabled end, + width = "half", --or "half" (optional) + }, + [9] = { + type = "colorpicker", + name = "Out Of Range Color", + tooltip = "The reticle color when the target is out of range", + getFunc = function() return db.hostileOORColor.r, db.hostileOORColor.g, db.hostileOORColor.b end, + setFunc = function(r,g,b,a) + db.hostileOORColor.r = r + db.hostileOORColor.g = g + db.hostileOORColor.b = b + hostileOORColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [10] = { + type = "checkbox", + name = "In Range", + tooltip = "If enabled, the reticle color will change when the target is in range", + getFunc = function() return db.hostileInRangeEnabled end, + setFunc = function() db.hostileInRangeEnabled = not db.hostileInRangeEnabled end, + width = "half", --or "half" (optional) + }, + [11] = { + type = "slider", + name = "In Range Distance", + tooltip = "Set the distance that determines when a target is in range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.hostileInRangeDistance end, + setFunc = function(value) db.hostileInRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [12] = { + type = "colorpicker", + name = "In Range Color", + tooltip = "The reticle color when the target is in range", + getFunc = function() return db.hostileIRColor.r, db.hostileIRColor.g, db.hostileIRColor.b end, + setFunc = function(r,g,b,a) + db.hostileIRColor.r = r + db.hostileIRColor.g = g + db.hostileIRColor.b = b + hostileIRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [13] = { + type = "checkbox", + name = "In Melee Range", + tooltip = "If enabled, the reticle color will change when the target is in melee range", + getFunc = function() return db.hostileInMeleeRangeEnabled end, + setFunc = function() db.hostileInMeleeRangeEnabled = not db.hostileInMeleeRangeEnabled end, + width = "half", --or "half" (optional) + }, + [14] = { + type = "slider", + name = "In Melee Range Distance", + tooltip = "Set the distance that determines when a target is in melee range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.hostileInMeleeRangeDistance end, + setFunc = function(value) db.hostileInMeleeRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [15] = { + type = "colorpicker", + name = "In Melee Range Color", + tooltip = "The reticle color when the target is in melee range", + getFunc = function() return db.hostileIMRColor.r, db.hostileIMRColor.g, db.hostileIMRColor.b end, + setFunc = function(r,g,b,a) + db.hostileIMRColor.r = r + db.hostileIMRColor.g = g + db.hostileIMRColor.b = b + hostileIMRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + }, + }, + [3] = { + type = "submenu", + name = "Allies", + tooltip = "Settings for allies", --(optional) + controls = { + [1] = { + type = "checkbox", + name = "Show Name", + tooltip = "If enabled, the target name is shown above the reticle", + getFunc = function() return db.alliesNameEnabled end, + setFunc = function() db.alliesNameEnabled = not db.alliesNameEnabled end, + width = "half", --or "half" (optional) + }, + [2] = { + type = "checkbox", + name = "Show Level", + tooltip = "If enabled, the target level is shown above the reticle", + getFunc = function() return db.alliesLevelEnabled end, + setFunc = function() db.alliesLevelEnabled = not db.alliesLevelEnabled end, + width = "half", --or "half" (optional) + }, + [3] = { + type = "checkbox", + name = "Show Range", + tooltip = "If enabled, the target range is shown at the top-right of the reticle", + getFunc = function() return db.alliesRangeEnabled end, + setFunc = function() db.alliesRangeEnabled = not db.alliesRangeEnabled end, + width = "half", --or "half" (optional) + }, + [4] = { + type = "checkbox", + name = "Show Target Difficulty", + tooltip = "If enabled, the target difficulty is shown as *'s above the reticle", + getFunc = function() return db.alliesDifficultyEnabled end, + setFunc = function() db.alliesDifficultyEnabled = not db.alliesDifficultyEnabled end, + width = "half", --or "half" (optional) + }, + [5] = { + type = "checkbox", + name = "Colorize Reticle", + tooltip = "If enabled, the color of the target reticle is colorized to reflect range status", + getFunc = function() return db.alliesReticleColoringEnabled end, + setFunc = function() db.alliesReticleColoringEnabled = not db.alliesReticleColoringEnabled end, + width = "half", --or "half" (optional) + }, + [6] = { + type = "checkbox", + name = "Colorize Range", + tooltip = "If enabled, the color of the target range is colorized to reflect range status", + getFunc = function() return db.alliesRangeColoringEnabled end, + setFunc = function() db.alliesRangeColoringEnabled = not db.alliesRangeColoringEnabled end, + width = "half", --or "half" (optional) + }, + [7] = { + type = "checkbox", + name = "Colorize Name and Level", + tooltip = "If enabled, the color of the name and level is colorized to reflect range status", + getFunc = function() return db.alliesNameLevelColoringEnabled end, + setFunc = function() db.alliesNameLevelColoringEnabled = not db.alliesNameLevelColoringEnabled end, + width = "half", --or "half" (optional) + }, + [8] = { + type = "checkbox", + name = "Out Of Range", + tooltip = "If enabled, the reticle color will change when the target is out of range", + getFunc = function() return db.alliesOutOfRangeEnabled end, + setFunc = function() db.alliesOutOfRangeEnabled = not db.alliesOutOfRangeEnabled end, + width = "half", --or "half" (optional) + }, + [9] = { + type = "colorpicker", + name = "Out Of Range Color", + tooltip = "The reticle color when the target is out of range", + getFunc = function() return db.alliesOORColor.r, db.alliesOORColor.g, db.alliesOORColor.b end, + setFunc = function(r,g,b,a) + db.alliesOORColor.r = r + db.alliesOORColor.g = g + db.alliesOORColor.b = b + alliesOORColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [10] = { + type = "checkbox", + name = "In Range", + tooltip = "If enabled, the reticle color will change when the target is in range", + getFunc = function() return db.alliesInRangeEnabled end, + setFunc = function() db.alliesInRangeEnabled = not db.alliesInRangeEnabled end, + width = "half", --or "half" (optional) + }, + [11] = { + type = "slider", + name = "In Range Distance", + tooltip = "Set the distance that determines when a target is in range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.alliesInRangeDistance end, + setFunc = function(value) db.alliesInRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [12] = { + type = "colorpicker", + name = "In Range Color", + tooltip = "The reticle color when the target is in range", + getFunc = function() return db.alliesIRColor.r, db.alliesIRColor.g, db.alliesIRColor.b end, + setFunc = function(r,g,b,a) + db.alliesIRColor.r = r + db.alliesIRColor.g = g + db.alliesIRColor.b = b + alliesIRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [13] = { + type = "checkbox", + name = "In Melee Range", + tooltip = "If enabled, the reticle color will change when the target is in melee range", + getFunc = function() return db.alliesInMeleeRangeEnabled end, + setFunc = function() db.alliesInMeleeRangeEnabled = not db.alliesInMeleeRangeEnabled end, + width = "half", --or "half" (optional) + }, + [14] = { + type = "slider", + name = "In Melee Range Distance", + tooltip = "Set the distance that determines when a target is in melee range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.alliesInMeleeRangeDistance end, + setFunc = function(value) db.alliesInMeleeRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [15] = { + type = "colorpicker", + name = "In Melee Range Color", + tooltip = "The reticle color when the target is in melee range", + getFunc = function() return db.alliesIMRColor.r, db.alliesIMRColor.g, db.alliesIMRColor.b end, + setFunc = function(r,g,b,a) + db.alliesIMRColor.r = r + db.alliesIMRColor.g = g + db.alliesIMRColor.b = b + alliesIMRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + }, + }, + [4] = { + type = "submenu", + name = "Neutral Targets", + tooltip = "Settings for neutral targets", --(optional) + controls = { + [1] = { + type = "checkbox", + name = "Show Name", + tooltip = "If enabled, the target name is shown above the reticle", + getFunc = function() return db.neutralNameEnabled end, + setFunc = function() db.neutralNameEnabled = not db.neutralNameEnabled end, + width = "half", --or "half" (optional) + }, + [2] = { + type = "checkbox", + name = "Show Level", + tooltip = "If enabled, the target level is shown above the reticle", + getFunc = function() return db.neutralLevelEnabled end, + setFunc = function() db.neutralLevelEnabled = not db.neutralLevelEnabled end, + width = "half", --or "half" (optional) + }, + [3] = { + type = "checkbox", + name = "Show Range", + tooltip = "If enabled, the target range is shown at the top-right of the reticle", + getFunc = function() return db.neutralRangeEnabled end, + setFunc = function() db.neutralRangeEnabled = not db.neutralRangeEnabled end, + width = "half", --or "half" (optional) + }, + [4] = { + type = "checkbox", + name = "Show Target Difficulty", + tooltip = "If enabled, the target difficulty is shown as *'s above the reticle", + getFunc = function() return db.neutralDifficultyEnabled end, + setFunc = function() db.neutralDifficultyEnabled = not db.neutralDifficultyEnabled end, + width = "half", --or "half" (optional) + }, + [5] = { + type = "checkbox", + name = "Colorize Reticle", + tooltip = "If enabled, the color of the target reticle is colorized to reflect range status", + getFunc = function() return db.neutralReticleColoringEnabled end, + setFunc = function() db.neutralReticleColoringEnabled = not db.neutralReticleColoringEnabled end, + width = "half", --or "half" (optional) + }, + [6] = { + type = "checkbox", + name = "Colorize Range", + tooltip = "If enabled, the color of the target range is colorized to reflect range status", + getFunc = function() return db.neutralRangeColoringEnabled end, + setFunc = function() db.neutralRangeColoringEnabled = not db.neutralRangeColoringEnabled end, + width = "half", --or "half" (optional) + }, + [7] = { + type = "checkbox", + name = "Colorize Name and Level", + tooltip = "If enabled, the color of the name and level is colorized to reflect range status", + getFunc = function() return db.neutralNameLevelColoringEnabled end, + setFunc = function() db.neutralNameLevelColoringEnabled = not db.neutralNameLevelColoringEnabled end, + width = "half", --or "half" (optional) + }, + [8] = { + type = "checkbox", + name = "Out Of Range", + tooltip = "If enabled, the reticle color will change when the target is out of range", + getFunc = function() return db.neutralOutOfRangeEnabled end, + setFunc = function() db.neutralOutOfRangeEnabled = not db.neutralOutOfRangeEnabled end, + width = "half", --or "half" (optional) + }, + [9] = { + type = "colorpicker", + name = "Out Of Range Color", + tooltip = "The reticle color when the target is out of range", + getFunc = function() return db.neutralOORColor.r, db.neutralOORColor.g, db.neutralOORColor.b end, + setFunc = function(r,g,b,a) + db.neutralOORColor.r = r + db.neutralOORColor.g = g + db.neutralOORColor.b = b + neutralOORColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [10] = { + type = "checkbox", + name = "In Range", + tooltip = "If enabled, the reticle color will change when the target is in range", + getFunc = function() return db.neutralInRangeEnabled end, + setFunc = function() db.neutralInRangeEnabled = not db.neutralInRangeEnabled end, + width = "half", --or "half" (optional) + }, + [11] = { + type = "slider", + name = "In Range Distance", + tooltip = "Set the distance that determines when a target is in range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.neutralInRangeDistance end, + setFunc = function(value) db.neutralInRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [12] = { + type = "colorpicker", + name = "In Range Color", + tooltip = "The reticle color when the target is in range", + getFunc = function() return db.neutralIRColor.r, db.neutralIRColor.g, db.neutralIRColor.b end, + setFunc = function(r,g,b,a) + db.neutralIRColor.r = r + db.neutralIRColor.g = g + db.neutralIRColor.b = b + neutralIRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [13] = { + type = "checkbox", + name = "In Melee Range", + tooltip = "If enabled, the reticle color will change when the target is in melee range", + getFunc = function() return db.neutralInMeleeRangeEnabled end, + setFunc = function() db.neutralInMeleeRangeEnabled = not db.neutralInMeleeRangeEnabled end, + width = "half", --or "half" (optional) + }, + [14] = { + type = "slider", + name = "In Melee Range Distance", + tooltip = "Set the distance that determines when a target is in melee range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.neutralInMeleeRangeDistance end, + setFunc = function(value) db.neutralInMeleeRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [15] = { + type = "colorpicker", + name = "In Melee Range Color", + tooltip = "The reticle color when the target is in melee range", + getFunc = function() return db.neutralIMRColor.r, db.neutralIMRColor.g, db.neutralIMRColor.b end, + setFunc = function(r,g,b,a) + db.neutralIMRColor.r = r + db.neutralIMRColor.g = g + db.neutralIMRColor.b = b + neutralIMRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + }, + }, + [5] = { + type = "submenu", + name = "NPC Targets", + tooltip = "Settings for NPC targets", --(optional) + controls = { + [1] = { + type = "checkbox", + name = "Show Name", + tooltip = "If enabled, the target name is shown above the reticle", + getFunc = function() return db.npcsNameEnabled end, + setFunc = function() db.npcsNameEnabled = not db.npcsNameEnabled end, + width = "half", --or "half" (optional) + }, + [2] = { + type = "checkbox", + name = "Show Level", + tooltip = "If enabled, the target level is shown above the reticle", + getFunc = function() return db.npcsLevelEnabled end, + setFunc = function() db.npcsLevelEnabled = not db.npcsLevelEnabled end, + width = "half", --or "half" (optional) + }, + [3] = { + type = "checkbox", + name = "Show Range", + tooltip = "If enabled, the target range is shown at the top-right of the reticle", + getFunc = function() return db.npcsRangeEnabled end, + setFunc = function() db.npcsRangeEnabled = not db.npcsRangeEnabled end, + width = "half", --or "half" (optional) + }, + [4] = { + type = "checkbox", + name = "Show Target Difficulty", + tooltip = "If enabled, the target difficulty is shown as *'s above the reticle", + getFunc = function() return db.npcsDifficultyEnabled end, + setFunc = function() db.npcsDifficultyEnabled = not db.npcsDifficultyEnabled end, + width = "half", --or "half" (optional) + }, + [5] = { + type = "checkbox", + name = "Colorize Reticle", + tooltip = "If enabled, the color of the target reticle is colorized to reflect range status", + getFunc = function() return db.npcsReticleColoringEnabled end, + setFunc = function() db.npcsReticleColoringEnabled = not db.npcsReticleColoringEnabled end, + width = "half", --or "half" (optional) + }, + [6] = { + type = "checkbox", + name = "Colorize Range", + tooltip = "If enabled, the color of the target range is colorized to reflect range status", + getFunc = function() return db.npcsRangeColoringEnabled end, + setFunc = function() db.npcsRangeColoringEnabled = not db.npcsRangeColoringEnabled end, + width = "half", --or "half" (optional) + }, + [7] = { + type = "checkbox", + name = "Colorize Name and Level", + tooltip = "If enabled, the color of the name and level is colorized to reflect range status", + getFunc = function() return db.npcsNameLevelColoringEnabled end, + setFunc = function() db.npcsNameLevelColoringEnabled = not db.npcsNameLevelColoringEnabled end, + width = "half", --or "half" (optional) + }, + [8] = { + type = "checkbox", + name = "Out Of Range", + tooltip = "If enabled, the reticle color will change when the target is out of range", + getFunc = function() return db.npcsOutOfRangeEnabled end, + setFunc = function() db.npcsOutOfRangeEnabled = not db.npcsOutOfRangeEnabled end, + width = "half", --or "half" (optional) + }, + [9] = { + type = "colorpicker", + name = "Out Of Range Color", + tooltip = "The reticle color when the target is out of range", + getFunc = function() return db.npcsOORColor.r, db.npcsOORColor.g, db.npcsOORColor.b end, + setFunc = function(r,g,b,a) + db.npcsOORColor.r = r + db.npcsOORColor.g = g + db.npcsOORColor.b = b + npcsOORColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [10] = { + type = "checkbox", + name = "In Range", + tooltip = "If enabled, the reticle color will change when the target is in range", + getFunc = function() return db.npcsInRangeEnabled end, + setFunc = function() db.npcsInRangeEnabled = not db.npcsInRangeEnabled end, + width = "half", --or "half" (optional) + }, + [11] = { + type = "slider", + name = "In Range Distance", + tooltip = "Set the distance that determines when a target is in range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.npcsInRangeDistance end, + setFunc = function(value) db.npcsInRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [12] = { + type = "colorpicker", + name = "In Range Color", + tooltip = "The reticle color when the target is in range", + getFunc = function() return db.npcsIRColor.r, db.npcsIRColor.g, db.npcsIRColor.b end, + setFunc = function(r,g,b,a) + db.npcsIRColor.r = r + db.npcsIRColor.g = g + db.npcsIRColor.b = b + npcsIRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + [13] = { + type = "checkbox", + name = "In Melee Range", + tooltip = "If enabled, the reticle color will change when the target is in melee range", + getFunc = function() return db.npcsInMeleeRangeEnabled end, + setFunc = function() db.npcsInMeleeRangeEnabled = not db.npcsInMeleeRangeEnabled end, + width = "half", --or "half" (optional) + }, + [14] = { + type = "slider", + name = "In Melee Range Distance", + tooltip = "Set the distance that determines when a target is in melee range", + min = 0, + max = 60, + step = 1, --(optional) + getFunc = function() return db.npcsInMeleeRangeDistance end, + setFunc = function(value) db.npcsInMeleeRangeDistance = value end, + width = "half", --or "half" (optional) + }, + [15] = { + type = "colorpicker", + name = "In Melee Range Color", + tooltip = "The reticle color when the target is in melee range", + getFunc = function() return db.npcsIMRColor.r, db.npcsIMRColor.g, db.npcsIMRColor.b end, + setFunc = function(r,g,b,a) + db.npcsIMRColor.r = r + db.npcsIMRColor.g = g + db.npcsIMRColor.b = b + npcsIMRColorHex = RGBPercToHex(r,g,b) + end, + width = "half", --or "half" (optional) + }, + }, + }, + } + + LAM:RegisterAddonPanel("RangeReticle", panelData) + LAM:RegisterOptionControls("RangeReticle", optionsTable) end function GetColor(imrColor, irColor, oorColor, inMeleeRangeEnabled, inRangeEnabled, outOfRangeEnabled, targetInMeleeRange, targetInRange) @@ -500,6 +778,9 @@ function OnRangeUpdate() -- Get target name and reaction local targetReaction = GetUnitReaction('reticleover') local targetName = GetUnitName('reticleover') + local targetClass = GetUnitClass('reticleover') -- TODO + local targetRank, targetSubRank = GetUnitAvARank('reticleover') -- TODO + local targetGrouped = IsUnitGrouped('reticleover') -- TODO -- Local variables to store what needs to be done local nameEnabled = false @@ -599,52 +880,11 @@ function OnRangeUpdate() local selfX, selfY, selfH = GetMapPlayerPosition('player') -- Get map details - local mapWidth, mapHeight = GetMapNumTiles() local mapType = GetMapType() local mapContentType = GetMapContentType() - --MAPTYPE_NONE: 0 - --MAPTYPE_SUBZONE: 1 - --MAPTYPE_ZONE: 2 - --MAPTYPE_WORLD: 3 - --MAPTYPE_ALLIANCE: 4 - --MAPTYPE_COSMIC: 5 - - --MAP_CONTENT_NONE: 0 - --MAP_CONTENT_AVA: 1 - --MAP_CONTENT_DUNGEON: 2 - -- Calculate and display target range if targetX and targetY then - -- For debugging map types - --[[if true then - CHAT_SYSTEM:AddMessage("Width: " .. tostring(mapWidth)) - CHAT_SYSTEM:AddMessage("Height: " .. tostring(mapHeight)) - CHAT_SYSTEM:AddMessage("Type: " .. tostring(mapType)) - CHAT_SYSTEM:AddMessage("Content: " .. tostring(mapContentType)) - local dimensionsX, dimensionsY = ZO_WorldMapContainer:GetDimensions() - CHAT_SYSTEM:AddMessage("WMDimensions: " .. tostring(dimensionsX) .. ', ' .. tostring(dimensionsY)) - local dimensionsX1, dimensionsY1 = ZO_WorldMapContainer1:GetDimensions() - CHAT_SYSTEM:AddMessage("1Dimensions: " .. tostring(dimensionsX1) .. ', ' .. tostring(dimensionsY1)) - local dimensionsX2, dimensionsY2 = ZO_WorldMapContainer2:GetDimensions() - CHAT_SYSTEM:AddMessage("2Dimensions: " .. tostring(dimensionsX2) .. ', ' .. tostring(dimensionsY2)) - local dimensionsX3, dimensionsY3 = ZO_WorldMapContainer3:GetDimensions() - CHAT_SYSTEM:AddMessage("3Dimensions: " .. tostring(dimensionsX3) .. ', ' .. tostring(dimensionsY3)) - local dimensionsX4, dimensionsY4 = ZO_WorldMapContainer4:GetDimensions() - CHAT_SYSTEM:AddMessage("4Dimensions: " .. tostring(dimensionsX4) .. ', ' .. tostring(dimensionsY4)) - - CHAT_SYSTEM:AddMessage("Self: " .. tostring(selfX) .. ', ' .. tostring(selfY)) - CHAT_SYSTEM:AddMessage("Target: " .. tostring(targetX) .. ', ' .. tostring(targetY)) - - --local mdata = getmetatable(ZO_WorldMapContainer1) - --local mdata = getmetatable(ZO_WorldMapContainer) - --tprint(mdata) - CHAT_SYSTEM:AddMessage("H: " .. tostring(ZO_WorldMapContainer:GetHeight())) --405 - CHAT_SYSTEM:AddMessage("W: " .. tostring(ZO_WorldMapContainer:GetWidth())) --405 - - CHAT_SYSTEM:AddMessage("ZIndex: " .. tostring(GetCurrentMapZoneIndex())) - end]] - local dimensionsX, dimensionsY = ZO_WorldMapContainer:GetDimensions() local multiplier = 5.0 @@ -777,6 +1017,61 @@ function OnRangeUpdate() end end +-- Slash command handlers +local function CommandHandler(text) + -- Display help + if text == nil or string.len(text) <= 0 or string.lower(text) == "help" then + ChatMessage("RangeReticle Help:") + ChatMessage("/rret : display help.") + ChatMessage("/rret dbg : dump debug information to chat") + elseif text ~= nil and string.lower(text) == "dbg" then + end +end + +-- Debug info to chat window +local function Debug() + -- Get details of what's under the reticle + local targetX, targetY, targetH = GetMapPlayerPosition('reticleover') + + -- Get details of the player + local selfX, selfY, selfH = GetMapPlayerPosition('player') + + -- Get map details + local mapIndex = GetCurrentMapIndex() + local mapZoneIndex = GetCurrentMapZoneIndex() + local mapWidth, mapHeight = GetMapNumTiles() + local mapType = GetMapType() + local mapContentType = GetMapContentType() + local mapCurrentFloor, mapNumFloors = GetMapFloorInfo() + local mapName = GetMapName() + + --MAPTYPE_NONE: 0 + --MAPTYPE_SUBZONE: 1 + --MAPTYPE_ZONE: 2 + --MAPTYPE_WORLD: 3 + --MAPTYPE_ALLIANCE: 4 + --MAPTYPE_COSMIC: 5 + + --MAP_CONTENT_NONE: 0 + --MAP_CONTENT_AVA: 1 + --MAP_CONTENT_DUNGEON: 2 + + CHAT_SYSTEM:AddMessage("Map Index: " .. tostring(mapIndex)) + CHAT_SYSTEM:AddMessage("Map Zone Index: " .. tostring(mapZoneIndex)) + CHAT_SYSTEM:AddMessage("Map W/H: " .. tostring(mapWidth) .. ', ' .. tostring(mapHeight)) + CHAT_SYSTEM:AddMessage("Map Type: " .. tostring(mapType)) + CHAT_SYSTEM:AddMessage("Map Content Type: " .. tostring(mapContentType)) + CHAT_SYSTEM:AddMessage("Floor Cur/Num: " .. tostring(mapCurrentFloor) .. ', ' .. tostring(mapNumFloors)) + CHAT_SYSTEM:AddMessage("Map Name: " .. tostring(mapName)) + CHAT_SYSTEM:AddMessage("Target X/Y/H: " .. tostring(targetX) .. ', ' .. tostring(targetY) .. ', ' .. tostring(targetH)) + CHAT_SYSTEM:AddMessage("Target X/Y/H: " .. tostring(selfX) .. ', ' .. tostring(selfY) .. ', ' .. tostring(selfH)) + + local dimensionsX, dimensionsY = ZO_WorldMapContainer:GetDimensions() + CHAT_SYSTEM:AddMessage("WMDimensions: " .. tostring(dimensionsX) .. ', ' .. tostring(dimensionsY)) + local dimensionsX1, dimensionsY1 = ZO_WorldMapContainer1:GetDimensions() + CHAT_SYSTEM:AddMessage("1Dimensions: " .. tostring(dimensionsX1) .. ', ' .. tostring(dimensionsY1)) +end + -- Reticle hidden update local function OnReticleHiddenUpdate(event) local reticleHidden = IsReticleHidden() diff --git a/RangeReticle.txt b/RangeReticle.txt index ba148c2..f4e3ed0 100755 --- a/RangeReticle.txt +++ b/RangeReticle.txt @@ -1,12 +1,12 @@ ## Title: Range Reticle - by Adein -## APIVersion: 100004 +## APIVersion: 100005 ## Version: @project-version@ ## Author: Adein -## OptionalDependsOn: LibAddonMenu-1.0 +## OptionalDependsOn: LibAddonMenu-2.0 ## SavedVariables: Range_ReticleDB libs\LibStub\LibStub.lua -libs\LibAddonMenu-1.0\LibAddonMenu-1.0.lua +libs\LibAddonMenu-2.0\LibAddonMenu-2.0.lua RangeReticle.lua RangeReticle.xml diff --git a/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua b/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua deleted file mode 100755 index 7e382b1..0000000 --- a/libs/LibAddonMenu-1.0/LibAddonMenu-1.0.lua +++ /dev/null @@ -1,373 +0,0 @@ -local MAJOR, MINOR = "LibAddonMenu-1.0", 6 -local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR) -if not lam then return end --the same or newer version of this lib is already loaded into memory - ---UPVALUES-- -lam.lastAddedControl = {} -local lastAddedControl = lam.lastAddedControl -local wm = GetWindowManager() -local strformat = string.format -local tostring = tostring -local round = zo_round -local optionsWindow = ZO_OptionsWindowSettingsScrollChild - ---maybe return the controls from the creation functions? - -function lam:CreateControlPanel(controlPanelID, controlPanelName) - local panelID - - if _G[controlPanelID] then - panelID = _G[controlPanelID] - return panelID - end - - ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelName) - - --disables Defaults button because we don't need it, but keybind still works :/ ... - panelID = _G[controlPanelID] - ZO_PreHook("ZO_OptionsWindow_ChangePanels", function(panel) - local enable = (panel ~= panelID) - ZO_OptionsWindowResetToDefaultButton:SetEnabled(enable) - ZO_OptionsWindowResetToDefaultButton:SetKeybindEnabled(enable) - end) - - return panelID -end - -function lam:AddHeader(panelID, controlName, text) - local header = wm:CreateControlFromVirtual(controlName, optionsWindow, lastAddedControl[panelID] and "ZO_Options_SectionTitle_WithDivider" or "ZO_Options_SectionTitle") - if lastAddedControl[panelID] then - header:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 15) - else - header:SetAnchor(TOPLEFT) - end - header.controlType = OPTIONS_SECTION_TITLE - header.panel = panelID - header.text = text - - ZO_OptionsWindow_InitializeControl(header) - - lastAddedControl[panelID] = header - - return header -end - - ---To-Do list: ---extra sub-options window out to the right?? (or maybe addon list?) ---find alternatives to handler hooks - -function lam:AddSlider(panelID, controlName, text, tooltip, minValue, maxValue, step, getFunc, setFunc, warning, warningText) - local slider = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Slider") - slider:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6) - slider.controlType = OPTIONS_SLIDER - slider.system = SETTING_TYPE_UI - slider.panel = panelID - slider.text = text - slider.tooltipText = tooltip - slider.showValue = true - slider.showValueMin = minValue - slider.showValueMax = maxValue - local range = maxValue - minValue - local slidercontrol = slider:GetNamedChild("Slider") - local slidervalue = slider:GetNamedChild("ValueLabel") - slidercontrol:SetValueStep(1/range * step) - slider:SetHandler("OnShow", function() - local curValue = getFunc() - slidercontrol:SetValue((curValue - minValue)/range) - slidervalue:SetText(tostring(curValue)) - end) - slidercontrol:SetHandler("OnValueChanged", function (self, value) - self:SetValue(value) - value = round(value*range + minValue) - slidervalue:SetText(strformat("%d", value)) - end) - slidercontrol:SetHandler("OnSliderReleased", function(self, value) - value = round(value*range + minValue) - setFunc(value) - end) - - if warning then - slider.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", slider, "ZO_Options_WarningIcon") - slider.warning:SetAnchor(RIGHT, slidercontrol, LEFT, -5, 0) - slider.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(slider) - - lastAddedControl[panelID] = slider - - return slider -end - -function lam:AddDropdown(panelID, controlName, text, tooltip, validChoices, getFunc, setFunc, warning, warningText) - local dropdown = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Dropdown") - dropdown:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6) - dropdown.controlType = OPTIONS_DROPDOWN - dropdown.system = SETTING_TYPE_UI - dropdown.panel = panelID - dropdown.text = text - dropdown.tooltipText = tooltip - dropdown.valid = validChoices - local dropmenu = ZO_ComboBox_ObjectFromContainer(GetControl(dropdown, "Dropdown")) - local setText = dropmenu.m_selectedItemText.SetText - local selectedName - ZO_PreHookHandler(dropmenu.m_selectedItemText, "OnTextChanged", function(self) - if dropmenu.m_selectedItemData then - selectedName = dropmenu.m_selectedItemData.name - setText(self, selectedName) - setFunc(selectedName) - end - end) - dropdown:SetHandler("OnShow", function() - dropmenu:SetSelectedItem(getFunc()) - end) - - if warning then - dropdown.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", dropdown, "ZO_Options_WarningIcon") - dropdown.warning:SetAnchor(RIGHT, dropdown:GetNamedChild("Dropdown"), LEFT, -5, 0) - dropdown.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(dropdown) - - lastAddedControl[panelID] = dropdown - - return dropdown -end - -function lam:AddCheckbox(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText) - local checkbox = wm:CreateControlFromVirtual(controlName, optionsWindow, "ZO_Options_Checkbox") - checkbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6) - checkbox.controlType = OPTIONS_CHECKBOX - checkbox.system = SETTING_TYPE_UI - checkbox.settingId = _G[strformat("SETTING_%s", controlName)] - checkbox.panel = panelID - checkbox.text = text - checkbox.tooltipText = tooltip - - local checkboxButton = checkbox:GetNamedChild("Checkbox") - - ZO_PreHookHandler(checkbox, "OnShow", function() - checkboxButton:SetState(getFunc() and 1 or 0) - checkboxButton:toggleFunction(getFunc()) - end) - ZO_PreHookHandler(checkboxButton, "OnClicked", function() setFunc(not getFunc()) end) - - if warning then - checkbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", checkbox, "ZO_Options_WarningIcon") - checkbox.warning:SetAnchor(RIGHT, checkboxButton, LEFT, -5, 0) - checkbox.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(checkbox) - - lastAddedControl[panelID] = checkbox - - return checkbox -end - -function lam:AddColorPicker(panelID, controlName, text, tooltip, getFunc, setFunc, warning, warningText) - local colorpicker = wm:CreateTopLevelWindow(controlName) - colorpicker:SetParent(optionsWindow) - colorpicker:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10) - colorpicker:SetResizeToFitDescendents(true) - colorpicker:SetWidth(510) - colorpicker:SetMouseEnabled(true) - - colorpicker.label = wm:CreateControl(controlName.."Label", colorpicker, CT_LABEL) - local label = colorpicker.label - label:SetDimensions(300, 26) - label:SetAnchor(TOPLEFT) - label:SetFont("ZoFontWinH4") - label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) - label:SetText(text) - - colorpicker.color = wm:CreateControl(controlName.."Color", colorpicker, CT_CONTROL) - local color = colorpicker.color - color:SetDimensions(200,26) - color:SetAnchor(RIGHT) - - color.thumb = wm:CreateControl(controlName.."ColorThumb", color, CT_TEXTURE) - local thumb = color.thumb - thumb:SetDimensions(36, 18) - thumb:SetAnchor(LEFT, color, LEFT, 4, 0) - local r, g, b, a = getFunc() - thumb:SetColor(r, g, b, a or 1) - - color.border = wm:CreateControl(controlName.."ColorBorder", color, CT_TEXTURE) - local border = color.border - border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds") - border:SetTextureCoords(0, .625, 0, .8125) - border:SetDimensions(40, 22) - border:SetAnchor(CENTER, thumb, CENTER, 0, 0) - - local ColorPickerCallback - if not ColorPickerCallback then - ColorPickerCallback = function(r, g, b, a) - thumb:SetColor(r, g, b, a or 1) - setFunc(r, g, b, a) - end - end - - colorpicker.controlType = OPTIONS_CUSTOM - colorpicker.customSetupFunction = function(colorpicker) - colorpicker:SetHandler("OnMouseUp", function(self, btn, upInside) - if upInside then - local r, g, b, a = getFunc() - COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, text) - end - end) - end - colorpicker.panel = panelID - colorpicker.tooltipText = tooltip - colorpicker:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) - colorpicker:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) - - if warning then - colorpicker.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", colorpicker, "ZO_Options_WarningIcon") - colorpicker.warning:SetAnchor(RIGHT, colorpicker:GetNamedChild("Color"), LEFT, -5, 0) - colorpicker.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(colorpicker) - - lastAddedControl[panelID] = colorpicker - - return colorpicker -end - -function lam:AddEditBox(panelID, controlName, text, tooltip, isMultiLine, getFunc, setFunc, warning, warningText) - local editbox = wm:CreateTopLevelWindow(controlName) - editbox:SetParent(optionsWindow) - editbox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10) - editbox:SetResizeToFitDescendents(true) - editbox:SetWidth(510) - editbox:SetMouseEnabled(true) - - editbox.label = wm:CreateControl(controlName.."Label", editbox, CT_LABEL) - local label = editbox.label - label:SetDimensions(300, 26) - label:SetAnchor(TOPLEFT) - label:SetFont("ZoFontWinH4") - label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) - label:SetText(text) - - editbox.bg = wm:CreateControlFromVirtual(controlName.."BG", editbox, "ZO_EditBackdrop") - local bg = editbox.bg - bg:SetDimensions(200,isMultiLine and 100 or 24) - bg:SetAnchor(RIGHT) - editbox.edit = wm:CreateControlFromVirtual(controlName.."Edit", bg, isMultiLine and "ZO_DefaultEditMultiLineForBackdrop" or "ZO_DefaultEditForBackdrop") - editbox.edit:SetText(getFunc()) - editbox.edit:SetHandler("OnFocusLost", function(self) setFunc(self:GetText()) end) - - - editbox.panel = panelID - editbox.tooltipText = tooltip - editbox:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) - editbox:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) - - if warning then - editbox.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", editbox, "ZO_Options_WarningIcon") - editbox.warning:SetAnchor(TOPRIGHT, editbox:GetNamedChild("BG"), TOPLEFT, -5, 0) - editbox.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(editbox) - - lastAddedControl[panelID] = editbox - - return editbox -end - -function lam:AddButton(panelID, controlName, text, tooltip, onClick, warning, warningText) - local button = wm:CreateTopLevelWindow(controlName) - button:SetParent(optionsWindow) - button:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 6) - button:SetDimensions(510, 28) - button:SetMouseEnabled(true) - - button.btn = wm:CreateControlFromVirtual(controlName.."Button", button, "ZO_DefaultButton") - local btn = button.btn - btn:SetAnchor(TOPRIGHT) - btn:SetWidth(200) - btn:SetText(text) - btn:SetHandler("OnClicked", onClick) - - button.controlType = OPTIONS_CUSTOM - button.customSetupFunction = function() end --move handlers into this function? (since I created a function...) - button.panel = panelID - btn.tooltipText = tooltip - btn:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) - btn:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) - - if warning then - button.warning = wm:CreateControlFromVirtual(controlName.."WarningIcon", button, "ZO_Options_WarningIcon") - button.warning:SetAnchor(RIGHT, btn, LEFT, -5, 0) - button.warning.tooltipText = warningText - end - - ZO_OptionsWindow_InitializeControl(button) - - lastAddedControl[panelID] = button - - return button -end - -function lam:AddDescription(panelID, controlName, text, titleText) - local textBox = wm:CreateTopLevelWindow(controlName) - textBox:SetParent(optionsWindow) - textBox:SetAnchor(TOPLEFT, lastAddedControl[panelID], BOTTOMLEFT, 0, 10) - textBox:SetResizeToFitDescendents(true) - textBox:SetWidth(510) - - if titleText then - textBox.title = wm:CreateControl(controlName.."Title", textBox, CT_LABEL) - local title = textBox.title - title:SetWidth(510) - title:SetAnchor(TOPLEFT, textBox, TOPLEFT) - title:SetFont("ZoFontWinH4") - title:SetText(titleText) - end - - textBox.desc = wm:CreateControl(controlName.."Text", textBox, CT_LABEL) - local desc = textBox.desc - desc:SetWidth(510) - if titleText then - desc:SetAnchor(TOPLEFT, textBox.title, BOTTOMLEFT) - else - desc:SetAnchor(TOPLEFT) - end - desc:SetVerticalAlignment(TEXT_ALIGN_TOP) - desc:SetFont("ZoFontGame") - desc:SetText(text) - - textBox.controlType = OPTIONS_CUSTOM - textBox.panel = panelID - - ZO_OptionsWindow_InitializeControl(textBox) - - lastAddedControl[panelID] = textBox - - return textBox -end - - ---test controls & examples-- ---[[local controlPanelID = lam:CreateControlPanel("ZAM_ADDON_OPTIONS", "ZAM Addons") -lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON", "TEST ADDON") -lam:AddDescription(controlPanelID, "ZAM_Addons_TESTDESC", "This is a test description.", "Header") -lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER", "Test slider", "Adjust the slider.", 1, 10, 1, function() return 7 end, function(value) end, true, "needs UI reload") -lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN", "Test Dropdown", "Pick something!", {"thing 1", "thing 2", "thing 3"}, function() return "thing 2" end, function(self,valueString) print(valueString) end) -local checkbox1 = true -lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX", "Test Checkbox", "On or off?", function() return checkbox1 end, function(value) checkbox1 = not checkbox1 print(value, checkbox1) end) -lam:AddColorPicker(controlPanelID, "ZAM_TESTCOLORPICKER", "Test color picker", "What's your favorite color?", function() return 1, 1, 0 end, function(r,g,b) print(r,g,b) end) -lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX", "Test Edit Box", "This is a tooltip!", false, function() return "hi" end, function(text) print(text) end) -lam:AddHeader(controlPanelID, "ZAM_Addons_TESTADDON2", "TEST ADDON 2") -local checkbox2 = false -lam:AddCheckbox(controlPanelID, "ZAM_TESTCHECKBOX2", "Test Checkbox 2", "On or off?", function() return checkbox2 end, function(value) checkbox2 = not checkbox2 print(value, checkbox2) end) -lam:AddButton(controlPanelID, "ZAM_TESTBUTTON", "Test Button", "Click me", function() print("hi") end, true, "oh noez!") -lam:AddEditBox(controlPanelID, "ZAM_TESTEDITBOX2", "Test Edit Box 2", "This is a tooltip!", true, function() return "hi" end, function(text) print(text) end, true, "warning text") -lam:AddSlider(controlPanelID, "ZAM_TESTSLIDER2", "Test slider 2", "Adjust the slider.", 50, 100, 10, function() return 80 end, function(value) end) -lam:AddDropdown(controlPanelID, "ZAM_TESTDROPDOWN2", "Test Dropdown 2", "Pick something!", {"thing 4", "thing 5", "thing 6"}, function() return "thing 6" end, function(self,valueString) print(valueString) end) -]]-- \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua b/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua new file mode 100644 index 0000000..1ab94cf --- /dev/null +++ b/libs/LibAddonMenu-2.0/LibAddonMenu-2.0.lua @@ -0,0 +1,322 @@ +-- LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah) -- +-- All Rights Reserved -- +-- Permission is granted to use Seerah's LibAddonMenu-2.0 -- +-- in your project. Any modifications to LibAddonMenu-2.0 -- +-- may not be redistributed. -- +-------------------------------------------------------------- + + +--Register LAM with LibStub +local MAJOR, MINOR = "LibAddonMenu-2.0", 16 +local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR) +if not lam then return end --the same or newer version of this lib is already loaded into memory + + +--UPVALUES-- +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert +local optionsWindow = ZO_OptionsWindowSettingsScrollChild +local _ + +local addonsForList = {} +local addonToOptionsMap = {} +local optionsCreated = {} +lam.widgets = lam.widgets or {} +local widgets = lam.widgets + + +--METHOD: REGISTER WIDGET-- +--each widget has its version checked before loading, +--so we only have the most recent one in memory +--Usage: +-- widgetType = "string"; the type of widget being registered +-- widgetVersion = integer; the widget's version number +LAMCreateControl = LAMCreateControl or {} +local lamcc = LAMCreateControl + +function lam:RegisterWidget(widgetType, widgetVersion) + if widgets[widgetType] and widgets[widgetType] >= widgetVersion then + return false + else + widgets[widgetType] = widgetVersion + return true + end +end + + +--METHOD: OPEN TO ADDON PANEL-- +--opens to a specific addon's option panel +--Usage: +-- panel = userdata; the panel returned by the :RegisterOptionsPanel method +--local settings = {en = "Settings", de = "Einstellungen", fr = "Réglages"} +--local locSettings = settings[GetCVar("Language.2")] +local locSettings = GetString(SI_GAME_MENU_SETTINGS) +function lam:OpenToPanel(panel) + SCENE_MANAGER:Show("gameMenuInGame") + zo_callLater(function() + ZO_GameMenu_InGame.gameMenu.headerControls[locSettings]:SetOpen(true) + SCENE_MANAGER:AddFragment(OPTIONS_WINDOW_FRAGMENT) + --ZO_OptionsWindow_ChangePanels(lam.panelID) + KEYBOARD_OPTIONS:ChangePanels(lam.panelID) + --if not lam.panelSubCategoryControl then + -- lam.panelSubCategoryControl = _G["ZO_GameMenu_InGameNavigationContainerScrollChildZO_GameMenu_SubCategory"..(lam.panelID + 1)] + --end + --ZO_TreeEntry_OnMouseUp(lam.panelSubCategoryControl, true) + panel:SetHidden(false) + end, 200) +end + + +--INTERNAL FUNCTION +--creates controls when options panel is first shown +--controls anchoring of these controls in the panel +local function CreateOptionsControls(panel) + local addonID = panel:GetName() + local optionsTable = addonToOptionsMap[addonID] + + if optionsTable then + local lastAddedControl, lacAtHalfRow + for _, widgetData in ipairs(optionsTable) do + local widgetType = widgetData.type + if widgetType == "submenu" then + local submenu = LAMCreateControl[widgetType](panel, widgetData) + if lastAddedControl then + submenu:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15) + else + submenu:SetAnchor(TOPLEFT) + end + lastAddedControl = submenu + lacAtHalfRow = false + + local lastAddedControlSub, lacAtHalfRowSub + for _, subWidgetData in ipairs(widgetData.controls) do + local subWidgetType = subWidgetData.type + local subWidget = LAMCreateControl[subWidgetType](submenu, subWidgetData) + local isHalf = subWidgetData.width == "half" + if lastAddedControlSub then + if lacAtHalfRowSub and isHalf then + subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, TOPRIGHT, 5, 0) + lacAtHalfRowSub = false + else + subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, BOTTOMLEFT, 0, 15) + lacAtHalfRowSub = isHalf and true or false + lastAddedControlSub = subWidget + end + else + subWidget:SetAnchor(TOPLEFT) + lacAtHalfRowSub = isHalf and true or false + lastAddedControlSub = subWidget + end + end + else + local widget = LAMCreateControl[widgetType](panel, widgetData) + local isHalf = widgetData.width == "half" + if lastAddedControl then + if lacAtHalfRow and isHalf then + widget:SetAnchor(TOPLEFT, lastAddedControl, TOPRIGHT, 10, 0) + lacAtHalfRow = false + else + widget:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15) + lacAtHalfRow = isHalf and true or false + lastAddedControl = widget + end + else + widget:SetAnchor(TOPLEFT) + lacAtHalfRow = isHalf and true or false + lastAddedControl = widget + end + end + end + end + + optionsCreated[addonID] = true + cm:FireCallbacks("LAM-PanelControlsCreated", panel) +end + + +--INTERNAL FUNCTION +--handles switching between panels +local function ToggleAddonPanels(panel) --called in OnShow of newly shown panel + local currentlySelected = LAMAddonPanelsMenu.currentlySelected + if currentlySelected and currentlySelected ~= panel then + currentlySelected:SetHidden(true) + end + LAMAddonPanelsMenu.currentlySelected = panel + + if not optionsCreated[panel:GetName()] then --if this is the first time opening this panel, create these options + CreateOptionsControls(panel) + end + + cm:FireCallbacks("LAM-RefreshPanel", panel) +end + + +--METHOD: REGISTER ADDON PANEL +--registers your addon with LibAddonMenu and creates a panel +--Usage: +-- addonID = "string"; unique ID which will be the global name of your panel +-- panelData = table; data object for your panel - see controls\panel.lua +function lam:RegisterAddonPanel(addonID, panelData) + local panel = lamcc.panel(nil, panelData, addonID) --addonID==global name of panel + panel:SetHidden(true) + panel:SetAnchor(TOPLEFT, LAMAddonPanelsMenu, TOPRIGHT, 10, 0) + panel:SetAnchor(BOTTOMLEFT, LAMAddonPanelsMenu, BOTTOMRIGHT, 10, 0) + panel:SetWidth(549) + panel:SetDrawLayer(DL_OVERLAY) + tinsert(addonsForList, {panel = addonID, name = panelData.name}) + panel:SetHandler("OnShow", ToggleAddonPanels) + if panelData.slashCommand then + SLASH_COMMANDS[panelData.slashCommand] = function() + lam:OpenToPanel(panel) + end + end + + return panel --return for authors creating options manually +end + + +--METHOD: REGISTER OPTION CONTROLS +--registers the options you want shown for your addon +--these are stored in a table where each key-value pair is the order +--of the options in the panel and the data for that control, respectively +--see exampleoptions.lua for an example +--see controls\<widget>.lua for each widget type +--Usage: +-- addonID = "string"; the same string passed to :RegisterAddonPanel +-- optionsTable = table; the table containing all of the options controls and their data +function lam:RegisterOptionControls(addonID, optionsTable) --optionsTable = {sliderData, buttonData, etc} + addonToOptionsMap[addonID] = optionsTable +end + + +--INTERNAL FUNCTION +--handles switching between LAM's Addon Settings panel and other panels in the Settings menu +local oldDefaultButton = ZO_OptionsWindowResetToDefaultButton +local oldCallback = oldDefaultButton.callback +local dummyFunc = function() end +local panelWindow = ZO_OptionsWindow +local bgL = ZO_OptionsWindowBGLeft +local bgR = ZO_OptionsWindowBGLeftBGRight +local function HandlePanelSwitching(self, panel) + if panel == lam.panelID then --our addon settings panel + oldDefaultButton:SetCallback(dummyFunc) + oldDefaultButton:SetHidden(true) + oldDefaultButton:SetAlpha(0) --just because it still bugs out + panelWindow:SetDimensions(999, 960) + bgL:SetWidth(666) + bgR:SetWidth(333) + else + local shown = LAMAddonPanelsMenu.currentlySelected + if shown then shown:SetHidden(true) end + oldDefaultButton:SetCallback(oldCallback) + oldDefaultButton:SetHidden(false) + oldDefaultButton:SetAlpha(1) + panelWindow:SetDimensions(768, 914) + bgL:SetWidth(512) + bgR:SetWidth(256) + end +end + + +--INTERNAL FUNCTION +--creates LAM's Addon Settings panel +local function CreateAddonSettingsPanel() + if not LAMSettingsPanelCreated then + local controlPanelID = "LAM_ADDON_SETTINGS_PANEL" + --Russian for TERAB1T's RuESO addon, which creates an "ru" locale + --game font does not support Cyrillic, so they are using custom fonts + extended latin charset + --Spanish provided by Luisen75 for their translation project + local controlPanelNames = { + en = "Addon Settings", + fr = "Extensions", + de = "Erweiterungen", + ru = "Îacòpoéêè äoïoìîeîèé", + es = "Configura Addons", + } + + ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelNames[GetCVar("Language.2")] or controlPanelName["en"]) + + lam.panelID = _G[controlPanelID] + + --ZO_PreHook("ZO_OptionsWindow_ChangePanels", HandlePanelSwitching) + ZO_PreHook(ZO_SharedOptions, "ChangePanels", HandlePanelSwitching) + + LAMSettingsPanelCreated = true + end +end + + +--INTERNAL FUNCTION +--adds each registered addon to the menu in LAM's panel +local function CreateAddonButtons(list, addons) + for i = 1, #addons do + local button = wm:CreateControlFromVirtual("LAMAddonMenuButton"..i, list.scrollChild, "ZO_DefaultTextButton") + button.name = addons[i].name + button.panel = _G[addons[i].panel] + button:SetText(button.name) + button:SetHorizontalAlignment(TEXT_ALIGN_LEFT) + button:SetWidth(190) + if i == 1 then + button:SetAnchor(TOPLEFT, list.scrollChild, TOPLEFT, 5, 5) + else + button:SetAnchor(TOPLEFT, _G["LAMAddonMenuButton"..i-1], BOTTOMLEFT) + end + button:SetHandler("OnClicked", function(self) self.panel:SetHidden(false) end) + end +end + + +--INTERNAL FUNCTION +--creates the left-hand menu in LAM's panel +local function CreateAddonList() + local list + --check if an earlier loaded copy of LAM created it already + list = LAMAddonPanelsMenu or wm:CreateControlFromVirtual("LAMAddonPanelsMenu", optionsWindow, "ZO_ScrollContainer") + list:ClearAnchors() + list:SetAnchor(TOPLEFT) + list:SetHeight(675) + list:SetWidth(200) + + list.bg = list.bg or wm:CreateControl(nil, list, CT_BACKDROP) + local bg = list.bg + bg:SetAnchorFill() --offsets of 8? + bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16) + bg:SetCenterColor(0, 0, 0, 0) + + list.scrollChild = LAMAddonPanelsMenuScrollChild + list.scrollChild:SetResizeToFitPadding(0, 15) + + local generatedButtons + list:SetHandler("OnShow", function(self) + if not generatedButtons and #addonsForList > 0 then + --we're about to show our list for the first time - let's sort the buttons before creating them + table.sort(addonsForList, function(a, b) + return a.name < b.name + end) + CreateAddonButtons(list, addonsForList) + self.currentlySelected = LAMAddonMenuButton1 and LAMAddonMenuButton1.panel + --since our addon panels don't have a parent, let's make sure they hide when we're done with them + ZO_PreHookHandler(ZO_OptionsWindow, "OnHide", function() self.currentlySelected:SetHidden(true) end) + generatedButtons = true + end + if self.currentlySelected then self.currentlySelected:SetHidden(false) end + end) + + --list.controlType = OPTIONS_CUSTOM + --list.panel = lam.panelID + list.data = { + controlType = OPTIONS_CUSTOM, + panel = lam.panelID, + } + + ZO_OptionsWindow_InitializeControl(list) + + return list +end + + +--INITIALIZING +CreateAddonSettingsPanel() +CreateAddonList() + diff --git a/libs/LibAddonMenu-2.0/controls/button.lua b/libs/LibAddonMenu-2.0/controls/button.lua new file mode 100644 index 0000000..187e901 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/button.lua @@ -0,0 +1,89 @@ +--[[buttonData = { + type = "button", + name = "My Button", + tooltip = "Button's tooltip text.", + func = function() end, + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + icon = "icon\\path.dds", --(optional) + warning = "Will need to reload the UI.", --(optional) + reference = "MyAddonButton" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 5 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("button", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + control.button:SetEnabled(not disable) +end + + +--controlName is optional +function LAMCreateControl.button(parent, buttonData, controlName) + local control = wm:CreateTopLevelWindow(controlName or buttonData.reference) + control:SetParent(parent.scroll or parent) + + local isHalfWidth = buttonData.width == "half" + control:SetDimensions(isHalfWidth and 250 or 510, isHalfWidth and 55 or 28) + control:SetMouseEnabled(true) + + if buttonData.icon then + control.button = wm:CreateControl(nil, control, CT_BUTTON) + control.button:SetDimensions(26, 26) + control.button:SetNormalTexture(buttonData.icon) + control.button:SetPressedOffset(2, 2) + else + --control.button = wm:CreateControlFromVirtual(controlName.."Button", control, "ZO_DefaultButton") + control.button = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultButton") + control.button:SetWidth(isHalfWidth and 180 or 200) + control.button:SetText(buttonData.name) + end + local button = control.button + button:SetAnchor(isHalfWidth and CENTER or RIGHT) + button:SetClickSound("Click") + --button.tooltipText = buttonData.tooltip + button.data = {tooltipText = buttonData.tooltip} + button:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + button:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + button:SetHandler("OnClicked", function(self, ...) + buttonData.func(self, ...) + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + end) + + if buttonData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(RIGHT, button, LEFT, -5, 0) + --control.warning.tooltipText = buttonData.warning + control.warning.data = {tooltipText = buttonData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = buttonData + + if buttonData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + + --this is here because buttons don't have an UpdateValue method + if control.panel.data.registerForRefresh then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/checkbox.lua b/libs/LibAddonMenu-2.0/controls/checkbox.lua new file mode 100644 index 0000000..a777c7d --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/checkbox.lua @@ -0,0 +1,172 @@ +--[[checkboxData = { + type = "checkbox", + name = "My Checkbox", + tooltip = "Checkbox's tooltip text.", + getFunc = function() return db.var end, + setFunc = function(value) db.var = value doStuff() end, + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + warning = "Will need to reload the UI.", --(optional) + default = defaults.var, --(optional) + reference = "MyAddonCheckbox" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 7 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("checkbox", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert +--label +local enabledColor = ZO_DEFAULT_ENABLED_COLOR +local enabledHLcolor = ZO_HIGHLIGHT_TEXT +local disabledColor = ZO_DEFAULT_DISABLED_COLOR +local disabledHLcolor = ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR +--checkbox +local checkboxColor = ZO_NORMAL_TEXT +local checkboxHLcolor = ZO_HIGHLIGHT_TEXT + + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + control.label:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or control.value and ZO_DEFAULT_ENABLED_COLOR or ZO_DEFAULT_DISABLED_COLOR):UnpackRGBA()) + control.checkbox:SetColor((disable and ZO_DEFAULT_DISABLED_COLOR or ZO_NORMAL_TEXT):UnpackRGBA()) + --control:SetMouseEnabled(not disable) + --control:SetMouseEnabled(true) + + control.isDisabled = disable +end + +local function ToggleCheckbox(control) + if control.value then + control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + control.checkbox:SetText(control.checkedText) + else + control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + control.checkbox:SetText(control.uncheckedText) + end +end + +local function UpdateValue(control, forceDefault, value) + if forceDefault then --if we are forcing defaults + value = control.data.default + control.data.setFunc(value) + elseif value ~= nil then --our value could be false + control.data.setFunc(value) + --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + else + value = control.data.getFunc() + end + control.value = value + + ToggleCheckbox(control) +end + +local function OnMouseEnter(control) + ZO_Options_OnMouseEnter(control) + + if control.isDisabled then return end + + local label = control.label + if control.value then + label:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA()) + else + label:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA()) + end + control.checkbox:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA()) +end + +local function OnMouseExit(control) + ZO_Options_OnMouseExit(control) + + if control.isDisabled then return end + + local label = control.label + if control.value then + label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + else + label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + end + control.checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA()) +end + + +--controlName is optional +function LAMCreateControl.checkbox(parent, checkboxData, controlName) + local control = wm:CreateTopLevelWindow(controlName or checkboxData.reference) + control:SetParent(parent.scroll or parent) + control:SetMouseEnabled(true) + --control.tooltipText = checkboxData.tooltip + control:SetHandler("OnMouseEnter", OnMouseEnter) + control:SetHandler("OnMouseExit", OnMouseExit) + control:SetHandler("OnMouseUp", function(control) + if control.isDisabled then return end + PlaySound(SOUNDS.DEFAULT_CLICK) + control.value = not control.value + control:UpdateValue(false, control.value) + end) + + control.label = wm:CreateControl(nil, control, CT_LABEL) + local label = control.label + label:SetFont("ZoFontWinH4") + label:SetText(checkboxData.name) + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetHeight(26) + + control.checkbox = wm:CreateControl(nil, control, CT_LABEL) + local checkbox = control.checkbox + checkbox:SetFont("ZoFontGameBold") + checkbox:SetColor(ZO_NORMAL_TEXT:UnpackRGBA()) + control.checkedText = GetString(SI_CHECK_BUTTON_ON):upper() + control.uncheckedText = GetString(SI_CHECK_BUTTON_OFF):upper() + + local isHalfWidth = checkboxData.width == "half" + if isHalfWidth then + control:SetDimensions(250, 55) + checkbox:SetDimensions(100, 26) + checkbox:SetAnchor(BOTTOMRIGHT) + label:SetAnchor(TOPLEFT) + label:SetAnchor(TOPRIGHT) + else + control:SetDimensions(510, 30) + checkbox:SetDimensions(200, 26) + checkbox:SetAnchor(RIGHT) + label:SetAnchor(LEFT) + label:SetAnchor(RIGHT, checkbox, LEFT, -5, 0) + end + + if checkboxData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(RIGHT, checkbox, LEFT, -5, 0) + --control.warning.tooltipText = checkboxData.warning + control.warning.data = {tooltipText = checkboxData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = checkboxData + control.data.tooltipText = checkboxData.tooltip + + if checkboxData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + end + control.UpdateValue = UpdateValue + control:UpdateValue() + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/colorpicker.lua b/libs/LibAddonMenu-2.0/controls/colorpicker.lua new file mode 100644 index 0000000..abd9ba4 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/colorpicker.lua @@ -0,0 +1,140 @@ +--[[colorpickerData = { + type = "colorpicker", + name = "My Color Picker", + tooltip = "Color Picker's tooltip text.", + getFunc = function() return db.r, db.g, db.b, db.a end, --(alpha is optional) + setFunc = function(r,g,b,a) db.r=r, db.g=g, db.b=b, db.a=a end, --(alpha is optional) + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + warning = "Will need to reload the UI.", --(optional) + default = {r = defaults.r, g = defaults.g, b = defaults.b, a = defaults.a}, --(optional) table of default color values (or default = defaultColor, where defaultColor is a table with keys of r, g, b[, a]) + reference = "MyAddonColorpicker" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 5 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("colorpicker", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert + + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + if disable then + control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + else + control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + end + + control.isDisabled = disable +end + +local function UpdateValue(control, forceDefault, valueR, valueG, valueB, valueA) + if forceDefault then --if we are forcing defaults + local color = control.data.default + valueR, valueG, valueB, valueA = color.r, color.g, color.b, color.a + control.data.setFunc(valueR, valueG, valueB, valueA) + elseif valueR and valueG and valueB then + control.data.setFunc(valueR, valueG, valueB, valueA or 1) + --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + else + valueR, valueG, valueB, valueA = control.data.getFunc() + end + + control.thumb:SetColor(valueR, valueG, valueB, valueA or 1) +end + + +function LAMCreateControl.colorpicker(parent, colorpickerData, controlName) + local control = wm:CreateTopLevelWindow(controlName or colorpickerData.reference) + control:SetParent(parent.scroll or parent) + control:SetMouseEnabled(true) + --control.tooltipText = colorpickerData.tooltip + control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + + control.label = wm:CreateControl(nil, control, CT_LABEL) + local label = control.label + label:SetDimensions(300, 26) + label:SetAnchor(TOPLEFT) + label:SetFont("ZoFontWinH4") + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetText(colorpickerData.name) + + control.color = wm:CreateControl(nil, control, CT_CONTROL) + local color = control.color + + local isHalfWidth = colorpickerData.width == "half" + if isHalfWidth then + control:SetDimensions(250, 55) + label:SetDimensions(250, 26) + color:SetDimensions(100, 24) + color:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT) + else + control:SetDimensions(510, 30) + label:SetDimensions(300, 26) + color:SetDimensions(200, 24) + color:SetAnchor(TOPRIGHT) + end + + control.thumb = wm:CreateControl(nil, color, CT_TEXTURE) + local thumb = control.thumb + thumb:SetDimensions(36, 18) + thumb:SetAnchor(LEFT, color, LEFT, 4, 0) + + color.border = wm:CreateControl(nil, color, CT_TEXTURE) + local border = color.border + border:SetTexture("EsoUI\\Art\\ChatWindow\\chatOptions_bgColSwatch_frame.dds") + border:SetTextureCoords(0, .625, 0, .8125) + border:SetDimensions(40, 22) + border:SetAnchor(CENTER, thumb, CENTER, 0, 0) + + local function ColorPickerCallback(r, g, b, a) + control:UpdateValue(false, r, g, b, a) + end + + control:SetHandler("OnMouseUp", function(self, btn, upInside) + if self.isDisabled then return end + + if upInside then + local r, g, b, a = colorpickerData.getFunc() + COLOR_PICKER:Show(ColorPickerCallback, r, g, b, a, colorpickerData.name) + end + end) + + if colorpickerData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(RIGHT, control.color, LEFT, -5, 0) + --control.warning.tooltipText = colorpickerData.warning + control.warning.data = {tooltipText = colorpickerData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = colorpickerData + control.data.tooltipText = colorpickerData.tooltip + + if colorpickerData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + end + control.UpdateValue = UpdateValue + control:UpdateValue() + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/custom.lua b/libs/LibAddonMenu-2.0/controls/custom.lua new file mode 100644 index 0000000..54c9775 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/custom.lua @@ -0,0 +1,45 @@ +--[[customData = { + type = "custom", + reference = "MyAddonCustomControl", --(optional) unique name for your control to use as reference + refreshFunc = function(customControl) end, --(optional) function to call when panel/controls refresh + width = "full", --or "half" (optional) +} ]] + +local widgetVersion = 4 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("custom", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local tinsert = table.insert + +local function UpdateValue(control) + if control.data.refreshFunc then + control.data.refreshFunc(control) + end +end + +function LAMCreateControl.custom(parent, customData, controlName) + local control = wm:CreateTopLevelWindow(controlName or customData.reference) + control:SetResizeToFitDescendents(true) + control:SetParent(parent.scroll or parent) + + local isHalfWidth = customData.width == "half" + if isHalfWidth then --note these restrictions + control:SetDimensionConstraints(250, 55, 250, 100) + control:SetDimensions(250, 55) + else + control:SetDimensionConstraints(510, 30, 510, 100) + control:SetDimensions(510, 30) + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = customData + + control.UpdateValue = UpdateValue + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/description.lua b/libs/LibAddonMenu-2.0/controls/description.lua new file mode 100644 index 0000000..5d7219d --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/description.lua @@ -0,0 +1,67 @@ +--[[descriptionData = { + type = "description", + title = "My Title", --(optional) + text = "My description text to display.", + width = "full", --or "half" (optional) + reference = "MyAddonDescription" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 4 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("description", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local tinsert = table.insert + +local function UpdateValue(control) + if control.title then + control.title:SetText(control.data.title) + end + control.desc:SetText(control.data.text) +end + +function LAMCreateControl.description(parent, descriptionData, controlName) + local control = wm:CreateTopLevelWindow(controlName or descriptionData.reference) + control:SetResizeToFitDescendents(true) + control:SetParent(parent.scroll or parent) + local isHalfWidth = descriptionData.width == "half" + if isHalfWidth then + control:SetDimensionConstraints(250, 55, 250, 100) + control:SetDimensions(250, 55) + else + control:SetDimensionConstraints(510, 40, 510, 100) + control:SetDimensions(510, 30) + end + + control.desc = wm:CreateControl(nil, control, CT_LABEL) + local desc = control.desc + desc:SetVerticalAlignment(TEXT_ALIGN_TOP) + desc:SetFont("ZoFontGame") + desc:SetText(descriptionData.text) + desc:SetWidth(isHalfWidth and 250 or 510) + + if descriptionData.title then + control.title = wm:CreateControl(nil, control, CT_LABEL) + local title = control.title + title:SetWidth(isHalfWidth and 250 or 510) + title:SetAnchor(TOPLEFT, control, TOPLEFT) + title:SetFont("ZoFontWinH4") + title:SetText(descriptionData.title) + desc:SetAnchor(TOPLEFT, title, BOTTOMLEFT) + else + desc:SetAnchor(TOPLEFT) + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = descriptionData + + control.UpdateValue = UpdateValue + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control + +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/dropdown.lua b/libs/LibAddonMenu-2.0/controls/dropdown.lua new file mode 100644 index 0000000..94cd820 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/dropdown.lua @@ -0,0 +1,153 @@ +--[[dropdownData = { + type = "dropdown", + name = "My Dropdown", + tooltip = "Dropdown's tooltip text.", + choices = {"table", "of", "choices"}, + sort = "name-up", --or "name-down", "numeric-up", "numeric-down" (optional) - if not provided, list will not be sorted + getFunc = function() return db.var end, + setFunc = function(var) db.var = var doStuff() end, + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + warning = "Will need to reload the UI.", --(optional) + default = defaults.var, --(optional) + reference = "MyAddonDropdown" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 7 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("dropdown", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert + + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + control.dropdown:SetEnabled(not disable) + if disable then + control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + else + control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + end +end + +local function UpdateValue(control, forceDefault, value) + if forceDefault then --if we are forcing defaults + value = control.data.default + control.data.setFunc(value) + control.dropdown:SetSelectedItem(value) + elseif value then + control.data.setFunc(value) + --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + else + value = control.data.getFunc() + control.dropdown:SetSelectedItem(value) + end +end + +local function DropdownCallback(choice, choiceText, choice) + choice.control:UpdateValue(false, choiceText) +end + +local function UpdateChoices(control, choices) + control.dropdown:ClearItems() --remove previous choices --(need to call :SetSelectedItem()?) + + --build new list of choices + local choices = choices or control.data.choices + for i = 1, #choices do + local entry = control.dropdown:CreateItemEntry(choices[i], DropdownCallback) + entry.control = control + control.dropdown:AddItem(entry, not control.data.sort and ZO_COMBOBOX_SUPRESS_UPDATE) --if sort type/order isn't specified, then don't sort + end +end + +local function GrabSortingInfo(sortInfo) + local t, i = {}, 1 + for info in string.gmatch(sortInfo, "([^%-]+)") do + t[i] = info + i = i + 1 + end + + return t +end + + +local comboboxCount = 1 +function LAMCreateControl.dropdown(parent, dropdownData, controlName) + local control = wm:CreateTopLevelWindow(controlName or dropdownData.reference) + control:SetParent(parent.scroll or parent) + control:SetMouseEnabled(true) + --control.tooltipText = dropdownData.tooltip + control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + + control.label = wm:CreateControl(nil, control, CT_LABEL) + local label = control.label + label:SetAnchor(TOPLEFT) + label:SetFont("ZoFontWinH4") + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetText(dropdownData.name) + + control.combobox = wm:CreateControlFromVirtual(parent:GetName().."Combobox"..comboboxCount, control, "ZO_ComboBox") + comboboxCount = comboboxCount + 1 + local combobox = control.combobox + combobox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end) + combobox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end) + control.dropdown = ZO_ComboBox_ObjectFromContainer(combobox) + local dropdown = control.dropdown + if dropdownData.sort then + local sortInfo = GrabSortingInfo(dropdownData.sort) + local sortType, sortOrder = sortInfo[1], sortInfo[2] + dropdown:SetSortOrder(sortOrder == "up" and ZO_SORT_ORDER_UP or ZO_SORT_ORDER_DOWN, sortType == "name" and ZO_SORT_BY_NAME or ZO_SORT_BY_NAME_NUMERIC) + end + + local isHalfWidth = dropdownData.width == "half" + if isHalfWidth then + control:SetDimensions(250, 55) + label:SetDimensions(250, 26) + combobox:SetDimensions(225, 26) + combobox:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT) + else + control:SetDimensions(510, 30) + label:SetDimensions(300, 26) + combobox:SetDimensions(200, 26) + combobox:SetAnchor(TOPRIGHT) + end + + if dropdownData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(RIGHT, combobox, LEFT, -5, 0) + --control.warning.tooltipText = dropdownData.warning + control.warning.data = {tooltipText = dropdownData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = dropdownData + control.data.tooltipText = dropdownData.tooltip + + if dropdownData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + end + control.UpdateChoices = UpdateChoices + control:UpdateChoices(dropdownData.choices) + control.UpdateValue = UpdateValue + control:UpdateValue() + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/editbox.lua b/libs/LibAddonMenu-2.0/controls/editbox.lua new file mode 100644 index 0000000..0d273d3 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/editbox.lua @@ -0,0 +1,155 @@ +--[[editboxData = { + type = "editbox", + name = "My Editbox", + tooltip = "Editbox's tooltip text.", + getFunc = function() return db.text end, + setFunc = function(text) db.text = text doStuff() end, + isMultiline = true, --boolean + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + warning = "Will need to reload the UI.", --(optional) + default = defaults.text, --(optional) + reference = "MyAddonEditbox" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 6 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("editbox", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local tinsert = table.insert + + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + if disable then + control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + control.editbox:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA()) + else + control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + control.editbox:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + end + --control.editbox:SetEditEnabled(not disable) + control.editbox:SetMouseEnabled(not disable) +end + +local function UpdateValue(control, forceDefault, value) + if forceDefault then --if we are forcing defaults + value = control.data.default + control.data.setFunc(value) + control.editbox:SetText(value) + elseif value then + control.data.setFunc(value) + --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + else + value = control.data.getFunc() + control.editbox:SetText(value) + end +end + + +function LAMCreateControl.editbox(parent, editboxData, controlName) + local control = wm:CreateTopLevelWindow(controlName or editboxData.reference) + control:SetParent(parent.scroll or parent) + control:SetMouseEnabled(true) + control:SetResizeToFitDescendents(true) + --control.tooltipText = editboxData.tooltip + control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + + control.label = wm:CreateControl(nil, control, CT_LABEL) + local label = control.label + label:SetAnchor(TOPLEFT) + label:SetFont("ZoFontWinH4") + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetText(editboxData.name) + + control.bg = wm:CreateControlFromVirtual(nil, control, "ZO_EditBackdrop") + local bg = control.bg + + if editboxData.isMultiline then + control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditMultiLineForBackdrop") + control.editbox:SetHandler("OnMouseWheel", function(self, delta) + if self:HasFocus() then --only set focus to new spots if the editbox is currently in use + local cursorPos = self:GetCursorPosition() + local text = self:GetText() + local textLen = text:len() + local newPos + if delta > 0 then --scrolling up + local reverseText = text:reverse() + local revCursorPos = textLen - cursorPos + local revPos = reverseText:find("\n", revCursorPos+1) + newPos = revPos and textLen - revPos + else --scrolling down + newPos = text:find("\n", cursorPos+1) + end + if newPos then --if we found a new line, then scroll, otherwise don't + self:SetCursorPosition(newPos) + end + end + end) + else + control.editbox = wm:CreateControlFromVirtual(nil, bg, "ZO_DefaultEditForBackdrop") + end + local editbox = control.editbox + editbox:SetText(editboxData.getFunc()) + editbox:SetMaxInputChars(3000) + editbox:SetHandler("OnFocusLost", function(self) control:UpdateValue(false, self:GetText()) end) + editbox:SetHandler("OnEscape", function(self) self:LoseFocus() control:UpdateValue(false, self:GetText()) end) + editbox:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end) + editbox:SetHandler("OnMouseExit", function() ZO_Options_OnMouseExit(control) end) + + local isHalfWidth = editboxData.width == "half" + if isHalfWidth then + control:SetDimensions(250, 55) + label:SetDimensions(250, 26) + bg:SetDimensions(225, editboxData.isMultiline and 74 or 24) + bg:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT) + if editboxData.isMultiline then + editbox:SetDimensionConstraints(210, 74, 210, 500) + end + else + control:SetDimensions(510, 30) + label:SetDimensions(300, 26) + bg:SetDimensions(200, editboxData.isMultiline and 100 or 24) + bg:SetAnchor(TOPRIGHT) + if editboxData.isMultiline then + editbox:SetDimensionConstraints(185, 100, 185, 500) + end + end + + if editboxData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(TOPRIGHT, control.bg, TOPLEFT, -5, 0) + --control.warning.tooltipText = editboxData.warning + control.warning.data = {tooltipText = editboxData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = editboxData + control.data.tooltipText = editboxData.tooltip + + if editboxData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + end + control.UpdateValue = UpdateValue + control:UpdateValue() + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/header.lua b/libs/LibAddonMenu-2.0/controls/header.lua new file mode 100644 index 0000000..bbf2c60 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/header.lua @@ -0,0 +1,47 @@ +--[[headerData = { + type = "header", + name = "My Header", + width = "full", --or "half" (optional) + reference = "MyAddonHeader" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 4 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("header", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local tinsert = table.insert + +local function UpdateValue(control) + control.header:SetText(control.data.name) +end + +function LAMCreateControl.header(parent, headerData, controlName) + local control = wm:CreateTopLevelWindow(controlName or headerData.reference) + control:SetParent(parent.scroll or parent) + local isHalfWidth = headerData.width == "half" + control:SetDimensions(isHalfWidth and 250 or 510, 30) + + control.divider = wm:CreateControlFromVirtual(nil, control, "ZO_Options_Divider") + local divider = control.divider + divider:SetWidth(isHalfWidth and 250 or 510) + divider:SetAnchor(TOPLEFT) + + control.header = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel") + local header = control.header + header:SetAnchor(TOPLEFT, divider, BOTTOMLEFT) + header:SetAnchor(BOTTOMRIGHT) + header:SetText(headerData.name) + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = headerData + + control.UpdateValue = UpdateValue + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/panel.lua b/libs/LibAddonMenu-2.0/controls/panel.lua new file mode 100644 index 0000000..5f9f41b --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/panel.lua @@ -0,0 +1,138 @@ +--[[panelData = { + type = "panel", + name = "Window Title", + displayName = "My Longer Window Title", --(optional) (can be useful for long addon names or if you want to colorize it) + author = "Seerah", --(optional) + version = "2.0", --(optional) + slashCommand = "/myaddon", --(optional) will register a keybind to open to this panel (don't forget to include the slash!) + registerForRefresh = true, --boolean (optional) (will refresh all options controls when a setting is changed and when the panel is shown) + registerForDefaults = true, --boolean (optional) (will set all options controls back to default values) + resetFunc = function() print("defaults reset") end, --(optional) custom function to run after settings are reset to defaults +} ]] + + +local widgetVersion = 8 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("panel", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER + +local function RefreshPanel(control) + local panel = control.panel or control --callback can be fired by a single control or by the panel showing + local panelControls = panel.controlsToRefresh + + for i = 1, #panelControls do + local updateControl = panelControls[i] + if updateControl ~= control then + if updateControl.UpdateValue then + updateControl:UpdateValue() + end + if updateControl.UpdateDisabled then + updateControl:UpdateDisabled() + end + end + end +end + +local function ForceDefaults(panel) + local panelControls = panel.controlsToRefresh + + for i = 1, #panelControls do + local updateControl = panelControls[i] + if updateControl.UpdateValue and updateControl.data.default ~= nil then + updateControl:UpdateValue(true) + end + end + + if panel.data.resetFunc then + panel.data.resetFunc() + end + + cm:FireCallbacks("LAM-RefreshPanel", panel) +end +ESO_Dialogs["LAM_DEFAULTS"] = { + title = { + text = SI_OPTIONS_RESET_TITLE, + }, + mainText = { + text = SI_OPTIONS_RESET_PROMPT, + align = TEXT_ALIGN_CENTER, + }, + buttons = { + [1] = { + text = SI_OPTIONS_RESET, + callback = function(dialog) ForceDefaults(dialog.data[1]) end, + }, + [2] = { + text = SI_DIALOG_CANCEL, + }, + }, +} + +local callbackRegistered = false +LAMCreateControl.scrollCount = LAMCreateControl.scrollCount or 1 +function LAMCreateControl.panel(parent, panelData, controlName) + local control = wm:CreateTopLevelWindow(controlName) + control:SetParent(parent) + + control.bg = wm:CreateControl(nil, control, CT_BACKDROP) + local bg = control.bg + bg:SetAnchorFill() + bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16) + bg:SetCenterColor(0, 0, 0, 0) + + control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel") + local label = control.label + label:SetAnchor(TOPLEFT, control, TOPLEFT, 10, 10) + label:SetText(panelData.displayName and panelData.displayName or panelData.name) + + if panelData.author or panelData.version then + control.info = wm:CreateControl(nil, control, CT_LABEL) + local info = control.info + info:SetFont("$(CHAT_FONT)|14|soft-shadow-thin") + info:SetColor(ZO_HIGHLIGHT_TEXT:UnpackRGBA()) + info:SetHeight(13) + info:SetAnchor(TOPRIGHT, control, BOTTOMRIGHT, -5, 2) + if panelData.author and panelData.version then + --info:SetText("Version: "..panelData.version.." - "..GetString(SI_ADDON_MANAGER_AUTHOR)..": "..panelData.author) + info:SetText(string.format("Version: %s - %s: %s", panelData.version, GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author)) + elseif panelData.author then + info:SetText(string.format("%s: %s", GetString(SI_ADDON_MANAGER_AUTHOR), panelData.author)) + else + info:SetText("Version: "..panelData.version) + end + end + + control.container = wm:CreateControlFromVirtual("LAMAddonPanelContainer"..LAMCreateControl.scrollCount, control, "ZO_ScrollContainer") + LAMCreateControl.scrollCount = LAMCreateControl.scrollCount + 1 + local container = control.container + container:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 20) + container:SetAnchor(BOTTOMRIGHT, control, BOTTOMRIGHT, -3, -3) + control.scroll = GetControl(control.container, "ScrollChild") + control.scroll:SetResizeToFitPadding(0, 20) + + if panelData.registerForDefaults then + control.defaultButton = wm:CreateControlFromVirtual(nil, control, "ZO_DefaultTextButton") + local defaultButton = control.defaultButton + defaultButton:SetFont("ZoFontDialogKeybindDescription") + defaultButton:SetHorizontalAlignment(TEXT_ALIGN_LEFT) + --defaultButton:SetText("Reset To Defaults") + defaultButton:SetText(GetString(SI_OPTIONS_RESET_TITLE)) + defaultButton:SetDimensions(200, 30) + defaultButton:SetAnchor(TOPLEFT, control, BOTTOMLEFT, 0, 2) + defaultButton:SetHandler("OnClicked", function() + ZO_Dialogs_ShowDialog("LAM_DEFAULTS", {control}) + end) + end + + if panelData.registerForRefresh and not callbackRegistered then --don't want to register our callback more than once + cm:RegisterCallback("LAM-RefreshPanel", RefreshPanel) + callbackRegistered = true + end + + control.data = panelData + control.controlsToRefresh = {} + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/slider.lua b/libs/LibAddonMenu-2.0/controls/slider.lua new file mode 100644 index 0000000..f7ab0a3 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/slider.lua @@ -0,0 +1,184 @@ +--[[sliderData = { + type = "slider", + name = "My Slider", + tooltip = "Slider's tooltip text.", + min = 0, + max = 20, + step = 1, --(optional) + getFunc = function() return db.var end, + setFunc = function(value) db.var = value doStuff() end, + width = "full", --or "half" (optional) + disabled = function() return db.someBooleanSetting end, --or boolean (optional) + warning = "Will need to reload the UI.", --(optional) + default = defaults.var, --(optional) + reference = "MyAddonSlider" --(optional) unique global reference to control +} ]] + + +local widgetVersion = 5 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("slider", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local cm = CALLBACK_MANAGER +local round = zo_round +local strformat = string.format +local tinsert = table.insert + +local function UpdateDisabled(control) + local disable + if type(control.data.disabled) == "function" then + disable = control.data.disabled() + else + disable = control.data.disabled + end + + control.slider:SetEnabled(not disable) + control.slidervalue:SetEditEnabled(not disable) + if disable then + control.label:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + control.minText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + control.maxText:SetColor(ZO_DEFAULT_DISABLED_COLOR:UnpackRGBA()) + control.slidervalue:SetColor(ZO_DEFAULT_DISABLED_MOUSEOVER_COLOR:UnpackRGBA()) + else + control.label:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + control.minText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + control.maxText:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + control.slidervalue:SetColor(ZO_DEFAULT_ENABLED_COLOR:UnpackRGBA()) + end +end + +local function UpdateValue(control, forceDefault, value) + if forceDefault then --if we are forcing defaults + value = control.data.default + control.data.setFunc(value) + elseif value and value >= control.data.min and value <= control.data.max then + control.data.setFunc(value) + --after setting this value, let's refresh the others to see if any should be disabled or have their settings changed + if control.panel.data.registerForRefresh then + cm:FireCallbacks("LAM-RefreshPanel", control) + end + else + value = control.data.getFunc() + end + + control.slider:SetValue(value) + control.slidervalue:SetText(value) +end + + +function LAMCreateControl.slider(parent, sliderData, controlName) + local control = wm:CreateTopLevelWindow(controlName or sliderData.reference) + control:SetParent(parent.scroll or parent) + local isHalfWidth = sliderData.width == "half" + if isHalfWidth then + control:SetDimensions(250, 55) + else + control:SetDimensions(510, 40) + end + control:SetMouseEnabled(true) + --control.tooltipText = sliderData.tooltip + control:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + control:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + + control.label = wm:CreateControl(nil, control, CT_LABEL) + local label = control.label + label:SetFont("ZoFontWinH4") + label:SetDimensions(isHalfWidth and 250 or 300, 26) + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetAnchor(isHalfWidth and TOPLEFT or LEFT) + label:SetText(sliderData.name) + + --skipping creating the backdrop... Is this the actual slider texture? + control.slider = wm:CreateControl(nil, control, CT_SLIDER) + local slider = control.slider + slider:SetDimensions(190, 14) + if isHalfWidth then + slider:SetAnchor(TOPRIGHT, label, BOTTOMRIGHT, -5, 2) + else + slider:SetAnchor(RIGHT, control, RIGHT, -5, -5) + end + slider:SetMouseEnabled(true) + slider:SetOrientation(ORIENTATION_HORIZONTAL) + --put nil for highlighted texture file path, and what look to be texture coords + slider:SetThumbTexture("EsoUI\\Art\\Miscellaneous\\scrollbox_elevator.dds", "EsoUI\\Art\\Miscellaneous\\scrollbox_elevator_disabled.dds", nil, 8, 16) + local minValue = sliderData.min + local maxValue = sliderData.max + slider:SetMinMax(minValue, maxValue) + slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseEnter(control) end) + slider:SetHandler("OnMouseEnter", function() ZO_Options_OnMouseExit(control) end) + + slider.bg = wm:CreateControl(nil, slider, CT_BACKDROP) + local bg = slider.bg + bg:SetCenterColor(0, 0, 0) + bg:SetAnchor(TOPLEFT, slider, TOPLEFT, 0, 4) + bg:SetAnchor(BOTTOMRIGHT, slider, BOTTOMRIGHT, 0, -4) + bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-SliderBackdrop.dds", 32, 4) + + control.minText = wm:CreateControl(nil, slider, CT_LABEL) + local minText = control.minText + minText:SetFont("ZoFontGameSmall") + minText:SetAnchor(TOPLEFT, slider, BOTTOMLEFT) + minText:SetText(sliderData.min) + + control.maxText = wm:CreateControl(nil, slider, CT_LABEL) + local maxText = control.maxText + maxText:SetFont("ZoFontGameSmall") + maxText:SetAnchor(TOPRIGHT, slider, BOTTOMRIGHT) + maxText:SetText(sliderData.max) + + control.slidervalueBG = wm:CreateControlFromVirtual(nil, slider, "ZO_EditBackdrop") + control.slidervalueBG:SetDimensions(50, 16) + control.slidervalueBG:SetAnchor(TOP, slider, BOTTOM, 0, 0) + control.slidervalue = wm:CreateControlFromVirtual(nil, control.slidervalueBG, "ZO_DefaultEditForBackdrop") + local slidervalue = control.slidervalue + slidervalue:ClearAnchors() + slidervalue:SetAnchor(TOPLEFT, slidervaluebg, TOPLEFT, 3, 1) + slidervalue:SetAnchor(BOTTOMRIGHT, slidervaluebg, BOTTOMRIGHT, -3, -1) + slidervalue:SetTextType(TEXT_TYPE_NUMERIC) + slidervalue:SetFont("ZoFontGameSmall") + slidervalue:SetHandler("OnEscape", function(self) + self:LoseFocus() + control:UpdateValue() + end) + slidervalue:SetHandler("OnEnter", function(self) + self:LoseFocus() + control:UpdateValue(false, tonumber(self:GetText())) + end) + + local range = maxValue - minValue + slider:SetValueStep(sliderData.step or 1) + slider:SetHandler("OnValueChanged", function(self, value, eventReason) + if eventReason == EVENT_REASON_SOFTWARE then return end + self:SetValue(value) --do we actually need this line? + slidervalue:SetText(value) + end) + slider:SetHandler("OnSliderReleased", function(self, value) + --sliderData.setFunc(value) + control:UpdateValue(false, value) --does this work here instead? + end) + + if sliderData.warning then + control.warning = wm:CreateControlFromVirtual(nil, control, "ZO_Options_WarningIcon") + control.warning:SetAnchor(RIGHT, slider, LEFT, -5, 0) + --control.warning.tooltipText = sliderData.warning + control.warning.data = {tooltipText = sliderData.warning} + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is the submenu's parent + control.data = sliderData + control.data.tooltipText = sliderData.tooltip + + if sliderData.disabled then + control.UpdateDisabled = UpdateDisabled + control:UpdateDisabled() + end + control.UpdateValue = UpdateValue + control:UpdateValue() + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end \ No newline at end of file diff --git a/libs/LibAddonMenu-2.0/controls/submenu.lua b/libs/LibAddonMenu-2.0/controls/submenu.lua new file mode 100644 index 0000000..761dda5 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/submenu.lua @@ -0,0 +1,123 @@ +--[[submenuData = { + type = "submenu", + name = "Submenu Title", + tooltip = "My submenu tooltip", --(optional) + controls = {sliderData, buttonData} --(optional) used by LAM + reference = "MyAddonSubmenu" --(optional) unique global reference to control +} ]] + +local widgetVersion = 7 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("submenu", widgetVersion) then return end + +local wm = WINDOW_MANAGER +local am = ANIMATION_MANAGER +local tinsert = table.insert + + +local function UpdateValue(control) + control.label:SetText(control.data.name) + if control.data.tooltip then + --control.label.tooltipText = control.data.tooltip + control.label.data = {tooltipText = control.data.tooltip} + end +end + +local function AnimateSubmenu(clicked) + local control = clicked:GetParent() + control.open = not control.open + + if control.open then + control.animation:PlayFromStart() + else + control.animation:PlayFromEnd() + end +end + + +function LAMCreateControl.submenu(parent, submenuData, controlName) + local control = wm:CreateTopLevelWindow(controlName or submenuData.reference) + control:SetParent(parent.scroll or parent) + control.panel = parent + control:SetDimensions(523, 40) + + control.label = wm:CreateControlFromVirtual(nil, control, "ZO_Options_SectionTitleLabel") + local label = control.label + label:SetAnchor(TOPLEFT, control, TOPLEFT, 5, 5) + label:SetDimensions(520, 30) + label:SetWrapMode(TEXT_WRAP_MODE_ELLIPSIS) + label:SetText(submenuData.name) + label:SetMouseEnabled(true) + if submenuData.tooltip then + --label.tooltipText = submenuData.tooltip + label.data = {tooltipText = submenuData.tooltip} + label:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + label:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) + end + + control.scroll = wm:CreateControl(nil, control, CT_SCROLL) + local scroll = control.scroll + scroll:SetParent(control) + scroll:SetAnchor(TOPLEFT, label, BOTTOMLEFT, 0, 10) + scroll:SetDimensionConstraints(525, 0, 525, 2500) + + control.bg = wm:CreateControl(nil, label, CT_BACKDROP) + local bg = control.bg + bg:SetAnchor(TOPLEFT, label, TOPLEFT, -5, -5) + bg:SetAnchor(BOTTOMRIGHT, scroll, BOTTOMRIGHT, -7, 0) + bg:SetEdgeTexture("EsoUI\\Art\\Tooltips\\UI-Border.dds", 128, 16) + bg:SetCenterTexture("EsoUI\\Art\\Tooltips\\UI-TooltipCenter.dds") + bg:SetInsets(16, 16, -16, -16) + + control.arrow = wm:CreateControl(nil, bg, CT_TEXTURE) + local arrow = control.arrow + arrow:SetDimensions(28, 28) + arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds") --list_sortup for the other way + arrow:SetAnchor(TOPRIGHT, bg, TOPRIGHT, -5, 5) + + --figure out the cool animation later... + control.animation = am:CreateTimeline() + local animation = control.animation + animation:SetPlaybackType(ANIMATION_SIZE, 0) --2nd arg = loop count + --animation:SetDuration(1) + --animation:SetEasingFunction(ZO_LinearEase) --is this needed? + --animation:SetHeightStartAndEnd(40, 80) --SetStartAndEndHeight + --animation:SetStartAndEndHeight(40, 80) --SetStartAndEndHeight + --animation:SetAnimatedControl(control) + + control:SetResizeToFitDescendents(true) + control.open = false + label:SetHandler("OnMouseUp", AnimateSubmenu) + animation:SetHandler("OnStop", function(self, completedPlaying) + scroll:SetResizeToFitDescendents(control.open) + if control.open then + control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortup.dds") + scroll:SetResizeToFitPadding(5, 20) + else + control.arrow:SetTexture("EsoUI\\Art\\Miscellaneous\\list_sortdown.dds") + scroll:SetResizeToFitPadding(5, 0) + scroll:SetHeight(0) + end + end) + + --small strip at the bottom of the submenu that you can click to close it + control.btmToggle = wm:CreateControl(nil, control, CT_TEXTURE) + local btmToggle = control.btmToggle + btmToggle:SetMouseEnabled(true) + btmToggle:SetAnchor(BOTTOMLEFT, control.scroll, BOTTOMLEFT) + btmToggle:SetAnchor(BOTTOMRIGHT, control.scroll, BOTTOMRIGHT) + btmToggle:SetHeight(15) + btmToggle:SetAlpha(0) + btmToggle:SetHandler("OnMouseUp", AnimateSubmenu) + + control.data = submenuData + + control.UpdateValue = UpdateValue + + if control.panel.data.registerForRefresh or control.panel.data.registerForDefaults then --if our parent window wants to refresh controls, then add this to the list + tinsert(control.panel.controlsToRefresh, control) + end + + return control +end + diff --git a/libs/LibAddonMenu-2.0/controls/texture.lua b/libs/LibAddonMenu-2.0/controls/texture.lua new file mode 100644 index 0000000..928ab82 --- /dev/null +++ b/libs/LibAddonMenu-2.0/controls/texture.lua @@ -0,0 +1,51 @@ +--[[textureData = { + type = "texture", + image = "file/path.dds", + imageWidth = 64, --max of 250 for half width, 510 for full + imageHeight = 32, --max of 100 + tooltip = "Image's tooltip text.", --(optional) + width = "full", --or "half" (optional) + reference = "MyAddonTexture" --(optional) unique global reference to control +} ]] + +--add texture coords support? + +local widgetVersion = 5 +local LAM = LibStub("LibAddonMenu-2.0") +if not LAM:RegisterWidget("texture", widgetVersion) then return end + +local wm = WINDOW_MANAGER + +function LAMCreateControl.texture(parent, textureData, controlName) + local control = wm:CreateTopLevelWindow(controlName or textureData.reference) + control:SetResizeToFitDescendents(true) + control:SetParent(parent.scroll or parent) + + local isHalfWidth = textureData.width == "half" + if isHalfWidth then + control:SetDimensionConstraints(250, 55, 250, 100) + control:SetDimensions(250, 55) + else + control:SetDimensionConstraints(510, 30, 510, 100) + control:SetDimensions(510, 30) + end + + control.texture = wm:CreateControl(nil, control, CT_TEXTURE) + local texture = control.texture + texture:SetAnchor(CENTER) + texture:SetDimensions(textureData.imageWidth, textureData.imageHeight) + texture:SetTexture(textureData.image) + + if textureData.tooltip then + texture:SetMouseEnabled(true) + --texture.tooltipText = textureData.tooltip + texture.data = {tooltipText = textureData.tooltip} + texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) + texture:SetHandler("OnMouseEnter", ZO_Options_OnMouseExit) + end + + control.panel = parent.panel or parent --if this is in a submenu, panel is its parent + control.data = textureData + + return control +end \ No newline at end of file diff --git a/libs/LibStub/LibStub.lua b/libs/LibStub/LibStub.lua old mode 100755 new mode 100644 index bfd96df..879d132 --- a/libs/LibStub/LibStub.lua +++ b/libs/LibStub/LibStub.lua @@ -3,7 +3,7 @@ -- LibStub developed for World of Warcraft by above members of the WowAce community. -- Ported to Elder Scrolls Online by Seerah -local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 1 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! +local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! local LibStub = _G[LIBSTUB_MAJOR] local strformat = string.format @@ -24,7 +24,7 @@ if not LibStub or LibStub.minor < LIBSTUB_MINOR then function LibStub:GetLibrary(major, silent) if not self.libs[major] and not silent then - error(("Cannot find a library instance of %q."):strformat(tostring(major)), 2) + error(strformat("Cannot find a library instance of %q.", tostring(major)), 2) end return self.libs[major], self.minors[major] end