ProcessorContainer.py (13310B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\planet\pinContainers\ProcessorContainer.py 2 import blue 3 import localization 4 import uthread 5 import utillib 6 from carbon.common.script.sys.serviceConst import ROLE_GML 7 from carbonui import uiconst 8 from carbonui.primitives.container import Container 9 from carbonui.primitives.fill import Fill 10 from carbonui.util.effect import UIEffects 11 from carbonui.util.various_unsorted import SortListOfTuples 12 from eve.client.script.ui.control import eveIcon, eveScroll 13 from carbonui.button.group import ButtonGroup 14 from eve.client.script.ui.control.entries.item import Item 15 from eve.client.script.ui.control.entries.util import GetFromClass 16 from eve.client.script.ui.control.gauge import Gauge 17 from eve.client.script.ui.shared.planet import planetCommon 18 from eve.client.script.ui.shared.planet.pinContainers.BasePinContainer import BasePinContainer, CaptionAndSubtext 19 from eve.common.script.planet.entities import basePin 20 from fsdBuiltData.common.planet import get_schematic, get_schematic_name 21 22 class ProcessorContainer(BasePinContainer): 23 default_name = 'ProcessorContainer' 24 default_width = 320 25 INFO_CONT_HEIGHT = 100 26 panelIDs = [planetCommon.PANEL_SCHEMATICS, planetCommon.PANEL_PRODUCTS] + BasePinContainer.panelIDs 27 28 def ApplyAttributes(self, attributes): 29 BasePinContainer.ApplyAttributes(self, attributes) 30 if not attributes.panelID and self.pin.schematicID is None: 31 self.ShowPanel(planetCommon.PANEL_SCHEMATICS) 32 33 def PanelShowSchematics(self): 34 self.schematicsCont = Container(parent=self.actionCont, name='schematicsCont', align=uiconst.TOALL, state=uiconst.UI_HIDDEN) 35 btnGroup = ButtonGroup(parent=self.schematicsCont, line=False) 36 self.submitBtn = btnGroup.AddButton(localization.GetByLabel('UI/PI/Common/InstallSchematic'), self.InstallSchematic) 37 self.schematicsScroll = eveScroll.Scroll(parent=self.schematicsCont, name='schematicsScroll', align=uiconst.TOALL) 38 self.schematicsScroll.Startup() 39 self.schematicsScroll.sr.id = 'planetProcessorSchematicsScroll' 40 self.schematicsScroll.multiSelect = False 41 self.schematicsScroll.OnSelectionChange = self.OnSchematicScrollSelectionChange 42 uthread.new(self.LoadSchematicsScroll) 43 return self.schematicsCont 44 45 def LoadSchematicsScroll(self): 46 scrolllist = [] 47 for schematic in planetCommon.GetSchematicData(self.pin.typeID): 48 typeID = schematic.outputs[0].typeID 49 data = utillib.KeyVal(label=planetCommon.GetProductNameAndTier(typeID), schematic=schematic, itemID=None, typeID=typeID, getIcon=True, OnClick=None, OnDblClick=self.InstallSchematic) 50 sortBy = (planetCommon.GetTierByTypeID(typeID), schematic.name) 51 scrolllist.append((sortBy, GetFromClass(SchematicItem, {'label': planetCommon.GetProductNameAndTier(typeID), 52 'schematic': schematic, 53 'itemID': None, 54 'typeID': typeID, 55 'getIcon': True, 56 'OnClick': None, 57 'OnDblClick': self.InstallSchematic}))) 58 59 scrolllist = SortListOfTuples(scrolllist) 60 self.schematicsScroll.Load(contentList=scrolllist, headers=[]) 61 self._InitSelectedNode() 62 self.UpdateSubmitBtn() 63 64 def _InitSelectedNode(self): 65 for node in self.schematicsScroll.GetNodes(): 66 if self.GetPersistedSchematicSelected() == node.typeID: 67 self.schematicsScroll.SelectNode(node) 68 self.schematicsScroll.ScrollToNode(node) 69 70 def OnSchematicScrollSelectionChange(self, entries): 71 self.UpdateSubmitBtn() 72 73 def UpdateSubmitBtn(self): 74 entries = self.schematicsScroll.GetSelected() 75 if entries: 76 self.submitBtn.Enable() 77 else: 78 self.submitBtn.Disable() 79 80 def InstallSchematic(self, *args): 81 entries = self.schematicsScroll.GetSelected() 82 if not entries: 83 return 84 entry = entries[0] 85 schematicID = entry.schematic.schematicID 86 self.planetUISvc.myPinManager.InstallSchematic(self.pin.id, schematicID) 87 self.RenderIngredientGauges() 88 typeID = entry.schematic.outputs[0].typeID 89 self.PersistSchematicSelected(typeID) 90 self.ShowPanel(planetCommon.PANEL_CREATEROUTE, typeID, entry.schematic.outputs[0].quantity) 91 92 def PersistSchematicSelected(self, typeID): 93 settings.char.ui.Set(self._GetSchematicSettingID(), typeID) 94 95 def GetPersistedSchematicSelected(self): 96 if self.pin.schematicID: 97 schematic = planetCommon.GetSchematicDataForID(self.pin.schematicID) 98 return schematic.outputs[0].typeID 99 else: 100 return settings.char.ui.Get(self._GetSchematicSettingID(), None) 101 102 def _GetSchematicSettingID(self): 103 return 'planetProcessor_%s' % self.pin.typeID 104 105 def _GetInfoCont(self): 106 self.currProductTxt = CaptionAndSubtext(parent=self.infoContLeft, caption=localization.GetByLabel('UI/PI/Common/Producing'), align=uiconst.TOTOP) 107 self.ingredientsTxt = CaptionAndSubtext(parent=self.infoContLeft, state=uiconst.UI_DISABLED, caption=localization.GetByLabel('UI/PI/Common/SchematicInput'), align=uiconst.TOTOP, padding=(0, 2, 0, 2)) 108 self.ingredientCont = Container(name='ingredientCont', parent=self.infoContLeft, height=42, state=uiconst.UI_PICKCHILDREN, align=uiconst.TOTOP) 109 self.RenderIngredientGauges() 110 self.currCycleGauge = Gauge(parent=self.infoContRight, value=0.0, color=planetCommon.PLANET_COLOR_CYCLE, width=140, align=uiconst.TOTOP, padding=(0, 0, 10, 4)) 111 self.amountPerCycleTxt = CaptionAndSubtext(parent=self.infoContRight, caption=localization.GetByLabel('UI/PI/Common/OutputPerCycle'), align=uiconst.TOTOP) 112 self.amountPerHourTxt = CaptionAndSubtext(parent=self.infoContRight, caption=localization.GetByLabel('UI/PI/Common/OutputPerHour'), align=uiconst.TOTOP) 113 114 def RenderIngredientGauges(self): 115 self.ingredientCont.Flush() 116 self.ingredientGauges = {} 117 i = 0 118 colony = sm.GetService('planetUI').planet.GetColony(session.charid) 119 for typeID, amount in self.pin.GetConsumables().iteritems(): 120 hasIncomingRoute = colony.colonyData.HasIncomingRoute(self.pin.id, typeID) 121 gauge = ProcessorGaugeContainer(parent=self.ingredientCont, iconTypeID=typeID, maxAmount=amount, align=uiconst.TOLEFT, hasIncomingRoute=hasIncomingRoute, padRight=2) 122 self.ingredientGauges[typeID] = gauge 123 i += 1 124 125 if not self.pin.GetConsumables(): 126 self.ingredientsTxt.SetSubtext(localization.GetByLabel('UI/PI/Common/NoSchematicSelected')) 127 else: 128 self.ingredientsTxt.SetSubtext('') 129 130 def _UpdateInfoCont(self): 131 if self.pin.schematicID: 132 schematicObj = get_schematic(self.pin.schematicID) 133 schematicName = get_schematic_name(self.pin.schematicID, schematicObj) 134 for typeID, schematicType in schematicObj.types.iteritems(): 135 if not schematicType.isInput: 136 outputPerCycle = schematicType.quantity 137 outputTypeID = typeID 138 139 if self.pin.activityState < basePin.STATE_IDLE: 140 currCycle = 0 141 currCycleProportion = 0.0 142 status = localization.GetByLabel('UI/Common/Inactive') 143 elif self.pin.IsActive(): 144 nextCycle = self.pin.GetNextRunTime() 145 if nextCycle is None or nextCycle < blue.os.GetWallclockTime(): 146 status = localization.GetByLabel('UI/PI/Common/ProductionCompletionImminent') 147 else: 148 status = '<color=green>%s</color>' % localization.GetByLabel('UI/PI/Common/InProduction') 149 currCycle = self.pin.GetCycleTime() - (self.pin.GetNextRunTime() - blue.os.GetWallclockTime()) 150 currCycleProportion = currCycle / float(self.pin.GetCycleTime()) 151 else: 152 status = localization.GetByLabel('UI/PI/Common/WaitingForResources') 153 currCycle = 0 154 currCycleProportion = 0.0 155 else: 156 schematicName = localization.GetByLabel('UI/PI/Common/NothingExtracted') 157 status = localization.GetByLabel('UI/Common/Inactive') 158 currCycleProportion = 0.0 159 currCycle = 0 160 outputPerCycle = 0 161 outputTypeID = None 162 for typeID, amountNeeded in self.pin.GetConsumables().iteritems(): 163 amount = self.pin.GetContents().get(typeID, 0) 164 gauge = self.ingredientGauges.get(typeID) 165 if not gauge: 166 continue 167 gauge.SetValue(float(amount) / amountNeeded) 168 gauge.hint = localization.GetByLabel('UI/PI/Common/ProductionGaugeHint', resourceName=planetCommon.GetProductNameAndTier(typeID), amount=amount, amountNeeded=amountNeeded) 169 170 errorText = self._GetErrorText() 171 if errorText: 172 schematicName += '\n' + errorText 173 self.currProductTxt.SetSubtext(schematicName) 174 if self.pin.schematicID: 175 if self.pin.activityState < basePin.STATE_IDLE: 176 self.currCycleGauge.SetSubText(localization.GetByLabel('UI/PI/Common/InactiveEditMode')) 177 else: 178 self.currCycleGauge.SetSubText(localization.GetByLabel('UI/PI/Common/CycleTimeElapsed', currTime=long(currCycle), totalTime=self.pin.GetCycleTime())) 179 self.currProductTxt.SetIcon(outputTypeID) 180 self.currCycleGauge.SetValueInstantly(currCycleProportion) 181 self.currCycleGauge.SetText(status) 182 self.amountPerCycleTxt.SetSubtext(localization.GetByLabel('UI/PI/Common/UnitsAmount', amount=outputPerCycle)) 183 self.amountPerHourTxt.SetSubtext(localization.GetByLabel('UI/PI/Common/CapacityAmount', amount=self.pin.GetOutputVolumePerHour())) 184 185 def _GetErrorText(self): 186 errorText = '' 187 if self.IsSomeConsumableUnfulfilled(): 188 errorText = localization.GetByLabel('UI/PI/Common/InputRoutesMissing') 189 elif self.IsSomeProductUnrouted(): 190 errorText = localization.GetByLabel('UI/PI/Common/NotRouted') 191 if errorText: 192 errorText = '<color=red>%s</color>' % errorText 193 return errorText 194 195 196 class ProcessorGaugeContainer(Container): 197 default_state = uiconst.UI_NORMAL 198 default_align = uiconst.TOPLEFT 199 default_name = 'ProcessorGauge' 200 default_left = 0 201 default_top = 0 202 default_width = 32 203 default_height = 42 204 205 def ApplyAttributes(self, attributes): 206 self.uiEffects = UIEffects() 207 Container.ApplyAttributes(self, attributes) 208 self.value = attributes.Get('value', 0.0) 209 self.left = attributes.Get('left', 0) 210 self.top = attributes.Get('top', 0) 211 self.typeID = iconTypeID = attributes.Get('iconTypeID', 6) 212 hasIncomingRoute = attributes.hasIncomingRoute 213 color = planetCommon.PLANET_COLOR_USED_PROCESSOR 214 self.icon = eveIcon.Icon(parent=self, pos=(2, 2, 28, 28), state=uiconst.UI_DISABLED, typeID=iconTypeID, size=16, ignoreSize=True) 215 gaugeCont = Container(parent=self, pos=(0, 216 0, 217 self.width, 218 self.width), align=uiconst.TOPLEFT) 219 self.gauge = Fill(parent=gaugeCont, align=uiconst.TOLEFT, width=0, color=color, state=uiconst.UI_DISABLED) 220 self.bgFill = Fill(parent=gaugeCont, state=uiconst.UI_DISABLED) 221 if hasIncomingRoute: 222 self.bgFill.color = (255 / 255.0, 223 128 / 255.0, 224 0 / 255.0, 225 0.15) 226 else: 227 self.bgFill.color = planetCommon.PLANET_COLOR_NEEDSATTENTION 228 self.bgFill.opacity = 0.3 229 self.busy = False 230 self.SetValue(self.value) 231 232 def SetValue(self, value, frequency = 8.0): 233 if self.busy or value == self.value: 234 return 235 if value > 1.0: 236 value = 1.0 237 uthread.new(self._SetValue, value, frequency) 238 239 def _SetValue(self, value, frequency): 240 if not self or self.destroyed: 241 return 242 self.busy = True 243 self.value = value 244 self.uiEffects.MorphUIMassSpringDamper(self.gauge, 'width', int(self.width * value), newthread=0, float=0, dampRatio=0.6, frequency=frequency, minVal=0, maxVal=self.width, maxTime=1.0) 245 if not self or self.destroyed: 246 return 247 self.busy = False 248 249 def GetMenu(self): 250 ret = sm.GetService('menu').GetMenuFromItemIDTypeID(None, self.typeID, includeMarketDetails=True) 251 if session.role & ROLE_GML == ROLE_GML: 252 ret.append(('GM / WM Extras', self.GetGMMenu())) 253 return ret 254 255 def GetGMMenu(self): 256 return [('Add commodity to pin', self.AddCommodity, [])] 257 258 def AddCommodity(self): 259 pinID = sm.GetService('planetUI').currentContainer.pin.id 260 sm.GetService('planetUI').planet.GMAddCommodity(pinID, self.typeID) 261 262 263 class SchematicItem(Item): 264 265 def LoadTooltipPanel(self, tooltipPanel, *args): 266 schematicID = planetCommon.GetSchematicByOutput(self.sr.node.typeID) 267 schematic = planetCommon.GetSchematicDataForID(schematicID) 268 planetCommon.LoadSchematicTooltipPanel(tooltipPanel, schematic)