class JobsSummary(LayoutGrid): default_columns = 2 default_state = uiconst.UI_NORMAL def ApplyAttributes(self, attributes): LayoutGrid.ApplyAttributes(self, attributes) self.activityType = None self.jobData = None self.countCaption = Label(color=Color.GRAY, fontsize=10, top=2) self.AddCell(self.countCaption, cellPadding=(0, 0, 5, 0)) self.countLabel = Label() cell = self.AddCell(self.countLabel, cellPadding=(5, 0, 5, 3)) self.slotsErrorFrame = ErrorFrame(parent=cell, align=uiconst.TOALL, state=uiconst.UI_DISABLED, padBottom=3) label = Label(text=localization.GetByLabel('UI/Industry/ControlRange'), color=Color.GRAY, fontsize=10, top=2) self.AddCell(label, cellPadding=(0, 0, 5, 0)) self.rangeLabel = Label() cell = self.AddCell(self.rangeLabel, cellPadding=(5, 0, 5, 0)) self.rangeErrorFrame = ErrorFrame(parent=cell, align=uiconst.TOALL, state=uiconst.UI_DISABLED) def OnNewJobData(self, jobData): self.jobData = jobData if self.jobData: self.jobData.on_updated.connect(self.UpdateState) self.UpdateState() def UpdateState(self, *args): activityType = industryUIConst.GetActivityType(self.jobData.activityID) changed = self.activityType != activityType self.activityType = activityType if changed: uicore.animations.FadeOut(self, sleep=True, duration=0.1) if self.activityType == industryUIConst.MANUFACTURING: self.countCaption.text = localization.GetByLabel('UI/Industry/ManufacturingJobs') else: self.countCaption.text = localization.GetByLabel('UI/Industry/ScienceJobs') color = Color.RGBtoHex(*industryUIConst.GetActivityColor(self.activityType)) self.countLabel.text = '%s / <color=%s>%s</color>' % (self.jobData.used_slots, color, self.jobData.max_slots) skillLabel = industryUIConst.GetControlRangeLabel(self.jobData.max_distance) self.rangeLabel.text = '<color=%s>%s' % (color, skillLabel) if changed: uicore.animations.FadeIn(self, duration=0.3) if self.jobData and self.jobData.HasError(industry.Error.SLOTS_FULL): self.slotsErrorFrame.Show() else: self.slotsErrorFrame.Hide() if self.jobData and self.jobData.HasError(industry.Error.FACILITY_DISTANCE): self.rangeErrorFrame.Show() else: self.rangeErrorFrame.Hide() def LoadTooltipPanel(self, tooltipPanel, *args): JobsSummaryTooltipPanel(self.jobData, tooltipPanel) def GetTooltipDelay(self): return TOOLTIP_DELAY_GAMEPLAY def OnMouseEnter(self, *args): sm.GetService('audio').SendUIEvent('ind_mouseEnter')
class ActivityToggleButtonGroupButton(ToggleButtonGroupButton): def ApplyAttributes(self, attributes): ToggleButtonGroupButton.ApplyAttributes(self, attributes) self.activityID = attributes.activityID color = Color(*self.colorSelected).SetBrightness(0.75).GetRGBA() self.errorFrame = ErrorFrame(bgParent=self, state=uiconst.UI_HIDDEN, color=color, padding=1, idx=0) def ShowErrorFrame(self): if not self.isDisabled: self.errorFrame.Show() def HideErrorFrame(self): self.errorFrame.Hide() def GetHint(self, *args): hint = '<b>%s</b><br>%s' % ( localization.GetByLabel( industryUIConst.ACTIVITY_NAMES[self.activityID]), localization.GetByLabel( industryUIConst.ACTIVITY_HINTS[self.activityID])) if self.errorFrame.display: colorHex = Color.RGBtoHex(*industryUIConst.COLOR_NOTREADY) hint += '<br><b><color=%s>%s</color></b>' % ( colorHex, localization.GetByLabel('UI/Industry/ActivityNotSupported')) return hint
class PrimaryButton(Button): def ApplyAttributes(self, attributes): Button.ApplyAttributes(self, attributes) self.isStopPending = False self.isArrowsAnimating = False self.sr.label.uppercase = True self.sr.label.fontsize = 13 self.sr.label.bold = True self.pattern = Sprite(name='bgGradient', bgParent=self, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/buttonPattern.png', color=Color.GRAY2, idx=0) self.bg = Sprite(name='bg', bgParent=self, opacity=0.0, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/buttonBg.png', color=Color.GRAY2, idx=0, state=uiconst.UI_HIDDEN) self.arrows = Sprite(bgParent=self, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/arrowMask.png', textureSecondaryPath='res:/UI/Texture/Classes/Industry/CenterBar/arrows.png', spriteEffect=trinity.TR2_SFX_MODULATE, color=Color.GRAY2, idx=0) self.arrows.translationSecondary = (-0.16, 0) self.errorFrame = ErrorFrame(bgParent=self) self.errorFrame.Hide() color = attributes.color if color is None: color = sm.GetService('uiColor').GetUIColor(uiconst.COLORTYPE_UIHILIGHT) self.SetColor(color) def Update_Size_(self): if self.iconPath is None: self.width = self.fixedwidth or max(64, self.sr.label.width + 60) self.height = self.fixedheight or max(32, self.sr.label.textheight + 12) def AnimateArrows(self): if self.destroyed: return self.arrows.Show() if self.isArrowsAnimating: return diff = math.fabs(-0.16 - self.arrows.translationSecondary[0]) duration = diff / 0.16 if diff > 0.001: uicore.animations.MorphVector2(self.arrows, 'translationSecondary', self.arrows.translationSecondary, (-0.16, 0.0), duration=duration, curveType=uiconst.ANIM_LINEAR, callback=self._LoopArrowAnimation) else: self._LoopArrowAnimation() self.isArrowsAnimating = True def _LoopArrowAnimation(self): uicore.animations.MorphVector2(self.arrows, 'translationSecondary', (0.16, 0.0), (-0.16, 0.0), duration=2.0, curveType=uiconst.ANIM_LINEAR, loops=uiconst.ANIM_REPEAT) def StopAnimateArrows(self): if self.destroyed: return diff = math.fabs(-0.16 - self.arrows.translationSecondary[0]) duration = diff / 0.16 if diff: uicore.animations.MorphVector2(self.arrows, 'translationSecondary', self.arrows.translationSecondary, (-0.16, 0.0), duration=duration, curveType=uiconst.ANIM_LINEAR) self.isArrowsAnimating = False def HideArrows(self): self.StopAnimateArrows() self.arrows.Hide() def UpdateLabel(self): label = self.GetLabel() if label: text = localization.GetByLabel(label) if self.text != text: self.SetLabelAnimated(text) else: self.SetLabel('') def SetColor(self, color): underlayColor = Color(*color).SetBrightness(0.4).GetRGBA() self.underlay.SetFixedColor(underlayColor) blinkColor = Color(*color).SetSaturation(0.5).SetBrightness(0.9).GetRGBA() self.sr.hilite.SetRGBA(*blinkColor) for obj in (self.pattern, self.bg, self.arrows): uicore.animations.SpColorMorphTo(obj, obj.GetRGBA(), color, duration=0.3) def SetLabelAnimated(self, text): uthread.new(self._SetLabelAnimated, text) def _SetLabelAnimated(self, text): uicore.animations.FadeOut(self.sr.label, duration=0.15, sleep=True) self.SetLabel(text) uicore.animations.FadeIn(self.sr.label, duration=0.3)
class BaseContainerMETE(Container): default_align = uiconst.TOPLEFT default_state = uiconst.UI_NORMAL def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.value = 0.0 iconPath = attributes.iconPath iconSize = attributes.iconSize minValue = attributes.minValue maxValue = attributes.maxValue showBG = attributes.get('showBG', True) isCompact = attributes.get('isCompact', False) self.jobData = attributes.jobData self.gauge = Gauge(parent=self, align=uiconst.TOBOTTOM, state=uiconst.UI_DISABLED, height=6, gaugeHeight=6, padTop=1, backgroundColor=(1.0, 1.0, 1.0, 0.05)) if isCompact: self.icon = None self.valueLabel = None return mainCont = Container(name='mainCont', parent=self) if showBG: self.bg = StretchSpriteHorizontal( bgParent=mainCont, texturePath='res:/UI/Texture/Classes/Industry/Center/bgMETE.png' ) FillThemeColored(bgParent=self, opacity=0.5) else: self.bg = None left = 8 if showBG else 2 self.icon = Sprite(name='icon', parent=mainCont, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, pos=(left, 3, self.ICONSIZE, self.ICONSIZE), texturePath=self.ICONPATH, opacity=0.6) self.valueLabel = EveLabelMediumBold(parent=mainCont, align=uiconst.TOPRIGHT, top=4, left=left) self.removeIcon = Sprite( parent=mainCont, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, texturePath='res:/ui/texture/icons/73_16_45.png', pos=(0, 0, 12, 12), color=Color.RED, hint=localization.GetByLabel('UI/Industry/PreviewModeHint')) self.removeIcon.OnClick = self.OnRemoveIconClick self.previewEdit = SinglelineEdit(name='previewEdit', parent=mainCont, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, ints=(0, self.MAXVAL), OnChange=self.OnPreviewEdit, pos=(12, 0, 34, 20)) self.errorFrame = ErrorFrame(bgParent=self, padding=(1, 1, 1, 8)) def SetValue(self, value): if self.value * (value or 1) < 0.0: self.gauge.SetValueInstantly(0.0) self.value = value if value < 0: self.gauge.SetGaugeAlign(uiconst.TORIGHT_PROP) self.gauge.SetValue(float(value) / self.MINVAL) self.gauge.SetColor(COLOR_NOTREADY) else: self.gauge.SetGaugeAlign(uiconst.TOLEFT_PROP) self.gauge.SetValue(float(value) / self.MAXVAL) self.gauge.SetColor(COLOR_READY) if not self.valueLabel: return if value < 0: self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex( *COLOR_NOTREADY), value) elif value == 0: self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex( *COLOR_FRAME), value) else: self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex( *COLOR_READY), value) def OnMouseEnter(self, *args): sm.GetService('audio').SendUIEvent('ind_mouseEnter') def OnRemoveIconClick(self): self.ExitPreviewMode() def EnterPreviewMode(self): if not self.IsPreviewEnabled(): return self.previewEdit.Show() self.previewEdit.SetValue(self.GetPreviewEditValue()) self.valueLabel.Hide() self.errorFrame.Show() self.removeIcon.Show() uicore.registry.SetFocus(self.previewEdit) def ExitPreviewMode(self): self.previewEdit.Hide() self.valueLabel.Show() self.errorFrame.Hide() self.removeIcon.Hide() if self.jobData: self.jobData.timeEfficiency = None self.jobData.materialEfficiency = None self.jobData.update(self.jobData) def OnClick(self, *args): self.EnterPreviewMode() def OnMouseEnter(self, *args): if self.bg and self.IsPreviewEnabled(): uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.5, duration=0.3) def OnMouseExit(self, *args): if self.bg: uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.0, duration=0.3) def OnNewJobData(self, jobData): self.jobData = jobData self.ExitPreviewMode() def IsPreviewEnabled(self): if not self.jobData or self.jobData.activityID != industry.MANUFACTURING or self.jobData.jobID: return False return True def IsPreviewActive(self): return self.errorFrame.display def GetHint(self): if self.IsPreviewEnabled() and not self.IsPreviewActive(): return '<br><br>' + localization.GetByLabel( 'UI/Industry/EnterPreviewModeHint') return ''
class OutcomeItemContainer(Container): default_state = uiconst.UI_NORMAL default_clipChildren = True __notifyevents__ = ['OnIndustryViewExpandCollapse'] def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) sm.RegisterNotify(self) self.jobData = attributes.jobData self.videoThread = None self.iconCont = Container(name='iconCont', parent=self, align=CENTER, state=uiconst.UI_NORMAL, width=64, height=64) self.errorFrame = ErrorFrame(parent=self, align=uiconst.CENTER, pos=(0, 0, 64, 64), state=uiconst.UI_HIDDEN) self.qtyLabel = EveLabelLargeBold(parent=self, align=CENTER, top=42) FrameThemeColored(name='bgVignette', parent=self, texturePath='res:/UI/Texture/Classes/Industry/Output/bgVignette.png', cornerSize=30) self.videoCont = Container(name='videoCont', parent=self, align=uiconst.CENTER, width=324, height=199) self.previewContFill = FillThemeColored(parent=self) self.previewCont = PreviewContainer(parent=self, align=uiconst.TOALL, state=uiconst.UI_HIDDEN) self.leftProbabilityGradient = GradientSprite(name='leftProbabilityGradient', parent=self, align=uiconst.CENTERLEFT, state=uiconst.UI_HIDDEN, pos=(0, 0, 160, 64), rgbData=((0, (1.0, 1.0, 1.0)),), alphaData=((0.0, 0.5), (1.0, 0.0))) self.rightProbabilityGradient = GradientSprite(name='rightProbabilityGradient', parent=self, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, pos=(0, 0, 160, 64), rgbData=((0, (1.0, 1.0, 1.0)),), alphaData=((0.0, 0.0), (1.0, 0.5))) self.previewCont.navigation.LoadTooltipPanel = self.LoadIconContTooltipPanel self.previewCont.navigation.GetTooltipDelay = self.GetIconContTooltipDelay self.previewCont.navigation.GetMenu = self.GetMenu self.iconCont.LoadTooltipPanel = self.LoadIconContTooltipPanel self.iconCont.GetTooltipDelay = self.GetIconContTooltipDelay self.iconCont.OnMouseEnter = self.OnIconContMouseEnter self.iconCont.OnMouseExit = self.OnIconContMouseExit self.iconCont.OnClick = self.OnIconContClick self.iconCont.GetMenu = self.GetMenu self.iconCont.GetDragData = self.GetIconContDragData self.iconCont.isDragObject = True self.techIcon = Sprite(name='techIcon', parent=self.iconCont, width=16, height=16) self.icon = Icon(parent=self.iconCont, align=CENTER, state=uiconst.UI_DISABLED) self.bgCont = Container(name='bgCont', parent=self, align=uiconst.CENTER, width=201, height=192) self.bg = Sprite(bgParent=self.bgCont, texturePath='res:/UI/Texture/Classes/Industry/Output/itemBg.png') self.itemPattern = Sprite(bgParent=self.bgCont, texturePath='res:/UI/Texture/Classes/Industry/Output/itemBgColor.png') self.UpdateState() self.AnimEntry() def OnIndustryViewExpandCollapse(self): if not self.previewCont or self.jobData and self.jobData.activityID != industry.MANUFACTURING: return isCollapsed = settings.user.ui.Get('industryWndIsViewCollapsed', False) if not isCollapsed: self.AnimFadeSceneContIn() else: self.previewCont.Hide() self.previewContFill.opacity = 1.0 def AnimFadeSceneContIn(self): self.previewCont.Hide() self.previewContFill.opacity = 1.0 blue.synchro.SleepWallclock(250) self.previewCont.Show() uicore.animations.FadeTo(self.previewContFill, 1.0, 0.0, duration=0.6) def OnNewJobData(self, jobData): self.jobData = jobData self.UpdateState() if self.jobData: self.jobData.on_updated.connect(self.UpdateState) self.AnimEntry() def UpdateState(self, *args): if not self.jobData: self.previewCont.Hide() return typeID = self.jobData.GetProductTypeID() if IsPreviewable(typeID) and self.jobData.activityID == industry.MANUFACTURING: self.previewCont.Show() self.iconCont.Hide() newModel = self.previewCont.PreviewType(typeID) if newModel: self.previewContFill.Show() self.previewContFill.opacity = 1.0 self.previewCont.AnimEntry(1.5, 0.0, 0.5, -0.3) self.previewCont.sceneContainer.scene.sunDirection = (-0.5, -1.0, -1.0) self.bg.Hide() self.qtyLabel.top = 86 self.leftProbabilityGradient.Hide() self.rightProbabilityGradient.Hide() else: self.iconCont.Show() self.previewCont.Hide() self.bg.Show() self.qtyLabel.top = 42 if self.jobData.activityID == industry.RESEARCH_MATERIAL: self.icon.LoadIcon('res:/UI/Texture/Classes/Industry/iconME.png') self.icon.width = self.icon.height = 17 self.techIcon.texturePath = None elif self.jobData.activityID == industry.RESEARCH_TIME: self.icon.LoadIcon('res:/UI/Texture/Classes/Industry/iconTE.png') self.techIcon.texturePath = None self.icon.width = self.icon.height = 16 else: isCopy = self.jobData.activityID in (industry.COPYING, industry.INVENTION) oldTypeID = self.icon.typeID self.icon.LoadIconByTypeID(typeID, ignoreSize=True, isCopy=isCopy) self.icon.width = self.icon.height = 64 texturePath, hint = GetTechLevelIconPathAndHint(typeID) self.techIcon.texturePath = texturePath self.techIcon.hint = hint if oldTypeID != typeID: uicore.animations.FadeTo(self.icon, 0.0, 1.0, duration=0.6) if self.jobData.activityID == industry.INVENTION: width = self.jobData.probability * 160 color = GetJobColor(self.jobData) for gradient in (self.leftProbabilityGradient, self.rightProbabilityGradient): gradient.Show() gradient.SetRGBA(*color) uicore.animations.MorphScalar(gradient, 'width', gradient.width, width, duration=0.6) else: self.leftProbabilityGradient.Hide() self.rightProbabilityGradient.Hide() if self.jobData and self.jobData.product: self.iconCont.opacity = 1.0 uicore.animations.FadeTo(self.bgCont, self.bgCont.opacity, 1.0, duration=0.3) self.errorFrame.Hide() else: self.iconCont.opacity = 0.0 uicore.animations.FadeTo(self.bgCont, 0.3, 1.0, duration=2.0, curveType=uiconst.ANIM_WAVE, loops=uiconst.ANIM_REPEAT) self.errorFrame.Show() self.UpdateOutputQty() self.StopVideo() if self.jobData.status == industry.STATUS_DELIVERED: self.PlayVideoDelivered() def PlayVideoDelivered(self): self.PlayVideo('res:/video/Industry/deliveredIntro.bk2', 'res:/video/Industry/deliveredOutro.bk2', industryUIConst.GetActivityColor(self.jobData.activityID)) def PlayVideoFailed(self): self.PlayVideo('res:/video/Industry/failedIntro.bk2', 'res:/video/Industry/failedOutro.bk2', industryUIConst.COLOR_NOTREADY) def StopVideo(self): if self.videoThread: self.videoThread.kill() self.videoCont.Flush() def PlayVideo(self, introPath, outroPath, color): self.videoThread = uthread.new(self._PlayVideo, introPath, outroPath, color) def _PlayVideo(self, introPath, outroPath, color): self.videoCont.Flush() videoSprite = VideoSprite(parent=self.videoCont, align=uiconst.TOALL, spriteEffect=trinity.TR2_SFX_COPY, videoPath=introPath, color=color) while not videoSprite.isFinished: blue.synchro.Yield() blue.synchro.SleepWallclock(3000) videoSprite.Close() videoSprite = VideoSprite(parent=self.videoCont, align=uiconst.TOALL, spriteEffect=trinity.TR2_SFX_COPY, videoPath=outroPath, color=color) while not videoSprite.isFinished: blue.synchro.Yield() uicore.animations.FadeOut(videoSprite, callback=videoSprite.Close) def GetMenu(self): abstractInfo = KeyVal(bpData=self.GetBpData()) return sm.GetService('menu').GetMenuFormItemIDTypeID(None, self.jobData.product.typeID, ignoreMarketDetails=False, abstractInfo=abstractInfo) def LoadIconContTooltipPanel(self, tooltipPanel, *args): if self.jobData.activityID in (industry.RESEARCH_TIME, industry.RESEARCH_MATERIAL): return self.tooltipPanel = OutcomeTooltipPanel(jobData=self.jobData, tooltipPanel=tooltipPanel) def GetIconContTooltipDelay(self): return TOOLTIP_DELAY_GAMEPLAY def GetIconContDragData(self, *args): typeID = self.jobData.GetProductTypeID() if not typeID: return if isinstance(self.jobData.product, industry.Blueprint): bpData = self.jobData.product.GetCopy() else: bpData = None return [KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=typeID, label=cfg.invtypes.Get(typeID).name, bpData=bpData)] def UpdateOutputQty(self): if not self.jobData or not self.jobData.product: self.qtyLabel.text = '' return self.qtyLabel.text = self.jobData.GetProductAmountLabel() def AnimEntry(self): if not self.jobData: return uicore.animations.FadeTo(self.itemPattern, 0.0, 1.0, duration=0.6, timeOffset=1.35) uicore.animations.FadeTo(self.previewContFill, self.previewContFill.opacity, 0.0, duration=0.6, timeOffset=0, callback=self.previewContFill.Hide) def GetBpData(self): if not isinstance(self.jobData.product, industry.Blueprint): return None return self.jobData.product.GetCopy() def OnIconContClick(self, *args): if not self.jobData: return if self.jobData.activityID in (industry.RESEARCH_MATERIAL, industry.RESEARCH_TIME): return typeID = self.jobData.GetProductTypeID() if not typeID: return sm.GetService('info').ShowInfo(typeID, abstractinfo=KeyVal(bpData=self.GetBpData())) sm.GetService('audio').SendUIEvent('ind_click') def OnIconContMouseEnter(self, *args): uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.5, duration=0.15) sm.GetService('audio').SendUIEvent('ind_mouseEnter') def OnIconContMouseExit(self, *args): uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.0, duration=0.3)
class OutcomeContainer(Container): default_width = 327 default_height = 202 def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.jobData = None foregroundCont = Container( bgTexturePath= 'res:/UI/Texture/Classes/Industry/Output/outputContBg.png', parent=self, align=uiconst.CENTER, width=self.width, height=self.height, state=uiconst.UI_DISABLED) self.bgPattern = Frame( bgParent=foregroundCont, texturePath='res:/UI/Texture/Classes/Industry/Output/bgPattern.png', cornerSize=12) self.captionCont = ContainerAutoSize(name='captionCont', parent=self, align=uiconst.TOPLEFT, pos=(14, 10, 300, 0)) self.outcomeCaption = EveHeaderMedium( name='outcomeCaption', parent=self.captionCont, align=uiconst.TOTOP, bold=True, text=GetByLabel('UI/Industry/Outcome')) self.outcomeLabel = EveHeaderSmall(name='outcomeLabel', parent=self.captionCont, align=uiconst.TOTOP, bold=True) self.probabilityLabel = EveHeaderSmall(name='probabilityLabel', parent=self.captionCont, align=uiconst.TOTOP, bold=False, state=uiconst.UI_HIDDEN) self.probabilityLabel.LoadTooltipPanel = self.LoadProbabilityTooltipPanel self.probabilityLabel.GetTooltipDelay = self.GetProbabilityTooltipDelay self.copyInfoCont = Container(name='copyInfoCont', parent=self, align=uiconst.CENTERBOTTOM, pos=(0, 8, 300, 32), state=uiconst.UI_HIDDEN) self.containerME = ContainerME(parent=self.copyInfoCont, align=uiconst.TOPLEFT, width=71, height=30) self.runsPerCopyCont = ContainerAutoSize(name='runsPerCopyCont', parent=self.copyInfoCont, align=uiconst.CENTERTOP) self.containerTE = ContainerTE(parent=self.copyInfoCont, align=uiconst.TOPRIGHT, width=71, height=30) IndustryCaptionLabel(parent=self.runsPerCopyCont, text=localization.GetByLabel('UI/Industry/Runs'), align=uiconst.CENTERTOP) self.bpRunsLabel = EveLabelMediumBold(parent=self.runsPerCopyCont, align=uiconst.CENTERTOP, top=12) self.errorFrame = ErrorFrame(bgParent=self, padding=1) self.outcomeItem = OutcomeItemContainer(parent=self) FillUnderlay(bgParent=self, opacity=0.5) def LoadProbabilityTooltipPanel(self, tooltipPanel, *args): if not self.jobData: return self.tooltipPanel = ProbabilityTooltipPanel(jobData=self.jobData, tooltipPanel=tooltipPanel) def GetProbabilityTooltipDelay(self): return TOOLTIP_DELAY_GAMEPLAY def AnimEntry(self): if self.jobData: color = GetJobColor(self.jobData) for pattern in (self.bgPattern, self.outcomeCaption): uicore.animations.SpColorMorphTo(pattern, pattern.GetRGBA(), color, duration=0.3) self.errorFrame.Hide() def UpdateState(self): if self.jobData: self.outcomeLabel.text = self.jobData.GetProductLabel() self.UpdateCopyInfo() if self.jobData.activityID == industry.INVENTION: self.probabilityLabel.Show() color = Color.RGBtoHex(*GetJobColor(self.jobData)) self.probabilityLabel.text = localization.GetByLabel( 'UI/Industry/SuccessProbabilityPerRun', probability=self.jobData.probability * 100, color=color) else: self.probabilityLabel.Hide() else: self.outcomeLabel.text = '' self.probabilityLabel.Hide() def OnNewJobData(self, jobData): self.jobData = jobData self.UpdateState() self.outcomeItem.OnNewJobData(jobData) self.AnimEntry() def OnRunsChanged(self): self.UpdateState() def UpdateCopyInfo(self): bpData = self.jobData.GetProductNewBlueprint() if not bpData: self.copyInfoCont.Hide() return self.copyInfoCont.Show() self.containerME.SetValue(bpData.materialEfficiency) self.containerTE.SetValue(bpData.timeEfficiency) if bpData.original: self.runsPerCopyCont.Hide() else: self.runsPerCopyCont.Show() self.bpRunsLabel.text = '%s' % bpData.runsRemaining
class BlueprintCenter(Container): __notifyevents__ = ('OnIndustryWndMouseWheel', 'OnIndustryWndClick', 'OnBlueprintBrowserNumericInput') def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) sm.RegisterNotify(self) self.jobData = attributes.jobData self.newNumRuns = None self.setJobRunsThread = None self.oldJobData = None self.numericInputTimer = None self.iconCont = ItemIcon(parent=self, align=uiconst.CENTER, state=uiconst.UI_DISABLED, width=64, height=64, opacity=0.0) self.errorFrame = ErrorFrame(parent=self, align=uiconst.CENTER, state=uiconst.UI_DISABLED, width=80, height=80) self.ConstructBackground() self.runsCont = ContainerAutoSize(parent=self, align=uiconst.CENTER, top=100) self.runsCaption = IndustryCaptionLabel( name='runsCaption', parent=self.runsCont, align=uiconst.CENTERTOP, text=GetByLabel('UI/Industry/JobRuns')) self.runsEdit = BlueprintSingleLineEdit(parent=self.runsCont, align=uiconst.CENTERTOP, pos=(0, 12, 62, 0), OnChange=self.OnRunsEdit, autoselect=True) self.runsPerCopyCont = ContainerAutoSize(name='runsPerCopyCont', parent=self.runsCont, align=uiconst.CENTERTOP, top=38, state=uiconst.UI_HIDDEN) IndustryCaptionLabel(name='runsPerCopyCaption', parent=self.runsPerCopyCont, align=uiconst.CENTERTOP, text=GetByLabel('UI/Industry/RunsPerCopy')) self.runsPerCopyEdit = BlueprintSingleLineEdit( parent=self.runsPerCopyCont, align=uiconst.CENTERTOP, pos=(0, 12, 62, 0), OnChange=self.OnRunsPerCopyEdit, autoselect=True) self.gauge = None self.skillSprite = SkillIcon(parent=self, align=uiconst.CENTERBOTTOM, top=5, jobData=self.jobData) self.containerME = ContainerME(parent=self, align=uiconst.CENTER, pos=(113, -25, 71, 30), jobData=self.jobData, opacity=0.0) self.containerTE = ContainerTE(parent=self, align=uiconst.CENTER, pos=(113, 25, 71, 30), jobData=self.jobData, opacity=0.0) self.runsRemainingCont = ContainerAutoSize(name='bpCopyCont', parent=self, align=uiconst.CENTERTOP, state=uiconst.UI_NORMAL, top=90) self.runsRemainingCont.OnClick = self.OnRunsRemainingContClicked self.runsRemainingCaption = IndustryCaptionLabel( parent=self.runsRemainingCont, align=uiconst.CENTERTOP) self.runsRemainingLabel = EveLabelMediumBold( name='runsRemainingLabel', parent=self.runsRemainingCont, align=uiconst.CENTERTOP, top=14) self.UpdateState() self.AnimEntry() def OnRunsRemainingContClicked(self, *args): if self.runsEdit.state == uiconst.UI_NORMAL: self.runsEdit.SetValue(self.jobData.maxRuns) def OnBlueprintBrowserNumericInput(self, key, flag): if not self.numericInputTimer: self.runsEdit.SelectAll() else: self.numericInputTimer.kill() self.numericInputTimer = uthread.new(self.NumericInputTimer) self.runsEdit.OnChar(key, flag) def NumericInputTimer(self): blue.synchro.SleepWallclock(1000) self.numericInputTimer = None def OnJobUpdated(self, job): if self.jobData and self.jobData == job: self.UpdateStateJob() def UpdateStateJob(self): self.iconCont.Show() typeID = self.jobData.blueprint.blueprintTypeID self.iconCont.SetTypeID(typeID=typeID, bpData=self.jobData.blueprint) self.UpdateGaugeValue() self.UpdateStateRunsEdit() self.UpdateStateRunsPerCopyEdit() self.skillSprite.Show() self.UpdateRunsRemainingLabel() self.containerME.SetValue(self.jobData.blueprint.materialEfficiency) self.containerTE.SetValue(self.jobData.blueprint.timeEfficiency) self.jobData.on_updated.connect(self.OnJobUpdated) def UpdateRunsRemainingLabel(self): if not self.jobData: return if self.jobData.IsInstalled(): self.runsRemainingCont.Hide() else: runsText = self.jobData.GetRunsRemainingLabel() if runsText: self.runsRemainingCont.Show() self.runsRemainingLabel.text = runsText self.runsRemainingCaption.text = self.jobData.GetRunsRemainingCaption( ) else: self.runsRemainingCont.Hide() def SetNumRuns(self, numRuns): if not self.jobData.IsInstalled(): self.runsEdit.SetValue(numRuns) def UpdateStateRunsEdit(self): if self.jobData.IsInstalled(): self.runsEdit.IntMode(self.jobData.runs, self.jobData.runs) self.runsEdit.Show() self.runsCaption.Show() self.runsEdit.Disable() else: self.runsEdit.IntMode(1, self.jobData.maxRuns) self.runsEdit.Enable() self.runsEdit.Show() self.runsCaption.Show() self.runsEdit.SetValue(self.jobData.runs) def UpdateStateRunsPerCopyEdit(self): if self.jobData.activityID == industry.COPYING: if self.jobData.IsInstalled(): self.runsPerCopyEdit.IntMode(self.jobData.licensedRuns, self.jobData.licensedRuns) self.runsPerCopyEdit.Disable() else: self.runsPerCopyEdit.IntMode(1, self.jobData.maxLicensedRuns) self.runsPerCopyEdit.Enable() self.runsPerCopyEdit.SetValue(self.jobData.licensedRuns) self.runsPerCopyCont.Show() else: self.runsPerCopyCont.Hide() def UpdateState(self): if self.jobData: self.UpdateStateJob() else: self.iconCont.Hide() self.runsEdit.Hide() self.runsPerCopyCont.Hide() self.runsCaption.Hide() self.skillSprite.Hide() self.runsRemainingCont.Hide() self.containerME.SetValue(0.0) self.containerTE.SetValue(0.0) def ReconstructGauge(self): if self.gauge: self.gauge.Close() self.gauge = None if not self.jobData: return color = GetJobColor(self.jobData) h, s, b = Color(*color).GetHSB() colorEnd = Color(*color).SetBrightness(b * 0.5).GetRGBA() self.gauge = BlueprintGaugeCircular(name='gauge', parent=self, align=uiconst.CENTER, radius=64, lineWidth=4, colorStart=color, colorEnd=colorEnd, jobData=self.jobData) def AnimWedges(self, startVal, endVal, duration, curveType=None): uicore.animations.MorphScalar(self.topWedge, 'top', startVal, endVal, duration=duration, curveType=curveType) uicore.animations.MorphScalar(self.bottomWedge, 'top', startVal, endVal, duration=duration, curveType=curveType) uicore.animations.MorphScalar(self.leftWedge, 'left', startVal, endVal, duration=duration, curveType=curveType) uicore.animations.MorphScalar(self.rightWedge, 'left', startVal, endVal, duration=duration, curveType=curveType) def AnimEntry(self): duration = 0.7 if self.jobData: self.HideDashes() if self.topWedge.top < WEDGE_TRAVEL: self.AnimWedges(0, WEDGE_TRAVEL, duration) else: self.AnimWedges(WEDGE_TRAVEL, 18, 0.5, curveType=uiconst.ANIM_WAVE) if not self.IsSameBlueprint(): uicore.animations.FadeTo(self.iconCont, 0.0, 1.0, duration=0.5) for obj in (self.containerME, self.containerTE): obj.Enable() uicore.animations.FadeIn(obj, duration=duration) else: self.AnimWedges(self.topWedge.top, 0.0, duration) for obj in (self.containerME, self.containerTE): obj.Disable() uicore.animations.FadeOut(obj, duration=duration) self.ShowDashes() if self.jobData and self.jobData.IsPreview(): uicore.animations.FadeTo(self.iconCont, 0.0, 0.65, duration=0.5) self.errorFrame.Show() wedgeColor = industryUIConst.COLOR_NOTREADY else: self.errorFrame.Hide() wedgeColor = Color.WHITE for dots in self.wedgeDots: dots.SetRGBA(*wedgeColor) if self.gauge: uicore.animations.BlinkIn(self.gauge, 0.0, 1.0, timeOffset=0.98) for dots in self.wedgeDots: uicore.animations.BlinkIn(dots, 0.0, 0.85, timeOffset=0.78) for pattern in self.wedgeBg: if self.jobData and self.jobData.IsPreview(): color = industryUIConst.COLOR_NOTREADY else: color = GetJobColor(self.jobData) uicore.animations.SpColorMorphTo(pattern, pattern.GetRGBA(), color, duration=0.3) def IsSameBlueprint(self): if not self.oldJobData or not self.jobData: return False if self.jobData: return self.jobData.blueprint.IsSameBlueprint( self.oldJobData.blueprint) return False def UpdateGaugeValue(self): if not self.gauge or not self.jobData: return self.gauge.SetValue(self.jobData.GetGaugeValue()) def SetJobRuns(self, value): if self.setJobRunsThread is None: self.setJobRunsThread = uthread.new(self._SetJobRuns) self.newNumRuns = value def _SetJobRuns(self): while self.jobData and self.newNumRuns is not None: if self.newNumRuns != self.jobData.runs: newNumRuns = self.newNumRuns self.newNumRuns = None self.jobData.runs = newNumRuns sm.GetService('audio').SendUIEvent('ind_runsChanged') blue.synchro.SleepWallclock(100) self.setJobRunsThread = None def OnRunsEdit(self, value): try: value = int(value) except ValueError: return if self.jobData and not self.jobData.IsInstalled(): self.SetJobRuns(value) def OnRunsChanged(self): self.UpdateGaugeValue() self.UpdateRunsRemainingLabel() def OnRunsPerCopyEdit(self, value): try: value = int(value) except ValueError: return self.jobData.licensedRuns = value def ConstructBackground(self): Frame(name='bgFrame', parent=self, align=uiconst.CENTER, state=uiconst.UI_DISABLED, width=75, height=75, opacity=0.1) blueprintBg = FrameThemeColored( name='blueprintBgFill', parent=self, align=uiconst.CENTER, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Industry/Center/bgFrame.png', width=90, height=90) self.dashesCont = Container(name='dashesCont', parent=self, state=uiconst.UI_DISABLED, pos=(75, 0, 150, 150), align=uiconst.CENTER) self.bgCont = Container(name='bgCont', parent=self, state=uiconst.UI_DISABLED, width=150, height=150, align=uiconst.CENTER) self.topWedge = Container(name='topWedge', parent=self.bgCont, align=uiconst.CENTERTOP, pos=(0, 0, 84, 60)) topLines = Sprite( bgParent=self.topWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/wedgeTopBottom.png') topDots = Sprite( bgParent=self.topWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/dotsTopBottom.png') topBg = Sprite( bgParent=self.topWedge, texturePath='res:/UI/Texture/classes/Industry/Center/bgTop.png', color=COLOR_FRAME) self.bottomWedge = Container(name='bottomWedge', parent=self.bgCont, align=uiconst.CENTERBOTTOM, pos=(0, 0, 84, 60)) bottomLines = Sprite( bgParent=self.bottomWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/wedgeTopBottom.png', rotation=pi) bottomDots = Sprite( bgParent=self.bottomWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/dotsTopBottom.png', rotation=pi) bottomBg = Sprite( bgParent=self.bottomWedge, texturePath='res:/UI/Texture/classes/Industry/Center/bgBottom.png', color=COLOR_FRAME) self.leftWedge = Container(name='leftWedge', parent=self.bgCont, align=uiconst.CENTERLEFT, pos=(0, 0, 60, 84)) leftLines = Sprite( bgParent=self.leftWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/wedgeLeftRight.png') leftDots = Sprite( bgParent=self.leftWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/dotsLeftRight.png') leftBg = Sprite( bgParent=self.leftWedge, texturePath='res:/UI/Texture/classes/Industry/Center/bgLeft.png', color=COLOR_FRAME) self.rightWedge = Container(name='rightWedge', parent=self.bgCont, align=uiconst.CENTERRIGHT, pos=(0, 0, 60, 84)) rightLines = Sprite( bgParent=self.rightWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/wedgeLeftRight.png', rotation=pi) rightDots = Sprite( bgParent=self.rightWedge, texturePath= 'res:/UI/Texture/classes/Industry/Center/dotsLeftRight.png', rotation=pi) rightBg = Sprite( bgParent=self.rightWedge, texturePath='res:/UI/Texture/classes/Industry/Center/bgRight.png', color=COLOR_FRAME) self.wedgeLines = [topLines, bottomLines, leftLines, rightLines] self.wedgeDots = [topDots, bottomDots, leftDots, rightDots] self.wedgeBg = [topBg, bottomBg, leftBg, rightBg] def ShowDashes(self): for rotation in (0, pi / 2, pi, 3 * pi / 2): BlueDash(parent=self.dashesCont, align=uiconst.CENTERLEFT, rotation=pi / 4 + rotation, rotationCenter=(0.0, 0.5)) def HideDashes(self): self.dashesCont.Flush() def OnNewJobData(self, jobData): self.oldJobData = self.jobData self.jobData = jobData self.skillSprite.OnNewJobData(jobData) self.containerME.OnNewJobData(jobData) self.containerTE.OnNewJobData(jobData) self.ReconstructGauge() if self.gauge: self.gauge.OnNewJobData(jobData) self.UpdateState() self.AnimEntry() self.numericInputTimer = None def OnIndustryWndMouseWheel(self, *args): if not self.jobData: return self.runsEdit.OnMouseWheel() if uicore.registry.GetFocus() != self.runsEdit: uicore.registry.SetFocus(self.runsEdit) def OnIndustryWndClick(self): if not self.jobData: return uicore.registry.SetFocus(self.runsEdit)
class SubmitButton(Button): def ApplyAttributes(self, attributes): Button.ApplyAttributes(self, attributes) self.tooltipErrors = None self.jobData = attributes.jobData self.isStopPending = False self.isArrowsAnimating = False self.func = self.ClickFunc self.sr.label.uppercase = True self.sr.label.fontsize = 13 self.sr.label.bold = True self.pattern = Sprite( name='bgGradient', bgParent=self, texturePath= 'res:/UI/Texture/Classes/Industry/CenterBar/buttonPattern.png', color=Color.GRAY2, idx=0) self.bg = Sprite( name='bg', bgParent=self, opacity=0.0, texturePath= 'res:/UI/Texture/Classes/Industry/CenterBar/buttonBg.png', color=Color.GRAY2, idx=0, state=uiconst.UI_HIDDEN) self.arrows = Sprite( bgParent=self, texturePath= 'res:/UI/Texture/Classes/Industry/CenterBar/arrowMask.png', textureSecondaryPath= 'res:/UI/Texture/Classes/Industry/CenterBar/arrows.png', spriteEffect=trinity.TR2_SFX_MODULATE, color=Color.GRAY2, idx=0) self.arrows.translationSecondary = (-0.16, 0) self.errorFrame = ErrorFrame(bgParent=self) self.errorFrame.Hide() def OnNewJobData(self, jobData): self.oldJobData = self.jobData self.jobData = jobData self.isStopPending = False if self.jobData: self.jobData.on_updated.connect(self.OnJobUpdated) self.jobData.on_errors.connect(self.OnJobUpdated) self.UpdateState() def OnJobUpdated(self, *args): self.UpdateState() def GetColor(self): if not self.jobData or self.jobData.status == industry.STATUS_DELIVERED: return Color.GRAY2 if self.jobData.errors or self.isStopPending: return industryUIConst.COLOR_RED color = industryUIConst.GetJobColor(self.jobData) if self.jobData and self.jobData.status == industry.STATUS_UNSUBMITTED: color = Color(*color).SetAlpha(0.5).GetRGBA() return color def AnimateArrows(self): self.arrows.Show() if self.isArrowsAnimating: return uicore.animations.MorphVector2(self.arrows, 'translationSecondary', (0.16, 0.0), (-0.16, 0.0), duration=2.0, curveType=uiconst.ANIM_LINEAR, loops=uiconst.ANIM_REPEAT) self.isArrowsAnimating = True def StopAnimateArrows(self): if self.destroyed: return diff = math.fabs(-0.16 - self.arrows.translationSecondary[0]) duration = diff / 0.16 if diff: uicore.animations.MorphVector2(self.arrows, 'translationSecondary', self.arrows.translationSecondary, (-0.16, 0.0), duration=duration, curveType=uiconst.ANIM_LINEAR) self.isArrowsAnimating = False def HideArrows(self): self.StopAnimateArrows() self.arrows.Hide() def UpdateState(self): uicore.animations.FadeIn(self.sr.label) color = self.GetColor() underlayColor = Color(*color).SetBrightness(0.4).GetRGBA() self.underlay.SetFixedColor(underlayColor) blinkColor = Color( *color).SetSaturation(0.5).SetBrightness(0.9).GetRGBA() self.sr.hilite.SetRGBA(*blinkColor) for obj in (self.pattern, self.bg, self.arrows): uicore.animations.SpColorMorphTo(obj, obj.GetRGBA(), color, duration=0.3) self.UpdateLabel() if not self.jobData: return if self.jobData.errors: self.errorFrame.Show() self.HideArrows() else: self.errorFrame.Hide() self.arrows.Show() if self.jobData.status == industry.STATUS_INSTALLED: if not self.oldJobData or self.oldJobData.status != industry.STATUS_INSTALLED: self.AnimateArrows() elif self.jobData.status == industry.STATUS_DELIVERED: self.HideArrows() else: self.StopAnimateArrows() if self.jobData.status == industry.STATUS_READY: self.Blink(time=3000) else: self.Blink(False) if self.jobData and self.jobData.status > industry.STATUS_READY: self.Disable() else: self.Enable() def UpdateLabel(self): if not self.jobData or self.jobData.status == industry.STATUS_UNSUBMITTED: label = 'UI/Industry/Start' elif self.jobData.status in (industry.STATUS_INSTALLED, industry.STATUS_PAUSED): if self.isStopPending: label = 'UI/Common/Confirm' else: label = 'UI/Industry/Stop' elif self.jobData.status == industry.STATUS_READY: label = 'UI/Industry/Deliver' else: label = None if label: text = localization.GetByLabel(label) if self.text != text: self.SetLabelAnimated(text) else: self.SetLabel('') def SetLabelAnimated(self, text): uthread.new(self._SetLabelAnimated, text) def _SetLabelAnimated(self, text): uicore.animations.FadeOut(self.sr.label, duration=0.15, sleep=True) self.SetLabel(text) uicore.animations.FadeIn(self.sr.label, duration=0.3) def LoadTooltipPanel(self, tooltipPanel, *args): if self.tooltipErrors is not None: errors = self.tooltipErrors self.tooltipErrors = None else: errors = self.jobData.errors SubmitButtonTooltipPanel(status=self.jobData.status, errors=errors, tooltipPanel=tooltipPanel) def GetTooltipDelay(self): return TOOLTIP_DELAY_GAMEPLAY def ClickFunc(self, *args): if self.jobData.IsInstalled(): if self.jobData.status == industry.STATUS_READY: sm.GetService('industrySvc').CompleteJob(self.jobData.jobID) sm.GetService('audio').SendUIEvent('ind_jobDelivered') elif self.isStopPending: try: sm.GetService('industrySvc').CancelJob(self.jobData.jobID) finally: self.isStopPending = False self.UpdateState() else: self.isStopPending = True self.UpdateState() else: try: self.Disable() if not self.jobData.errors: self.AnimateArrows() sm.GetService('industrySvc').InstallJob(self.jobData) sm.GetService('audio').SendUIEvent('ind_jobStarted') except UserError as exception: if getattr(exception, 'msg', None) == 'IndustryValidationError': self.tooltipErrors = exception.args[1]['errors'] uicore.uilib.tooltipHandler.RefreshTooltipForOwner(self) raise finally: self.Enable() self.StopAnimateArrows() def OnMouseEnter(self, *args): Button.OnMouseEnter(self, *args) sm.GetService('audio').SendUIEvent('ind_mouseEnter')