class ItemIcon(Container): default_align = uiconst.TOPLEFT default_state = uiconst.UI_NORMAL default_width = 32 default_height = 32 isDragObject = True def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) self.typeID = attributes.typeID self.itemID = attributes.Get('itemID', None) self.bpData = attributes.Get('bpData', False) self.techIcon = Sprite(name='techIcon', parent=self, width=16, height=16) self.icon = Icon(parent=self, align=uiconst.TOALL, state=uiconst.UI_DISABLED) self.SetTypeID(self.typeID, self.bpData) def SetTypeID(self, typeID, bpData = None): self.typeID = typeID self.bpData = bpData self.icon.LoadIconByTypeID(typeID, ignoreSize=True, isCopy=self.IsBlueprintCopy()) from eve.client.script.ui.util.uix import GetTechLevelIconPathAndHint texturePath, hint = GetTechLevelIconPathAndHint(typeID) if texturePath: self.techIcon.texturePath = texturePath self.techIcon.hint = hint self.techIcon.Show() else: self.techIcon.Hide() def IsBlueprintCopy(self): if not self.bpData: return False return not self.bpData.original def GetMenu(self): return sm.GetService('menu').GetMenuFormItemIDTypeID(self.itemID, self.typeID, ignoreMarketDetails=0, abstractInfo=KeyVal(bpData=self.bpData)) def OnClick(self): sm.GetService('info').ShowInfo(self.typeID, self.itemID, abstractinfo=KeyVal(bpData=self.bpData)) def GetHint(self): return cfg.invtypes.Get(self.typeID).description def GetDragData(self): return [KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=self.typeID, label=cfg.invtypes.Get(self.typeID).name, bpData=self.bpData)]
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 FittingSlot(FittingSlotBase): __guid__ = 'xtriui.FittingSlot2' __notifyevents__ = ['OnRefreshModuleBanks'] default_name = 'fittingSlot' default_width = 44 default_height = 54 default_align = uiconst.TOPLEFT default_state = uiconst.UI_NORMAL isDragObject = True slotsToHintDict = { 'hiSlot': ('UI/Fitting/EmptyHighPowerSlot', 'EmptyHighSlot'), 'medSlot': ('UI/Fitting/EmptyMediumPowerSlot', 'EmptyMidSlot'), 'loSlot': ('UI/Fitting/EmptyLowPowerSlot', 'EmptyLowSlot'), 'subSystemSlot': ('UI/Fitting/EmptySubsystemSlot', ''), 'rigSlot': ('UI/Fitting/EmptyRigSlot', '') } @telemetry.ZONE_METHOD def ApplyAttributes(self, attributes): FittingSlotBase.ApplyAttributes(self, attributes) self.flagIcon = uicontrols.Icon(parent=self, name='flagIcon', align=uiconst.CENTER, state=uiconst.UI_DISABLED, width=self.width, height=self.height) self.sr.underlay = Sprite( bgParent=self, name='underlay', state=uiconst.UI_DISABLED, padding=(-10, -5, -10, -5), texturePath='res:/UI/Texture/Icons/81_64_1.png') self.groupMark = None self.chargeIndicator = None sm.RegisterNotify(self) self.radCosSin = attributes.radCosSin self.invReady = 1 self.UpdateFitting() def ConstructGroupMark(self): if self.groupMark: return self.groupMark = Sprite(parent=self, name='groupMark', pos=(-10, 14, 16, 16), align=uiconst.CENTER, state=uiconst.UI_NORMAL, idx=0) self.groupMark.GetMenu = self.GetGroupMenu def ConstructChargeIndicator(self): if self.chargeIndicator: return self.chargeIndicator = Sprite( parent=self, name='chargeIndicator', padTop=-2, height=7, align=uiconst.TOTOP, state=uiconst.UI_HIDDEN, texturePath='res:/UI/Texture/Icons/81_64_2.png', ignoreSize=True) self.chargeIndicator.rectWidth = 44 self.chargeIndicator.rectHeight = 7 def OnRefreshModuleBanks(self): self.SetGroup() def SetGroup(self): try: if self.controller.GetModule( ) is not None and not self.controller.SlotExists(): self.controller.DestroyWeaponBank() except ReferenceError: pass parentID = self.controller.GetParentID() allGroupsDict = settings.user.ui.Get('linkedWeapons_groupsDict', {}) groupDict = allGroupsDict.get(parentID, {}) ret = self.GetBankGroup(groupDict) if ret is None: if self.groupMark: self.groupMark.Hide() return groupNumber = ret.groupNumber self.ConstructGroupMark() self.groupMark.state = uiconst.UI_NORMAL self.groupMark.rotation = -self.GetRotation() if groupNumber < 0: availGroups = [1, 2, 3, 4, 5, 6, 7, 8] for masterID, groupNum in groupDict.iteritems(): if groupNum in availGroups: availGroups.remove(groupNum) groupNumber = availGroups[0] if availGroups else '' self.groupMark.texturePath = 'res:/UI/Texture/Icons/73_16_%s.png' % ( 176 + groupNumber) self.groupMark.hint = localization.GetByLabel('UI/Fitting/GroupNumber', groupNumber=groupNumber) groupDict[ret.masterID] = groupNumber allGroupsDict[parentID] = groupDict settings.user.ui.Set('linkedWeapons_groupsDict', allGroupsDict) def GetBankGroup(self, groupDict): module = self.controller.GetModule() try: if not module: return None except ReferenceError: return None masterID = self.controller.IsInWeaponBank() if not masterID: return None if masterID in groupDict: groupNumber = groupDict.get(masterID) else: groupNumber = -1 ret = util.KeyVal() ret.masterID = masterID ret.groupNumber = groupNumber return ret def PrepareUtilButtons(self): self.RemoveUtilButtons() self.utilButtons = [] if not self.controller.GetModule(): return myrad, cos, sin, cX, cY = self.radCosSin btns = self.GetUtilBtns() rad = myrad - 34 i = 0 for btnData in btns: left = int((rad - i * 16) * cos) + cX - 16 / 2 top = int((rad - i * 16) * sin) + cY - 16 / 2 utilBtn = FittingUtilBtn(parent=self.parent, icon=btnData.iconPath, left=left, top=top, btnData=btnData, mouseOverFunc=self.ShowUtilButtons, controller=self.controller) if btnData.onlineBtn == 1: self.sr.onlineButton = utilBtn self.utilButtons.append(utilBtn) i += 1 def RemoveUtilButtons(self): for btn in self.utilButtons: btn.Close() def GetUtilBtns(self): btns = [] if self.controller.GetCharge(): btns += self.GetChargesBtns() isRig = False for effect in cfg.dgmtypeeffects.get(self.controller.GetModuleTypeID(), []): if effect.effectID == const.effectRigSlot: isRig = True break isSubSystem = evetypes.GetCategoryID( self.controller.GetModuleTypeID()) == const.categorySubSystem isOnlinable = self.controller.IsOnlineable() if isRig: btns += self.GetRigsBtns() elif isSubSystem: btns += self.GetSubSystemBtns() else: btns += self.GetModuleBtns(isOnlinable) return btns def GetChargesBtns(self): moduleTypeID = self.controller.GetModuleTypeID() btns = [ UtilBtnData(localization.GetByLabel('UI/Fitting/RemoveCharge'), 'ui_38_16_200', self.controller.Unfit, 1, 0), UtilBtnData(localization.GetByLabel('UI/Fitting/ShowChargeInfo'), 'ui_38_16_208', self.ShowChargeInfo, 1, 0), UtilBtnData(evetypes.GetName(moduleTypeID), inventorycommon.typeHelpers.GetIconFile(moduleTypeID), None, 1, 0) ] return btns def GetSubSystemBtns(self): btns = [ UtilBtnData(localization.GetByLabel('UI/Commands/ShowInfo'), 'ui_38_16_208', self.ShowInfo, 1, 0) ] return btns @telemetry.ZONE_METHOD def UpdateFitting(self): if self.destroyed: return if not self.controller.SlotExists() and not self.controller.GetModule( ): if self.controller.IsSubsystemSlot( ) and self.controller.parentController.HasStance(): self.HideSlot() else: self.DisableSlot() self.HideChargeIndicator() self.RemoveUtilButtons() return self.EnableSlot() self.SetDragState() if self.controller.GetCharge(): chargeQty = self.controller.GetChargeQuantity() if self.controller.GetModule() is None: portion = 1.0 else: cap = self.controller.GetChargeCapacity() if cap.capacity == 0: portion = 1.0 else: portion = cap.used / cap.capacity step = max(0, min(4, int(portion * 5.0))) self.ConstructChargeIndicator() self.chargeIndicator.rectTop = 10 * step self.chargeIndicator.state = uiconst.UI_NORMAL self.chargeIndicator.hint = '%s %d%%' % (evetypes.GetName( self.controller.GetCharge().typeID), portion * 100) elif not self.controller.GetModule(): self.HideUtilButtons(1) self.HideChargeIndicator() elif self.controller.IsChargeable(): self.ConstructChargeIndicator() self.chargeIndicator.rectTop = 0 self.chargeIndicator.state = uiconst.UI_NORMAL self.chargeIndicator.hint = localization.GetByLabel( 'UI/Fitting/NoCharge') else: self.HideChargeIndicator() if self.controller.GetModule(): self.tooltipPanelClassInfo = TooltipModuleWrapper() modulehint = evetypes.GetName(self.controller.GetModuleTypeID()) if self.controller.GetCharge(): modulehint += '<br>%s' % localization.GetByLabel( 'UI/Fitting/ChargeQuantity', charge=self.controller.GetCharge().typeID, chargeQuantity=chargeQty) if not self.controller.SlotExists(): modulehint = localization.GetByLabel( 'UI/Fitting/SlotDoesNotExist') self.hint = modulehint else: self.tooltipPanelClassInfo = None self.hint = self._emptyHint tooltipName = self._emptyTooltip if tooltipName: SetFittingTooltipInfo(targetObject=self, tooltipName=tooltipName, includeDesc=False) self.PrepareUtilButtons() iconSize = int(48 * GetScaleFactor()) self.flagIcon.SetSize(iconSize, iconSize) if self.controller.GetCharge() or self.controller.GetModule(): self.flagIcon.LoadIconByTypeID( (self.controller.GetCharge() or self.controller.GetModule()).typeID, ignoreSize=True) self.flagIcon.rotation = -self.GetRotation() else: rev = 0 slotIcon = { const.flagSubSystemSlot0: 'res:/UI/Texture/Icons/81_64_9.png', const.flagSubSystemSlot1: 'res:/UI/Texture/Icons/81_64_10.png', const.flagSubSystemSlot2: 'res:/UI/Texture/Icons/81_64_11.png', const.flagSubSystemSlot3: 'res:/UI/Texture/Icons/81_64_12.png', const.flagSubSystemSlot4: 'res:/UI/Texture/Icons/81_64_13.png' }.get(self.controller.GetFlagID(), None) if slotIcon is None: slotIcon = { const.effectLoPower: 'res:/UI/Texture/Icons/81_64_5.png', const.effectMedPower: 'res:/UI/Texture/Icons/81_64_6.png', const.effectHiPower: 'res:/UI/Texture/Icons/81_64_7.png', const.effectRigSlot: 'res:/UI/Texture/Icons/81_64_8.png' }.get(self.controller.GetPowerType(), None) else: rev = 1 if slotIcon is not None: self.flagIcon.LoadIcon(slotIcon, ignoreSize=True) if rev: self.flagIcon.rotation = mathUtil.DegToRad(180.0) else: self.flagIcon.rotation = 0.0 self.SetGroup() self.UpdateOnlineDisplay() self.Hilite(0) def HideChargeIndicator(self): if self.chargeIndicator: self.chargeIndicator.Hide() def IsCharge(self, typeID): return evetypes.GetCategoryID(typeID) == const.categoryCharge def AddItem(self, item, sourceLocation=None): if not getattr(item, 'typeID', None): return if not RigFittingCheck(item): return requiredSkills = sm.GetService('skills').GetRequiredSkills(item.typeID) skills = sm.GetService('skills').GetSkills() for skillID, level in requiredSkills.iteritems(): if getattr(skills.get(skillID, None), 'skillLevel', 0) < level: sm.GetService('tutorial').OpenTutorialSequence_Check( uix.skillfittingTutorial) break if self.IsCharge(item.typeID) and self.controller.IsChargeable(): self.controller.FitCharge(item) validFitting = False for effect in cfg.dgmtypeeffects.get(item.typeID, []): if self.IsFittableItem(effect): validFitting = True if effect.effectID == self.controller.GetPowerType(): shift = uicore.uilib.Key(uiconst.VK_SHIFT) isFitted = item.locationID == self.controller.GetParentID( ) and item.flagID != const.flagCargo if isFitted and shift: if self.controller.GetModule(): if self.controller.GetModule( ).typeID == item.typeID: self.controller.LinkWithWeapon(item) return else: uicore.Message( 'CustomNotify', { 'notify': localization.GetByLabel( 'UI/Fitting/GroupingIncompatible') }) return self.controller.FitModule(item) return uicore.Message( 'ItemDoesntFitPower', { 'item': evetypes.GetName(item.typeID), 'slotpower': cfg.dgmeffects.Get( self.controller.GetPowerType()).displayName, 'itempower': cfg.dgmeffects.Get(effect.effectID).displayName }) if not validFitting: raise UserError('ItemNotHardware', {'itemname': item.typeID}) def IsFittableItem(self, effect): isFittableItem = effect.effectID in (const.effectHiPower, const.effectMedPower, const.effectLoPower, const.effectSubSystem, const.effectRigSlot, const.effectServiceSlot) return isFittableItem def GetMenu(self): if self.controller.GetModuleTypeID() and self.controller.GetModuleID(): m = FittingSlotBase.GetMenu(self) m += self.GetGroupMenu() return m def GetGroupMenu(self, *args): masterID = self.controller.IsInWeaponBank() if masterID: return [(uiutil.MenuLabel('UI/Fitting/ClearGroup'), self.UnlinkModule, ())] return [] def ShowChargeInfo(self, *args): if self.controller.GetCharge(): sm.GetService('info').ShowInfo(self.controller.GetCharge().typeID, self.controller.GetCharge().itemID) def UnlinkModule(self): self.controller.DestroyWeaponBank() def _OnEndDrag(self, *args): self.left = self.top = -2 def OnEndDrag(self, *args): if self.controller.GetModule() is not None: sm.ScatterEvent('OnResetSlotLinkingMode', self.controller.GetModule().typeID) def GetTooltipPosition(self): rect, point = self.PositionHint() return rect def GetTooltipPointer(self): rect, point = self.PositionHint() return point def UpdateInfo_TimedCall(self, *args): if self.destroyed or self.moduleButtonHint.destroyed: self.moduleButtonHint = None self.updateTimer = None return if self.controller.GetModuleTypeID(): if self.controller.GetCharge(): chargeItemID = self.controller.GetCharge().itemID else: chargeItemID = None self.moduleButtonHint.UpdateAllInfo(self.controller.GetModuleID(), chargeItemID, fromWhere='fitting') def PositionHint(self, *args): myRotation = self.rotation + 2 * math.pi myRotation = -myRotation sl, st, sw, sh = self.parent.GetAbsolute() cX = sl + sw / 2.0 cY = st + sh / 2.0 rad, cos, sin, oldcX, oldcY = self.radCosSin hintLeft = int(round(rad * cos)) hintTop = int(round(rad * sin)) cap = rad * 0.7 if hintLeft < -cap: point = uiconst.POINT_RIGHT_2 elif hintLeft > cap: point = uiconst.POINT_LEFT_2 elif hintTop < -cap: if hintLeft < 0: point = uiconst.POINT_BOTTOM_3 else: point = uiconst.POINT_BOTTOM_1 elif hintLeft < 0: point = uiconst.POINT_TOP_3 else: point = uiconst.POINT_TOP_1 return ((hintLeft + cX - 15, hintTop + cY - 15, 30, 30), point) def OnDropData(self, dragObj, nodes): if self.controller.GetModule( ) is not None and not self.controller.SlotExists(): return items = self.GetDroppedItems(nodes) chargeTypeID = None chargeItems = [] for item in items: if not getattr(item, 'typeID', None): lg.Info('fittingUI', 'Dropped a non-item here', item) return if self.controller.IsChargeable() and self.IsCharge(item.typeID): if chargeTypeID is None: chargeTypeID = item.typeID if chargeTypeID == item.typeID: chargeItems.append(item) elif self.controller.IsInWeaponBank(item): ret = uicore.Message( 'CustomQuestion', { 'header': localization.GetByLabel('UI/Common/Confirm'), 'question': localization.GetByLabel('UI/Fitting/ClearGroupModule') }, uiconst.YESNO) if ret == uiconst.ID_YES: uthread.new(self.AddItem, item) else: uthread.new(self.AddItem, item) if len(chargeItems): self.controller.FitCharges(chargeItems) def _OnClose(self, *args): self.updateTimer = None moduleButtonHint = getattr(uicore.layer.hint, 'moduleButtonHint', None) if moduleButtonHint and not moduleButtonHint.destroyed: if moduleButtonHint.fromWhere == 'fitting': uicore.layer.hint.moduleButtonHint.FadeOpacity(0.0)
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 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')
def Hide(self, *args): Sprite.Hide(self, *args) uicore.animations.FadeOut(self, duration=0.3)