skillPlanContents.py (9568B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\skillPlan\contents\skillPlanContents.py 2 import blue 3 import evetypes 4 import itertoolsext 5 from carbon.common.script.sys.serviceConst import ROLE_GML 6 from carbonui import uiconst 7 from carbonui.control.button import Button 8 from carbonui.control.checkbox import Checkbox 9 from carbonui.control.scrollContainer import ScrollContainer 10 from carbonui.primitives.container import Container 11 from carbonui.primitives.containerAutoSize import ContainerAutoSize 12 from carbonui.uicore import uicore 13 from eve.client.script.ui.control.eveLabel import EveCaptionLarge 14 from eve.client.script.ui.control.utilMenu import UtilMenu 15 from eve.client.script.ui.quickFilter import QuickFilterEdit 16 from eve.client.script.ui.skillPlan.contents.SkillPlanContentsSkillEntry import SkillPlanContentsSkillEntry 17 from eve.client.script.ui.skillPlan.skillPlanConst import NO_REQ 18 from eve.client.script.ui.skillPlan.skillPlanUtil import GetPreReqsAndRequiredForSkillLevel, GetRequirementStateForEntry 19 from eve.client.script.ui.skillPlan.skillQueuePanel.skillQueueButtons import OmegaButton 20 from eveui import clipboard 21 from localization import GetByLabel 22 from player_messaging.client.ui_message import prompt_player_fsd_dialog 23 from skills.client.util import buy_missing_skills 24 from skills.skillplan.loggers.skillPlanLogger import log_certified_skill_plan_buy_missing_skillbooks_clicked, log_certified_skill_plan_omega_button_clicked 25 from skills.skillplan.skillPlanService import GetSkillPlanSvc 26 27 def IsHideTrainedSkillsEnabled(): 28 return settings.char.ui.Get('SkillPlanContentsHideTrained', True) 29 30 31 def SetHideTrainedSkillsEnabled(isEnabled): 32 settings.char.ui.Set('SkillPlanContentsHideTrained', isEnabled) 33 34 35 class SkillPlanOmegaButton(OmegaButton): 36 37 def ApplyAttributes(self, attributes): 38 super(SkillPlanOmegaButton, self).ApplyAttributes(attributes) 39 self.skillPlan = attributes.skillPlan 40 41 def OnClick(self, *args): 42 super(SkillPlanOmegaButton, self).OnClick(*args) 43 if self.skillPlan.IsCertified(): 44 log_certified_skill_plan_omega_button_clicked(self.skillPlan.GetID()) 45 46 def SetSkillPlan(self, skillPlan): 47 self.skillPlan = skillPlan 48 49 50 class SkillPlanContents(Container): 51 __notifyevents__ = ['OnSkillsChanged', 52 'OnSkillQueueChanged', 53 'OnSubscriptionChanged', 54 'OnSkillsAvailable'] 55 56 def ApplyAttributes(self, attributes): 57 super(SkillPlanContents, self).ApplyAttributes(attributes) 58 sm.RegisterNotify(self) 59 self.skillPlan = None 60 self.entries = [] 61 self.askedAboutTracking = False 62 self.topCont = ContainerAutoSize(name='topCont', parent=self, align=uiconst.TOTOP, alignMode=uiconst.TOPLEFT, padBottom=10) 63 self.ConstructTopCont() 64 self.filtersCont = Container(name='filtersCont', parent=self, align=uiconst.TOTOP, height=26, padBottom=20) 65 self.ConstructFiltersCont() 66 self.skillbooksMissingBtn = Button(parent=self, align=uiconst.TOBOTTOM, state=uiconst.UI_HIDDEN, func=self.OnMissingSkillbooksButton, padTop=5, analyticID='BuyAllMissingSkillbooks') 67 self.omegaButton = SkillPlanOmegaButton(name='omegaButton', parent=self, align=uiconst.TOBOTTOM, iconSize=32, fixedheight=36, padTop=10, label=GetByLabel('UI/CloneState/UpgradeCloneState'), skillPlan=self.skillPlan) 68 self.scroll = ScrollContainer(parent=self, align=uiconst.TOALL) 69 70 def ConstructTopCont(self): 71 EveCaptionLarge(parent=self.topCont, name='skillPlanOverviewLabel', align=uiconst.TOPLEFT, text=GetByLabel('UI/SkillPlan/SkillPlanOverview')) 72 UtilMenu(parent=self.topCont, align=uiconst.CENTERRIGHT, texturePath='res:/UI/Texture/Icons/77_32_49.png', pos=(-5, 0, 24, 24), GetUtilMenu=self.GetUtilMenu, iconSize=24) 73 74 def ConstructFiltersCont(self): 75 self.quickFilterEdit = QuickFilterEdit(parent=self.filtersCont, align=uiconst.TORIGHT, width=140, callback=self.OnQuickFilterEdit) 76 checkboxCont = Container(name='checkboxCont', parent=self.filtersCont, clipChildren=True) 77 Checkbox(parent=checkboxCont, align=uiconst.CENTERLEFT, text=GetByLabel('UI/SkillPlan/HideTrainedSkills'), callback=self.OnHideTrainedCheckbox, checked=IsHideTrainedSkillsEnabled()) 78 79 def GetUtilMenu(self, menuParent): 80 menuParent.AddIconEntry(icon='res:/UI/Texture/classes/UtilMenu/BulletIcon.png', text=GetByLabel('UI/SkillPlan/CopySkillsToClipboard'), callback=self.CopySkillsToClipboard) 81 if session.role & ROLE_GML: 82 menuParent.AddIconEntry(icon='res:/UI/Texture/classes/UtilMenu/BulletIcon.png', text='Train all skills', callback=self._TrainAllSkillsInPlan) 83 84 def _TrainAllSkillsInPlan(self): 85 if session.role & ROLE_GML: 86 skillsAndLevels = {t:l for t, l in self.skillPlan.GetSkillRequirements()} 87 sm.GetService('info').DoGiveSkills(skillsAndLevels, None) 88 89 def CopySkillsToClipboard(self): 90 clipboard.set(self.skillPlan.GetRequirementsClipboardText()) 91 92 def OnHideTrainedCheckbox(self, cb, *args): 93 SetHideTrainedSkillsEnabled(cb.GetValue()) 94 self.PopulateScroll() 95 96 def OnQuickFilterEdit(self): 97 self.PopulateScroll() 98 99 def OnMissingSkillbooksButton(self, *args): 100 skillsBought = buy_missing_skills(self.skillPlan.GetMissingSkillbooks()) 101 if skillsBought and self.skillPlan.IsCertified(): 102 log_certified_skill_plan_buy_missing_skillbooks_clicked(self.skillPlan.GetID()) 103 104 def SetSkillPlan(self, skillPlan): 105 if skillPlan != self.skillPlan: 106 self.skillPlan = skillPlan 107 self.UpdateSkillsMissingBanner() 108 self.UpdateOmegaBanner() 109 self.omegaButton.SetSkillPlan(skillPlan) 110 self.PopulateScroll() 111 112 def UpdateSkillsMissingBanner(self): 113 if not self.skillPlan: 114 return 115 numMissing = len(self.skillPlan.GetMissingSkillbooks()) 116 if numMissing: 117 self.skillbooksMissingBtn.label = GetByLabel('UI/SkillPlan/BuyMissingSkillbooks', numMissing=numMissing) 118 self.skillbooksMissingBtn.Show() 119 else: 120 self.skillbooksMissingBtn.Hide() 121 122 def UpdateOmegaBanner(self): 123 if self.skillPlan.IsOmegaLocked(): 124 self.omegaButton.Show() 125 else: 126 self.omegaButton.Hide() 127 128 def PopulateScroll(self): 129 self.scroll.Flush() 130 self.entries = [] 131 for typeID, level in self.skillPlan.GetSkillRequirements(): 132 if not self.IsSkillVisible(level, typeID): 133 continue 134 entry = self._ConstructEntry(level, typeID) 135 self.entries.append(entry) 136 blue.pyos.BeNice() 137 138 if not self.entries: 139 self.scroll.ShowNoContentHint(GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SkillTabs/NoSkillsMatchingFilters')) 140 141 def _ConstructEntry(self, level, typeID): 142 entry = SkillPlanContentsSkillEntry(parent=self.scroll, typeID=typeID, level=level, padBottom=8) 143 entry.onClickSignal.connect(self.OnEntryClicked) 144 entry.onDblClickSignal.connect(self.OnEntryDblClicked) 145 entry.onSkillAddedToQueue.connect(self.OnEntrySkillAddedToQueue) 146 return entry 147 148 def IsSkillVisible(self, level, typeID): 149 if IsHideTrainedSkillsEnabled() and sm.GetService('skills').GetMyLevel(typeID) >= level: 150 return False 151 filterTxt = self.quickFilterEdit.GetValue() 152 if filterTxt and filterTxt.lower() not in evetypes.GetName(typeID).lower(): 153 return False 154 return True 155 156 def OnEntryDblClicked(self, entry): 157 sm.GetService('skillqueue').AddSkillToQueue(entry.typeID) 158 159 def OnEntryClicked(self, clickedEntry): 160 prereqs, reqForTypeIDs = GetPreReqsAndRequiredForSkillLevel(clickedEntry.typeID, clickedEntry.level) 161 if uicore.uilib.Key(uiconst.VK_CONTROL): 162 deselectEntry = itertoolsext.first_or_default(self.entries, lambda x: x.isSelected) == clickedEntry 163 else: 164 deselectEntry = False 165 for entry in self.entries: 166 if entry == clickedEntry: 167 if deselectEntry: 168 entry.SetDeselected() 169 else: 170 entry.SetSelected() 171 entry.UpdateReqState(NO_REQ) 172 else: 173 entry.SetDeselected() 174 if deselectEntry: 175 entry.UpdateReqState(NO_REQ) 176 else: 177 reqState = GetRequirementStateForEntry(clickedEntry.typeID, clickedEntry.level, entry, prereqs, reqForTypeIDs) 178 entry.UpdateReqState(reqState) 179 180 def OnEntrySkillAddedToQueue(self, typeID, level): 181 if not GetSkillPlanSvc().IsSkillPlanTracked(self.skillPlan.GetID()) and not self.askedAboutTracking: 182 if prompt_player_fsd_dialog('AskTrackPlan', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 183 GetSkillPlanSvc().SetTrackedSkillPlanID(self.skillPlan.GetID()) 184 self.askedAboutTracking = True 185 186 def OnSkillsChanged(self, skills): 187 self._RefreshEntries() 188 189 def OnSkillQueueChanged(self): 190 self._RefreshEntries() 191 192 def _RefreshEntries(self): 193 for entry in self.entries: 194 entry.Refresh() 195 196 def OnSkillsAvailable(self, typeIDs): 197 for entry in self.entries: 198 if entry.typeID in typeIDs: 199 entry.Refresh() 200 201 self.UpdateSkillsMissingBanner() 202 203 def OnSubscriptionChanged(self): 204 self._RefreshEntries()