jobEntry.py (14199B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\industry\jobEntry.py 2 from evePathfinder.core import IsUnreachableJumpCount 3 import blue 4 import carbonui.const as uiconst 5 import eve.client.script.ui.util.uix as uix 6 import eveformat.client 7 import evetypes 8 import industry 9 import localization 10 import uthread 11 from carbon.common.script.sys.service import ROLE_GML 12 from carbon.common.script.util.commonutils import StripTags 13 from carbonui.primitives.container import Container 14 from carbonui.primitives.containerAutoSize import ContainerAutoSize 15 from carbonui.primitives.gradientSprite import GradientSprite 16 from carbonui.primitives.sprite import Sprite 17 from carbonui.uicore import uicore 18 from eve.client.script.ui.control.baseListEntry import BaseListEntryCustomColumns 19 from carbonui.control.button import Button 20 from eve.client.script.ui.control.eveIcon import Icon 21 from eve.client.script.ui.control.eveLabel import Label, EveLabelMedium 22 from eve.client.script.ui.control.gauge import Gauge 23 from eve.client.script.ui.shared.industry import industryUIConst 24 from eve.client.script.ui.shared.industry.industryUIConst import VIEWMODE_ICONLIST 25 from eve.client.script.ui.shared.industry.installationActivityIcon import InstallationActivityIcon 26 from eve.common.script.util.eveFormat import FmtSystemSecStatus 27 from eveservices.menu import GetMenuService 28 from menu import MenuLabel 29 30 def IsPersonalJob(ownerID): 31 return ownerID == session.charid 32 33 34 class JobEntry(BaseListEntryCustomColumns): 35 default_name = 'JobEntry' 36 37 def ApplyAttributes(self, attributes): 38 BaseListEntryCustomColumns.ApplyAttributes(self, attributes) 39 self.jobData = self.node.jobData 40 self.item = self.node.item 41 self.viewMode = self.node.viewMode 42 self.AddColumnStatusIcon() 43 self.AddColumnStatus() 44 self.AddColumnText('x %s' % self.jobData.runs) 45 self.AddColumnActivity() 46 self.AddColumnBlueprintLabel() 47 self.AddColumnJumps() 48 self.AddColumnText(self.GetSecurityLabel()) 49 self.AddColumnInstallationName() 50 self.AddColumnText(self.jobData.GetOutputLocationName()) 51 if not IsPersonalJob(self.jobData.ownerID): 52 self.AddColumnText(self.jobData.GetInstallerName()) 53 self.AddColumnText(self.jobData.GetStartDateLabel()) 54 self.AddColumnText(self.jobData.GetEndDateLabel()) 55 56 def AddColumnBlueprintLabel(self): 57 col = self.AddColumnContainer() 58 texturePath, hint = uix.GetTechLevelIconPathAndHint(self.jobData.blueprint.blueprintTypeID) 59 if texturePath: 60 techIconSize = 16 if self.viewMode == VIEWMODE_ICONLIST else 12 61 Sprite(name='techIcon', parent=col, texturePath=texturePath, hint=hint, width=techIconSize, height=techIconSize) 62 if self.viewMode == VIEWMODE_ICONLIST: 63 iconSize = 32 64 Icon(parent=col, typeID=self.jobData.blueprint.blueprintTypeID, isCopy=not self.jobData.blueprint.original, ignoreSize=True, align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, width=iconSize, height=iconSize, left=2) 65 else: 66 iconSize = 0 67 Label(parent=col, text=self.jobData.blueprint.GetLabel(), align=uiconst.CENTERLEFT, left=iconSize + 4, idx=0) 68 69 def AddColumnStatusIcon(self): 70 col = self.AddColumnContainer() 71 self.statusIcon = Sprite(parent=col, align=uiconst.CENTER, width=16, height=16) 72 self.UpdateStatusIcon() 73 74 def UpdateStatusIcon(self): 75 texturePath, color = industryUIConst.GetStatusIconAndColor(self.jobData.status) 76 self.statusIcon.texturePath = texturePath 77 self.statusIcon.SetRGBA(*color) 78 79 def AddColumnStatus(self): 80 col = self.AddColumnContainer() 81 self.jobStateCont = JobStateContainer(parent=col, align=uiconst.TOALL, padding=2, jobData=self.jobData) 82 83 def AddColumnActivity(self): 84 col = self.AddColumnContainer() 85 ICONSIZE = 20 if self.viewMode == VIEWMODE_ICONLIST else 16 86 InstallationActivityIcon(parent=col, align=uiconst.CENTER, pos=(0, 87 0, 88 ICONSIZE, 89 ICONSIZE), activityID=self.jobData.activityID, isEnabled=True) 90 91 def AddColumnJumps(self): 92 jumps = self.node.jumps 93 if not IsUnreachableJumpCount(jumps): 94 self.AddColumnText(jumps) 95 else: 96 col = self.AddColumnContainer() 97 Sprite(name='infinityIcon', parent=col, align=uiconst.CENTERLEFT, pos=(6, 0, 11, 6), texturePath='res:/UI/Texture/Classes/Industry/infinity.png', opacity=Label.default_color[3]) 98 99 def AddColumnInstallationName(self): 100 self.AddColumnText(self.jobData.GetFacilityName()) 101 102 @staticmethod 103 def GetDynamicHeight(node, width): 104 if node.viewMode == VIEWMODE_ICONLIST: 105 return 36 106 else: 107 return 20 108 109 @staticmethod 110 def GetDefaultColumnWidth(): 111 return {localization.GetByLabel('UI/Generic/Status'): 90, 112 localization.GetByLabel('UI/Industry/Activity'): 32, 113 localization.GetByLabel('UI/Industry/Blueprint'): 230, 114 localization.GetByLabel('UI/Industry/Facility'): 230, 115 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/Installer'): 120} 116 117 def GetSecurityLabel(self): 118 return eveformat.solar_system_security_status(self.jobData.solarSystemID) 119 120 @staticmethod 121 def GetColumnSortValues(jobData, jumps): 122 if jobData.facilityID == session.stationid or jobData.solarSystemID == session.solarsystemid: 123 jumps = -1 124 if IsPersonalJob(jobData.ownerID): 125 return (jobData.status, 126 (-jobData.status, jobData.endDate), 127 jobData.runs, 128 jobData.activityID, 129 evetypes.GetName(jobData.blueprint.blueprintTypeID), 130 jumps, 131 sm.GetService('map').GetSecurityStatus(jobData.solarSystemID), 132 jobData.GetFacilityName(), 133 jobData.GetOutputLocationName(), 134 jobData.startDate, 135 jobData.endDate) 136 else: 137 return (jobData.status, 138 (-jobData.status, jobData.endDate), 139 jobData.runs, 140 jobData.activityID, 141 evetypes.GetName(jobData.blueprint.blueprintTypeID), 142 jumps, 143 sm.GetService('map').GetSecurityStatus(jobData.solarSystemID), 144 jobData.GetFacilityName(), 145 jobData.GetOutputLocationName(), 146 jobData.GetInstallerName(), 147 jobData.startDate, 148 jobData.endDate) 149 150 @staticmethod 151 def GetHeaders(isPersonalJob = True): 152 if isPersonalJob: 153 return ('', 154 localization.GetByLabel('UI/Generic/Status'), 155 localization.GetByLabel('UI/Industry/JobRuns'), 156 localization.GetByLabel('UI/Industry/Activity'), 157 localization.GetByLabel('UI/Industry/Blueprint'), 158 localization.GetByLabel('UI/Common/Jumps'), 159 localization.GetByLabel('UI/Common/Security'), 160 localization.GetByLabel('UI/Industry/Facility'), 161 localization.GetByLabel('UI/Industry/OutputLocation'), 162 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/InstallDate'), 163 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/EndDate')) 164 else: 165 return ('', 166 localization.GetByLabel('UI/Generic/Status'), 167 localization.GetByLabel('UI/Industry/JobRuns'), 168 localization.GetByLabel('UI/Industry/Activity'), 169 localization.GetByLabel('UI/Industry/Blueprint'), 170 localization.GetByLabel('UI/Common/Jumps'), 171 localization.GetByLabel('UI/Common/Security'), 172 localization.GetByLabel('UI/Industry/Facility'), 173 localization.GetByLabel('UI/Industry/OutputLocation'), 174 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/Installer'), 175 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/InstallDate'), 176 localization.GetByLabel('UI/ScienceAndIndustry/ScienceAndIndustryWindow/EndDate')) 177 178 def GetMenu(self): 179 m = GetMenuService().GetMenuFromItemIDTypeID(self.jobData.blueprintID, self.jobData.blueprintTypeID, includeMarketDetails=True) 180 label = MenuLabel('UI/Industry/Facility') 181 m.append((label, GetMenuService().CelestialMenu(itemID=self.jobData.facilityID))) 182 if bool(session.role & ROLE_GML): 183 m.append(None) 184 m.append(('GM: Complete Job', sm.GetService('industrySvc').CompleteJob, (self.jobData.jobID, self.jobData.solarSystemID))) 185 m.append(('GM: Cancel Job', sm.GetService('industrySvc').CancelJob, (self.jobData.jobID, self.jobData.solarSystemID))) 186 m.append(None) 187 m.append(('jobID: {}'.format(self.jobData.jobID), blue.pyos.SetClipboardData, (str(self.jobData.jobID),))) 188 return m 189 190 def UpdateValues(self, animate, num): 191 self.jobStateCont.UpdateValue(animate, num) 192 193 def OnStatusChanged(self, status, successfulRuns): 194 self.jobData.status = status 195 self.jobData.successfulRuns = successfulRuns 196 self.jobStateCont.OnStatusChanged() 197 if status > industry.STATUS_READY: 198 if self.jobData.activityID == industry.MANUFACTURING: 199 color = industryUIConst.COLOR_MANUFACTURING 200 else: 201 color = industryUIConst.COLOR_SCIENCE 202 for col in self.columns: 203 col.opacity = 0.3 204 205 self.AnimFlash(color) 206 self.UpdateStatusIcon() 207 208 def AnimFlash(self, color): 209 width = 500 210 flashCont = Container(parent=self, idx=0, align=uiconst.TOPLEFT, width=width, height=self.height) 211 flashGradient = GradientSprite(bgParent=flashCont, rgbData=[(0, color[:3])], alphaData=[(0, 0.0), (0.9, 0.4), (1.0, 0.0)]) 212 arrows = Sprite(parent=flashCont, align=uiconst.CENTERLEFT, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/arrows.png', pos=(0, 213 0, 214 375, 215 self.height), color=color, opacity=0.15, tileX=True) 216 duration = self.width / 600.0 217 uicore.animations.MorphScalar(flashCont, 'left', -width, self.width + width, duration=duration, curveType=uiconst.ANIM_LINEAR) 218 uicore.animations.FadeTo(flashCont, 0.0, 1.0, duration=duration, callback=flashCont.Close, curveType=uiconst.ANIM_WAVE) 219 220 @classmethod 221 def GetCopyData(cls, node): 222 jobData = node.jobData 223 labelList = [StripTags(jobData.GetJobStateLabel()), 224 unicode(jobData.runs), 225 localization.GetByLabel(industryUIConst.ACTIVITY_NAMES.get(jobData.activityID)), 226 evetypes.GetName(jobData.blueprint.blueprintTypeID), 227 unicode(node.jumps), 228 unicode(FmtSystemSecStatus(sm.GetService('map').GetSecurityStatus(jobData.solarSystemID), 1)[0]), 229 jobData.GetFacilityName(), 230 jobData.GetOutputLocationName()] 231 if not IsPersonalJob(jobData.ownerID): 232 labelList += [jobData.GetInstallerName()] 233 labelList += [jobData.GetStartDateLabel(), jobData.GetEndDateLabel()] 234 return '\t'.join(labelList) 235 236 237 class JobStateContainer(Container): 238 default_state = uiconst.UI_NORMAL 239 240 def ApplyAttributes(self, attributes): 241 Container.ApplyAttributes(self, attributes) 242 self.jobData = attributes.jobData 243 self.ConstructLayout() 244 self.UpdateValue() 245 246 def ConstructLayout(self): 247 if not self.jobData: 248 return 249 if self.jobData.status == industry.STATUS_READY: 250 self.deliverBtn = Button(name='deliverBtn', parent=self, align=uiconst.TOALL, label='<b>' + localization.GetByLabel('UI/Industry/Deliver'), func=self.OnDeliverBtn, padding=2) 251 self.deliverBtn.width = self.deliverBtn.height = 0 252 self.deliverBtn.Blink(time=3000) 253 self.Enable() 254 else: 255 self.Disable() 256 gaugeCont = ContainerAutoSize(name='gaugeCont', parent=self, align=uiconst.TOBOTTOM) 257 mainCont = Container(name='mainCont', parent=self) 258 self.deliverBtn = None 259 self.valueLabel = EveLabelMedium(parent=mainCont, align=uiconst.CENTERLEFT, left=4) 260 if self.jobData.status == industry.STATUS_INSTALLED: 261 if self.jobData.activityID == industry.MANUFACTURING: 262 color = industryUIConst.COLOR_MANUFACTURING 263 elif self.jobData.activityID == industry.REACTION: 264 color = industryUIConst.COLOR_REACTION 265 else: 266 color = industryUIConst.COLOR_SCIENCE 267 self.gauge = Gauge(parent=gaugeCont, align=uiconst.TOTOP, state=uiconst.UI_DISABLED, color=color, height=6, gaugeHeight=6, padTop=1, backgroundColor=(1.0, 1.0, 1.0, 0.05)) 268 269 def OnStatusChanged(self): 270 self.Flush() 271 self.ConstructLayout() 272 if self.jobData.status == industry.STATUS_DELIVERED: 273 uicore.animations.FadeTo(self.valueLabel, 0.0, 1.0) 274 275 def UpdateValue(self, animate = False, num = 0): 276 if not self.jobData or self.jobData.status in (industry.STATUS_READY, industry.STATUS_UNSUBMITTED): 277 return 278 if self.jobData.status == industry.STATUS_INSTALLED: 279 progressRatio = self.jobData.GetJobProgressRatio() 280 if progressRatio: 281 self.gauge.SetValueInstantly(progressRatio) 282 if animate and progressRatio != 1.0: 283 self.gauge.AnimFlash(1.0, duration=3.0, timeOffset=num * 0.1) 284 self.valueLabel.text = self.jobData.GetJobStateLabel() 285 286 def OnDeliverBtn(self, *args): 287 sm.GetService('industrySvc').CompleteJob(self.jobData.jobID, self.jobData.solarSystemID) 288 sm.GetService('audio').SendUIEvent('ind_jobDelivered') 289 290 def OnNewJobData(self, jobData): 291 self.jobData = jobData 292 self.OnStatusChanged() 293 self.UpdateValue(animate=True) 294 295 def StartUpdate(self): 296 uthread.new(self._UpdateThread) 297 298 def _UpdateThread(self): 299 while not self.destroyed: 300 self.UpdateValue() 301 blue.synchro.SleepWallclock(500)