New options GUI

This commit is contained in:
Sica 2025-04-10 04:28:01 +02:00
parent 7b5a5c6a63
commit 646542e716
14 changed files with 740 additions and 25 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
update.sh

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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

View File

@ -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

View File

@ -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 )