local _,rematch = ... local L = rematch.localization local C = rematch.constants local settings = rematch.settings --[[ Red panel buttons across bottom of dialog ]] RematchDialogPanelButtonMixin = {} function RematchDialogPanelButtonMixin:OnClick() local info = rematch.dialog:GetDialogInfo() if not info then return end -- for acceptFunc or otherFunc (if defined) run them before closing dialog in case any OnHides reset controls if self==rematch.dialog.AcceptButton and info.acceptFunc then info.acceptFunc(rematch.dialog.Canvas,info,info.subject) if info.stayOnAccept then return -- don't hide dialog if stayOnAccept defined end elseif self==rematch.dialog.OtherButton and info.otherFunc then info.otherFunc(rematch.dialog.Canvas,info,info.subject) if info.stayOnOther then return -- don't hide dialog if stayOnOther defined end end rematch.dialog:Hide() -- run cancelFunc after the dialog hides in case another dialog wants to be shown in this cancelFunc if self==rematch.dialog.CancelButton and info.cancelFunc then info.cancelFunc(rematch.dialog.Canvas,info,info.subject) end end --[[ Text, SmallText and Help dialog controls ]] RematchDialogTextMixin = {} function RematchDialogTextMixin:SetText(text) self.Text:SetText(text) self:SetHeight(self.Text:GetStringHeight()) end function RematchDialogTextMixin:SetTextColor(r,g,b) self.Text:SetTextColor(r,g,b) end --[[ Feedback dialog control ]] RematchDialogFeedbackMixin = {} -- for Feedback widget with an icon+text, this function is called from canvas.Feedback:Set(icon,text) -- and will set the icon to one for "warning", "info", "success", "failure" or "unknown" and color text appropriately -- if icon is none of those, then it will use that icon and set text to white function RematchDialogFeedbackMixin:Set(icon,text) if icon=="warning" then self.Icon:SetTexture("Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew") self.Text:SetTextColor(1,0.5,0.25) elseif icon=="info" then self.Icon:SetTexture("Interface\\Common\\help-i") self.Text:SetTextColor(1,0.82,0) elseif icon=="success" then self.Icon:SetTexture("Interface\\RaidFrame\\ReadyCheck-Ready") self.Text:SetTextColor(0,1,0) elseif icon=="failure" or icon=="invalid" then self.Icon:SetTexture("Interface\\RaidFrame\\ReadyCheck-NotReady") self.Text:SetTextColor(1,0.25,0.25) elseif icon=="unknown" then self.Icon:SetTexture("Interface\\RaidFrame\\ReadyCheck-Waiting") self.Text:SetTextColor(1,0.82,0) elseif icon=="mail" then self.Icon:SetTexture("Interface\\HelpFrame\\ReportLagIcon-Mail") self.Text:SetTextColor(0.533,0.733,1) else self.Icon:SetTexture(icon) self.Text:SetTextColor(0.9,0.9,0.9) end self.Text:SetText(text) end -- for dialogs that "hide" feedback by setting its alpha to 0, reset to make it visible for other dialogs function RematchDialogFeedbackMixin:Reset() self:SetAlpha(1) end --[[ EditBox dialog control ]] RematchDialogEditBoxMixin = {} function RematchDialogEditBoxMixin:SetText(text,highlight) self.EditBox:SetText(text) if highlight then self.EditBox:HighlightText() end end function RematchDialogEditBoxMixin:SetTextColor(r,g,b) self.EditBox:SetTextColor(r,g,b) end function RematchDialogEditBoxMixin:SetLabel(text) self.Label:SetText(text) end function RematchDialogEditBoxMixin:GetText() return self.EditBox:GetText() end function RematchDialogEditBoxMixin:SetEnabled(enable) self.EditBox:SetEnabled(enable) if not enabled then self.EditBox:ClearHighlightText() self.EditBox.Clear:Hide() end for i=1,3 do self.EditBox.Back[i]:SetShown(enable) end end function RematchDialogEditBoxMixin:OnLoad() self.EditBox:SetScript("OnEscapePressed",function(self) rematch.dialog.CancelButton:Click() end) self.EditBox:SetScript("OnTabPressed",function(self) if rematch.dialog.Canvas.MultiLineEditBox:IsVisible() then rematch.dialog.Canvas.MultiLineEditBox:SetFocus(true) end end) self.EditBox:SetScript("OnEnterPressed",function(self) if rematch.dialog.AcceptButton:IsEnabled() then rematch.dialog.AcceptButton:Click() end end) self.EditBox:SetScript("OnTextChanged",function(self) rematch.dialog:OnChange() -- function to call the changeFunc end) end --[[ MultiLineEditBox dialog control ]] RematchDialogMultiLineEditBoxMixin = {} function RematchDialogMultiLineEditBoxMixin:SetText(text,highlight) if type(text)~="table" then self.ScrollFrame.EditBox:SetText(text or "") if highlight then self.ScrollFrame.EditBox:HighlightText() end else rematch.utils.SpoolText(self,self.ScrollFrame.EditBox,text,highlight) end end function RematchDialogMultiLineEditBoxMixin:GetText() return self.ScrollFrame.EditBox:GetText() end function RematchDialogMultiLineEditBoxMixin:SetFocus(getFocus) self.ScrollFrame.EditBox:SetFocus(getFocus) end function RematchDialogMultiLineEditBoxMixin:ScrollToTop() self.ScrollFrame.EditBox:SetCursorPosition(0) end function RematchDialogMultiLineEditBoxMixin:OnLoad() -- EditBox self.ScrollFrame.EditBox:SetScript("OnEscapePressed",function(self) rematch.dialog:Hide() end) self.ScrollFrame.EditBox:SetScript("OnTabPressed",function(self) self:Insert(" ") end) self.ScrollFrame.EditBox:SetScript("OnCursorChanged",function(self,x,y,w,h) ScrollingEdit_OnCursorChanged(self, x, y, w, h) end) self.ScrollFrame.EditBox:SetScript("OnUpdate",function(self,elapsed) ScrollingEdit_OnUpdate(self, elapsed, self:GetParent()) end) self.ScrollFrame.EditBox:SetScript("OnTextChanged",function(self,userInput) if userInput then rematch.dialog.OnChange(self) end end) -- setup ScrollFrame local scrollBar = self.ScrollFrame.ScrollBar scrollBar:ClearAllPoints() scrollBar:SetPoint("TOPRIGHT",4,-12) scrollBar:SetPoint("BOTTOMRIGHT",4,11) local up = _G[scrollBar:GetName().."ScrollUpButton"] local down = _G[scrollBar:GetName().."ScrollDownButton"] scrollBar.trackBG:SetColorTexture(0.03,0.03,0.03) scrollBar.trackBG:SetPoint("TOPLEFT",up,"TOPLEFT",0,-4) scrollBar.trackBG:SetPoint("BOTTOMRIGHT",down,"BOTTOMRIGHT",-1,4) up:SetPoint("TOP",0,13) down:SetPoint("BOTTOM",0,-13) -- ScrollFrame script handlers self.ScrollFrame:SetScript("OnSizeChanged",function(self,w) self.EditBox:SetWidth(w-23) end) self.ScrollFrame:SetScript("OnMouseDown",function(self) self.EditBox:SetFocus(true) end) self.ScrollFrame:SetScript("OnHide",function(self) self.PleaseWait:Hide() end) end function RematchDialogMultiLineEditBoxMixin:OnHide() self:SetHeight(C.DIALOG_MULTILINE_EDITBOX_HEIGHT) end --[[ CheckButton dialog control ]] RematchDialogCheckButtonMixin = {} function RematchDialogCheckButtonMixin:SetText(text) self.Check:SetText(text) self.Check:ClearAllPoints() self.Check:SetPoint("CENTER",2-(self.Check.Text:GetStringWidth()/2),0) end function RematchDialogCheckButtonMixin:SetChecked(isChecked) self.Check:SetChecked(isChecked) end function RematchDialogCheckButtonMixin:GetChecked() return self.Check:GetChecked() end function RematchDialogCheckButtonMixin:OnLoad() self.Check:SetScript("OnClick",function(self) rematch.dialog.OnChange(self) end) end function RematchDialogCheckButtonMixin:SetEnabled(isEnabled) self.Check:SetEnabled(isEnabled) end function RematchDialogCheckButtonMixin:Reset() self.Check:Enable() self.Check:SetChecked(false) self.Check.tooltipTitle = nil self.Check.tooltipBody = nil end --[[ Icon dialog control ]] RematchDialogIconMixin = {} function RematchDialogIconMixin:SetTexture(texture) self.Texture:SetTexture(texture) end function RematchDialogIconMixin:SetTexCoord(...) self.Texture:SetTexCoord(...) end --[[ ColorPicker dialog control ]] RematchDialogColorPickerMixin = {} function RematchDialogColorPickerMixin:OnLoad() self.Swatches[1]:SetColor() -- set first swatch to nil/default color local colors = {} -- add expansion colors first for i=0,#C.EXPANSION_COLORS do tinsert(colors,C.EXPANSION_COLORS[i]) end -- add additional group colors for _,color in ipairs(C.COLOR_PICKER_COLORS) do tinsert(colors,color) end for i=1,#colors do self.Swatches[i+1] = CreateFrame("Button",nil,self,"RematchDialogColorPickerSwatchTemplate") if (i)%8==0 then self.Swatches[i+1]:SetPoint("TOPLEFT",self.Swatches[i-7],"BOTTOMLEFT",0,-4) else self.Swatches[i+1]:SetPoint("TOPLEFT",self.Swatches[i],"TOPRIGHT",4,0) end self.Swatches[i+1]:SetColor(colors[i]) end self:SetHeight(ceil((#colors+1)/8)*24-4+8) end function RematchDialogColorPickerMixin:Update() for i=1,#self.Swatches do self.Swatches[i].Selected:SetShown(self.Swatches[i].color==self.color) end end function RematchDialogColorPickerMixin:Set(color) if not color then self:Reset() else self.color = color self:Update() end end function RematchDialogColorPickerMixin:Reset() self.color = nil self:Update() end -- Swatches in color picker dialog control RematchDialogColorPickerSwatchTemplateMixin = {} function RematchDialogColorPickerSwatchTemplateMixin:OnClick() self:GetParent().color = self.color self:GetParent():Update() rematch.dialog.OnChange(self:GetParent()) end --[[ DropDown dialog control ]] RematchDialogDropDownMixin = {} function RematchDialogDropDownMixin:SetLabel(text) if self.Label then self.Label:SetText(text) end end function RematchDialogDropDownMixin:GetSelection() return self.DropDown:GetSelection() end --[[ RematchDialogPetMixin ]] RematchDialogPetMixin = {} function RematchDialogPetMixin:Fill(petID) self.ListButtonPet:Fill(petID) end --[[ RematchDialogTeamMixin ]] RematchDialogTeamMixin = {} function RematchDialogTeamMixin:Fill(teamID) self.ListButtonTeam:Fill(teamID) end --[[ LayoutTabs dialog control ]] RematchDialogLayoutTabsMixin = {} function RematchDialogLayoutTabsMixin:OnLoad() for _,tab in ipairs(self.Tabs) do tab:SetScript("OnClick",self.TabOnClick) end end -- takes an ordered list of {name,layout[,hasStuffFunc,clearStuffFunc]},{name,layout[,hasStuffFunc,clearStuffFunc]},etc (up to 4) and creates tabs -- hasStuffFunc returns true if this tab has stuff to clear (blue highlight in tab) -- clearStuffFunc clears the content in the tab -- clicking one of the tabs changes to the associated named layout function RematchDialogLayoutTabsMixin:SetTabs(layouts) assert(type(layouts)=="table" and type(layouts[1])=="table" and #layouts[1]>=2,"Invalid LayoutTabs. Must be {{tab_name, layout_name}, {tab_name, layout_name}, etc.}") self.layouts = layouts local numTabs = min(#layouts,#self.Tabs) -- maxing at 4 tabs for i=1,numTabs do self.Tabs[i].layout = layouts[i][2] self.Tabs[i]:SetText(layouts[i][1]) self.Tabs[i]:SetSelected(i==1) -- first tab is always first one selected self.Tabs[i]:Show() end for i=numTabs+1,#self.Tabs do self.Tabs[i]:Hide() end self.RightBorder:SetPoint("BOTTOMLEFT",self.Tabs[numTabs],"BOTTOMRIGHT") self.Clear:SetScript("OnClick",function() -- note self is the mixin here using closure local tabNeedsCleared for i=1,#self.layouts do if rematch.dialog:GetDialogInfo().layoutTab==self.layouts[i][2] and type(self.layouts[i][3])=="function" and self.layouts[i][3](self:GetParent()) then tabNeedsCleared = i -- the current tab needs cleared end end -- if tabNeedsCleared define, only clear that tab; otherwise clear all tabs for i=tabNeedsCleared or 1,tabNeedsCleared or #self.layouts do if self.layouts[i][4] and type(self.layouts[i][4])=="function" then self.layouts[i][4](self:GetParent()) -- run the clearStuffFunc for the tab if defined end end self:Update() end) end function RematchDialogLayoutTabsMixin:TabOnClick() local tabs = self:GetParent().Tabs for i=1,#tabs do tabs[i]:SetSelected(self:GetID()==i) end rematch.menus:Hide() rematch.dialog:GetDialogInfo().layoutTab = self:GetParent().layouts[self:GetID()][2] rematch.dialog:ChangeLayout(self.layout) end -- goes to a layout tab by layoutname ("Default", "Preferences", etc; non-localized) function RematchDialogLayoutTabsMixin:GoToTab(layoutTab) -- go through each layout and click the one named for i,tab in ipairs(self.layouts) do if tab[2]==layoutTab then self.Tabs[i]:Click() end end end -- hide the HasStuff blue highlight when layout tabs are hidden function RematchDialogLayoutTabsMixin:OnHide() for _,tab in ipairs(self.Tabs) do tab.HasStuff:Hide() end self.Clear:Hide() end -- call in a dialog's OnChange to update the highlights and whether the clear button is shown function RematchDialogLayoutTabsMixin:Update() local hasStuff = false for i=1,#self.layouts do if self.layouts[i][3] and type(self.layouts[i][3])=="function" and self.layouts[i][3](self:GetParent()) then self.Tabs[i].HasStuff:Show() hasStuff = true else self.Tabs[i].HasStuff:Hide() end end self.Clear:SetShown(hasStuff) end --[[ Small editboxes in preferences dialog control (min/max health/level) ]] RematchDialogNumberEditBoxMixin = {} function RematchDialogNumberEditBoxMixin:OnTextChanged() local text=self:GetText() local valid=text:gsub("[^\.0123456789]","") if text~=valid then self:SetText(valid) end self.Clear:SetShown(valid and valid:len()>0) rematch.dialog:OnChange() end function RematchDialogNumberEditBoxMixin:OnTabPressed() if self.tabNext and self:GetParent()[self.tabNext] then self:GetParent()[self.tabNext]:SetFocus() end end function RematchDialogNumberEditBoxMixin:OnEnterPressed() if rematch.dialog.AcceptButton:IsEnabled() then rematch.dialog.AcceptButton:Click() end end function RematchDialogNumberEditBoxMixin:AllowEdits(enabled) if enabled then self:Enable() self.Label:SetTextColor(1,0.82,0) else self:Disable() self.Label:SetTextColor(0.5,0.5,0.5) self:ClearHighlightText() self.Clear:Hide() end end --[[ Preferences dialog control ]] RematchDialogPreferencesMixin = {} function RematchDialogPreferencesMixin:OnLoad() -- labels self.LevelLabel:SetText(L["Level"]) self.MinLevel.Label:SetText(L["Min:"]) self.MaxLevel.Label:SetText(L["Max:"]) self.HealthLabel:SetText(L["Health"]) self.MinHealth.Label:SetText(L["Min:"]) self.MaxHealth.Label:SetText(L["Max:"]) self.AllowMM:SetText(format(L["%s %s or %s"],L["Allow any"],C.MAGIC_TEXT_ICON,C.MECHANICAL_TEXT_ICON)) self.ExpectedDamage.Label:SetText(L["Expected Damage Taken:"]) -- tooltips self.MinLevel.tooltipTitle = L["Minimum Level"] self.MinLevel.tooltipBody = L["This is the minimum level preferred for a leveling pet.\n\nLevels can be partial amounts. Level 4.33 is level 4 with 33% xp towards level 5."] self.MaxLevel.tooltipTitle = L["Maximum Level"] self.MaxLevel.tooltipBody = L["This is the maximum level preferred for a leveling pet.\n\nLevels can be partial amounts. Level 23.45 is level 23 with 45% xp towards level 24."] self.MinHealth.tooltipTitle = L["Minimum Health"] self.MinHealth.tooltipBody = L["This is the minimum health preferred for a leveling pet.\n\nThe queue will prefer leveling pets with at least this much health (adjusted by expected damage taken if any chosen)."] self.MaxHealth.tooltipTitle = L["Maximum Health"] self.MaxHealth.tooltipBody = L["This is the maximum health preferred for a leveling pet."] self.AllowMM.tooltipTitle = format(L["%s %s or %s"],L["Allow any"],C.MAGIC_TEXT_ICON,C.MECHANICAL_TEXT_ICON) self.AllowMM.tooltipBody = L["Allow low-health and low-level Magic or Mechanical pets to ignore the Minimum Health or Level, since their racials allow them to often survive a hit that would ordinarily kill them."] self.AllowMM:SetScript("OnClick",function(self) rematch.dialog:OnChange() PlaySound(C.SOUND_CHECKBUTTON) end) end -- sets the preferences control to the given values (unordered table of minHP, maxHP, minXP, maxXP, allowMM, expectedDD) function RematchDialogPreferencesMixin:Set(values) if type(values)~="table" then values = {} -- nothing given, clear everything end self.MinHealth:SetText(tonumber(values.minHP) or "") self.MaxHealth:SetText(tonumber(values.maxHP) or "") self.MinLevel:SetText(tonumber(values.minXP) or "") self.MaxLevel:SetText(tonumber(values.maxXP) or "") self.AllowMM:SetChecked(values.allowMM and true) self.expectedDD = tonumber(values.expectedDD) self:UpdateExpectedDamage() rematch.dialog:OnChange() end -- returns the currently picked preferences in the control as an unordered table -- if utable given, preferences will be stored in that table; otherwise a reused table returned local preferencesResults = {} -- reused to minimize garbage creation; but be careful not to assign this table reference to anything! function RematchDialogPreferencesMixin:Get(utable) local results = utable or preferencesResults wipe(results) results.minHP = tonumber(self.MinHealth:GetText()) results.maxHP = tonumber(self.MaxHealth:GetText()) results.minXP = tonumber(self.MinLevel:GetText()) results.maxXP = tonumber(self.MaxLevel:GetText()) results.allowMM = self.AllowMM:GetChecked() or nil results.expectedDD = self.expectedDD return results end -- if disable is true, desaturate all buttons function RematchDialogPreferencesMixin:UpdateExpectedDamage() self.ExpectedDamage.Selected:Hide() for i=1,10 do if self.expectedDD==i and not self.isDisabled then self.ExpectedDamage.Selected:SetPoint("TOPLEFT",self.ExpectedDamage.Buttons[i],"TOPLEFT",-1,1) self.ExpectedDamage.Selected:SetPoint("BOTTOMRIGHT",self.ExpectedDamage.Buttons[i],"BOTTOMRIGHT",1,-1) self.ExpectedDamage.Selected:Show() end if not self.isDisabled then self.ExpectedDamage.Buttons[i]:SetDesaturated(self.expectedDD and self.expectedDD~=i) else self.ExpectedDamage.Buttons[i]:SetDesaturated(true) end end end -- returns true if any control has a value that needs cleared function RematchDialogPreferencesMixin:IsAnyUsed() return (tonumber(self.MinHealth:GetText()) or tonumber(self.MaxHealth:GetText()) or tonumber(self.MinLevel:GetText()) or tonumber(self.MaxLevel:GetText()) or self.AllowMM:GetChecked() or self.expectedDD) and true or false end function RematchDialogPreferencesMixin:SetEnabled(enable) self.isDisabled = not enable self.MinLevel:AllowEdits(enable) self.MaxLevel:AllowEdits(enable) self.MinHealth:AllowEdits(enable) self.MaxHealth:AllowEdits(enable) self.AllowMM:SetEnabled(enable) if enable then self.LevelLabel:SetTextColor(1,0.82,0) self.HealthLabel:SetTextColor(1,0.82,0) self.AllowMM:SetText(format(L["%s %s or %s"],L["Allow any"],C.MAGIC_TEXT_ICON,C.MECHANICAL_TEXT_ICON)) self.ExpectedDamage.Label:SetTextColor(1,0.82,0) self:UpdateExpectedDamage() else self.LevelLabel:SetTextColor(0.5,0.5,0.5) self.HealthLabel:SetTextColor(0.5,0.5,0.5) self.AllowMM:SetText(format(L["%s %s or %s"],L["Allow any"],C.MAGIC_DISABLED_TEXT_ICON,C.MECHANICAL_DISABLED_TEXT_ICON)) self.ExpectedDamage.Label:SetTextColor(0.5,0.5,0.5) self:UpdateExpectedDamage() end end -- automatically called when dialog closes, re-enables preferences if it wasn't enabled function RematchDialogPreferencesMixin:Reset() self:SetEnabled(true) end --[[ Preferences Expected Damage buttons ]] RematchDialogExpectedDDMixin = {} function RematchDialogExpectedDDMixin:OnEnter() if not self:GetParent():GetParent().isDisabled then rematch.textureHighlight:Show(self) end local minHP = tonumber(self:GetParent():GetParent().MinHealth:GetText()) if not minHP then rematch.tooltip:ShowSimpleTooltip(self,L["Expected Damage Taken"],L["The minimum health of pets can be adjusted by the type of damage they are expected to receive."]) else rematch.tooltip:ShowSimpleTooltip(self,format(L["Damage Expected: %s"],rematch.utils:PetTypeAsText(self.key))) rematch.tooltip:AddLine(format(L["Minimum Health: %d"],minHP)) rematch.tooltip:AddLine(format(L[" For %s pets: \124cffffffff%d"],rematch.utils:PetTypeAsText(C.HINTS_OFFENSE[self.key][1]),minHP*1.5)) rematch.tooltip:AddLine(format(L[" For %s pets: \124cffffffff%d"],rematch.utils:PetTypeAsText(C.HINTS_OFFENSE[self.key][2]),minHP*2/3)) rematch.tooltip:Show() end end function RematchDialogExpectedDDMixin:OnLeave() rematch.textureHighlight:Hide() rematch.tooltip:Hide() end function RematchDialogExpectedDDMixin:OnMouseDown() if not self:GetParent():GetParent().isDisabled then rematch.textureHighlight:Hide() end end function RematchDialogExpectedDDMixin:OnMouseUp() if GetMouseFocus()==self and not self:GetParent():GetParent().isDisabled then rematch.textureHighlight:Show(self) local preferences = self:GetParent():GetParent() -- texture -> ExpectedDamage -> Preferences if preferences.expectedDD==self.key then preferences.expectedDD = nil else preferences.expectedDD = self.key end preferences:UpdateExpectedDamage() rematch.dialog:OnChange() end end --[[ Read-Only Preferences for non-editable display of preferences ]] RematchDialogPreferencesReadOnlyMixin = {} function RematchDialogPreferencesReadOnlyMixin:OnLoad() -- labels self.LevelLabel:SetText(L["Level"]) self.MinLevel.Label:SetText(L["Min:"]) self.MaxLevel.Label:SetText(L["Max:"]) self.HealthLabel:SetText(L["Health"]) self.MinHealth.Label:SetText(L["Min:"]) self.MaxHealth.Label:SetText(L["Max:"]) self.ExpectedDamage.Label:SetText(L["Expected Damage Taken:"]) end function RematchDialogPreferencesReadOnlyMixin:Set(values) if type(values)~="table" then values = {} -- nothing given, clear everything end local minHP = tonumber(values.minHP) rematch.utils:SetDimText(self.MinHealth.Label,not minHP) self.MinHealth.Text:SetText(minHP or "") local maxHP = tonumber(values.maxHP) rematch.utils:SetDimText(self.MaxHealth.Label,not maxHP) self.MaxHealth.Text:SetText(tonumber(values.maxHP) or "") local minXP = tonumber(values.minXP) rematch.utils:SetDimText(self.MinLevel.Label,not minXP) self.MinLevel.Text:SetText(minXP or "") local maxXP = tonumber(values.maxXP) rematch.utils:SetDimText(self.MaxLevel.Label,not maxXP) self.MaxLevel.Text:SetText(maxXP or "") rematch.utils:SetDimText(self.LevelLabel,not minXP and not maxXP) rematch.utils:SetDimText(self.HealthLabel,not minHP and not maxHP) rematch.utils:SetDimText(self.ExpectedDamage.Label,not values.expectedDD) self.ExpectedDamage.Selected:Hide() for i=1,10 do if values.expectedDD==i then self.ExpectedDamage.Selected:SetPoint("TOPLEFT",self.ExpectedDamage.Buttons[i],"TOPLEFT",-1,1) self.ExpectedDamage.Selected:SetPoint("BOTTOMRIGHT",self.ExpectedDamage.Buttons[i],"BOTTOMRIGHT",1,-1) self.ExpectedDamage.Selected:Show() end self.ExpectedDamage.Buttons[i]:SetDesaturated(values.expectedDD~=i) end if values.allowMM then self.AllowMM:SetTexture("Interface\\Buttons\\UI-CheckBox-Check") self.AllowMMLabel:SetText(format(L["%s %s or %s"],L["Allow any"],C.MAGIC_TEXT_ICON,C.MECHANICAL_TEXT_ICON)) self.AllowMMLabel:SetTextColor(1,0.82,0) else self.AllowMM:SetTexture("Interface\\Buttons\\UI-CheckBox-Up") self.AllowMMLabel:SetText(format(L["%s %s or %s"],L["Allow any"],C.MAGIC_DISABLED_TEXT_ICON,C.MECHANICAL_DISABLED_TEXT_ICON)) self.AllowMMLabel:SetTextColor(0.5,0.5,0.5) end rematch.utils:SetDimText(self.AllowMMLabel,not values.allowMM) end --[[ IconPicker functions ]] local iconRows = {} -- ordered list of indexes 1..n for each row of icons to display local iconSearch = "" RematchDialogIconPickerMixin = {} function RematchDialogIconPickerMixin:OnLoad() self.SearchBox.Instructions:SetText(L["Search Icons"]) self.List:Setup({ allData = iconRows, normalTemplate = "RematchDialogIconPickerRowTemplate", normalFill = self.FillNormal, normalHeight = 26 }) end function RematchDialogIconPickerMixin:OnShow() self.SearchBox:SetScript("OnTextChanged",function() self:UpdateList() end) if self.SearchBox:GetText()~="" then self.SearchBox.Clear:Click() end end function RematchDialogIconPickerMixin:OnHide() self.SearchBox:SetScript("OnTextChanged",nil) end function RematchDialogIconPickerMixin:UpdateList() -- recreate a list of rows based on the number of icons (potentially reduced by a search happening) wipe(iconRows) iconSearch = self.SearchBox:GetText() for i=1,ceil(#rematch.allIcons:GetIcons(iconSearch)/7) do tinsert(iconRows,i) end self.List:Update() end function RematchDialogIconPickerMixin:FillNormal(row) local allIcons = rematch.allIcons:GetIcons(iconSearch) local numIcons = #allIcons local offset = (row-1)*7 for i=1,#self.Icons do local index = offset + i if index <= numIcons then self.Icons[i]:SetTexture(allIcons[index]) self.Icons[i].fileID = allIcons[index] self.Icons[i]:Show() else self.Icons[i].fileID = nil self.Icons[i]:Hide() end end end function RematchDialogIconPickerMixin:SetIcon(icon) self.Icon:SetTexture(icon) self.icon = icon end function RematchDialogIconPickerMixin:GetIcon() return self.icon or C.REMATCH_ICON end --[[ IconPicker Icon "button"(texture) script handlers ]] RematchDialogIconPickerIconMixin = {} function RematchDialogIconPickerIconMixin:OnEnter() rematch.textureHighlight:Show(self) end function RematchDialogIconPickerIconMixin:OnLeave() rematch.textureHighlight:Hide() end function RematchDialogIconPickerIconMixin:OnMouseDown() rematch.textureHighlight:Hide() end function RematchDialogIconPickerIconMixin:OnMouseUp() if GetMouseFocus()==self then rematch.textureHighlight:Show(self) self:GetParent():GetParent():GetParent():GetParent():GetParent():SetIcon(self.fileID) end end --[[ TeamPicker is a control to list and pick teams or targets that contains a List autoscrollbox and a Picker autoscrollbox ]] RematchDialogTeamPickerMixin = {} function RematchDialogTeamPickerMixin:OnLoad() self.Lister.Top.AddButton:SetText(C.ADD_TEXT_ICON..L[" Add"]) self.Lister.Top.DeleteButton:SetText(C.DELETE_TEXT_ICON..L[" Delete"]) self.Lister.Top.UpButton:SetText(C.UP_TEXT_ICON..L[" Up"]) self.Lister.Top.DownButton:SetText(C.DOWN_TEXT_ICON..L[" Down"]) self.Picker.Top.CancelButton:SetText(CANCEL) self.teamList = {} -- ordered list of teamIDs or targetIDs for Lister self.listType = nil -- C.LIST_MODE_TEAMS, C.LIST_MODE_TARGETS or C.LIST_MODE_GROUPS self.selectedID = nil -- teamID or targetID that's selected in Lister self.pickList = {} -- ordered list of groupIDs/headerIDs and teamIDs/targetIDs for Picker self.pickHeaders = {} -- expanded headers for Picker -- setup autoScrollBox for Lister, the list of teams/targets/groups self.Lister.List:Setup({ allData = self.teamList, normalTemplate = "RematchCompactTeamListButtonTemplate", normalFill = self.FillLister, normalHeight = 26, selects = { Selected = {color={1,0.82,0}, parentKey="Back", drawLayer="ARTWORK"}, }, }) -- setup autoScrollBox self.Picker.List:Setup({ allData = self.pickList, normalTemplate = "RematchCompactTeamListButtonTemplate", normalFill = self.FillPicker, normalHeight = 26, headerTemplate = "RematchHeaderTeamListButtonTemplate", headerFill = self.FillHeader, headerCriteria = self.IsHeader, headerHeight = 26, placeholderTemplate = "RematchPlaceholderListButtonTemplate", placeholderFill = self.FillPlaceholder, placeholderCriteria = self.IsPlaceholder, placeholderHeight = 26, expandedHeaders = self.pickHeaders, allButton = self.Picker.Top.AllButton, searchBox = self.Picker.Top.SearchBox, searchHit = self.PickerSearchHit, onScroll = rematch.menus.Hide, }) for _,button in ipairs({"AddButton","DeleteButton","UpButton","DownButton"}) do self.Lister.Top[button]:SetScript("OnClick",self[button.."OnClick"]) end self.Picker.Top.CancelButton:SetScript("OnClick",self.CancelButtonOnClick) -- deferred script handlers from autoscrollbox self.Lister.List.TeamOnClick = self.ListerButtonOnClick self.Picker.List.HeaderOnClick = self.PickerHeaderOnClick self.Picker.List.TeamOnClick = self.PickerButtonOnClick end function RematchDialogTeamPickerMixin:SetList(listType,teamList) assert(listType==C.LIST_TYPE_TEAM or listType==C.LIST_TYPE_TARGET or listType==C.LIST_TYPE_GROUP,"Invalid list type for dialog team list") assert(type(teamList)=="table","Invalid list for dialog team list") self.listType = listType wipe(self.teamList) -- making a copy of the table for _,id in ipairs(teamList) do tinsert(self.teamList,id) end self.Lister:Show() self.Picker:Hide() self.Lister.List:Select("Selected",nil,true) -- clear selected but don't refresh (following update will do that) self:UpdateLister() end function RematchDialogTeamPickerMixin:GetList() return CopyTable(self.teamList) -- don't pass a reference to this table to minimize anything messing it up end -- when dialog hides, this will wipe the lists/search function RematchDialogTeamPickerMixin:Reset() wipe(self.teamList) wipe(self.pickList) wipe(self.pickHeaders) self.Picker.Top.SearchBox.Clear:Click() end -- for use with clear button on layout tabs, clears list and returns to lister function RematchDialogTeamPickerMixin:Clear() wipe(self.teamList) self.Picker:Hide() self.Lister:Show() self:UpdateLister() rematch.dialog:OnChange() end --[[ Lister functions ]] function RematchDialogTeamPickerMixin:FillLister(id) self:Fill(id) end -- updates the Lister list (if justButtons not true) and the Add/Delete/Up/Down buttons function RematchDialogTeamPickerMixin:UpdateLister(justButtons) if not justButtons then self.Lister.List:Update() end -- enable/disable Delete/Up/Down buttons local selectedData = self.Lister.List:GetSelected("Selected") local enableDelete = selectedData and true or false -- if anything selected, delete enabled self.Lister.Top.DeleteButton:SetEnabled(enableDelete) self.Lister.Top.DeleteButton:SetText(format("%s %s",enableDelete and C.DELETE_TEXT_ICON or C.DELETE_DISABLED_TEXT_ICON,L["Delete"])) local enableUp = selectedData and self.teamList[1]~=selectedData -- if any but topmost data selected, up enabled self.Lister.Top.UpButton:SetEnabled(enableUp) self.Lister.Top.UpButton:SetText(format("%s %s",enableUp and C.UP_TEXT_ICON or C.UP_DISABLED_TEXT_ICON,L["Up"])) local enableDown = selectedData and self.teamList[#self.teamList]~=selectedData -- if any but bottommost data selected, down enabled self.Lister.Top.DownButton:SetEnabled(enableDown) self.Lister.Top.DownButton:SetText(format("%s %s",enableDown and C.DOWN_TEXT_ICON or C.DOWN_DISABLED_TEXT_ICON,L["Down"])) end -- click of a teamID/targetID in the Lister panel always selects the teamID/targetID and updates the list function RematchDialogTeamPickerMixin:ListerButtonOnClick(button) if button~="RightButton" then local list = self:GetParent():GetParent():GetParent() -- the AutoScrollBox List local parent = list:GetParent():GetParent() -- the TeamPicker control list:Select("Selected",self.teamID or self.targetID) parent:UpdateLister(true) -- whole list doesn't need updated, just the buttons end end function RematchDialogTeamPickerMixin:AddButtonOnClick() local parent = self:GetParent():GetParent():GetParent() -- the TeamPicker control parent.Lister:Hide() parent.Picker:Show() if parent.listType==C.LIST_TYPE_TARGET then wipe(parent.pickList) rematch.targetsPanel:PopulateTargetList(parent.pickList) elseif parent.listType==C.LIST_TYPE_TEAM then rematch.teamsPanel:PopulateTeamList(parent.pickList) else wipe(parent.pickList) end parent.Picker.List:Update() end -- deletes the selected id from the teamList function RematchDialogTeamPickerMixin:DeleteButtonOnClick() local list = self:GetParent():GetParent().List -- the AutoScrollBox List local parent = self:GetParent():GetParent():GetParent() -- the TeamPicker control local selectedData = list:GetSelected("Selected") local index = rematch.utils:GetIndexByValue(parent.teamList,selectedData) if index then rematch.utils:TableRemoveByValue(parent.teamList,selectedData) local newData = parent.teamList[max(index-1,1)] -- it's okay if it's nil (list empty) list:Select("Selected",newData,true) -- change selection to the previous teamID/targetID that remains parent:UpdateLister() rematch.dialog:OnChange() end end -- moves the selected id up the teamList function RematchDialogTeamPickerMixin:UpButtonOnClick() local list = self:GetParent():GetParent().List -- the AutoScrollBox List local parent = self:GetParent():GetParent():GetParent() -- the TeamPicker control local selectedData = list:GetSelected("Selected") local index = rematch.utils:GetIndexByValue(parent.teamList,selectedData) if index>1 then local tempData = parent.teamList[index-1] -- swap values at index and index-1 parent.teamList[index-1] = selectedData parent.teamList[index] = tempData parent:UpdateLister() rematch.dialog:OnChange() end end -- moves the selected id down the teamList function RematchDialogTeamPickerMixin:DownButtonOnClick() local list = self:GetParent():GetParent().List -- the AutoScrollBox List local parent = self:GetParent():GetParent():GetParent() -- the TeamPicker control local selectedData = list:GetSelected("Selected") local index = rematch.utils:GetIndexByValue(parent.teamList,selectedData) if index < #parent.teamList then local tempData = parent.teamList[index+1] -- swap values at index and index+1 parent.teamList[index+1] = selectedData parent.teamList[index] = tempData parent:UpdateLister() rematch.dialog:OnChange() end end -- click of Cancel in the Picker part of the control, returns to Lister frame function RematchDialogTeamPickerMixin:CancelButtonOnClick() local parent = self:GetParent():GetParent():GetParent() -- the TeamPicker control parent.Picker:Hide() parent.Lister:Show() end --[[ Picker functions ]] function RematchDialogTeamPickerMixin:FillPicker(id) self:Fill(id) end function RematchDialogTeamPickerMixin:FillHeader(id) self:Fill(id) end -- if listType is target, then picker is display teams and vice versa function RematchDialogTeamPickerMixin:FillPlaceholder(id) local list = self:GetParent():GetParent():GetParent() -- the AutoScrollBox List local parent = list:GetParent():GetParent() -- the TeamPicker control if parent.listType==C.LIST_TYPE_TEAM then rematch.teamsPanel.FillPlaceholder(self,id) elseif parent.listType==C.LIST_TYPE_TARGET then rematch.targetsPanel.FillPlaceholder(self,id) end end function RematchDialogTeamPickerMixin:IsHeader(id) return type(id)=="string" and (id:match("^group:") or id:match("^header")) and true or false end function RematchDialogTeamPickerMixin:IsPlaceholder(id) return type(id)=="string" and id:match("^placeholder:") and true or false end function RematchDialogTeamPickerMixin:PickerHeaderOnClick() local list = self:GetParent():GetParent():GetParent() -- the AutoScrollBox List list:ToggleHeader(self.groupID or self.headerID) end function RematchDialogTeamPickerMixin:PickerButtonOnClick(button) local list = self:GetParent():GetParent():GetParent() -- the AutoScrollBox List local parent = list:GetParent():GetParent() -- the TeamPicker control local id = self.teamID or self.targetID if id then rematch.utils:TableInsertDistinct(parent.teamList,id) parent.Picker:Hide() parent.Lister:Show() parent.Lister.List:Select("Selected",id) parent:UpdateLister() parent.Lister.List:BlingData(id) rematch.dialog:OnChange() end end function RematchDialogTeamPickerMixin:PickerSearchHit(mask,id) local parent = self:GetParent():GetParent() -- the TeamPicker control if parent.listType==C.LIST_TYPE_TEAM then -- if list type is target, searching teams return rematch.teamsPanel.SearchHit(self,mask,id) elseif parent.listType==C.LIST_TYPE_TARGET then -- if list type is team, searching targets return rematch.targetsPanel.SearchHit(self,mask,id) else return false end end --[[ group picker ]] RematchDialogGroupPickerMixin = {} function RematchDialogGroupPickerMixin:OnLoad() self.Top.CancelButton.Text:SetText(CANCEL) self.Top.Label:SetText(L["Choose a group for this team"]) self.Top.CancelButton:SetScript("OnClick",function(self) rematch.dialog:ChangeLayout(self:GetParent():GetParent().returnLayout or "Default") end) self.groupList = {} -- ordered list of groupIDs to list -- setup autoScrollBox for Lister, the list of teams/targets/groups self.List:Setup({ allData = self.groupList, normalTemplate = "RematchDialogGroupPickerListButtonTemplate", normalFill = self.FillGroup, normalHeight = 26 }) end -- sets the layout to return to when group picked or cancelled -- if noSideline is true then it also makes the list take up the whole control without a "Pick a team" cancel prompt function RematchDialogGroupPickerMixin:SetReturn(layoutName,noSideline) self.returnLayout = layoutName self.noSideline = noSideline if noSideline then self.Top:Hide() self.List:SetPoint("TOPLEFT",self.Top,"TOPLEFT") else self.Top:Show() self.List:SetPoint("TOPLEFT",self.Top,"BOTTOMLEFT",0,-2) end end function RematchDialogGroupPickerMixin:Update() wipe(self.groupList) for _,groupID in ipairs(settings.GroupOrder) do tinsert(self.groupList,groupID) end self.List:Update() end function RematchDialogGroupPickerMixin:OnShow() self:Update() self.List:ScrollToTop() end function RematchDialogGroupPickerMixin:FillGroup(groupID) self.groupID = groupID self.Text:SetText(rematch.utils:GetFormattedGroupName(groupID)) local group = groupID and rematch.savedGroups[groupID] self.Icon:SetTexture(group and group.icon or "Interface\\Icons\\INV_Misc_QuestionMark") local xoff = -22 rematch.badges:ClearBadges(self.Badges) if group.preferences then rematch.badges:AddBadge(self.Badges,"preferences","RIGHT",self.Icon,"LEFT",-2,-1,-1) xoff = xoff - C.BADGE_SIZE - 1 end self.Text:SetPoint("BOTTOMRIGHT",xoff,2) end RematchDialogGroupPickerListButtonMixin = {} function RematchDialogGroupPickerListButtonMixin:OnEnter() rematch.textureHighlight:Show(self.Back) end function RematchDialogGroupPickerListButtonMixin:OnLeave() rematch.textureHighlight:Hide() end function RematchDialogGroupPickerListButtonMixin:OnMouseDown() rematch.textureHighlight:Hide() end function RematchDialogGroupPickerListButtonMixin:OnMouseUp() if GetMouseFocus()==self then rematch.textureHighlight:Show(self.Back) end end function RematchDialogGroupPickerListButtonMixin:OnClick(button) if button~="RightButton" then local picker = self:GetParent():GetParent():GetParent():GetParent() if not picker.noSideline then rematch.savedTeams.sideline.groupID = self.groupID end settings.LastSelectedGroup = self.groupID rematch.dialog:OnChange() rematch.dialog:ChangeLayout(picker.returnLayout or "Default") end end --[[ combobox is a combination editbox and dropdown ]] RematchDialogComboBoxMixin = {} function RematchDialogComboBoxMixin:OnLoad() self.ComboBox.Text:SetScript("OnEscapePressed",function(self,...) rematch.dialog.CancelButton:Click() end) self.ComboBox.Text:SetScript("OnEnterPressed",function(self,...) if rematch.dialog.AcceptButton:IsEnabled() then rematch.dialog.AcceptButton:Click() end end) self.ComboBox.Text:SetScript("OnTextChanged",function(self,...) rematch.dialog:OnChange() -- function to call the changeFunc when text changes end) end function RematchDialogComboBoxMixin:SetText(text) self.ComboBox.Text:SetText(text) end function RematchDialogComboBoxMixin:GetText() return self.ComboBox.Text:GetText() end function RematchDialogComboBoxMixin:SetLabel(text) self.Label:SetText(text) end function RematchDialogComboBoxMixin:SetList(list) local menu = {} for index,text in ipairs(list) do tinsert(menu,{text=text,value=index}) end self.ComboBox:BasicSetup(menu) end function RematchDialogComboBoxMixin:SetTextColor(r,g,b) self.ComboBox.Text:SetTextColor(r,g,b) end --[[ pet button with pet card mouse events ]] RematchDialogPetButtonMixin = {} function RematchDialogPetButtonMixin:OnEnter() rematch.textureHighlight:Show(self.Icon) rematch.cardManager:OnEnter(rematch.petCard,self,self.petID) end function RematchDialogPetButtonMixin:OnLeave() rematch.textureHighlight:Hide() rematch.cardManager:OnLeave(rematch.petCard,self,self.petID) end function RematchDialogPetButtonMixin:OnMouseDown() rematch.textureHighlight:Hide() end function RematchDialogPetButtonMixin:OnMouseUp() if GetMouseFocus()==self then rematch.textureHighlight:Show(self.Icon) end end function RematchDialogPetButtonMixin:OnClick() rematch.cardManager:OnClick(rematch.petCard,self,self.petID) end --[[ pet with abilities is a single pet button with an ability bar]] RematchDialogPetWithAbilitiesMixin = {} -- fills the pet and abilities function RematchDialogPetWithAbilitiesMixin:Fill(petID,ability1,ability2,ability3) self.Pet.petID = petID self.Pet:FillPet(petID) self.AbilityBar:FillAbilityBar(petID,ability1,ability2,ability3) end -- fills the pet and abilities from the given loadout slot function RematchDialogPetWithAbilitiesMixin:FillFromLoadout(slot) self:Fill(C_PetJournal.GetPetLoadOutInfo(slot)) end -- fills the pets and abilities from the given teamID slot function RematchDialogPetWithAbilitiesMixin:FillFromTeamID(slot,teamID) local team = rematch.savedTeams[teamID] if team then self:Fill(team.pets[slot],rematch.petTags:GetAbilities(team.tags[slot])) else -- if team doesn't exist, make it an empty pet and abilities self:Fill("empty") end end --[[ team with abilities is 3 pets with abilities ]] RematchDialogTeamWithAbilitiesMixin = {} function RematchDialogTeamWithAbilitiesMixin:FillFromLoadout() for i=1,3 do self.Pets[i]:FillFromLoadout(i) end end function RematchDialogTeamWithAbilitiesMixin:FillFromTeamID(teamID) for i=1,3 do self.Pets[i]:FillFromTeamID(i,teamID) end end --[[ RematchDialogGroupSelectMixin ]] RematchDialogGroupSelectMixin = {} function RematchDialogGroupSelectMixin:OnLoad() self.Label:SetText(L["Group:"]) self.Button:SetScript("OnEnter",function(self) for i=1,3 do self.Highlights[i]:Show() end end) self.Button:SetScript("OnLeave",function(self) for i=1,3 do self.Highlights[i]:Hide() end end) self.Button:SetScript("OnMouseDown",self.Button:GetScript("OnLeave")) self.Button:SetScript("OnMouseUp",function(self) if GetMouseFocus()==self then self:GetScript("OnEnter")(self) end end) self.Button:SetScript("OnClick",function(self) rematch.dialog:ChangeLayout(self:GetParent().returnLayout or "GroupPick") end) end function RematchDialogGroupSelectMixin:Fill(groupID) groupID = groupID or "group:none" local group = rematch.savedGroups[groupID] or rematch.savedGroups["group:none"] self.Button.Name:SetText(rematch.utils:GetFormattedGroupName(groupID)) self.Button.Icon:SetTexture(group.icon) local xoff = -22 rematch.badges:ClearBadges(self.Button.Badges) if group.preferences then rematch.badges:AddBadge(self.Button.Badges,"preferences","RIGHT",self.Button.Icon,"LEFT",-2,-1,-1) xoff = xoff - C.BADGE_SIZE - 1 end self.Button.Name:SetPoint("RIGHT",xoff,-1) end -- sets the layout to return to when the button is clicked function RematchDialogGroupSelectMixin:SetReturn(layoutName) self.returnLayout = layoutName end function RematchDialogGroupSelectMixin:Reset() self.returnLayout = nil end --[[ RematchDialogWinRecordMixin ]] RematchDialogWinRecordMixin = {} function RematchDialogWinRecordMixin:OnLoad() self.Wins.Label:SetText(format("%s%s ",C.HEX_GREEN,L["Wins:"])) self.Wins:SetJustifyH("CENTER") self.Losses.Label:SetText(format("%s%s ",C.HEX_RED,L["Losses:"])) self.Losses:SetJustifyH("CENTER") self.Draws.Label:SetText(format("%s%s ",C.HEX_GOLD,L["Draws:"])) self.Draws:SetJustifyH("CENTER") end -- updates the display of total battles and disables the minus buttons for stats at 0 (which are nil; winrecord never keeps a 0 value) -- (this doesn't update editboxes, that's only done in a Set which also calls this) function RematchDialogWinRecordMixin:Update() local winrecord = self:Get() self.WinsMinus:SetEnabled(winrecord.wins and true or false) self.LossesMinus:SetEnabled(winrecord.losses and true or false) self.DrawsMinus:SetEnabled(winrecord.draws and true or false) self.TotalBattles:SetText(format(L["Total Battles: %s%s"],C.HEX_WHITE,winrecord.battles>0 and winrecord.battles or L["None"])) if winrecord.battles>0 then local percent = floor(0.5+(winrecord.wins or 0)*100/winrecord.battles) self.WinRate:SetText(format(L["Win Rate: %d%%"],percent)) if percent >= 60 then self.WinRate:SetTextColor(0.25,0.75,0.25) elseif percent <= 40 then self.WinRate:SetTextColor(1,0.25,0.25) else self.WinRate:SetTextColor(1,0.82,0) end self.WinRate:Show() else self.WinRate:Hide() -- don't show rate if there's no battles end end -- clicking a + or - beside one of the editboxes will increment/decrement the value in the editbox (empty of 0) -- parentKey is either "Wins", "Losses" or "Draws"; modifier is either -1 or +1 function RematchDialogWinRecordMixin:AdjustEditBox(parentKey,modifier) local value = max(0,tonumber(self[parentKey]:GetText()) or 0) + modifier -- the OnTextChanged in the editbox will trigger an OnChange that does an Update self[parentKey]:SetText(value<1 and "" or value) end -- sets the winrecord control to the given values (unordered table of wins, losses, draws, battles) function RematchDialogWinRecordMixin:Set(winrecord) if type(winrecord)~="table" then winrecord = {} -- nothing given, clear everything end self.Wins:SetText(winrecord.wins or "") self.Losses:SetText(winrecord.losses or "") self.Draws:SetText(winrecord.draws or "") rematch.dialog:OnChange() end -- returns the current winrecord values in the control as an unordered table -- if utable given, winrecord will be stored in that table; otherwise a reused table returned local winrecordResults = {} -- reused to minimize garbage creation; but be careful not to assign this table reference to anything! function RematchDialogWinRecordMixin:Get(utable) local results = utable or winrecordResults wipe(results) results.wins = tonumber(self.Wins:GetText()) results.losses = tonumber(self.Losses:GetText()) results.draws = tonumber(self.Draws:GetText()) results.battles = (results.wins or 0) + (results.losses or 0) + (results.draws or 0) return results end --[[ IncludeCheckButtons ]] RematchDialogIncludeCheckButtons = {} function RematchDialogIncludeCheckButtons:OnLoad() self.IncludePreferences:SetText(L["Include Preferences"]) self.IncludeNotes:SetText(L["Include Notes"]) self.IncludePreferences:SetScript("OnClick",function() rematch.dialog:OnChange() end) self.IncludeNotes:SetScript("OnClick",function() rematch.dialog:OnChange() end) end -- sets the check for settings and enables/disbaled for the given teamID (if any) function RematchDialogIncludeCheckButtons:Update(teamID) self.IncludePreferences:SetChecked(settings.ExportIncludePreferences) self.IncludeNotes:SetChecked(settings.ExportIncludeNotes) self.IncludePreferences:SetEnabled(not teamID or (rematch.savedTeams[teamID] and rematch.savedTeams[teamID].preferences and true or false)) self.IncludeNotes:SetEnabled(not teamID or (rematch.savedTeams[teamID] and rematch.savedTeams[teamID].notes and true or false)) end --[[ RematchDialogListDataMixin ]] RematchDialogListDataMixin = {} -- data should be an ordered list with a sub-ordered list of values, for example: -- { {"This is line 1",1}, -- {"This is second line","two"} -- {"This line","III"}, etc. } function RematchDialogListDataMixin:Set(data) local maxLabelWidth = 0 local maxDataWidth = 0 local height = 0 for i,info in ipairs(data) do if not self.ListItems[i] then -- if a ListItem isn't made for this row yet, make one self.ListItems[i] = CreateFrame("Frame",nil,self,"RematchDialogListItemTemplate") self.ListItems[i]:SetPoint("TOPLEFT",self.ListItems[i-1],"BOTTOMLEFT") self.ListItems[i]:SetPoint("TOPRIGHT",self.ListItems[i-1],"BOTTOMRIGHT") end local item = self.ListItems[i] item:Show() item.Label:SetText(info[1]) item.Data:SetText(info[2]) maxLabelWidth = max(maxLabelWidth,item.Label:GetStringWidth()) maxDataWidth = max(maxDataWidth,item.Data:GetStringWidth()) height = height + floor(item:GetHeight()+0.5) end -- hide any leftover listitem frames for i=#data+1,#self.ListItems do self.ListItems[i]:Hide() end self:SetHeight(height) self:SetWidth(maxLabelWidth+maxDataWidth+8) end --[[ RematchDialogConflictRadiosMixin ]] RematchDialogConflictRadiosMixin = {} function RematchDialogConflictRadiosMixin:OnLoad() self.Label:SetText(L["When teams/groups share the same name:"]) self.CreateCopyRadio:SetText(L["Create a new copy"]) self.OverwriteRadio:SetText(L["Overwrite existing one"]) self:SetWidth(max(self.CreateCopyRadio.Text:GetStringWidth(),self.OverwriteRadio.Text:GetStringWidth())+30) end function RematchDialogConflictRadiosMixin:Update() local overwrite = settings.ImportConflictOverwrite self.CreateCopyRadio:SetChecked(not overwrite) self.OverwriteRadio:SetChecked(overwrite) end function RematchDialogConflictRadiosMixin:SetImportConflictOverwrite(overwrite) settings.ImportConflictOverwrite = overwrite self:Update() rematch.dialog:OnChange() end function RematchDialogConflictRadiosMixin:IsOverwrite() return settings.ImportConflictOverwrite end --[[ RematchDialogMultiTeamMixin ]] RematchDialogMultiTeamMixin = {} -- takes an ordered list of teamIDs and displays the first one with option to select different teams function RematchDialogMultiTeamMixin:SetTeams(teams,index) if type(teams)~="table" then teams = {} index = nil end self.teams = teams self.index = index self.PrevTeamButton:SetShown(#teams>1) self.NextTeamButton:SetShown(#teams>1) self.ListButtonTeam:SetPoint("BOTTOMRIGHT",#teams>1 and -22 or 0,0) self:Update() end function RematchDialogMultiTeamMixin:Update() local teamID = type(self.teams)=="table" and self.index and self.teams[self.index] local team = teamID and rematch.savedTeams[teamID] self.ListButtonTeam:SetShown(team and true or false) self.ListButtonTeam.teamID = teamID self.ListButtonTeam:Fill(teamID) -- regular team list button fill doesn't do status; do that here if team and team.pets then for i=1,3 do local petInfo = rematch.petInfo:Fetch(team.pets[i]) if petInfo.isDead then self.ListButtonTeam.Status[i]:SetTexCoord(0,0.3125,0,0.625) self.ListButtonTeam.Status[i]:Show() elseif petInfo.isInjured then self.ListButtonTeam.Status[i]:SetTexCoord(0.3125,0.625,0,0.625) self.ListButtonTeam.Status[i]:Show() else self.ListButtonTeam.Status[i]:Hide() end end end self.PrevTeamButton:SetEnabled(self.index~=1) self.NextTeamButton:SetEnabled(self.index~=#self.teams) end function RematchDialogMultiTeamMixin:PrevTeam() self.index = max(self.index-1,1) self:Update() end function RematchDialogMultiTeamMixin:NextTeam() self.index = min(self.index+1,#self.teams) self:Update() end -- returns the currently-chosen teamID function RematchDialogMultiTeamMixin:GetTeamID() local teamID = self.ListButtonTeam.teamID return rematch.savedTeams[teamID] and teamID end --[[ RematchDialogSliderMixin ]] RematchDialogSliderMixin = {} function RematchDialogSliderMixin:OnLoad() self.Slider:RegisterCallback("OnValueChanged",function(_,value) local oldValue = self.value self.value = value self:Update() -- for setting up changing callbacks if self.onValueChangedFunc and oldValue~=value then self.onValueChangedFunc(self,value) end end) end -- refreshFunc should call this to set up the slider and its label format and callback function -- here steps is number of steps, so 50 to 200 with 5 increment would be -- labelFormat is a string.format pattern for the label above the slider, such as "Scale: %d%%" -- onValueChangedFunc will be called with (self,value) where self is the slider dialog control function RematchDialogSliderMixin:Setup(value,minValue,maxValue,steps,labelFormat,onValueChangedFunc) self.Slider:Init(value,minValue,maxValue,steps) self.labelFormat = labelFormat or "%s" self.value = value -- initial value if type(onValueChangedFunc)=="function" then self.onValueChangedFunc = onValueChangedFunc end self:Update() end function RematchDialogSliderMixin:Update() local labelFormat = self.labelFormat or "%s" self.Label:SetText(format(labelFormat,self.value or "")) end function RematchDialogSliderMixin:Reset() self.onValueChanged = nil end --[[ RematchDialogBarChartMixin ]] RematchDialogBarChartMixin = {} -- sets the chart to display the given info, which is an ordered list of: -- [1] = {icon="file", value=number, max=maxValue, r=red, g=green, b=blue} function RematchDialogBarChartMixin:Set(info) local numBars = #info -- create new bars if any needed for i=2,numBars do if not self.Bars[i] then self.Bars[i] = CreateFrame("Frame",nil,self,"RematchDialogBarChartBarTemplate") self.Bars[i]:SetPoint("BOTTOMLEFT",self.Bars[i-1],"BOTTOMRIGHT") end end -- show only bars that should be shown for i,bar in ipairs(self.Bars) do bar:SetShown(i<=numBars) bar:SetWidth(250/numBars) end for i,info in ipairs(info) do self.Bars[i].Bar:SetVertexColor(info.r or 1,info.g or 1,info.b or 1) local value = info.value local maxValue = info.maxValue and max(0.1,info.maxValue) or 0.1 local formattedValue = info.formattedValue and format(info.formattedValue,value) or value self.Bars[i].Bar:SetHeight(max(0.1,min(148,value*148/maxValue))) self.Bars[i].Value:SetText(formattedValue) --bar.Bar:SetHeight(random(148)) self.Bars[i].Icon:SetTexture(info.icon) end end --[[ RematchDialogBattleSummaryMixin ]] RematchDialogBattleSummaryMixin= {} function RematchDialogBattleSummaryMixin:OnLoad() self.WinLabel:SetText(L["Won"]) self.LossLabel:SetText(L["Lost"]) self.DrawLabel:SetText(L["Draw"]) end -- fills the BattleSummary control with totals of all team battles and returns teamID of team that won the most function RematchDialogBattleSummaryMixin:Fill() local battles = 0 local teams = 0 local wins = 0 local losses = 0 local draws = 0 local bestTeamID local bestTeamIDWins = 0 for teamID,team in rematch.savedTeams:AllTeams() do if team.winrecord then local recordWins = team.winrecord.wins or 0 local recordLosses = team.winrecord.losses or 0 local recordDraws = team.winrecord.draws or 0 local recordBattles = team.winrecord.battles or recordWins+recordLosses+recordDraws teams = teams + 1 battles = battles + recordBattles wins = wins + recordWins losses = losses + recordLosses draws = draws + recordDraws if recordWins > bestTeamIDWins then bestTeamID = teamID bestTeamIDWins = recordWins end end end self.TotalBattles:SetText(format(L["%s%d\124r Battles for %s%d\124r Teams"],C.HEX_WHITE,battles,C.HEX_WHITE,teams)) self.WinAmount:SetText(wins) self.LossAmount:SetText(losses) self.DrawAmount:SetText(draws) self.WinPercent:SetText(battles>0 and floor(wins*100/battles+0.5).."%" or "--") self.LossPercent:SetText(battles>0 and floor(losses*100/battles+0.5).."%" or "--") self.DrawPercent:SetText(battles>0 and floor(draws*100/battles+0.5).."%" or "--") return bestTeamID end