class ExtraInfoEntry(Container): default_padLeft = 30 default_padRight = 30 default_padTop = 6 def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) info = attributes.info self.icon = Sprite(name='arrow', parent=self, pos=(0, 0, info['size'], info['size']), texturePath=info['path'], state=uiconst.UI_DISABLED, align=uiconst.TOPLEFT) self.text = EveLabelSmall(name='tipsHeader', text=info['text'], parent=self, left=info['size'] + 2, top=1, align=uiconst.TOPLEFT) iconColor = info.get('color', None) if iconColor: self.icon.SetRGB(*iconColor) def UpdateAlignment(self, *args, **kwds): retVal = Container.UpdateAlignment(self, *args, **kwds) if getattr(self, 'icon', None) and getattr(self, 'text', None): newHeight = max(self.icon.height + 2 * self.icon.top, self.text.textheight + 2 * self.text.padTop) self.height = newHeight return retVal
def AddArrowSprites(self, height, width): texturePath = 'res:/UI/Texture/classes/Lobby/takeControl2.png' self.spriteCont.left = 0 s = Sprite(parent=self.spriteCont, texturePath=texturePath, align=uiconst.CENTER, pos=(0, 0, 35, 30), state=uiconst.UI_DISABLED) s.SetRGB(*self.arrowColor) self.arrowSprites.append(s)
def AddArrowSprites(self, height, width): w = -width if self.isLeftBtn else width for i in xrange(3): texturePath = 'res:/UI/Texture/classes/Lobby/%s.png' % (i + 1) s = Sprite(parent=self.spriteCont, texturePath=texturePath, align=uiconst.CENTERTOP, pos=(0, 0, w, height), state=uiconst.UI_DISABLED) s.SetRGB(*self.arrowColor) self.arrowSprites.append(s)
def _CreateTimer(self, timerName='timer', rotation=0, texturePath=None, textureSecondaryPath=None, color=None): if not texturePath or not textureSecondaryPath: return None timer = Sprite(name=timerName, parent=self, align=uiconst.TOALL, texturePath=texturePath, textureSecondaryPath=textureSecondaryPath, blendMode=1, spriteEffect=trinity.TR2_SFX_MODULATE, state=uiconst.UI_DISABLED) if color: timer.SetRGB(*color) timer.baseRotation = rotation timer.rotationSecondary = rotation return timer
class AchievementGroup(ContainerAutoSize): default_padTop = 3 default_padBottom = 3 headerHeight = 20 default_alignMode = uiconst.TOTOP texturePath = 'res:/UI/Texture/Classes/InfoPanels/opportunitiesIcon_Explore.png' progressBackground = 'res:/UI/Texture/Classes/InfoPanels/opportunitiesFillBar.png' fillBox = 'res:/UI/Texture/Classes/InfoPanels/opportunitiesFillBox.png' checkmarkPath = 'res:/UI/Texture/Classes/InfoPanels/opportunitiesCheck.png' def ApplyAttributes(self, attributes): ContainerAutoSize.ApplyAttributes(self, attributes) self.groupInfo = attributes.groupInfo self.isExpanded = attributes.isExpanded self.clickCallback = attributes.clickCallback iconColumn = Container(parent=self, name='iconColumn', align=uiconst.TOLEFT, width=20) self.icon = Sprite(name='groupIcon', parent=iconColumn, pos=(0, 0, 16, 16), texturePath=self.groupInfo.iconPath, state=uiconst.UI_DISABLED, align=uiconst.CENTERTOP) headerCont = Container(parent=self, name='headerCont', align=uiconst.TOTOP, state=uiconst.UI_NORMAL, height=self.headerHeight) headerCont.OnClick = (self.clickCallback, self.groupInfo, self.isExpanded) headerCont.OnMouseEnter = self.OnMouseEnterHeader headerCont.OnMouseExit = self.OnMouseExitHeader self.bodyCont = ContainerAutoSize(parent=self, name='bodyCont', align=uiconst.TOTOP) Fill(bgParent=self.bodyCont, color=(0.1, 0.1, 0.1, 0.2)) self.groupText = EveLabelMediumBold(name='groupText', text=self.groupInfo.groupName, parent=headerCont, left=4, align=uiconst.CENTERLEFT) self.progressText = EveLabelMediumBold(name='progressText', text='', parent=headerCont, left=4, align=uiconst.CENTERRIGHT) self.fillBoxFrame = Frame(bgParent=headerCont, name='progress', texturePath=self.fillBox, cornerSize=2) progressCont = Container(parent=headerCont, name='progressCont', align=uiconst.TOALL) bgColor = [x for x in COLOR_COMPLETED[:3]] + [0.15] self.completedBg = Fill(bgParent=progressCont, color=tuple(bgColor)) self.completedBg.display = False self.progressFrame = Frame(parent=progressCont, name='progressFrame', texturePath=self.progressBackground, cornerSize=2, width=0.0, align=uiconst.TOLEFT_PROP) self.checkmark = Sprite(name='checkmark', parent=headerCont, pos=(0, 0, 16, 16), texturePath=self.checkmarkPath, state=uiconst.UI_DISABLED, align=uiconst.CENTERRIGHT) self.SetProgress() if self.isExpanded: self.AddAchievementEntries() self.AddExtraInfo() self.AddPadding() def SetProgress(self): totalNum = len(self.groupInfo.achievements) completed = len( [x for x in self.groupInfo.achievements if x.completed]) percentage = float(completed) / totalNum self.progressFrame.width = percentage self.progressText.text = GetByLabel( 'UI/Achievements/InfoPanelGroupPercentage', percentCompleted=round(percentage * 100)) if completed >= totalNum: self.SetCompletedProgress() elif completed < 1: self.SetNotStartedProgress() else: self.SetIncompleteProgress() def SetCompletedProgress(self): self.SetProgressStates(color=COLOR_COMPLETED, bgOn=True, showProgressFrame=False, showCheckMark=True, showProgressText=False) def SetIncompleteProgress(self): self.SetProgressStates(color=COLOR_INCOMPLETED_TEXT) def SetNotStartedProgress(self): self.SetProgressStates(color=COLOR_NOT_STARTED_TEXT, showProgressFrame=False) def SetProgressStates(self, color, bgOn=False, showProgressFrame=True, showCheckMark=False, showProgressText=True): self.completedBg.display = bgOn self.progressFrame.display = showProgressFrame self.checkmark.display = showCheckMark self.progressText.display = showProgressText self.progressText.SetRGB(*color) self.groupText.SetRGB(*color) self.icon.SetRGB(*color) def AddAchievementEntries(self): for eachAchievement in self.groupInfo.achievements: entry = AchievementEntry(parent=self.bodyCont, align=uiconst.TOTOP, achievement=eachAchievement) def AddExtraInfo(self): if not self.groupInfo.extraInfo: return extraInfo = self.groupInfo.extraInfo sectionHeader = SectionHeader( parent=self.bodyCont, headerText=GetByLabel('UI/Achievements/TipsAndInfoHeader'), toggleFunc=self.OnInfoHeaderClicked, state=uiconst.UI_NORMAL, align=uiconst.TOTOP) self.infoCont = ContainerAutoSize(parent=self.bodyCont, name='infoCont', align=uiconst.TOTOP) self.tipsText = EveLabelSmall(name='tipsText', text=self.groupInfo.groupHint, parent=self.infoCont, padLeft=16, align=uiconst.TOTOP) for each in extraInfo: ExtraInfoEntry(parent=self.infoCont, info=each, align=uiconst.TOTOP) def AddPadding(self): Container(parent=self.bodyCont, name='padding', align=uiconst.TOTOP, height=6) def OnInfoHeaderClicked(self, *args): self.infoCont.display = not self.infoCont.display def OnMouseEnterHeader(self, *args): self.ChangeAlphaOnUIElements(2.0) def OnMouseExitHeader(self, *args): self.ChangeAlphaOnUIElements(1.0) def ChangeAlphaOnUIElements(self, alpha): self.fillBoxFrame.SetAlpha(alpha) self.progressText.SetAlpha(alpha) self.groupText.SetAlpha(alpha)
class SellItemContainer(BuySellItemContainerBase): __guid__ = 'uicls.SellItemContainer' belowColor = '<color=0xffff5050>' aboveColor = '<color=0xff00ff00>' totaLabelPath = 'UI/Market/MarketQuote/AskTotal' def ApplyAttributes(self, attributes): self.item = attributes.item self.typeID = self.item.typeID BuySellItemContainerBase.ApplyAttributes(self, attributes) self.adjustQtyAndPriceTimer = None self.isUpdating = False self.singleton = self.item.singleton self.itemID = self.item.itemID self.itemName = evetypes.GetName(self.typeID) self.brokersFee = 0.0 self.salesTax = 0.0 self.totalSum = 0.0 self.stationID = attributes.stationID self.limits = self.quoteSvc.GetSkillLimits(self.stationID) self.solarSystemID = attributes.solarSystemID self.regionID = self.GetRegionID() self.locationID = self.item.locationID self.bestBid = attributes.bestBid self.bestPrice = attributes.bestPrice self.totalStrikethroughLine = None self.priceAmountWarning = None self.deltaCont = Container(parent=self, align=uiconst.TORIGHT, width=30) theRestCont = Container(name='theRestCont', parent=self, align=uiconst.TOALL) self.totalCont = Container(name='totalCont', parent=theRestCont, align=uiconst.TORIGHT_PROP, width=0.3) self.priceCont = Container(name='priceCont', parent=theRestCont, align=uiconst.TORIGHT_PROP, width=0.22) self.qtyCont = Container(name='qtyCont', parent=theRestCont, align=uiconst.TORIGHT_PROP, width=0.15) self.itemCont = Container(name='itemCont', parent=theRestCont, align=uiconst.TORIGHT_PROP, width=0.33) self.deleteCont = Container(name='deleteCont', parent=self.itemCont, align=uiconst.TORIGHT, width=24) self.deleteButton = ButtonIcon( texturePath='res:/UI/Texture/Icons/73_16_210.png', pos=(0, 0, 16, 16), align=uiconst.CENTERRIGHT, parent=self.deleteCont, hint=GetByLabel('UI/Generic/RemoveItem'), idx=0, func=self.RemoveItem) self.deleteCont.display = False self.textCont = Container(name='textCont', parent=self.itemCont, align=uiconst.TOALL) self.errorBg = ErrorFrame(bgParent=self) self.DrawItem() self.DrawQty() self.DrawPrice() self.DrawTotal() self.DrawDelta() self.estimatedSellCount = self.GetSellCountEstimate() self.SetTotalSumAndLabel() self.brokersFeePerc = self.limits.GetBrokersFeeForLocation( self.stationID) self.UpdateBrokersFee() self.GetSalesTax() self.ShowNoSellOrders() self.UpdateOrderStateInUI() def GetRegionID(self): return cfg.mapSystemCache.Get(session.solarsystemid2).regionID def OnDurationChanged(self, duration): self.OnChange() def ShowNoSellOrders(self, force=False): if self.IsImmediateOrder() and (self.bestBid is None or force): uicore.animations.FadeIn(self.errorBg, 0.35, duration=0.3) def GetDuration(self): from eve.client.script.ui.shared.market.sellMulti import SellItems wnd = SellItems.GetIfOpen() if not wnd: return return wnd.durationCombo.GetValue() def DrawQty(self): qty = self.item.stacksize self.qtyEdit = SinglelineEdit(name='qtyEdit', parent=self.qtyCont, align=uiconst.TOTOP, top=11, padLeft=4) self.qtyEdit.IntMode(*(1, long(qty))) self.qtyEdit.SetValue(qty) self.qtyEdit.OnChange = self.OnChange self.qtyEdit.hint = GetByLabel('UI/Common/Quantity') def DrawPrice(self): self.priceEdit = SinglelineEdit(name='priceEdit', parent=self.priceCont, align=uiconst.TOTOP, top=11, padLeft=8) self.priceEdit.FloatMode(*(0.01, 9223372036854.0, 2)) self.priceEdit.SetValue(self.bestPrice) self.priceEdit.OnChange = self.OnChange self.priceEdit.hint = GetByLabel('UI/Market/MarketQuote/AskPrice') def DrawDelta(self): self.deltaContainer = SellDeltaContainer(parent=self.deltaCont, delta=self.GetDelta(), func=self.OpenMarket, align=uiconst.CENTERRIGHT) self.deltaContainer.LoadTooltipPanel = self.LoadDeltaTooltip self.UpdateDelta() def GetTradeWndClass(self): from eve.client.script.ui.shared.market.sellMulti import SellItems return SellItems def LoadDeltaTooltip(self, tooltipPanel, *args): tooltipPanel.LoadGeneric2ColumnTemplate() tooltipPanel.cellPadding = (4, 1, 4, 1) tooltipPanel.AddLabelLarge( text=GetByLabel('UI/Market/MarketQuote/AskPrice')) tooltipPanel.AddLabelLarge(text=FmtISK(self.priceEdit.GetValue()), align=uiconst.CENTERRIGHT) tooltipPanel.AddSpacer(1, 8, colSpan=tooltipPanel.columns) tooltipPanel.AddLabelMedium( text='%s %s' % (GetByLabel('UI/Market/MarketQuote/RegionalAdverage'), self.GetDeltaText())) tooltipPanel.AddLabelMedium(text=FmtISK(self.averagePrice), align=uiconst.CENTERRIGHT) tooltipPanel.AddLabelMedium( text=GetByLabel('UI/Market/MarketQuote/BestRegional')) bestMatch = tooltipPanel.AddLabelMedium(text='', align=uiconst.CENTERRIGHT) bestMatchDetails = tooltipPanel.AddLabelSmall( text='', align=uiconst.CENTERRIGHT, colSpan=tooltipPanel.columns) if not self.bestBid: bestMatch.text = GetByLabel('UI/Contracts/ContractEntry/NoBids') bestMatchDetails.text = GetByLabel( 'UI/Market/MarketQuote/ImmediateWillFail') bestMatch.color = (1.0, 0.275, 0.0, 1.0) bestMatchDetails.color = (1.0, 0.275, 0.0, 1.0) else: bestMatch.text = FmtISK(self.bestBid.price) bestMatchText, volRemaining = self.GetBestMatchText() bestMatchDetails.text = bestMatchText bestMatchDetails.SetAlpha(0.6) if volRemaining: vol = tooltipPanel.AddLabelSmall(text=volRemaining, align=uiconst.CENTERRIGHT, colSpan=tooltipPanel.columns) vol.SetAlpha(0.6) def GetBestMatchText(self): jumps = max(self.bestBid.jumps - max(0, self.bestBid.range), 0) minVolumeText = None if jumps == 0 and self.stationID == self.bestBid.stationID: jumpText = GetByLabel('UI/Market/MarketQuote/ItemsInSameStation') else: jumpText = GetByLabel('UI/Market/MarketQuote/JumpsFromThisSystem', jumps=jumps) if self.bestBid.minVolume > 1 and self.bestBid.volRemaining >= self.bestBid.minVolume: minVolumeText = GetByLabel( 'UI/Market/MarketQuote/SimpleMinimumVolume', min=self.bestBid.minVolume) return (GetByLabel('UI/Market/MarketQuote/SellQuantity', volRemaining=long(self.bestBid.volRemaining), jumpText=jumpText), minVolumeText) def DrawItem(self): iconCont = Container(parent=self.textCont, align=uiconst.TOLEFT, width=32, padding=4) self.iconInnerCont = Container(name='iconInnerCont', parent=iconCont, align=uiconst.CENTERLEFT, pos=(0, 0, 32, 32)) self.wheel = LoadingWheel(parent=self.iconInnerCont, pos=(0, 0, 48, 48), align=uiconst.CENTER, idx=0) self.wheel.display = False self.techIcon = Sprite(parent=self.iconInnerCont, pos=(0, 0, 16, 16), align=uiconst.TOPLEFT, state=uiconst.UI_NORMAL) self.icon = Icon(parent=self.iconInnerCont, typeID=self.typeID, state=uiconst.UI_DISABLED, ignoreSize=True, pos=(0, 0, 32, 32)) GetTechLevelIcon(self.techIcon, 1, self.typeID) itemName = GetByLabel('UI/Contracts/ContractsWindow/ShowInfoLink', showInfoName=self.itemName, info=('showinfo', self.typeID, self.item.itemID)) self.itemNameLabel = Label(text=itemName, parent=self.textCont, left=40, align=uiconst.CENTERLEFT, state=uiconst.UI_NORMAL, autoFadeSides=35, fontsize=12) def UpdateBrokersFee(self): fee = self.quoteSvc.BrokersFee(self.stationID, self.totalSum, self.brokersFeePerc) feeAmount = fee.amt self.brokersFee = feeAmount def GetSalesTax(self): tax = self.totalSum * self.limits['acc'] self.salesTax = tax def GetTotalSum(self): self.GetTotalSumAndDisplaySum() return self.totalSum def GetTotalSumAndDisplaySum(self): price = self.GetPrice() qty = self.GetQty() sumToDisplay = price * qty totalSum = sumToDisplay if self.IsImmediateOrder(): if self.estimatedSellCount == 0: totalSum = 0 elif self.estimatedSellCount < qty: sumToDisplay = self.estimatedSellCount * price totalSum = sumToDisplay self.totalSum = totalSum return (totalSum, sumToDisplay) def UpdateTotalSumLabel(self, totalSum, sumToDisplay): self.totalLabel.text = FmtISK(sumToDisplay) if sumToDisplay != totalSum: self.ConstructTotalStrikethroughLine() self.totalStrikethroughLine.width = self.totalLabel.textwidth else: self.ChangeTotalStrikethroughDisplay(display=False) def OnChange(self, *args): if self.adjustQtyAndPriceTimer: self.adjustQtyAndPriceTimer.KillTimer() self.adjustQtyAndPriceTimer = AutoTimer(200, self.AdjustQtyAndPrice_thread, *args) self.SetItemLoading() def AdjustQtyAndPrice_thread(self, *args): self.adjustQtyTimer = None if self.destroyed: return self.estimatedSellCount = self.GetSellCountEstimate() self.SetTotalSumAndLabel() self.UpdateBrokersFee() self.GetSalesTax() self.deltaContainer.display = True self.UpdateDelta() self.wheel.display = False self.isUpdating = False if self.parentEditFunc: self.parentEditFunc(args) self.UpdateOrderStateInUI() def SetItemLoading(self): self.totalLabel.text = NA_CHAR self.deltaContainer.display = False self.wheel.display = True self.isUpdating = True def SetTotalSumAndLabel(self): totalSum, displaySum = self.GetTotalSumAndDisplaySum() self.UpdateTotalSumLabel(totalSum, displaySum) def UpdateOrderStateInUI(self): duration = self.GetDuration() if duration != 0: self.ChangePriceAmountWarningDisplay(display=False) self.HideNoSellOrders() return qty = self.GetQty() if self.estimatedSellCount == 0: self.ShowNoSellOrders(force=True) self.ChangePriceAmountWarningDisplay(display=False) elif self.estimatedSellCount < qty: self.HideNoSellOrders() self.PrepareWarningInfo(self.estimatedSellCount, qty) else: self.HideNoSellOrders() self.ChangePriceAmountWarningDisplay(display=False) def PrepareWarningInfo(self, estimatedSellCount, qtyToSell): self.ConstructPriceAmountWarning() self.ConstructQtyBg() self.ChangePriceAmountWarningDisplay(display=True) self.priceAmountWarning.info = (estimatedSellCount, qtyToSell) def GetPrice(self): price = self.priceEdit.GetValue() return price def GetQty(self): qty = self.qtyEdit.GetValue() return qty def GetQtyToSell(self): qty = self.GetQty() if self.IsImmediateOrder(): return min(self.estimatedSellCount, qty) else: return qty def IsImmediateOrder(self): isImmediate = self.GetDuration() == 0 return isImmediate def SetQtyAndPrice(self, newQty, newPrice): self.qtyEdit.SetValue(newQty) self.priceEdit.SetValue(newPrice) self.OnChange() def GetSellCountEstimate(self): return self.quoteSvc.GetSellCountEstimate(self.typeID, self.stationID, self.GetPrice(), self.GetQty()) def MakeSingle(self): self.height = 80 self.qtyCont.width = 0 self.itemCont.width = 0.42 self.totalCont.width = 0.36 self.itemNameLabel.fontsize = 14 self.totalLabel.fontsize = 14 self.itemNameLabel.left = 72 self.icon.SetSize(64, 64) self.wheel.SetSize(64, 64) self.iconInnerCont.SetSize(64, 64) self.priceEdit.padLeft = 4 self.priceEdit.align = uiconst.TOBOTTOM self.qtyEdit.top = 20 self.priceEdit.top = 20 self.qtyEdit.SetParent(self.priceCont) if self.priceAmountWarning: self.priceAmountWarning.top = -10 def RemoveSingle(self): self.height = 40 self.qtyCont.width = 0.15 self.itemCont.width = 0.33 self.totalCont.width = 0.3 self.itemNameLabel.fontsize = 12 self.totalLabel.fontsize = 12 self.itemNameLabel.left = 40 self.icon.SetSize(32, 32) self.wheel.SetSize(48, 48) self.iconInnerCont.SetSize(32, 32) self.priceEdit.align = uiconst.TOTOP self.qtyEdit.top = 11 self.priceEdit.top = 11 self.priceEdit.padLeft = 8 self.qtyEdit.SetParent(self.qtyCont) if self.priceAmountWarning: self.priceAmountWarning.top = 0 def ConstructPriceAmountWarning(self): if self.priceAmountWarning: return None cont = Container(name='priceAmountWarning', parent=self.itemCont, align=uiconst.TORIGHT, left=-4, width=16, idx=0) self.priceAmountWarning = Sprite( parent=cont, pos=(0, 0, 16, 16), align=uiconst.CENTER, texturePath='res:/ui/texture/icons/44_32_7.png') self.priceAmountWarning.SetRGB(1.0, 0.3, 0.3, 0.8) self.priceAmountWarning.info = (None, None) self.priceAmountWarning.GetHint = self.GetWarningHint def ConstructQtyBg(self): if getattr(self.qtyEdit, 'warningBg', None): return warningBg = Fill(bgParent=self.qtyEdit, color=(1, 0, 0, 0.3)) self.qtyEdit.warningBg = warningBg def ConstructTotalStrikethroughLine(self): if self.totalStrikethroughLine: return self.totalStrikethroughLine = Line(parent=self.totalCont, align=uiconst.CENTERRIGHT, pos=(2, 0, 0, 1), idx=0, color=(1, 1, 1, 0.8)) def ChangeTotalStrikethroughDisplay(self, display=False): if self.totalStrikethroughLine: self.totalStrikethroughLine.display = display def ChangePriceAmountWarningDisplay(self, display=False): if self.priceAmountWarning: self.priceAmountWarning.display = display if getattr(self.qtyEdit, 'warningBg', None): self.qtyEdit.warningBg.display = display def GetWarningHint(self): estimatedSellCount, qtyToSell = self.priceAmountWarning.info if estimatedSellCount is None or qtyToSell is None: return txt = GetByLabel('UI/Market/MarketQuote/QtyPriceWarning', estimatedSellNum=int(estimatedSellCount), tryingToSellNum=qtyToSell) return txt
class FittingSlotGhost(FittingSlotBase): __guid__ = 'xtriui.FittingSlotGhost' __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.dontHaveLine = None self.moduleSlotFill = None self.skillSprite = None self.groupMark = None self.chargeIndicator = None sm.RegisterNotify(self) self.radCosSin = attributes.radCosSin self.invReady = 1 self.UpdateFitting() self.controller.on_simulation_mode_changed.connect( self.UpdateSimulationMode) def ConstructDontHaveLine(self): if self.dontHaveLine: return self.dontHaveLine = Sprite( parent=self, name='dontHaveLine', align=uiconst.TOALL, state=uiconst.UI_DISABLED, texturePath='res:/UI/Texture/classes/Fitting/moduleFrameDots.png', padding=(-10, -5, -10, -5), color=(1, 1, 0, 1.0)) def ConstructModuleSlotFill(self): if self.moduleSlotFill: return self.moduleSlotFill = Sprite( parent=self, name='moduleSlotFill', align=uiconst.TOALL, state=uiconst.UI_DISABLED, padding=(-8, -4, -8, -4), texturePath='res:/UI/Texture/classes/Fitting/moduleSlotFill.png', color=(1, 1, 1, 0.5)) self.moduleSlotFill.display = False def ConstructSkillSprite(self): if self.skillSprite: return self.skillSprite = Sprite( parent=self, name='skillSprite', align=uiconst.TOALL, state=uiconst.UI_DISABLED, padding=(-8, -4, -8, -4), texturePath='res:/UI/Texture/classes/Fitting/slotGlowInner.png', color=(1, 1, 1, 0.5)) self.skillSprite.display = False 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): for btn in self.utilButtons: btn.Close() 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 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 def DisableSlot(self): FittingSlotBase.DisableSlot(self) self.UpdateGhostFittingIcons(None) self.Hilite(0) def EnableSlot(self): FittingSlotBase.EnableSlot(self) self.sr.underlay.display = True def HideSlot(self): self.state = uiconst.UI_HIDDEN @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() 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) if self.chargeIndicator: self.chargeIndicator.Hide() elif self.controller.IsChargeable(): self.ConstructChargeIndicator() self.chargeIndicator.rectTop = 0 self.chargeIndicator.state = uiconst.UI_NORMAL self.chargeIndicator.hint = localization.GetByLabel( 'UI/Fitting/NoCharge') elif self.chargeIndicator: self.chargeIndicator.Hide() 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.UpdateStatusDisplay() self.UpdateGhostFittingIcons(self.controller.GetModule()) if not self.hilitedFromMathing: self.Hilite(0) def IsCharge(self, typeID): return evetypes.GetCategoryID(typeID) == const.categoryCharge def Add(self, item, sourceLocation=None): if self.controller.parentController.IsSimulated(): return self.AddSimulatedItem(item, sourceLocation) else: guid = getattr(item, '__guid__', None) if guid is None or guid in ('listentry.InvItem', 'xtriui.InvItem'): return self.AddRealItem(item, sourceLocation) sm.GetService('ghostFittingSvc').LoadCurrentShip() return self.AddSimulatedItem(item, sourceLocation) def AddSimulatedItem(self, item, sourceLocation): if not IsRightSlotForType(item.typeID, self.controller.GetPowerType()): return shipID = self.controller.GetParentID() ghostFittingSvc = sm.GetService('ghostFittingSvc') ghostFittingSvc.FitModuleToShipAndChangeState( shipID, self.controller.GetFlagID(), item.typeID) ghostFittingSvc.SendFittingSlotsChangedEvent() def AddRealItem(self, item, sourceLocation=None): if not getattr(item, 'typeID', None): return if not RigFittingCheck(item): return requiredSkills = sm.GetService('skills').GetRequiredSkills(item.typeID) for skillID, level in requiredSkills.iteritems(): if getattr( sm.GetService('skills').HasSkill(skillID), '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.effectID): 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, effectID): isFittableItem = 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 OnDblClick(self, *args): if self.controller.IsSimulated(): sm.ScatterEvent('OnSlotDblClicked', self.controller.GetFlagID()) def OnClick(self, *args): if self.controller.IsSimulated() and self.controller.GetSimulationMode( ) == SIMULATION_MODULES: return self.OnClickSimulated() def OnClickSimulated(self): if self.controller.GetModule() is None: return uicore.registry.SetFocus(self) typeID = self.controller.GetModuleTypeID() itemKey = self.controller.GetModuleID() flagID = self.controller.GetFlagID() ghostFittingSvc = sm.GetService('ghostFittingSvc') ghostFittingSvc.SwitchBetweenModes(itemKey, typeID, flagID) self.UpdateStatusDisplay() def UpdateStatusDisplay(self): self.HideElement(self.moduleSlotFill) ghostFittingSvc = sm.GetService('ghostFittingSvc') simulationMode = ghostFittingSvc.GetSimulationMode() if not self.controller.parentController.IsSimulated( ) or simulationMode != SIMULATION_MODULES: return itemKey = self.controller.GetModuleID() typeID = self.controller.GetModuleTypeID() flagID = self.controller.GetFlagID() if itemKey is None or typeID is None: return typeEffectInfo = ghostFittingSvc.GetDefaultAndOverheatEffect(typeID) currentStatus = ghostFittingSvc.GetModuleStatus( itemKey, typeID, flagID) self.flagIcon.SetAlpha(1.0) self.ConstructModuleSlotFill() if typeEffectInfo.defaultEffect and typeEffectInfo.isActivatable: texturePath = 'res:/UI/Texture/classes/Fitting/slotGlowInner.png' else: texturePath = 'res:/UI/Texture/classes/Fitting/slotGlowOuter.png' self.moduleSlotFill.SetTexturePath(texturePath) self.moduleSlotFill.display = True if currentStatus == OFFLINE: self.flagIcon.SetAlpha(0.25) self.moduleSlotFill.SetRGB(0.5, 0.5, 0.5, 0.2) elif currentStatus == ONLINE: self.moduleSlotFill.SetRGB(0.5, 0.5, 0.5, 1.5) elif currentStatus == ACTIVE: self.ConstructModuleSlotFill() self.moduleSlotFill.SetRGB(1, 1, 0, 1.0) elif currentStatus == OVERHEATED: self.ConstructModuleSlotFill() self.moduleSlotFill.SetRGB(1, 0, 0, 1.0) 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) else: uthread.new(self.Add, 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) def GetDroppedItems(self, nodes): items = [] for node in nodes: if node.__guid__ in ('listentry.InvItem', 'xtriui.InvItem'): invType = node.rec if self.controller.IsFittableType(invType.typeID): items.append(invType) elif node.__guid__ in ('listentry.GenericMarketItem', 'listentry.Item', 'listentry.FittingModuleEntry'): if self.controller.IsFittableType(node.typeID): items.append(node.invtype or util.KeyVal(typeID=node.typeID)) return items def UpdateGhostFittingIcons(self, invItem): fittingSvc = sm.GetService('fittingSvc') if fittingSvc.IsShipSimulated() and invItem: self.SetMissingIcon(invItem) self.SetSkillIcon(invItem) else: self.HideElement(self.dontHaveLine) self.HideElement(self.skillSprite) self.HideElement(self.moduleSlotFill) self.sr.underlay.display = True def HideElement(self, element): if element: element.display = False def SetMissingIcon(self, invItem): return self.ConstructDontHaveLine() self.dontHaveLine.display = False self.sr.underlay.display = True if invItem is None or not session.stationid2: return hangarInv = sm.GetService('invCache').GetInventory( const.containerHangar) items = hangarInv.List(const.flagHangar) for eachItem in items: if eachItem.typeID == invItem.typeID: return self.dontHaveLine.display = True self.sr.underlay.display = False def SetSkillIcon(self, invItem): simulationMode = sm.GetService('ghostFittingSvc').GetSimulationMode() fittingSvc = sm.GetService('fittingSvc') if invItem is None or simulationMode != SIMULATION_SKILLS or not fittingSvc.IsShipSimulated( ): self.HideElement(self.skillSprite) return dogmaLocation = fittingSvc.GetCurrentDogmaLocation() missingSkills = dogmaLocation.CheckSkillRequirementsForType( invItem.typeID) self.ConstructSkillSprite() self.skillSprite.display = True if missingSkills: self.skillSprite.SetRGB(1, 0, 0, 0.5) else: self.skillSprite.SetRGB(0, 1, 0, 0.5) def UpdateSimulationMode(self, newMode): self.UpdateOnlineDisplay() self.UpdateStatusDisplay() self.UpdateGhostFittingIcons(self.controller.GetModule())