mirror of
https://github.com/sica42/RollFor.git
synced 2025-10-26 12:06:49 +00:00
New options GUI
This commit is contained in:
parent
7b5a5c6a63
commit
646542e716
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
update.sh
|
||||
@ -1,7 +1,7 @@
|
||||
## Interface: 11200
|
||||
## Title: RollFor
|
||||
## Author: Obszczymucha
|
||||
## Version: 4.7.4
|
||||
## Version: 4.7.5
|
||||
## Notes: An automated item roller with soft ressing support via raidres.fly.dev.
|
||||
## SavedVariables: RollForDb
|
||||
## SavedVariablesPerCharacter: RollForCharDb
|
||||
@ -65,6 +65,8 @@ src\AutoMasterLoot.lua
|
||||
src\RollTracker.lua
|
||||
src\RollController.lua
|
||||
src\RollingPopup.lua
|
||||
src\OptionsGuiElements.lua
|
||||
src\OptionsPopup.lua
|
||||
src\WinnersPopup.lua
|
||||
src\WinnersPopupGui.lua
|
||||
src\ConfirmPopup.lua
|
||||
|
||||
21
main.lua
21
main.lua
@ -134,7 +134,7 @@ local function create_components()
|
||||
---@type TooltipReader
|
||||
M.tooltip_reader = m.TooltipReader.new( M.api() )
|
||||
|
||||
-- TODO: Add type.
|
||||
---@type VersionBroadcast
|
||||
M.version_broadcast = m.VersionBroadcast.new( db( "version_broadcast" ), M.player_info, version.str )
|
||||
|
||||
---@type AwardedLoot
|
||||
@ -295,7 +295,7 @@ local function create_components()
|
||||
|
||||
---@type WinnersPopup
|
||||
M.winners_popup = m.WinnersPopup.new(
|
||||
popup_builder (),
|
||||
popup_builder(),
|
||||
m.FrameBuilder,
|
||||
db( "winners_popup" ),
|
||||
M.awarded_loot,
|
||||
@ -304,6 +304,18 @@ local function create_components()
|
||||
M.config
|
||||
)
|
||||
|
||||
---@type OptionsPopup
|
||||
M.options_popup = m.OptionsPopup.new(
|
||||
popup_builder(),
|
||||
M.awarded_loot,
|
||||
M.version_broadcast,
|
||||
M.config_event_bus,
|
||||
M.confirm_popup,
|
||||
db( "options_popup" ),
|
||||
db( "config" ),
|
||||
M.config
|
||||
)
|
||||
|
||||
-- TODO: Add type.
|
||||
M.softres_gui = m.SoftResGui.new( M.api, M.import_encoded_softres_data, M.softres_check, M.softres, clear_data, M.dropped_loot_announce.reset )
|
||||
|
||||
@ -314,7 +326,7 @@ local function create_components()
|
||||
M.usage_printer = m.UsagePrinter.new( M.chat )
|
||||
|
||||
-- TODO: Add type.
|
||||
M.minimap_button = m.MinimapButton.new( M.api, db( "minimap_button" ), M.softres_gui.toggle, M.winners_popup.toggle, M.softres_check, M.config )
|
||||
M.minimap_button = m.MinimapButton.new( M.api, db( "minimap_button" ), M.softres_gui.toggle, M.winners_popup.toggle, M.options_popup.toggle, M.softres_check, M.config )
|
||||
|
||||
-- TODO: Add type.
|
||||
M.master_loot_warning = m.MasterLootWarning.new( M.api, M.config, m.BossList.zones, M.player_info )
|
||||
@ -717,6 +729,9 @@ local function setup_slash_commands()
|
||||
|
||||
SLASH_RFW1 = "/rfw"
|
||||
M.api().SlashCmdList[ "RFW" ] = M.winners_popup.show
|
||||
SLASH_RFO1 = "/rfo"
|
||||
M.api().SlashCmdList[ "RFO" ] = M.options_popup.show
|
||||
|
||||
SLASH_RFT1 = "/rft"
|
||||
M.api().SlashCmdList[ "RFT" ] = M.sandbox.run
|
||||
|
||||
|
||||
@ -113,7 +113,6 @@ function M.new( db, group_roster, config )
|
||||
M.debug.add( "clear" )
|
||||
if not config.keep_award_data() or force then
|
||||
m.clear_table( db.awarded_items )
|
||||
--db.awarded_items.n = 0
|
||||
notify_subscribers( 'award_data_updated' )
|
||||
end
|
||||
end
|
||||
|
||||
@ -276,6 +276,11 @@ function M.new( ace_timer, player_info, rolling_popup, config )
|
||||
|
||||
if show_rolling then
|
||||
if command == "ROLL" then
|
||||
if not data.player_name then
|
||||
M.debug.add ( "No player_name on roll" )
|
||||
return
|
||||
end
|
||||
|
||||
roll_tracker.add( data.player_name, data.player_class, data.roll_type, data.roll )
|
||||
if data.player_name == player_info.get_name() then
|
||||
player_can_roll = false
|
||||
@ -335,7 +340,8 @@ function M.new( ace_timer, player_info, rolling_popup, config )
|
||||
tie_content()
|
||||
elseif command == "AWARDED" then
|
||||
if data.player_name == player_info.get_name() then
|
||||
m.api.PlaySound( "QUESTCOMPLETED" )
|
||||
m.api.PlaySound( "RaidWarning" )
|
||||
m.api.PlaySound( "PVPTHROUGHQUEUE" )
|
||||
end
|
||||
|
||||
if config.client_auto_hide_popup() then
|
||||
|
||||
@ -55,7 +55,7 @@ function M.new( roll_controller, softres, config )
|
||||
end
|
||||
|
||||
local tex = data.item.texture and string.gsub( data.item.texture, "Interface\\Icons\\", "" ) or ""
|
||||
local tmog_rolling_enabled = config.tmog_rolling_enabled() and (data.item.is_boss_loot or not config.auto_tmog_disable() )
|
||||
local tmog_rolling_enabled = config.tmog_rolling_enabled() and (data.item.is_boss_loot or not config.auto_tmog() )
|
||||
local softressing_players = softres.get( data.item.id )
|
||||
local sr_players = {}
|
||||
for _, player in ipairs( softressing_players ) do
|
||||
|
||||
@ -54,7 +54,7 @@ function M.new( db, event_bus )
|
||||
if not db.tmog_roll_threshold then db.tmog_roll_threshold = 98 end
|
||||
if not db.superwow_auto_loot_coins then db.superwow_auto_loot_coins = true end
|
||||
if db.tmog_rolling_enabled == nil then db.tmog_rolling_enabled = true end
|
||||
if db.auto_tmog_disable == nil then db.auto_tmog_disable = false end
|
||||
if db.auto_tmog == nil then db.auto_tmog = false end
|
||||
if db.show_ml_warning == nil then db.show_ml_warning = false end
|
||||
if db.default_rolling_time_seconds == nil then db.default_rolling_time_seconds = 8 end
|
||||
if db.master_loot_frame_rows == nil then db.master_loot_frame_rows = 5 end
|
||||
@ -499,11 +499,9 @@ function M.new( db, event_bus )
|
||||
client_show_roll_popup = get( "client_show_roll_popup" ),
|
||||
client_auto_hide_popup = get( "client_auto_hide_popup" ),
|
||||
enable_client_roll_popup = enable_client_roll_popup,
|
||||
auto_tmog_disable = get( "auto_tmog_disable" ),
|
||||
auto_class_announce = get( "auto_class_announce" ),
|
||||
award_filter = get( "award_filter" ),
|
||||
keep_award_data = get( "keep_award_data" ),
|
||||
loot_frame_cursor = get( "loot_frame_cursor" )
|
||||
notify_subscribers = notify_subscribers
|
||||
}
|
||||
|
||||
for toggle_key, _ in pairs( toggles ) do
|
||||
|
||||
@ -316,12 +316,7 @@ function M.tiny_button( parent, text, tooltip, color, font_size )
|
||||
button:SetWidth( 18 )
|
||||
button:SetHeight( 18 )
|
||||
|
||||
local highlight_texture = button:CreateTexture( nil, "HIGHLIGHT" )
|
||||
highlight_texture:SetTexture( "Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight" )
|
||||
highlight_texture:SetTexCoord( .1875, .78125, .21875, .78125 )
|
||||
highlight_texture:SetBlendMode( "ADD" )
|
||||
highlight_texture:SetAllPoints( button )
|
||||
|
||||
button:SetHighlightTexture( "Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight" )
|
||||
if text == 'X' then
|
||||
button:SetNormalTexture( "Interface\\Buttons\\UI-Panel-MinimizeButton-Up" )
|
||||
button:SetPushedTexture( "Interface\\Buttons\\UI-Panel-MinimizeButton-Down" )
|
||||
@ -329,6 +324,7 @@ function M.tiny_button( parent, text, tooltip, color, font_size )
|
||||
button:SetNormalTexture( "Interface\\AddOns\\RollFor\\assets\\tiny-button-up.tga" )
|
||||
button:SetPushedTexture( "Interface\\AddOns\\RollFor\\assets\\tiny-button-down.tga" )
|
||||
end
|
||||
button:GetHighlightTexture():SetTexCoord( .1875, .78125, .21875, .78125 )
|
||||
button:GetNormalTexture():SetTexCoord( .1875, .78125, .21875, .78125 )
|
||||
button:GetPushedTexture():SetTexCoord( .1875, .78125, .21875, .78125 )
|
||||
|
||||
@ -389,7 +385,7 @@ function M.tiny_button( parent, text, tooltip, color, font_size )
|
||||
end )
|
||||
button:SetScript( "OnLeave", function()
|
||||
local self = button
|
||||
if not self.active then
|
||||
if not self.active and not m.classic then
|
||||
self:SetBackdropBorderColor( .2, .2, .2, 1 )
|
||||
end
|
||||
if tooltip and m.api.GameTooltip:IsVisible() then
|
||||
@ -502,22 +498,23 @@ function M.titlebar( parent, title, on_close )
|
||||
end
|
||||
|
||||
local label = frame:CreateFontString( nil, "ARTWORK", "GameFontNormalSmall" )
|
||||
label:SetPoint( "TOPLEFT", 10, -12 )
|
||||
label:SetPoint( "TOPLEFT", 8, m.classic and -11 or -13 )
|
||||
label:SetPoint( "RIGHT", m.classic and -29 or 0, 0 )
|
||||
label:SetJustifyH( "CENTER" )
|
||||
label:SetTextColor( 1, 1, 1 )
|
||||
label:SetText( title )
|
||||
frame.title = label
|
||||
|
||||
local btn_close = M.tiny_button( parent, "X", "Close Window" )
|
||||
btn_close:SetPoint( "TOPRIGHT", m.classic and -7 or -5, -5 )
|
||||
btn_close:SetScript( "OnClick", function()
|
||||
local close_btn = M.tiny_button( parent, "X", "Close Window" )
|
||||
close_btn:SetPoint( "TOPRIGHT", -7, m.classic and -5 or -7 )
|
||||
close_btn:SetScript( "OnClick", function()
|
||||
if on_close then
|
||||
on_close()
|
||||
else
|
||||
if parent then parent:Hide() end
|
||||
end
|
||||
end )
|
||||
frame.close_btn = close_btn
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
@ -20,7 +20,7 @@ local ColorType = {
|
||||
Red = "Red"
|
||||
}
|
||||
|
||||
function M.new( api, db, manage_softres_fn, winners_popup_fn, softres_check, config )
|
||||
function M.new( api, db, manage_softres_fn, winners_popup_fn, options_popup_fn, softres_check, config )
|
||||
local icon_color
|
||||
|
||||
local function persist_angle( angle )
|
||||
@ -60,6 +60,8 @@ function M.new( api, db, manage_softres_fn, winners_popup_fn, softres_check, con
|
||||
|
||||
if m.is_shift_key_down() then
|
||||
winners_popup_fn()
|
||||
elseif m.is_ctrl_key_down() then
|
||||
options_popup_fn()
|
||||
else
|
||||
manage_softres_fn()
|
||||
end
|
||||
|
||||
@ -62,7 +62,7 @@ function M.new(
|
||||
local os_threshold = config.os_roll_threshold()
|
||||
local tmog_threshold = config.tmog_roll_threshold()
|
||||
local tmog_rolling_enabled = config.tmog_rolling_enabled()
|
||||
tmog_rolling_enabled = tmog_rolling_enabled and (item.is_boss_loot or not config.auto_tmog_disable() )
|
||||
tmog_rolling_enabled = tmog_rolling_enabled and (item.is_boss_loot or not config.auto_tmog() )
|
||||
|
||||
local function sort_rolls()
|
||||
local f = function( a, b )
|
||||
|
||||
416
src/OptionsGuiElements.lua
Normal file
416
src/OptionsGuiElements.lua
Normal file
@ -0,0 +1,416 @@
|
||||
RollFor = RollFor or {}
|
||||
local m = RollFor
|
||||
|
||||
if m.OptionsGuiElements then return end
|
||||
|
||||
---@class OptionsGuiElements
|
||||
---@field create_gui_entry fun( title: string, frames: Frame, populate: function )
|
||||
---@field entry_update fun()
|
||||
---@field create_backdrop fun( f: table, insert: number?, legacy: boolean?, transp: number?, backdropSetting: table? )
|
||||
---@field create_scroll_child fun( name: string, parent: Frame ): Frame
|
||||
---@field create_tab_frame fun( parent: table, title: string ): Frame
|
||||
---@field create_area fun( parent: table, title: string, func: function ): Frame
|
||||
---@field create_config fun( caption: string, setting: any, widget: string, tooltip: string?, ufunc: function? )
|
||||
|
||||
local M = {}
|
||||
|
||||
local function get_perfect_pixel()
|
||||
if M.pixel then return M.pixel end
|
||||
|
||||
local scale = m.api.GetCVar( "uiScale" )
|
||||
local resolution = m.api.GetCVar( "gxResolution" )
|
||||
local _, _, _, screenheight = string.find( resolution, "(.+)x(.+)" )
|
||||
|
||||
M.pixel = 768 / screenheight / scale
|
||||
M.pixel = M.pixel > 1 and 1 or M.pixel
|
||||
|
||||
return M.pixel
|
||||
end
|
||||
|
||||
function M.set_all_points_offset( frame, parent, offset )
|
||||
frame:SetPoint( "TOPLEFT", parent, "TOPLEFT", offset, -offset )
|
||||
frame:SetPoint( "BOTTOMRIGHT", parent, "BOTTOMRIGHT", -offset, offset )
|
||||
end
|
||||
|
||||
---@param title string
|
||||
---@param frames table
|
||||
---@param populate function
|
||||
function M.create_gui_entry( title, frames, populate )
|
||||
if not frames[ title ] then
|
||||
frames[ title ] = M.create_tab_frame( frames, title )
|
||||
frames[ title ].area = M.create_area( frames, title, populate )
|
||||
end
|
||||
end
|
||||
|
||||
function M.entry_update()
|
||||
if m.api.MouseIsOver( this ) and not this.over then
|
||||
this.tex:Show()
|
||||
this.over = true
|
||||
if this:GetParent():GetParent():GetParent():GetParent():GetParent().show_help then
|
||||
if this.tooltip then
|
||||
this:GetParent().tooltip = this
|
||||
m.api.GameTooltip:SetOwner( this, "ANCHOR_TOPLEFT" )
|
||||
m.api.GameTooltip:SetText( this.tooltip )
|
||||
m.api.GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
elseif not m.api.MouseIsOver( this ) and this.over then
|
||||
this.tex:Hide()
|
||||
this.over = nil
|
||||
if m.api.GameTooltip:IsShown() and this:GetParent().tooltip == this then
|
||||
m.api.GameTooltip:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.create_backdrop( f, inset, legacy, transp, backdropSetting )
|
||||
if not f then return end
|
||||
|
||||
local border = get_perfect_pixel()
|
||||
if inset then border = inset end
|
||||
|
||||
local br, bg, bb, ba = 0, 0, 0, 1
|
||||
local dr, dg, db, da = 0.2, 0.2, 0.2, 1
|
||||
local backdrop = {
|
||||
bgFile = "Interface\\BUTTONS\\WHITE8X8",
|
||||
tile = false,
|
||||
tileSize = 0,
|
||||
edgeFile = "Interface\\BUTTONS\\WHITE8X8",
|
||||
edgeSize = M.pixel,
|
||||
insets = { left = -M.pixel, right = -M.pixel, top = -M.pixel, bottom = -M.pixel },
|
||||
}
|
||||
|
||||
if transp and transp < tonumber( ba ) then ba = transp end
|
||||
|
||||
if legacy then
|
||||
if backdropSetting then f:SetBackdrop( backdropSetting ) end
|
||||
f:SetBackdrop( backdrop )
|
||||
f:SetBackdropColor( br, bg, bb, ba )
|
||||
f:SetBackdropBorderColor( dr, dg, db, da )
|
||||
else
|
||||
if not f.backdrop then
|
||||
if f:GetBackdrop() then f:SetBackdrop( nil ) end
|
||||
|
||||
local b = m.api.CreateFrame( "Frame", nil, f )
|
||||
local level = f:GetFrameLevel()
|
||||
if level < 1 then
|
||||
b:SetFrameLevel( level )
|
||||
else
|
||||
b:SetFrameLevel( level - 1 )
|
||||
end
|
||||
|
||||
f.backdrop = b
|
||||
end
|
||||
|
||||
f.backdrop:SetPoint( "TOPLEFT", f, "TOPLEFT", -border, border )
|
||||
f.backdrop:SetPoint( "BOTTOMRIGHT", f, "BOTTOMRIGHT", border, -border )
|
||||
f.backdrop:SetBackdrop( backdrop )
|
||||
f.backdrop:SetBackdropColor( br, bg, bb, ba )
|
||||
f.backdrop:SetBackdropBorderColor( dr, dg, db, da )
|
||||
end
|
||||
end
|
||||
|
||||
function M.create_scroll_frame( parent, name )
|
||||
local f = m.api.CreateFrame( "ScrollFrame", name, parent )
|
||||
|
||||
f.slider = m.api.CreateFrame( "Slider", nil, f )
|
||||
f.slider:SetOrientation( 'VERTICAL' )
|
||||
f.slider:SetPoint( "TOPLEFT", f, "TOPRIGHT", m.classic and -13 or -7, 0 )
|
||||
f.slider:SetPoint( "BOTTOMRIGHT", 0, 0 )
|
||||
f.slider:SetThumbTexture( "Interface\\BUTTONS\\WHITE8X8" )
|
||||
f.slider.thumb = f.slider:GetThumbTexture()
|
||||
f.slider.thumb:SetHeight( 50 )
|
||||
f.slider.thumb:SetTexture( .125, .624, .976, .5 )
|
||||
|
||||
f.slider:SetScript( "OnValueChanged", function()
|
||||
f:SetVerticalScroll( this:GetValue() )
|
||||
f.update_scroll_state()
|
||||
end )
|
||||
|
||||
f.update_scroll_state = function()
|
||||
f.slider:SetMinMaxValues( 0, f:GetVerticalScrollRange() )
|
||||
f.slider:SetValue( f:GetVerticalScroll() )
|
||||
|
||||
local r = f:GetHeight() + f:GetVerticalScrollRange()
|
||||
local v = f:GetHeight()
|
||||
local ratio = v / r
|
||||
|
||||
if ratio < 1 then
|
||||
local size = math.floor( v * ratio )
|
||||
f.slider.thumb:SetHeight( size )
|
||||
f.slider:Show()
|
||||
else
|
||||
f.slider:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
f.scroll = function( self, step )
|
||||
step = step or 0
|
||||
|
||||
local current = f:GetVerticalScroll()
|
||||
local max = f:GetVerticalScrollRange()
|
||||
local new = current - step
|
||||
|
||||
if new >= max then
|
||||
f:SetVerticalScroll( max )
|
||||
elseif new <= 0 then
|
||||
f:SetVerticalScroll( 0 )
|
||||
else
|
||||
f:SetVerticalScroll( new )
|
||||
end
|
||||
|
||||
f:update_scroll_state()
|
||||
end
|
||||
|
||||
f:EnableMouseWheel( 1 )
|
||||
f:SetScript( "OnMouseWheel", function()
|
||||
this:scroll( arg1 * 10 )
|
||||
end )
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
function M.create_scroll_child( parent, name )
|
||||
local f = m.api.CreateFrame( "Frame", name, parent )
|
||||
|
||||
-- dummy values required
|
||||
f:SetWidth( 1 )
|
||||
f:SetHeight( 1 )
|
||||
f:SetAllPoints( parent )
|
||||
|
||||
parent:SetScrollChild( f )
|
||||
|
||||
f:SetScript( "OnUpdate", function()
|
||||
this:GetParent():update_scroll_state()
|
||||
end )
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
function M.create_tab_frame( parent, title )
|
||||
if not parent.tab_area.count then parent.tab_area.count = 0 end
|
||||
|
||||
local f = m.api.CreateFrame( "Button", nil, parent.tab_area )
|
||||
f:SetPoint( "TOPLEFT", parent.tab_area, "TOPLEFT", parent.tab_area.count * 80, 0 )
|
||||
f:SetPoint( "BOTTOMRIGHT", parent.tab_area, "TOPLEFT", (parent.tab_area.count + 1) * 80, -20 )
|
||||
f.parent = parent
|
||||
|
||||
f:SetScript( "OnClick", function()
|
||||
if this.area:IsShown() then
|
||||
return
|
||||
else
|
||||
for id, name in pairs( this.parent ) do
|
||||
if type( name ) == "table" and name.area and id ~= "parent" then
|
||||
name.area:Hide()
|
||||
end
|
||||
end
|
||||
this.area:Show()
|
||||
end
|
||||
end )
|
||||
|
||||
f.bg = f:CreateTexture( nil, "BACKGROUND" )
|
||||
f.bg:SetAllPoints()
|
||||
|
||||
f.text = f:CreateFontString( nil, "LOW", "GameFontWhite" )
|
||||
f.text:SetAllPoints()
|
||||
f.text:SetText( title )
|
||||
|
||||
parent.tab_area.count = parent.tab_area.count + 1
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
function M.create_area( parent, title, func )
|
||||
local f = m.api.CreateFrame( "Frame", nil, parent.tab_area )
|
||||
f:SetPoint( "TOPLEFT", parent.tab_area, "TOPLEFT", 0, -20 )
|
||||
f:SetPoint( "BOTTOMRIGHT", parent.tab_area, "BOTTOMRIGHT", 0, 0 )
|
||||
f:Hide()
|
||||
|
||||
f.button = parent[ title ]
|
||||
f.bg = f:CreateTexture( nil, "BACKGROUND" )
|
||||
f.bg:SetTexture( 1, 1, 1, .05 )
|
||||
f.bg:SetAllPoints()
|
||||
|
||||
f:SetScript( "OnShow", function()
|
||||
this.indexed = true
|
||||
this.button.text:SetTextColor( 0.1254, 0.6235, 0.9764, 1 )
|
||||
this.button.bg:SetTexture( 1, 1, 1, 1 )
|
||||
this.button.bg:SetGradientAlpha( "VERTICAL", 1, 1, 1, .05, 0, 0, 0, 0 )
|
||||
end )
|
||||
|
||||
f:SetScript( "OnHide", function()
|
||||
this.button.text:SetTextColor( 1, 1, 1, 1 )
|
||||
this.button.bg:SetTexture( 0, 0, 0, 0 )
|
||||
end )
|
||||
|
||||
if func then
|
||||
f.scroll = M.create_scroll_frame( f )
|
||||
M.set_all_points_offset( f.scroll, f, 2 )
|
||||
f.scroll.content = M.create_scroll_child( f.scroll )
|
||||
f.scroll.content.parent = f.scroll
|
||||
f.scroll.content:SetScript( "OnShow", function()
|
||||
this.parent:UpdateScrollChildRect()
|
||||
if not this.setup then
|
||||
func()
|
||||
this.setup = true
|
||||
end
|
||||
end )
|
||||
end
|
||||
|
||||
return f
|
||||
end
|
||||
|
||||
---@param caption string
|
||||
---@param setting any|nil
|
||||
---@param widget string
|
||||
---@param tooltip string|nil
|
||||
---@param ufunc? function
|
||||
---@return Frame
|
||||
function M.create_config( caption, setting, widget, tooltip, ufunc )
|
||||
local function parse_options()
|
||||
local w = string.sub( widget, 1, (string.find( widget, "|", nil, true ) or 0) - 1 )
|
||||
local options = {}
|
||||
for key, value in string.gmatch( widget, ("|(%a+)=([^|]+)") ) do
|
||||
options[ key ] = tonumber( value ) or value
|
||||
end
|
||||
|
||||
return w, options
|
||||
end
|
||||
|
||||
this.object_count = this.object_count == nil and 0 or this.object_count + 1
|
||||
|
||||
local frame = m.api.CreateFrame( "Frame", nil, this )
|
||||
local config_db = this:GetParent():GetParent():GetParent().config_db
|
||||
|
||||
frame:SetWidth( this:GetParent():GetWidth() - 22 )
|
||||
frame:SetHeight( 22 )
|
||||
frame:SetPoint( "TOPLEFT", this, "TOPLEFT", 5, (this.object_count * -23) - 5 )
|
||||
frame.config = setting
|
||||
frame.tooltip = tooltip
|
||||
|
||||
local options
|
||||
widget, options = parse_options()
|
||||
|
||||
if not widget or (widget and widget ~= "button") then
|
||||
if widget ~= "header" then
|
||||
frame:SetScript( "OnUpdate", M.entry_update )
|
||||
frame.tex = frame:CreateTexture( nil, "BACKGROUND" )
|
||||
frame.tex:SetTexture( 1, 1, 1, .05 )
|
||||
frame.tex:SetAllPoints()
|
||||
frame.tex:Hide()
|
||||
end
|
||||
|
||||
frame.caption = frame:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
frame.caption:SetPoint( "LEFT", frame, "LEFT", 3, 1 )
|
||||
frame.caption:SetJustifyH( "LEFT" )
|
||||
frame.caption:SetText( caption )
|
||||
end
|
||||
|
||||
if widget == "header" then
|
||||
frame:SetBackdrop( nil )
|
||||
if not this.first_header then
|
||||
this.first_header = true
|
||||
frame:SetHeight( 20 )
|
||||
else
|
||||
frame:SetHeight( 40 )
|
||||
this.object_count = this.object_count + 1
|
||||
end
|
||||
frame.caption:SetJustifyH( "LEFT" )
|
||||
frame.caption:SetJustifyV( "BOTTOM" )
|
||||
frame.caption:SetTextColor( 0.1254, 0.6235, 0.9764, 1 )
|
||||
frame.caption:SetAllPoints( frame )
|
||||
end
|
||||
|
||||
if setting then
|
||||
if not widget or widget == "number" then
|
||||
frame.input = m.api.CreateFrame( "EditBox", nil, frame )
|
||||
M.create_backdrop( frame.input, nil, true )
|
||||
frame.input:SetTextInsets( 5, 5, 5, 5 )
|
||||
frame.input:SetTextColor( 0.1254, 0.6235, 0.9764, 1 )
|
||||
frame.input:SetJustifyH( "RIGHT" )
|
||||
frame.input:SetWidth( 50 )
|
||||
frame.input:SetHeight( 18 )
|
||||
frame.input:SetPoint( "RIGHT", -3, 0 )
|
||||
frame.input:SetFontObject( "GameFontNormal" )
|
||||
frame.input:SetAutoFocus( false )
|
||||
frame.input:SetText( config_db[ setting ] )
|
||||
frame.input:SetScript( "OnEscapePressed", function()
|
||||
this:ClearFocus()
|
||||
end )
|
||||
|
||||
frame.input:SetScript( "OnTextChanged", function()
|
||||
local v = tonumber( this:GetText() )
|
||||
local valid = v and ((not options.min or v >= options.min) and (not options.max or v <= options.max))
|
||||
|
||||
if valid then
|
||||
if config_db[ setting ] ~= v then
|
||||
config_db[ setting ] = v
|
||||
if ufunc then ufunc() end
|
||||
end
|
||||
this:SetTextColor( 0.1254, 0.6235, 0.9764, 1 )
|
||||
else
|
||||
this:SetTextColor( 1, .3, .3, 1 )
|
||||
end
|
||||
end )
|
||||
end
|
||||
|
||||
if widget == "checkbox" then
|
||||
frame.input = m.api.CreateFrame( "CheckButton", nil, frame, "UICheckButtonTemplate" )
|
||||
frame.input:SetNormalTexture( "" )
|
||||
frame.input:SetPushedTexture( "" )
|
||||
frame.input:SetHighlightTexture( "" )
|
||||
M.create_backdrop( frame.input, nil, true )
|
||||
frame.input:SetWidth( 14 )
|
||||
frame.input:SetHeight( 14 )
|
||||
frame.input:SetPoint( "RIGHT", -3, 1 )
|
||||
frame.input:SetScript( "OnClick", function()
|
||||
if this:GetChecked() then
|
||||
config_db[ setting ] = true
|
||||
else
|
||||
config_db [ setting ] = false
|
||||
end
|
||||
|
||||
if ufunc then ufunc() end
|
||||
end )
|
||||
|
||||
if config_db[ setting ] == true then frame.input:SetChecked() end
|
||||
end
|
||||
end
|
||||
|
||||
if widget == "button" then
|
||||
frame.button = m.api.CreateFrame( "Button", nil, frame, "UIPanelButtonTemplate" )
|
||||
M.create_backdrop( frame.button, nil, true )
|
||||
frame.button:SetNormalTexture( "" )
|
||||
frame.button:SetHighlightTexture( "" )
|
||||
frame.button:SetPushedTexture( "" )
|
||||
frame.button:SetDisabledTexture( "" )
|
||||
frame.button:SetText( caption )
|
||||
local w = frame.button:GetTextWidth() + 10
|
||||
frame.button:SetWidth( w )
|
||||
frame.button:SetHeight( 20 )
|
||||
frame.button:SetPoint( "TOPLEFT", (this:GetParent():GetWidth() / 2 - w / 2 - 10), -5 )
|
||||
frame.button:SetTextColor( 1, 1, 1, 1 )
|
||||
frame.button:SetScript( "OnClick", ufunc )
|
||||
frame.button:SetScript( "OnEnter", function()
|
||||
this:SetBackdropBorderColor( 0.1254, 0.6235, 0.9764, 1 )
|
||||
if this:GetParent():GetParent():GetParent():GetParent():GetParent():GetParent().show_help then
|
||||
if this:GetParent().tooltip then
|
||||
m.api.GameTooltip:SetOwner( this, "ANCHOR_TOPLEFT" )
|
||||
m.api.GameTooltip:SetText( this:GetParent().tooltip )
|
||||
m.api.GameTooltip:Show()
|
||||
end
|
||||
end
|
||||
end )
|
||||
frame.button:SetScript( "OnLeave", function()
|
||||
this:SetBackdropBorderColor( .2, .2, .2, 1 )
|
||||
if m.api.GameTooltip:IsShown() then
|
||||
m.api.GameTooltip:Hide()
|
||||
end
|
||||
end )
|
||||
end
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
m.OptionsGuiElements = M
|
||||
return M
|
||||
259
src/OptionsPopup.lua
Normal file
259
src/OptionsPopup.lua
Normal file
@ -0,0 +1,259 @@
|
||||
RollFor = RollFor or {}
|
||||
local m = RollFor
|
||||
|
||||
if m.OptionsPopup then return end
|
||||
|
||||
local info = m.pretty_print
|
||||
local blue = m.colors.blue
|
||||
|
||||
---@class OptionsGuiElements
|
||||
local e = m.OptionsGuiElements
|
||||
|
||||
---@class OptionsPopup
|
||||
---@field show fun( area: string )
|
||||
---@field hide fun()
|
||||
---@field toggle fun()
|
||||
|
||||
local M = m.Module.new( "OptionsPopup" )
|
||||
|
||||
M.center_point = { point = "CENTER", relative_point = "CENTER", x = 0, y = 150 }
|
||||
|
||||
---@param popup_builder PopupBuilder
|
||||
---@param awarded_loot AwardedLoot
|
||||
---@param version_broadcast VersionBroadcast
|
||||
---@param event_bus EventBus
|
||||
---@param confirm_popup ConfirmPopup
|
||||
---@param db table
|
||||
---@param config_db table
|
||||
---@param config Config
|
||||
function M.new( popup_builder, awarded_loot, version_broadcast, event_bus, confirm_popup, db, config_db, config )
|
||||
---@class Frame
|
||||
local popup
|
||||
local frames
|
||||
|
||||
local function on_drag_stop()
|
||||
if not popup then return end
|
||||
|
||||
if m.is_frame_out_of_bounds( popup ) then
|
||||
popup:position( db.point or M.center_point )
|
||||
return
|
||||
end
|
||||
|
||||
local anchor = popup:get_anchor_point()
|
||||
db.point = { point = anchor.point, relative_point = anchor.relative_point, x = anchor.x, y = anchor.y }
|
||||
end
|
||||
|
||||
local function create_popup()
|
||||
M.debug.add( "Create popup" )
|
||||
|
||||
local function notify()
|
||||
if this:GetObjectType() == "CheckButton" then
|
||||
config.notify_subscribers( this:GetParent().config, this:GetChecked() )
|
||||
else
|
||||
config.notify_subscribers( this:GetParent().config )
|
||||
end
|
||||
end
|
||||
|
||||
local frame = popup_builder
|
||||
:name( "RollForOptionsFrame" )
|
||||
:width( 400 )
|
||||
:height( 350 )
|
||||
:bg_file( "Interface/Buttons/WHITE8x8" )
|
||||
:sound()
|
||||
:movable()
|
||||
:on_drag_stop( on_drag_stop )
|
||||
:esc()
|
||||
:self_centered_anchor()
|
||||
:build()
|
||||
|
||||
if not m.classic then
|
||||
frame:backdrop_color( 0, 0, 0, .85 )
|
||||
frame:border_color( .2, .2, .2, 1 )
|
||||
end
|
||||
|
||||
local title_bar = m.GuiElements.titlebar( frame, blue( "RollFor" ) )
|
||||
title_bar.title:SetJustifyH( "LEFT" )
|
||||
|
||||
local help_btn = m.GuiElements.tiny_button( frame, "?", "Click this icon and then hover over a field for more information.", "#E6CC40" )
|
||||
help_btn:SetPoint( "RIGHT", title_bar.close_btn, "LEFT", m.classic and -4 or -5, 0 )
|
||||
help_btn:SetScript( "OnClick", function()
|
||||
this.active = not this.active
|
||||
if m.classic then
|
||||
if this.active then
|
||||
this:LockHighlight()
|
||||
else
|
||||
this:UnlockHighlight()
|
||||
end
|
||||
end
|
||||
this:GetParent().show_help = this.active
|
||||
end )
|
||||
|
||||
frames = {}
|
||||
frames.tab_area = m.api.CreateFrame( "Frame", "area", frame )
|
||||
frames.tab_area:SetPoint( "TOPLEFT", title_bar, "BOTTOMLEFT", 7, m.classic and 4 or 0 )
|
||||
frames.tab_area:SetPoint( "BOTTOMRIGHT", -7, m.classic and 9 or 7 )
|
||||
frames.tab_area.config_db = config_db
|
||||
e.create_backdrop( frames.tab_area )
|
||||
|
||||
e.create_gui_entry( "About", frames, function()
|
||||
this.title = this:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
this.title:SetFont( "FONTS\\FRIZQT__.TTF", 18 )
|
||||
this.title:SetPoint( "TOPLEFT", 0, -50 )
|
||||
this.title:SetPoint( "RIGHT", this.parent, "RIGHT", 0, 0 )
|
||||
this.title:SetJustifyH( "CENTER" )
|
||||
this.title:SetText( blue( "RollFor" ) )
|
||||
|
||||
this.versionc = this:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
this.versionc:SetPoint( "TOPLEFT", 140, -80 )
|
||||
this.versionc:SetWidth( 100 )
|
||||
this.versionc:SetJustifyH( "LEFT" )
|
||||
this.versionc:SetText( "Version:" )
|
||||
|
||||
this.version = this:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
this.version:SetPoint( "TOPRIGHT", 240, -80 )
|
||||
this.version:SetWidth( 100 )
|
||||
this.version:SetJustifyH( "RIGHT" )
|
||||
this.version:SetText( m.get_addon_version().str )
|
||||
|
||||
local new_version = version_broadcast.new_version_available()
|
||||
if new_version and m.is_new_version( m.get_addon_version().str, new_version ) then
|
||||
this.newversion = this:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
this.newversion:SetPoint( "TOPLEFT", 0, -100 )
|
||||
this.newversion:SetPoint( "RIGHT", this.parent, "RIGHT", 0, 0 )
|
||||
this.newversion:SetJustifyH( "CENTER" )
|
||||
this.newversion:SetText( string.format( "New version (%s) is available!", m.colors.highlight( string.format( "v%s", new_version ) ) ) )
|
||||
end
|
||||
|
||||
this.info = this:CreateFontString( "Status", "LOW", "GameFontWhite" )
|
||||
this.info:SetPoint( "TOPLEFT", 0, new_version and -140 or -120 )
|
||||
this.info:SetPoint( "RIGHT", this.parent, "RIGHT", 0, 0 )
|
||||
this.info:SetJustifyH( "CENTER" )
|
||||
this.info:SetText( "Check the minimap icon for new commands.\n\nBe a responsible Master Looter.\n\nHappy rolling! o7" )
|
||||
end )
|
||||
|
||||
e.create_gui_entry( "General", frames, function()
|
||||
e.create_config( "General settings", nil, "header" )
|
||||
e.create_config( "Classic look", "classic_look", "checkbox", "Toggle classic look. Requires /reload", function()
|
||||
event_bus.notify( "config_change_requires_ui_reload", { key = "classic_look" } )
|
||||
end )
|
||||
e.create_config( "Master loot warning", "show_ml_warning", "checkbox", "Show a warning if no master looter is set when targeting a boss.", notify )
|
||||
e.create_config( "Auto raid-roll", "auto_raid_roll", "checkbox", "Automatically do a raid-roll if noone rolls for an item", notify )
|
||||
e.create_config( "Auto group loot", "auto_group_loot", "checkbox", "Automatically sets loot mode back to group loot after boss is looted", notify )
|
||||
e.create_config( "Auto master loot", "auto_master_loot", "checkbox", "Automatically sets loot mode to master looter when a boss is targeted", notify )
|
||||
|
||||
e.create_config( "Minimap", "", "header" )
|
||||
e.create_config( "Hide minimap icon", "minimap_button_hidden", "checkbox", nil, notify )
|
||||
e.create_config( "Lock minimap icon", "minimap_button_locked", "checkbox", nil, notify )
|
||||
|
||||
e.create_config( "Awards data", nil, "header" )
|
||||
e.create_config( "Always keep awards data", "keep_award_data", "checkbox", "Prevents the addon from clearing award data on disconnects" )
|
||||
e.create_config( "Reset awards data", nil, "button", "Clears all the award data", function()
|
||||
if confirm_popup.is_visible() then
|
||||
confirm_popup.hide()
|
||||
return
|
||||
end
|
||||
|
||||
confirm_popup.show( { "This will clear the current winners data.", "Are you sure?" }, function( value )
|
||||
if value then
|
||||
awarded_loot.clear( true )
|
||||
end
|
||||
end )
|
||||
end )
|
||||
end )
|
||||
|
||||
e.create_gui_entry( "Looting", frames, function()
|
||||
e.create_config( "Loot settings", nil, "header" )
|
||||
e.create_config( "Master loot frame rows", "master_loot_frame_rows", "number|min=5|max=20", "Value must be between 5 and 20 rows", notify )
|
||||
e.create_config( "Auto-loot", "auto_loot", "checkbox", "Auto-loot items below loot thresold. BoP items will not be auto looted." )
|
||||
e.create_config( "Auto-loot coins with SuperWow", "superwow_auto_loot_coins", "checkbox", "Automatically loot coins (requires SuperWow mod)" )
|
||||
e.create_config( "Auto-loot messages", "auto_loot_messages", "checkbox", "Display auto-looted items in your private chat." )
|
||||
e.create_config( "Announce auto-looted items", "auto_loot_announce", "checkbox", "Announce auto-looted items above loot quality threshold to party/raid." )
|
||||
e.create_config( "Display loot frame at cursor", "loot_frame_cursor", "checkbox", "Display loot fram at cursor when looting.", function()
|
||||
config.notify_subscribers( 'reset_loot_frame' )
|
||||
end )
|
||||
e.create_config( "Reset loot frame position", nil, "button", nil, function()
|
||||
info( "Loot frame position has been reset." )
|
||||
config.notify_subscribers( "reset_loot_frame" )
|
||||
end )
|
||||
end )
|
||||
|
||||
e.create_gui_entry( "Rolling", frames, function()
|
||||
e.create_config( "Roll settings", nil, "header" )
|
||||
e.create_config( "Default rolling time", "default_rolling_time_seconds", "number|min=4|max=15", "Value must be between 4 and 15 seconds." )
|
||||
e.create_config( "Rolling popup lock", "rolling_popup_lock", "checkbox", "Locks the rolling popup position.", notify )
|
||||
e.create_config( "Show Raid roll again button", "raid_roll_again", "checkbox", nil, notify )
|
||||
e.create_config( "MainSpec rolling threshold", "ms_roll_threshold", "number" )
|
||||
e.create_config( "OffSpec rolling threshold", "os_roll_threshold", "number" )
|
||||
e.create_config( "Enable transmog rolling", "tmog_rolling_enabled", "checkbox" )
|
||||
e.create_config( "Transmog rolling threshold", "tmog_roll_threshold", "number" )
|
||||
e.create_config( "Disable transmog roll on trash loot", "auto_tmog", "checkbox", "Automatically disable tmog roll on trash loot." )
|
||||
e.create_config( "Announce class restriction on items", "auto_class_announce", "checkbox", "Roll message will display classes that can roll on items with class restrictions." )
|
||||
e.create_config( "Reset rolling popup position", "", "button", nil, function()
|
||||
info( "Rolling popup position has been reset." )
|
||||
config.notify_subscribers( "reset_rolling_popup" )
|
||||
end )
|
||||
end )
|
||||
|
||||
return frame
|
||||
end
|
||||
|
||||
local function refresh()
|
||||
M.debug.add( "refresh" )
|
||||
for id, frame in pairs( frames ) do
|
||||
if type( frame ) == "table" and frame.area then
|
||||
frame.area:Hide()
|
||||
if frame.area.scroll.content.setup then
|
||||
for _, child in ipairs( { frame.area.scroll.content:GetChildren() } ) do
|
||||
if child.config and child.input then
|
||||
if child.input:GetFrameType() == "CheckButton" then
|
||||
child.input:SetChecked( config_db[ child.config ] )
|
||||
elseif child.input:GetFrameType() == "EditBox" then
|
||||
child.input:SetText( config_db[ child.config ] )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function show( area )
|
||||
M.debug.add( "show" )
|
||||
if not popup then
|
||||
popup = create_popup()
|
||||
else
|
||||
refresh()
|
||||
end
|
||||
|
||||
popup:Show()
|
||||
if not area or area == "" then area = "About" end
|
||||
frames[ area ].area:Show()
|
||||
end
|
||||
|
||||
local function hide()
|
||||
M.debug.add( "hide" )
|
||||
|
||||
if popup then
|
||||
popup:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function toggle()
|
||||
M.debug.add( "toggle" )
|
||||
if popup and popup:IsVisible() then
|
||||
hide()
|
||||
else
|
||||
show()
|
||||
end
|
||||
end
|
||||
|
||||
---@type OptionsPopup
|
||||
return {
|
||||
show = show,
|
||||
hide = hide,
|
||||
toggle = toggle
|
||||
}
|
||||
end
|
||||
|
||||
m.OptionsPopup = M
|
||||
return M
|
||||
@ -5,6 +5,16 @@ if m.VersionBroadcast then return end
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class VersionBroadcast
|
||||
---@field on_group_changed fun()
|
||||
---@field broadcast fun()
|
||||
---@field on_version fun( their_version: string )
|
||||
---@field on_version_request fun( channel: string, requesting_player_name: string )
|
||||
---@field on_version_response fun( requesting_player_name: string, channel: string, their_name: string, their_class: PlayerClass, their_version: string )
|
||||
---@field group_version_request fun()
|
||||
---@field guild_version_request fun()
|
||||
---@field new_version_available fun(): string|boolean
|
||||
|
||||
local pp = m.pretty_print
|
||||
local ADDON_NAME = "RollFor"
|
||||
local orange = m.colors.orange
|
||||
@ -51,6 +61,7 @@ function M.new( db, player_info, my_version )
|
||||
|
||||
local function notify_about_new_version( ver )
|
||||
db.last_new_version_reminder_timestamp = m.lua.time()
|
||||
db.new_version = ver
|
||||
pp( string.format( "New version (%s) is available!", m.colors.highlight( string.format( "v%s", ver ) ) ) )
|
||||
pp( "https://github.com/obszczymucha/roll-for-vanilla/releases/download/latest/RollFor.zip" )
|
||||
end
|
||||
@ -106,6 +117,14 @@ function M.new( db, player_info, my_version )
|
||||
version_request( "GUILD" )
|
||||
end
|
||||
|
||||
local function new_version_available()
|
||||
if db.new_version then
|
||||
return db.new_version
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
on_group_changed = on_group_changed,
|
||||
broadcast = broadcast,
|
||||
@ -114,6 +133,7 @@ function M.new( db, player_info, my_version )
|
||||
on_version_response = on_version_response,
|
||||
group_version_request = group_version_request,
|
||||
guild_version_request = guild_version_request,
|
||||
new_version_available = new_version_available,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller,
|
||||
m.GuiElements.titlebar( popup, "Winners" )
|
||||
|
||||
local btn_reset = m.GuiElements.tiny_button( popup, "R", "Reset Sorting", "#20F99F" )
|
||||
btn_reset:SetPoint( "TOPRIGHT", m.classic and -29 or -23, m.classic and -5 or -5 )
|
||||
btn_reset:SetPoint( "TOPRIGHT", m.classic and -29 or -25, m.classic and -5 or -7 )
|
||||
btn_reset:SetScript( "OnClick", function()
|
||||
sort = nil
|
||||
refresh( offset )
|
||||
|
||||
Loading…
Reference in New Issue
Block a user