diff --git a/RollFor-BCC.toc b/RollFor-BCC.toc deleted file mode 100644 index 2ee9788..0000000 --- a/RollFor-BCC.toc +++ /dev/null @@ -1,94 +0,0 @@ -## Interface: 20502 -## Title: RollFor -## Author: Obszczymucha -## Version: 4.7.2 -## Notes: An automated item roller with soft ressing support via softres.it. -## SavedVariables: RollForDb -## SavedVariablesPerCharacter: RollForCharDb - -libs\bcc\LibStub\LibStub.lua -libs\bcc\Libs.xml - -src\bcc\compat.lua -src\bcc\Json.lua - -src\modules.lua -src\DebugBuffer.lua -src\Module.lua -src\Db.lua -src\Types.lua -src\Interface.lua -src\WowApi.lua -src\Config.lua -src\ItemUtils.lua -src\EventFrame.lua -src\LootFacade.lua -src\RollingLogicUtils.lua -src\DroppedLoot.lua -src\DroppedLootAnnounce.lua -src\TradeTracker.lua -src\SoftResDataTransformer.lua -src\SoftRes.lua -src\SoftResAwardedLootDecorator.lua -src\SoftResAbsentPlayersDecorator.lua -src\SoftResPresentPlayersDecorator.lua -src\SoftResMatchedNameDecorator.lua -src\AwardedLoot.lua -src\GroupRoster.lua -src\NameAutoMatcher.lua -src\NameManualMatcher.lua -src\NameMatchReport.lua -src\EventHandler.lua -src\SoftResGui.lua -src\VersionBroadcast.lua -src\MasterLoot.lua -src\MasterLootCandidateSelectionFrame.lua -src\SoftResCheck.lua -src\SoftResRollingLogic.lua -src\NonSoftResRollingLogic.lua -src\TieRollingLogic.lua -src\RaidRollRollingLogic.lua -src\UsagePrinter.lua -src\MinimapButton.lua -src\MasterLootWarning.lua -src\AutoLoot.lua -src\WinnerTracker.lua -src\FrameBuilder.lua -src\PopupBuilder.lua -src\LootAwardPopup.lua -src\MasterLootCandidates.lua -src\NewGroupEvent.lua -src\AutoGroupLoot.lua -src\BossList.lua -src\AutoMasterLoot.lua -src\RollTracker.lua -src\RollController.lua -src\RollingPopup.lua -src\SoftResRollGuiData.lua -src\TieRollGuiData.lua -src\RollingPopupContentTransformer.lua -src\GuiElements.lua -src\WelcomePopup.lua -src\InstaRaidRollRollingLogic.lua -src\EventBus.lua -src\LootList.lua -src\SoftResLootListDecorator.lua -src\LootFrame.lua -src\RollForAd.lua -src\RollingStrategyFactory.lua -src\RollingLogic.lua -src\ArgsParser.lua -src\RollResultAnnouncer.lua -src\ChatApi.lua -src\Chat.lua -src\PlayerInfo.lua -src\LootAwardCallback.lua -src\LootFacadeListener.lua -src\LootController.lua -src\TooltipReader.lua -src\UiReloadPopup.lua -src\Sandbox.lua -src\ModernLootFrameSkin.lua -src\OgLootFrameSkin.lua - -main.lua diff --git a/RollFor.toc b/RollFor.toc index e1f1f00..3b2194a 100644 --- a/RollFor.toc +++ b/RollFor.toc @@ -1,7 +1,7 @@ ## Interface: 11200 ## Title: RollFor ## Author: Obszczymucha -## Version: 4.7.2 +## Version: 4.7.4 ## Notes: An automated item roller with soft ressing support via raidres.fly.dev. ## SavedVariables: RollForDb ## SavedVariablesPerCharacter: RollForCharDb diff --git a/assets/arrow-down.tga b/assets/arrow-down.tga new file mode 100644 index 0000000..999b081 Binary files /dev/null and b/assets/arrow-down.tga differ diff --git a/assets/arrow-up.tga b/assets/arrow-up.tga new file mode 100644 index 0000000..f7776ca Binary files /dev/null and b/assets/arrow-up.tga differ diff --git a/assets/col.tga b/assets/col.tga deleted file mode 100644 index e261173..0000000 Binary files a/assets/col.tga and /dev/null differ diff --git a/src/AwardedLoot.lua b/src/AwardedLoot.lua index 83b1557..c66f842 100644 --- a/src/AwardedLoot.lua +++ b/src/AwardedLoot.lua @@ -11,6 +11,7 @@ local getn = m.getn ---@field award fun( player_name: string, item_id: number, roll_data: RollData?, rolling_strategy: RollingStrategyType?, item_link: ItemLink?, player_class: PlayerClass?, sr_plus: number? ) ---@field unaward fun( player_name: string, item_id: number ) ---@field get_winners fun() +---@field update_item fun( index: number, data: table ) ---@field has_item_been_awarded fun( player_name: string, item_id: number ): boolean ---@field has_item_been_awarded_to_any_player fun( item_id: ItemId ): boolean ---@field clear fun( force: boolean?) @@ -76,6 +77,17 @@ function M.new( db, group_roster, config ) return db.awarded_items end + ---@param index number + ---@param data table + local function update_item( index, data ) + local item = db.awarded_items[ index ] + if item and data then + for k, v in pairs( data ) do + item[ k ] = v + end + end + end + ---@param player_name string ---@param item_id number ---@return boolean @@ -101,6 +113,7 @@ 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 @@ -125,6 +138,7 @@ function M.new( db, group_roster, config ) award = award, unaward = unaward, get_winners = get_winners, + update_item = update_item, has_item_been_awarded = has_item_been_awarded, has_item_been_awarded_to_any_player = has_item_been_awarded_to_any_player, clear = clear, diff --git a/src/ClientBroadcast.lua b/src/ClientBroadcast.lua index a3b0ad8..bc00bee 100644 --- a/src/ClientBroadcast.lua +++ b/src/ClientBroadcast.lua @@ -57,7 +57,6 @@ function M.new( roll_controller, softres, config ) 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 softressing_players = softres.get( data.item.id ) - local sr_players = {} for _, player in ipairs( softressing_players ) do table.insert( sr_players, { diff --git a/src/FrameBuilder.lua b/src/FrameBuilder.lua index 81978c9..5a03bc9 100644 --- a/src/FrameBuilder.lua +++ b/src/FrameBuilder.lua @@ -111,7 +111,6 @@ M.interface = { ---@field parent fun( self: FrameBuilder, parent: Frame ): FrameBuilder ---@field name fun( self: FrameBuilder, name: string ): FrameBuilder ---@field type fun( self: FrameBuilder, name: string ): FrameBuilder ----@field parent fun( self: FrameBuilder, parent: Frame ): FrameBuilder ---@field height fun( self: FrameBuilder, height: number ): FrameBuilder ---@field width fun( self: FrameBuilder, width: number ): FrameBuilder ---@field point fun( self: FrameBuilder, p: Point ): FrameBuilder @@ -203,7 +202,7 @@ function M.new() edgeFile = "Interface\\Buttons\\WHITE8X8", tile = false, tileSize = 0, - edgeSize = 0.8, + edgeSize = options.border_size or 0.8, insets = { left = 0, right = 0, top = 0, bottom = 0 } } ) elseif options.frame_style == "Classic" then @@ -215,6 +214,15 @@ function M.new() edgeSize = options.border_size or 24, insets = { left = 5, right = 5, top = 5, bottom = 5 } } ) + elseif options.frame_style == "None" then + frame:SetBackdrop( { + bgFile = options.bg_file or "Interface/Buttons/WHITE8x8", + edgeFile = options.edge_file, + tile = true, + tileSize = 22, + edgeSize = options.border_size or 0, + insets = { left = 0, right = 0, top = 0, bottom = 0 } + } ) end if options.backdrop_color then diff --git a/src/WinnersPopup.lua b/src/WinnersPopup.lua index 5d47456..c2453fc 100644 --- a/src/WinnersPopup.lua +++ b/src/WinnersPopup.lua @@ -16,6 +16,8 @@ local filter = m.filter local M = m.Module.new( "WinnersPopup" ) --M.debug.enable() +ROW_HEIGHT = 14 + M.center_point = { point = "CENTER", relative_point = "CENTER", x = 0, y = 150 } ---@param popup_builder PopupBuilder @@ -32,25 +34,16 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, local headers local sort local sort_order = "asc" + local content_frame local scroll_frame + local offset = 0 + local row_count = 0 + local row_frames = {} local is_resizing local award_filters = config.award_filter() local winners_data db.point = db.point or M.center_point - --[[ - awarded_loot.award( "Zombiehunter", 16939, { roll_type = "SoftRes", roll = 112, player_name = "", player_class = "" }, "SoftResRoll", nil, "Hunter", 30 ) - awarded_loot.award( "Kevieboipro", 16939, { roll_type = "SoftRes", roll = 98, player_name = "", player_class = "" }, "SoftResRoll", nil, "Warrior", 20 ) - awarded_loot.award( "Kevieboipro", 19019, { roll_type = "Transmog", roll = 89, player_name = "", player_class = "" }, "NormalRoll", nil, "Warrior" ) - awarded_loot.award( "Dayknight", 5504, { roll_type = "MainSpec", roll = 53, player_name = "", player_class = "" }, "NormalRoll", nil, "Paladin" ) - awarded_loot.award( "Celilae", 5504, { roll_type = "MainSpec", roll = 78, player_name = "", player_class = "" }, "NormalRoll", nil, "Paladin" ) - awarded_loot.award( "Borazor", 16939, { roll_type = "SoftRes", roll = 112, player_name = "", player_class = "" }, "SoftResRoll", nil, "Hunter", 30 ) - awarded_loot.award( "Ryiana", 16939, { roll_type = "SoftRes", roll = 98, player_name = "", player_class = "" }, "SoftResRoll", nil, "Warrior", 20 ) - awarded_loot.award( "Tornapart", 19019, { roll_type = "Transmog", roll = 89, player_name = "", player_class = "" }, "NormalRoll", nil, "Warrior" ) - awarded_loot.award( "Dayknight", 5504, { roll_type = "MainSpec", roll = 53, player_name = "", player_class = "" }, "NormalRoll", nil, "Paladin" ) - awarded_loot.award( "Celilae", 5504, { roll_type = "MainSpec", roll = 78, player_name = "", player_class = "" }, "NormalRoll", nil, "Paladin" ) - awarded_loot.award( "Borazor", 16936, { roll_type = "SoftRes", roll = 112, player_name = "", player_class = "" }, "SoftResRoll", nil, "Hunter", 30 ) - ]] local function create_popup() M.debug.add( "create popup" ) @@ -66,6 +59,7 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, end local old_width + local old_height local function on_resize( self ) if not self or not is_resizing then return end local min_width, max_width, min_height, max_height = 225, 500, 173, 600 @@ -81,11 +75,13 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, end if not old_width then old_width = self:GetWidth() end - if (math.abs( (width) - old_width ) > 7) or (width <= min_width) then + if not old_height then old_height = self:GetHeight() end + if (math.abs( width - old_width ) > 7) or (width <= min_width) or (math.abs( height - old_height ) > (ROW_HEIGHT / 2)) then old_width = self:GetWidth() - refresh() + old_height = self:GetHeight() + refresh( offset, false ) end - scroll_frame:update_scroll_state() + --scroll_frame:update_scroll_state() end local function get_point() @@ -127,13 +123,13 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, else sort = self.sort end - refresh( true ) + refresh( offset ) end local function cb_on_change( cb_filter, cb_setting, value ) if cb_filter and cb_setting then award_filters[ cb_filter ][ cb_setting ] = value - refresh( true ) + refresh( offset ) end end @@ -143,7 +139,7 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, btn_reset:SetPoint( "TOPRIGHT", m.classic and -29 or -23, m.classic and -5 or -5 ) btn_reset:SetScript( "OnClick", function() sort = nil - refresh( true ) + refresh( offset ) end ) local btn_clear = m.GuiElements.tiny_button( popup, "C", "Clear data", "#209FF9" ) @@ -157,6 +153,7 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, confirm_popup.show( { "This will clear the current winners data.", "Are you sure?" }, function( value ) if value then awarded_loot.clear( true ) + refresh() end end ) end ) @@ -174,10 +171,11 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, btn_resize:SetPoint( "BOTTOMRIGHT", m.classic and -4 or 0, m.classic and 4 or 0 ) local padding_top = m.classic and -20 or -10 + local padding_side = m.classic and 30 or 20 headers = m.WinnersPopupGui.headers( popup, set_sort ) - headers:SetPoint( "TOPLEFT", 20, padding_top - 20 ) - headers:SetPoint( "RIGHT", -20, 0 ) + headers:SetPoint( "TOPLEFT", padding_side, padding_top - 20 ) + headers:SetPoint( "RIGHT", -padding_side, 0 ) m.WinnersPopupGui.create_dropdown( headers.item_id_header, award_filters, function( self ) m.WinnersPopupGui.create_checkbox_entry( self, "Poor", "item_quality.Poor", cb_on_change ) @@ -201,24 +199,30 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, m.WinnersPopupGui.create_checkbox_entry( self, "Other", "roll_type.NA", cb_on_change ) end ) - scroll_frame = m.WinnersPopupGui.create_scroll_frame( popup ) - scroll_frame:SetPoint( "TOPLEFT", 20, padding_top - 35 ) - scroll_frame:SetPoint( "BOTTOMRIGHT", -20, m.classic and 20 or 15 ) + scroll_frame = m.WinnersPopupGui.create_scroll_frame( popup, "RollForWinnersScrollFrame" ) + scroll_frame.name = scroll_frame:GetName() + scroll_frame:SetPoint( "TOPLEFT", padding_side, padding_top - 35 ) + scroll_frame:SetPoint( "BOTTOMRIGHT", -padding_side, m.classic and 20 or 15 ) + scroll_frame:SetScript( "OnVerticalScroll", function() + m.api.FauxScrollFrame_OnVerticalScroll( ROW_HEIGHT, function() + refresh( m.api.FauxScrollFrame_GetOffset( scroll_frame ), false ) + end ) + end ) - local inner_builder = frame_builder.new() - :parent( scroll_frame ) - :name( "RollForWinnersFrameInner" ) + content_frame = frame_builder.new() + :parent( popup ) + :name( "RollForWinnersFrameContent" ) :width( 250 ) :height( 100 ) - :point( { point = "TOPLEFT", relative_point = "TOPLEFT", relative_frame = "RollForWinnersFrame", x = 0, y = 0 } ) + :point( { point = "TOPLEFT", relative_point = "TOPLEFT", relative_frame = "RollForWinnersFrame", x = padding_side, y = padding_top - 35 } ) :bg_file( "Interface/Buttons/WHITE8x8" ) :gui_elements( m.WinnersPopupGui ) - :frame_style( "None" ) + :border_size( .5 ) + :border_color( .2, .2, .2, 1) + :frame_style( "Modern" ) + :build() - scroll_frame.content = inner_builder:build() - scroll_frame:SetScrollChild( scroll_frame.content ) - scroll_frame.content:SetAllPoints( scroll_frame ) - scroll_frame.content:Show() + content_frame:SetPoint( "BOTTOMRIGHT", popup, "BOTTOMRIGHT", -padding_side, m.classic and 20 or 15 ) return popup end @@ -285,9 +289,10 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, M.debug.add( "Get data" ) local db_data = awarded_loot.get_winners() winners_data = {} - for _, v in ipairs( db_data ) do + for index, v in ipairs( db_data ) do if v.item_link then table.insert( winners_data, { + index = index, player_name = v.player_name, player_class = v.player_class, item_id = v.item_id, @@ -302,16 +307,12 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, end end - if getn( winners_data ) == 0 then - scroll_frame:UpdateScrollChildRect() - return - end - filter_winners() if (sort) then table.sort( winners_data, sort_winners ) end end - function refresh( refresh_data ) + function refresh( new_offset, refresh_data ) + refresh_data = refresh_data == nil and true if not popup then popup = create_popup() make_content() @@ -319,61 +320,117 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, if not winners_data or refresh_data then get_data() end + local winners_count = getn( winners_data ) + local old_row_count = row_count + row_count = math.floor( ((popup:GetHeight() - (m.classic and 80 or 60)) / ROW_HEIGHT) + 0.4 ) + m.api.FauxScrollFrame_Update( scroll_frame, winners_count, row_count, ROW_HEIGHT ) + + if new_offset and new_offset == -1 then + offset = winners_count - row_count + if offset < 0 then offset = 0 end + elseif new_offset then + offset = new_offset + end + local show_sr_plus = award_filters[ "winning_roll" ][ "show_sr_plus" ] local got_sr_plus = false local content = {} - for _, item in pairs( winners_data ) do - table.insert( content, { - type = "winner", - player_name = item.player_name, - player_class = item.player_class, - item_link = item.item_link, - roll_type = item.roll_type, - rolling_strategy = item.rolling_strategy, - winning_roll = item.winning_roll, - sr_plus = item.sr_plus, - quality = item.quality - } ) + + for i, item in pairs( winners_data ) do + if i > offset and i <= row_count + offset then + table.insert( content, { + type = "winner", + index = item.index, + item_id = item.item_id, + player_name = item.player_name, + player_class = item.player_class, + item_link = item.item_link, + roll_type = item.roll_type, + rolling_strategy = item.rolling_strategy, + winning_roll = item.winning_roll, + sr_plus = item.sr_plus, + quality = item.quality + } ) + end if item.sr_plus then got_sr_plus = true end end + local function update_row( frame, v ) + local roll_type_abbrev = v.roll_type == "RR" and "RR" or v.roll_type == "NA" and "NA" or m.roll_type_abbrev( v.roll_type ) + local sr_plus = "" + + if not frame then + error( "Row frame is empty!" ) + return + end + + if show_sr_plus and got_sr_plus then + frame.winning_roll:GetParent():SetWidth( 50 ) + if v.sr_plus and v.rolling_strategy == m.Types.RollingStrategy.SoftResRoll and v.roll_type == m.Types.RollType.SoftRes then + sr_plus = string.format( "+%s ", v.sr_plus ) + end + else + frame.winning_roll:GetParent():SetWidth( 25 ) + end + + frame:SetItem( v.item_link ) + frame.player_name:SetText( c( v.player_name, v.player_class ) ) + frame.winning_roll:SetText( string.format( "%s%s", sr_plus, v.winning_roll or "-" ) ) + frame.roll_type:SetText( r( v.roll_type, roll_type_abbrev ) ) + frame.roll_type.value = v.roll_type + frame.roll_type.on_update_item = function( rt ) + awarded_loot.update_item( v.index, { roll_type = rt } ) + refresh() + end + frame:Show() + end + headers.winning_roll_header:SetWidth( (show_sr_plus and got_sr_plus) and 50 or 25 ) - scroll_frame.content:clear() - for _, v in ipairs( content ) do - scroll_frame.content.add_line( v.type, function( type, frame, lines ) - if type == "winner" then - local roll_type_abbrev = v.roll_type == "RR" and "RR" or v.roll_type == "NA" and "NA" or m.roll_type_abbrev( v.roll_type ) - local sr_plus = "" - - if show_sr_plus and got_sr_plus then - frame.winning_roll:GetParent():SetWidth( 50 ) - if v.sr_plus and v.rolling_strategy == m.Types.RollingStrategy.SoftResRoll and v.roll_type == m.Types.RollType.SoftRes then - sr_plus = string.format( "+%s ", v.sr_plus ) - end - else - frame.winning_roll:GetParent():SetWidth( 25 ) - end - - frame:SetItem( v.item_link ) - frame.player_name:SetText( c( v.player_name, v.player_class ) ) - frame.winning_roll:SetText( string.format( "%s%s", sr_plus, v.winning_roll or "-" ) ) - frame.roll_type:SetText( r( v.roll_type, roll_type_abbrev ) ) - - frame:SetPoint( "TOP", scroll_frame.content, "TOP", 0, -getn( lines ) * 14 ) - end - end, 0 ) + if row_count < old_row_count then + for i = row_count + 1, old_row_count do + row_frames[ i ].is_used = false + row_frames[ i ]:Hide() + end end - scroll_frame:UpdateScrollChildRect() - local tick = 0 - scroll_frame:SetScript( "OnUpdate", function() - scroll_frame:update_scroll_state() - tick = tick + 1 - if tick > 1 then - scroll_frame:SetScript( "OnUpdate", nil ) + if row_count > old_row_count then + for i = old_row_count, row_count - 1 do + if row_frames[ i + 1 ] then + row_frames[ i + 1 ].is_used = true + else + content_frame.add_line( "winner", function( type, frame, lines ) + frame:SetPoint( "TOP", content_frame, "TOP", 0, -i * ROW_HEIGHT ) + frame:Hide() + table.insert( row_frames, frame ) + end, 0 ) + end + if offset > 0 then offset = offset - 1 end end - end ) + end + + for i = 1, row_count do + row_frames[ i ]:Hide() + end + + for index, v in ipairs( content ) do + update_row( row_frames[ index ], v ) + end + + m.api.FauxScrollFrame_SetOffset( scroll_frame, offset ) + _G[ scroll_frame.name .. "ScrollBar" ]:SetValue( offset * ROW_HEIGHT ) + + if offset == 0 then + _G[ scroll_frame.name .. "ScrollBarScrollUpButton" ]:Disable() + else + _G[ scroll_frame.name .. "ScrollBarScrollUpButton" ]:Enable() + end + + if offset + math.min( row_count, winners_count ) == winners_count then + _G[ scroll_frame.name .. "ScrollBarScrollDownButton" ]:Disable() + else + _G[ scroll_frame.name .. "ScrollBarScrollDownButton" ]:Enable() + end end local function show() @@ -383,7 +440,8 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, make_content() end popup:Show() - refresh( true ) + offset = 0 + refresh( offset ) end local function hide() @@ -403,20 +461,12 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, end local function loot_awarded() - M.debug.add( "loot_awarded" ) + M.debug.add( "winners loot_awarded" ) if popup and popup:IsVisible() then - refresh( true ) - if not sort then - local max = scroll_frame:GetVerticalScrollRange() - local tick = 0 - scroll_frame:SetScript( "OnUpdate", function() - local new_max = scroll_frame:GetVerticalScrollRange() - tick = tick + 1 - if new_max > max or tick > 5 then - scroll_frame:SetVerticalScroll( new_max ) - scroll_frame:SetScript( "OnUpdate", nil ) - end - end ) + if sort then + refresh( 0 ) + else + refresh( -1 ) end end end @@ -424,7 +474,7 @@ function M.new( popup_builder, frame_builder, db, awarded_loot, roll_controller, local function award_data_updated() M.debug.add( "award_data_updated" ) if popup and popup:IsVisible() then - refresh( true ) + refresh( 0 ) end end diff --git a/src/WinnersPopupGui.lua b/src/WinnersPopupGui.lua index 3c52ed5..45a550e 100644 --- a/src/WinnersPopupGui.lua +++ b/src/WinnersPopupGui.lua @@ -60,12 +60,46 @@ function M.headers( parent, on_click ) return frame end +function M.roll_type_dropdown() + if not M.roll_type_dropdown_frame then + M.roll_type_dropdown_frame = m.api.CreateFrame( "Frame", "RollForRollTypeDropdown" ) + M.roll_type_dropdown_frame.displayMode = "MENU" + end + + if M.roll_type_dropdown_frame.initialize ~= M.roll_type_dropdown_menu then + m.api.CloseDropDownMenus() + M.roll_type_dropdown_frame.initialize = M.roll_type_dropdown_menu + end + + M.roll_type_dropdown_frame.value = this.inner.value + M.roll_type_dropdown_frame.on_update_item = this.inner.on_update_item + + local row = this:GetParent() + m.api.ToggleDropDownMenu( 1, nil, M.roll_type_dropdown_frame, row:GetName(), row:GetWidth() - 57, 0 ) +end + +function M.roll_type_dropdown_menu() + local info = {} + + for roll_type in pairs( m.Types.RollType ) do + info.text = m.roll_type_color( roll_type, m.roll_type_abbrev( roll_type ) ) + info.checked = M.roll_type_dropdown_frame.value == roll_type + info.arg1 = roll_type + info.func = function( rt ) + if M.roll_type_dropdown_frame.on_update_item then + M.roll_type_dropdown_frame.on_update_item( rt ) + end + end + m.api.UIDropDownMenu_AddButton( info, 1 ) + end +end + function M.winner( parent ) - local frame = m.api.CreateFrame( "Button", nil, parent ) - frame:SetWidth( 250 ) + M.winner_rows = M.winner_rows and M.winner_rows + 1 or 1 + local frame = m.api.CreateFrame( "Button", "RollForWinnerRow" .. M.winner_rows, parent ) frame:SetHeight( 14 ) - frame:SetPoint( "LEFT", parent:GetParent(), "LEFT", 0, 0 ) - frame:SetPoint( "RIGHT", parent:GetParent(), "RIGHT", 0, 0 ) + frame:SetPoint( "LEFT", parent, "LEFT", 0, 0 ) + frame:SetPoint( "RIGHT", parent, "RIGHT", 0, 0 ) frame:SetFrameStrata( "DIALOG" ) frame:SetFrameLevel( parent:GetFrameLevel() + 1 ) frame:SetBackdrop( { @@ -78,23 +112,6 @@ function M.winner( parent ) frame:SetBackdropColor( 0.125, 0.624, 0.976, a ) end - local function truncate_item_text( font_string, max_width ) - local item = font_string:GetText() - local original_text = string.gsub( m.ItemUtils.get_item_name( font_string:GetText() ), "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1" ) - local truncated_text = original_text - - while font_string:GetStringWidth() > max_width and string.len( truncated_text ) > 4 do - truncated_text = string.sub( truncated_text, 1, -2 ) - font_string:SetText( "[" .. truncated_text .. "...]" ) - end - - if original_text == truncated_text then - font_string:SetText( string.gsub( item, original_text, truncated_text ) ) - else - font_string:SetText( string.gsub( item, original_text, truncated_text .. "..." ) ) - end - end - blue_hover( 0 ) frame:SetScript( "OnEnter", function() blue_hover( .2 ) end ) frame:SetScript( "OnLeave", function() blue_hover( 0 ) end ) @@ -116,6 +133,12 @@ function M.winner( parent ) roll_type.inner:SetPoint( "LEFT", 5, 0 ) roll_type:SetPoint( "RIGHT", 0, 0 ) roll_type:SetHeight( 14 ) + roll_type:EnableMouse() + roll_type:SetScript( "onMouseUp", function() + if arg1 == "RightButton" then + M.roll_type_dropdown() + end + end ) frame.roll_type = roll_type.inner local winning_roll = m.GuiElements.create_text_in_container( "Frame", frame, 25, nil, "dummy" ) @@ -129,14 +152,16 @@ function M.winner( parent ) local item_link = m.GuiElements.create_text_in_container( "Button", frame, 1, "LEFT", "dummy" ) item_link.inner:SetFont( font_file, font_size ) item_link.inner:SetJustifyH( "LEFT" ) + item_link.inner:SetPoint( "LEFT", 0, 0 ) + item_link.inner:SetPoint( "RIGHT", 0, 0 ) + item_link.inner:SetHeight( 14 ) item_link:SetPoint( "LEFT", player_name, "RIGHT", 1, 0 ) item_link:SetPoint( "RIGHT", winning_roll, "LEFT", -1, 0 ) - item_link:SetHeight( item_link.inner:GetHeight() ) + item_link:SetHeight( 14 ) frame.item_link = item_link frame.SetItem = function( _, item_link_text ) item_link.inner:SetText( item_link_text ) - truncate_item_text( item_link.inner, frame:GetParent():GetParent():GetParent():GetWidth() - 145 - winning_roll:GetWidth() ) local tooltip_link = m.ItemUtils.get_tooltip_link( item_link_text ) @@ -244,62 +269,74 @@ function M.create_checkbox_entry( parent, text, setting, on_change ) end function M.create_scroll_frame( parent, name ) - local f = m.api.CreateFrame( "ScrollFrame", name, parent ) + local f = m.api.CreateFrame( "ScrollFrame", name, parent, "FauxScrollFrameTemplate" ) - f.slider = m.api.CreateFrame( "Slider", nil, f ) - f.slider:SetOrientation( "VERTICAL" ) - f.slider:SetPoint( "TOPLEFT", f, "TOPRIGHT", 1, 0 ) - f.slider:SetPoint( "BOTTOMRIGHT", 9, 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 ) + if m.classic then + local scroll_bar = _G[ name .. "ScrollBar" ] + scroll_bar:SetPoint( "TOPLEFT", name, "TOPRIGHT", 1, -16 ) + else + local scroll_bar = _G[ name .. "ScrollBar" ] + scroll_bar:SetWidth( 12 ) + scroll_bar:SetBackdrop( { + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Buttons\\WHITE8X8", + tile = false, + tileSize = 0, + edgeSize = 0.5, + insets = { left = 0, right = 0, top = 0, bottom = 0 } + } ) + scroll_bar:SetBackdropColor( 0, 0, 0, 0.8 ) + scroll_bar:SetBackdropBorderColor( .2, .2, .2, 1 ) + scroll_bar:SetPoint( "TOPLEFT", name, "TOPRIGHT", 3, -13.5 ) + scroll_bar:SetPoint( "BOTTOMLEFT", name, "BOTTOMRIGHT", 6, 14) - f.slider:SetScript( "OnValueChanged", function() - f:SetVerticalScroll( f.slider:GetValue() ) - f.update_scroll_state() - end ) + local thumb = _G[ name .. "ScrollBarThumbTexture" ] + thumb:SetTexture( "Interface\\Buttons\\WHITE8X8" ) + thumb:SetVertexColor( .8, .8, .8, .8 ) + thumb:SetWidth( 12 ) + thumb:SetHeight( 10 ) - f.update_scroll_state = function() - f.slider:SetMinMaxValues( 0, f:GetVerticalScrollRange() ) - f.slider:SetValue( f:GetVerticalScroll() ) + for i, button in { _G[ name .. "ScrollBarScrollUpButton" ], _G[ name .. "ScrollBarScrollDownButton" ] } do - local r = f:GetHeight() + f:GetVerticalScrollRange() - local v = f:GetHeight() - local ratio = v / r + for _, tex in { "Normal", "Highlight", "Pushed", "Disabled" } do + local texture = button[ "Get" .. tex .. "Texture" ]( button ) + texture:SetTexture( "Interface\\AddOns\\RollFor\\assets\\arrow-" .. (i == 1 and "up" or "down") .. ".tga" ) + texture:SetTexCoord( 0, 1, 0, 1 ) + texture:SetVertexColor( .8, .8, .8, .8 ) + texture:SetAlpha( .8 ) + texture:SetPoint( "TOPLEFT", 2, -1 ) + texture:SetPoint( "BOTTOMRIGHT", -2, 1 ) + end - if ratio < 0.999999 then - local size = math.floor( v * ratio ) - f.slider.thumb:SetHeight( size ) - f.slider:Show() - else - f.slider:Hide() + button:SetWidth( 12 ) + button:SetHeight( 12 ) + button:SetBackdrop( { + bgFile = "Interface\\Buttons\\WHITE8X8", + edgeFile = "Interface\\Buttons\\WHITE8X8", + tile = false, + tileSize = 0, + edgeSize = 0.5, + insets = { left = 0, right = 0, top = 0, bottom = 0 } + } ) + button:SetBackdropColor( 0, 0, 0, 1 ) + button:SetBackdropBorderColor( .2, .2, .2, 1 ) + button:GetDisabledTexture():SetAlpha( 0.4 ) + + if i == 1 then + button:SetPoint("BOTTOM", scroll_bar, "TOP", 0, 2 ) + else + button:SetPoint("TOP", scroll_bar, "BOTTOM", 0, -2 ) + end + + button:SetScript( "OnEnter", function() + this:SetBackdropBorderColor( .125, .624, .976, .5 ) + end ) + button:SetScript( "OnLeave", function() + this:SetBackdropBorderColor( .2, .2, .2, 1 ) + end ) 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() - f:scroll( arg1 * 10 ) - end ) - return f end diff --git a/src/modules.lua b/src/modules.lua index 53643e2..4a2f125 100644 --- a/src/modules.lua +++ b/src/modules.lua @@ -461,6 +461,10 @@ end function M.colorize_player_by_class( name, class ) if not class then return name end local color = M.api.RAID_CLASS_COLORS[ string.upper( class ) ].colorStr + if not color then + local c = M.api.RAID_CLASS_COLORS[ string.upper( class ) ] + color = string.format( "ff%02x%02x%02x", c.r * 255, c.g * 255, c.b * 255 ) + end return "|c" .. color .. name .. M.api.FONT_COLOR_CODE_CLOSE end diff --git a/update.sh b/update.sh new file mode 100644 index 0000000..20ed7ec --- /dev/null +++ b/update.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash + +cp -R ../roll-for-vanilla/RollFor/* . +rm RollFor-BCC.toc \ No newline at end of file