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
예제 #2
0
 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)
예제 #3
0
 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)
예제 #4
0
 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)
예제 #6
0
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
예제 #7
0
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())