예제 #1
0
class ItemIcon(Container):
    default_align = uiconst.TOPLEFT
    default_state = uiconst.UI_NORMAL
    default_width = 32
    default_height = 32
    isDragObject = True

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        self.typeID = attributes.typeID
        self.itemID = attributes.Get('itemID', None)
        self.bpData = attributes.Get('bpData', False)
        self.techIcon = Sprite(name='techIcon', parent=self, width=16, height=16)
        self.icon = Icon(parent=self, align=uiconst.TOALL, state=uiconst.UI_DISABLED)
        self.SetTypeID(self.typeID, self.bpData)

    def SetTypeID(self, typeID, bpData = None):
        self.typeID = typeID
        self.bpData = bpData
        self.icon.LoadIconByTypeID(typeID, ignoreSize=True, isCopy=self.IsBlueprintCopy())
        from eve.client.script.ui.util.uix import GetTechLevelIconPathAndHint
        texturePath, hint = GetTechLevelIconPathAndHint(typeID)
        if texturePath:
            self.techIcon.texturePath = texturePath
            self.techIcon.hint = hint
            self.techIcon.Show()
        else:
            self.techIcon.Hide()

    def IsBlueprintCopy(self):
        if not self.bpData:
            return False
        return not self.bpData.original

    def GetMenu(self):
        return sm.GetService('menu').GetMenuFormItemIDTypeID(self.itemID, self.typeID, ignoreMarketDetails=0, abstractInfo=KeyVal(bpData=self.bpData))

    def OnClick(self):
        sm.GetService('info').ShowInfo(self.typeID, self.itemID, abstractinfo=KeyVal(bpData=self.bpData))

    def GetHint(self):
        return cfg.invtypes.Get(self.typeID).description

    def GetDragData(self):
        return [KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=self.typeID, label=cfg.invtypes.Get(self.typeID).name, bpData=self.bpData)]
예제 #2
0
class PrimaryButton(Button):

    def ApplyAttributes(self, attributes):
        Button.ApplyAttributes(self, attributes)
        self.isStopPending = False
        self.isArrowsAnimating = False
        self.sr.label.uppercase = True
        self.sr.label.fontsize = 13
        self.sr.label.bold = True
        self.pattern = Sprite(name='bgGradient', bgParent=self, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/buttonPattern.png', color=Color.GRAY2, idx=0)
        self.bg = Sprite(name='bg', bgParent=self, opacity=0.0, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/buttonBg.png', color=Color.GRAY2, idx=0, state=uiconst.UI_HIDDEN)
        self.arrows = Sprite(bgParent=self, texturePath='res:/UI/Texture/Classes/Industry/CenterBar/arrowMask.png', textureSecondaryPath='res:/UI/Texture/Classes/Industry/CenterBar/arrows.png', spriteEffect=trinity.TR2_SFX_MODULATE, color=Color.GRAY2, idx=0)
        self.arrows.translationSecondary = (-0.16, 0)
        self.errorFrame = ErrorFrame(bgParent=self)
        self.errorFrame.Hide()
        color = attributes.color
        if color is None:
            color = sm.GetService('uiColor').GetUIColor(uiconst.COLORTYPE_UIHILIGHT)
        self.SetColor(color)

    def Update_Size_(self):
        if self.iconPath is None:
            self.width = self.fixedwidth or max(64, self.sr.label.width + 60)
            self.height = self.fixedheight or max(32, self.sr.label.textheight + 12)

    def AnimateArrows(self):
        if self.destroyed:
            return
        self.arrows.Show()
        if self.isArrowsAnimating:
            return
        diff = math.fabs(-0.16 - self.arrows.translationSecondary[0])
        duration = diff / 0.16
        if diff > 0.001:
            uicore.animations.MorphVector2(self.arrows, 'translationSecondary', self.arrows.translationSecondary, (-0.16, 0.0), duration=duration, curveType=uiconst.ANIM_LINEAR, callback=self._LoopArrowAnimation)
        else:
            self._LoopArrowAnimation()
        self.isArrowsAnimating = True

    def _LoopArrowAnimation(self):
        uicore.animations.MorphVector2(self.arrows, 'translationSecondary', (0.16, 0.0), (-0.16, 0.0), duration=2.0, curveType=uiconst.ANIM_LINEAR, loops=uiconst.ANIM_REPEAT)

    def StopAnimateArrows(self):
        if self.destroyed:
            return
        diff = math.fabs(-0.16 - self.arrows.translationSecondary[0])
        duration = diff / 0.16
        if diff:
            uicore.animations.MorphVector2(self.arrows, 'translationSecondary', self.arrows.translationSecondary, (-0.16, 0.0), duration=duration, curveType=uiconst.ANIM_LINEAR)
        self.isArrowsAnimating = False

    def HideArrows(self):
        self.StopAnimateArrows()
        self.arrows.Hide()

    def UpdateLabel(self):
        label = self.GetLabel()
        if label:
            text = localization.GetByLabel(label)
            if self.text != text:
                self.SetLabelAnimated(text)
        else:
            self.SetLabel('')

    def SetColor(self, color):
        underlayColor = Color(*color).SetBrightness(0.4).GetRGBA()
        self.underlay.SetFixedColor(underlayColor)
        blinkColor = Color(*color).SetSaturation(0.5).SetBrightness(0.9).GetRGBA()
        self.sr.hilite.SetRGBA(*blinkColor)
        for obj in (self.pattern, self.bg, self.arrows):
            uicore.animations.SpColorMorphTo(obj, obj.GetRGBA(), color, duration=0.3)

    def SetLabelAnimated(self, text):
        uthread.new(self._SetLabelAnimated, text)

    def _SetLabelAnimated(self, text):
        uicore.animations.FadeOut(self.sr.label, duration=0.15, sleep=True)
        self.SetLabel(text)
        uicore.animations.FadeIn(self.sr.label, duration=0.3)
예제 #3
0
class BaseContainerMETE(Container):
    default_align = uiconst.TOPLEFT
    default_state = uiconst.UI_NORMAL

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        self.value = 0.0
        iconPath = attributes.iconPath
        iconSize = attributes.iconSize
        minValue = attributes.minValue
        maxValue = attributes.maxValue
        showBG = attributes.get('showBG', True)
        isCompact = attributes.get('isCompact', False)
        self.jobData = attributes.jobData
        self.gauge = Gauge(parent=self,
                           align=uiconst.TOBOTTOM,
                           state=uiconst.UI_DISABLED,
                           height=6,
                           gaugeHeight=6,
                           padTop=1,
                           backgroundColor=(1.0, 1.0, 1.0, 0.05))
        if isCompact:
            self.icon = None
            self.valueLabel = None
            return
        mainCont = Container(name='mainCont', parent=self)
        if showBG:
            self.bg = StretchSpriteHorizontal(
                bgParent=mainCont,
                texturePath='res:/UI/Texture/Classes/Industry/Center/bgMETE.png'
            )
            FillThemeColored(bgParent=self, opacity=0.5)
        else:
            self.bg = None
        left = 8 if showBG else 2
        self.icon = Sprite(name='icon',
                           parent=mainCont,
                           align=uiconst.TOPLEFT,
                           state=uiconst.UI_DISABLED,
                           pos=(left, 3, self.ICONSIZE, self.ICONSIZE),
                           texturePath=self.ICONPATH,
                           opacity=0.6)
        self.valueLabel = EveLabelMediumBold(parent=mainCont,
                                             align=uiconst.TOPRIGHT,
                                             top=4,
                                             left=left)
        self.removeIcon = Sprite(
            parent=mainCont,
            align=uiconst.CENTERRIGHT,
            state=uiconst.UI_HIDDEN,
            texturePath='res:/ui/texture/icons/73_16_45.png',
            pos=(0, 0, 12, 12),
            color=Color.RED,
            hint=localization.GetByLabel('UI/Industry/PreviewModeHint'))
        self.removeIcon.OnClick = self.OnRemoveIconClick
        self.previewEdit = SinglelineEdit(name='previewEdit',
                                          parent=mainCont,
                                          align=uiconst.CENTERRIGHT,
                                          state=uiconst.UI_HIDDEN,
                                          ints=(0, self.MAXVAL),
                                          OnChange=self.OnPreviewEdit,
                                          pos=(12, 0, 34, 20))
        self.errorFrame = ErrorFrame(bgParent=self, padding=(1, 1, 1, 8))

    def SetValue(self, value):
        if self.value * (value or 1) < 0.0:
            self.gauge.SetValueInstantly(0.0)
        self.value = value
        if value < 0:
            self.gauge.SetGaugeAlign(uiconst.TORIGHT_PROP)
            self.gauge.SetValue(float(value) / self.MINVAL)
            self.gauge.SetColor(COLOR_NOTREADY)
        else:
            self.gauge.SetGaugeAlign(uiconst.TOLEFT_PROP)
            self.gauge.SetValue(float(value) / self.MAXVAL)
            self.gauge.SetColor(COLOR_READY)
        if not self.valueLabel:
            return
        if value < 0:
            self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex(
                *COLOR_NOTREADY), value)
        elif value == 0:
            self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex(
                *COLOR_FRAME), value)
        else:
            self.valueLabel.text = '<color=%s>%s%%' % (Color.RGBtoHex(
                *COLOR_READY), value)

    def OnMouseEnter(self, *args):
        sm.GetService('audio').SendUIEvent('ind_mouseEnter')

    def OnRemoveIconClick(self):
        self.ExitPreviewMode()

    def EnterPreviewMode(self):
        if not self.IsPreviewEnabled():
            return
        self.previewEdit.Show()
        self.previewEdit.SetValue(self.GetPreviewEditValue())
        self.valueLabel.Hide()
        self.errorFrame.Show()
        self.removeIcon.Show()
        uicore.registry.SetFocus(self.previewEdit)

    def ExitPreviewMode(self):
        self.previewEdit.Hide()
        self.valueLabel.Show()
        self.errorFrame.Hide()
        self.removeIcon.Hide()
        if self.jobData:
            self.jobData.timeEfficiency = None
            self.jobData.materialEfficiency = None
            self.jobData.update(self.jobData)

    def OnClick(self, *args):
        self.EnterPreviewMode()

    def OnMouseEnter(self, *args):
        if self.bg and self.IsPreviewEnabled():
            uicore.animations.FadeTo(self.bg,
                                     self.bg.opacity,
                                     1.5,
                                     duration=0.3)

    def OnMouseExit(self, *args):
        if self.bg:
            uicore.animations.FadeTo(self.bg,
                                     self.bg.opacity,
                                     1.0,
                                     duration=0.3)

    def OnNewJobData(self, jobData):
        self.jobData = jobData
        self.ExitPreviewMode()

    def IsPreviewEnabled(self):
        if not self.jobData or self.jobData.activityID != industry.MANUFACTURING or self.jobData.jobID:
            return False
        return True

    def IsPreviewActive(self):
        return self.errorFrame.display

    def GetHint(self):
        if self.IsPreviewEnabled() and not self.IsPreviewActive():
            return '<br><br>' + localization.GetByLabel(
                'UI/Industry/EnterPreviewModeHint')
        return ''
예제 #4
0
class FittingSlot(FittingSlotBase):
    __guid__ = 'xtriui.FittingSlot2'
    __notifyevents__ = ['OnRefreshModuleBanks']
    default_name = 'fittingSlot'
    default_width = 44
    default_height = 54
    default_align = uiconst.TOPLEFT
    default_state = uiconst.UI_NORMAL
    isDragObject = True
    slotsToHintDict = {
        'hiSlot': ('UI/Fitting/EmptyHighPowerSlot', 'EmptyHighSlot'),
        'medSlot': ('UI/Fitting/EmptyMediumPowerSlot', 'EmptyMidSlot'),
        'loSlot': ('UI/Fitting/EmptyLowPowerSlot', 'EmptyLowSlot'),
        'subSystemSlot': ('UI/Fitting/EmptySubsystemSlot', ''),
        'rigSlot': ('UI/Fitting/EmptyRigSlot', '')
    }

    @telemetry.ZONE_METHOD
    def ApplyAttributes(self, attributes):
        FittingSlotBase.ApplyAttributes(self, attributes)
        self.flagIcon = uicontrols.Icon(parent=self,
                                        name='flagIcon',
                                        align=uiconst.CENTER,
                                        state=uiconst.UI_DISABLED,
                                        width=self.width,
                                        height=self.height)
        self.sr.underlay = Sprite(
            bgParent=self,
            name='underlay',
            state=uiconst.UI_DISABLED,
            padding=(-10, -5, -10, -5),
            texturePath='res:/UI/Texture/Icons/81_64_1.png')
        self.groupMark = None
        self.chargeIndicator = None
        sm.RegisterNotify(self)
        self.radCosSin = attributes.radCosSin
        self.invReady = 1
        self.UpdateFitting()

    def ConstructGroupMark(self):
        if self.groupMark:
            return
        self.groupMark = Sprite(parent=self,
                                name='groupMark',
                                pos=(-10, 14, 16, 16),
                                align=uiconst.CENTER,
                                state=uiconst.UI_NORMAL,
                                idx=0)
        self.groupMark.GetMenu = self.GetGroupMenu

    def ConstructChargeIndicator(self):
        if self.chargeIndicator:
            return
        self.chargeIndicator = Sprite(
            parent=self,
            name='chargeIndicator',
            padTop=-2,
            height=7,
            align=uiconst.TOTOP,
            state=uiconst.UI_HIDDEN,
            texturePath='res:/UI/Texture/Icons/81_64_2.png',
            ignoreSize=True)
        self.chargeIndicator.rectWidth = 44
        self.chargeIndicator.rectHeight = 7

    def OnRefreshModuleBanks(self):
        self.SetGroup()

    def SetGroup(self):
        try:
            if self.controller.GetModule(
            ) is not None and not self.controller.SlotExists():
                self.controller.DestroyWeaponBank()
        except ReferenceError:
            pass

        parentID = self.controller.GetParentID()
        allGroupsDict = settings.user.ui.Get('linkedWeapons_groupsDict', {})
        groupDict = allGroupsDict.get(parentID, {})
        ret = self.GetBankGroup(groupDict)
        if ret is None:
            if self.groupMark:
                self.groupMark.Hide()
            return
        groupNumber = ret.groupNumber
        self.ConstructGroupMark()
        self.groupMark.state = uiconst.UI_NORMAL
        self.groupMark.rotation = -self.GetRotation()
        if groupNumber < 0:
            availGroups = [1, 2, 3, 4, 5, 6, 7, 8]
            for masterID, groupNum in groupDict.iteritems():
                if groupNum in availGroups:
                    availGroups.remove(groupNum)

            groupNumber = availGroups[0] if availGroups else ''
        self.groupMark.texturePath = 'res:/UI/Texture/Icons/73_16_%s.png' % (
            176 + groupNumber)
        self.groupMark.hint = localization.GetByLabel('UI/Fitting/GroupNumber',
                                                      groupNumber=groupNumber)
        groupDict[ret.masterID] = groupNumber
        allGroupsDict[parentID] = groupDict
        settings.user.ui.Set('linkedWeapons_groupsDict', allGroupsDict)

    def GetBankGroup(self, groupDict):
        module = self.controller.GetModule()
        try:
            if not module:
                return None
        except ReferenceError:
            return None

        masterID = self.controller.IsInWeaponBank()
        if not masterID:
            return None
        if masterID in groupDict:
            groupNumber = groupDict.get(masterID)
        else:
            groupNumber = -1
        ret = util.KeyVal()
        ret.masterID = masterID
        ret.groupNumber = groupNumber
        return ret

    def PrepareUtilButtons(self):
        self.RemoveUtilButtons()
        self.utilButtons = []
        if not self.controller.GetModule():
            return
        myrad, cos, sin, cX, cY = self.radCosSin
        btns = self.GetUtilBtns()
        rad = myrad - 34
        i = 0
        for btnData in btns:
            left = int((rad - i * 16) * cos) + cX - 16 / 2
            top = int((rad - i * 16) * sin) + cY - 16 / 2
            utilBtn = FittingUtilBtn(parent=self.parent,
                                     icon=btnData.iconPath,
                                     left=left,
                                     top=top,
                                     btnData=btnData,
                                     mouseOverFunc=self.ShowUtilButtons,
                                     controller=self.controller)
            if btnData.onlineBtn == 1:
                self.sr.onlineButton = utilBtn
            self.utilButtons.append(utilBtn)
            i += 1

    def RemoveUtilButtons(self):
        for btn in self.utilButtons:
            btn.Close()

    def GetUtilBtns(self):
        btns = []
        if self.controller.GetCharge():
            btns += self.GetChargesBtns()
        isRig = False
        for effect in cfg.dgmtypeeffects.get(self.controller.GetModuleTypeID(),
                                             []):
            if effect.effectID == const.effectRigSlot:
                isRig = True
                break

        isSubSystem = evetypes.GetCategoryID(
            self.controller.GetModuleTypeID()) == const.categorySubSystem
        isOnlinable = self.controller.IsOnlineable()
        if isRig:
            btns += self.GetRigsBtns()
        elif isSubSystem:
            btns += self.GetSubSystemBtns()
        else:
            btns += self.GetModuleBtns(isOnlinable)
        return btns

    def GetChargesBtns(self):
        moduleTypeID = self.controller.GetModuleTypeID()
        btns = [
            UtilBtnData(localization.GetByLabel('UI/Fitting/RemoveCharge'),
                        'ui_38_16_200', self.controller.Unfit, 1, 0),
            UtilBtnData(localization.GetByLabel('UI/Fitting/ShowChargeInfo'),
                        'ui_38_16_208', self.ShowChargeInfo, 1, 0),
            UtilBtnData(evetypes.GetName(moduleTypeID),
                        inventorycommon.typeHelpers.GetIconFile(moduleTypeID),
                        None, 1, 0)
        ]
        return btns

    def GetSubSystemBtns(self):
        btns = [
            UtilBtnData(localization.GetByLabel('UI/Commands/ShowInfo'),
                        'ui_38_16_208', self.ShowInfo, 1, 0)
        ]
        return btns

    @telemetry.ZONE_METHOD
    def UpdateFitting(self):
        if self.destroyed:
            return
        if not self.controller.SlotExists() and not self.controller.GetModule(
        ):
            if self.controller.IsSubsystemSlot(
            ) and self.controller.parentController.HasStance():
                self.HideSlot()
            else:
                self.DisableSlot()
            self.HideChargeIndicator()
            self.RemoveUtilButtons()
            return
        self.EnableSlot()
        self.SetDragState()
        if self.controller.GetCharge():
            chargeQty = self.controller.GetChargeQuantity()
            if self.controller.GetModule() is None:
                portion = 1.0
            else:
                cap = self.controller.GetChargeCapacity()
                if cap.capacity == 0:
                    portion = 1.0
                else:
                    portion = cap.used / cap.capacity
            step = max(0, min(4, int(portion * 5.0)))
            self.ConstructChargeIndicator()
            self.chargeIndicator.rectTop = 10 * step
            self.chargeIndicator.state = uiconst.UI_NORMAL
            self.chargeIndicator.hint = '%s %d%%' % (evetypes.GetName(
                self.controller.GetCharge().typeID), portion * 100)
        elif not self.controller.GetModule():
            self.HideUtilButtons(1)
            self.HideChargeIndicator()
        elif self.controller.IsChargeable():
            self.ConstructChargeIndicator()
            self.chargeIndicator.rectTop = 0
            self.chargeIndicator.state = uiconst.UI_NORMAL
            self.chargeIndicator.hint = localization.GetByLabel(
                'UI/Fitting/NoCharge')
        else:
            self.HideChargeIndicator()
        if self.controller.GetModule():
            self.tooltipPanelClassInfo = TooltipModuleWrapper()
            modulehint = evetypes.GetName(self.controller.GetModuleTypeID())
            if self.controller.GetCharge():
                modulehint += '<br>%s' % localization.GetByLabel(
                    'UI/Fitting/ChargeQuantity',
                    charge=self.controller.GetCharge().typeID,
                    chargeQuantity=chargeQty)
            if not self.controller.SlotExists():
                modulehint = localization.GetByLabel(
                    'UI/Fitting/SlotDoesNotExist')
            self.hint = modulehint
        else:
            self.tooltipPanelClassInfo = None
            self.hint = self._emptyHint
            tooltipName = self._emptyTooltip
            if tooltipName:
                SetFittingTooltipInfo(targetObject=self,
                                      tooltipName=tooltipName,
                                      includeDesc=False)
        self.PrepareUtilButtons()
        iconSize = int(48 * GetScaleFactor())
        self.flagIcon.SetSize(iconSize, iconSize)
        if self.controller.GetCharge() or self.controller.GetModule():
            self.flagIcon.LoadIconByTypeID(
                (self.controller.GetCharge()
                 or self.controller.GetModule()).typeID,
                ignoreSize=True)
            self.flagIcon.rotation = -self.GetRotation()
        else:
            rev = 0
            slotIcon = {
                const.flagSubSystemSlot0: 'res:/UI/Texture/Icons/81_64_9.png',
                const.flagSubSystemSlot1: 'res:/UI/Texture/Icons/81_64_10.png',
                const.flagSubSystemSlot2: 'res:/UI/Texture/Icons/81_64_11.png',
                const.flagSubSystemSlot3: 'res:/UI/Texture/Icons/81_64_12.png',
                const.flagSubSystemSlot4: 'res:/UI/Texture/Icons/81_64_13.png'
            }.get(self.controller.GetFlagID(), None)
            if slotIcon is None:
                slotIcon = {
                    const.effectLoPower: 'res:/UI/Texture/Icons/81_64_5.png',
                    const.effectMedPower: 'res:/UI/Texture/Icons/81_64_6.png',
                    const.effectHiPower: 'res:/UI/Texture/Icons/81_64_7.png',
                    const.effectRigSlot: 'res:/UI/Texture/Icons/81_64_8.png'
                }.get(self.controller.GetPowerType(), None)
            else:
                rev = 1
            if slotIcon is not None:
                self.flagIcon.LoadIcon(slotIcon, ignoreSize=True)
            if rev:
                self.flagIcon.rotation = mathUtil.DegToRad(180.0)
            else:
                self.flagIcon.rotation = 0.0
        self.SetGroup()
        self.UpdateOnlineDisplay()
        self.Hilite(0)

    def HideChargeIndicator(self):
        if self.chargeIndicator:
            self.chargeIndicator.Hide()

    def IsCharge(self, typeID):
        return evetypes.GetCategoryID(typeID) == const.categoryCharge

    def AddItem(self, item, sourceLocation=None):
        if not getattr(item, 'typeID', None):
            return
        if not RigFittingCheck(item):
            return
        requiredSkills = sm.GetService('skills').GetRequiredSkills(item.typeID)
        skills = sm.GetService('skills').GetSkills()
        for skillID, level in requiredSkills.iteritems():
            if getattr(skills.get(skillID, None), 'skillLevel', 0) < level:
                sm.GetService('tutorial').OpenTutorialSequence_Check(
                    uix.skillfittingTutorial)
                break

        if self.IsCharge(item.typeID) and self.controller.IsChargeable():
            self.controller.FitCharge(item)
        validFitting = False
        for effect in cfg.dgmtypeeffects.get(item.typeID, []):
            if self.IsFittableItem(effect):
                validFitting = True
                if effect.effectID == self.controller.GetPowerType():
                    shift = uicore.uilib.Key(uiconst.VK_SHIFT)
                    isFitted = item.locationID == self.controller.GetParentID(
                    ) and item.flagID != const.flagCargo
                    if isFitted and shift:
                        if self.controller.GetModule():
                            if self.controller.GetModule(
                            ).typeID == item.typeID:
                                self.controller.LinkWithWeapon(item)
                                return
                            else:
                                uicore.Message(
                                    'CustomNotify', {
                                        'notify':
                                        localization.GetByLabel(
                                            'UI/Fitting/GroupingIncompatible')
                                    })
                                return
                    self.controller.FitModule(item)
                    return
                uicore.Message(
                    'ItemDoesntFitPower', {
                        'item':
                        evetypes.GetName(item.typeID),
                        'slotpower':
                        cfg.dgmeffects.Get(
                            self.controller.GetPowerType()).displayName,
                        'itempower':
                        cfg.dgmeffects.Get(effect.effectID).displayName
                    })

        if not validFitting:
            raise UserError('ItemNotHardware', {'itemname': item.typeID})

    def IsFittableItem(self, effect):
        isFittableItem = effect.effectID in (const.effectHiPower,
                                             const.effectMedPower,
                                             const.effectLoPower,
                                             const.effectSubSystem,
                                             const.effectRigSlot,
                                             const.effectServiceSlot)
        return isFittableItem

    def GetMenu(self):
        if self.controller.GetModuleTypeID() and self.controller.GetModuleID():
            m = FittingSlotBase.GetMenu(self)
            m += self.GetGroupMenu()
            return m

    def GetGroupMenu(self, *args):
        masterID = self.controller.IsInWeaponBank()
        if masterID:
            return [(uiutil.MenuLabel('UI/Fitting/ClearGroup'),
                     self.UnlinkModule, ())]
        return []

    def ShowChargeInfo(self, *args):
        if self.controller.GetCharge():
            sm.GetService('info').ShowInfo(self.controller.GetCharge().typeID,
                                           self.controller.GetCharge().itemID)

    def UnlinkModule(self):
        self.controller.DestroyWeaponBank()

    def _OnEndDrag(self, *args):
        self.left = self.top = -2

    def OnEndDrag(self, *args):
        if self.controller.GetModule() is not None:
            sm.ScatterEvent('OnResetSlotLinkingMode',
                            self.controller.GetModule().typeID)

    def GetTooltipPosition(self):
        rect, point = self.PositionHint()
        return rect

    def GetTooltipPointer(self):
        rect, point = self.PositionHint()
        return point

    def UpdateInfo_TimedCall(self, *args):
        if self.destroyed or self.moduleButtonHint.destroyed:
            self.moduleButtonHint = None
            self.updateTimer = None
            return
        if self.controller.GetModuleTypeID():
            if self.controller.GetCharge():
                chargeItemID = self.controller.GetCharge().itemID
            else:
                chargeItemID = None
            self.moduleButtonHint.UpdateAllInfo(self.controller.GetModuleID(),
                                                chargeItemID,
                                                fromWhere='fitting')

    def PositionHint(self, *args):
        myRotation = self.rotation + 2 * math.pi
        myRotation = -myRotation
        sl, st, sw, sh = self.parent.GetAbsolute()
        cX = sl + sw / 2.0
        cY = st + sh / 2.0
        rad, cos, sin, oldcX, oldcY = self.radCosSin
        hintLeft = int(round(rad * cos))
        hintTop = int(round(rad * sin))
        cap = rad * 0.7
        if hintLeft < -cap:
            point = uiconst.POINT_RIGHT_2
        elif hintLeft > cap:
            point = uiconst.POINT_LEFT_2
        elif hintTop < -cap:
            if hintLeft < 0:
                point = uiconst.POINT_BOTTOM_3
            else:
                point = uiconst.POINT_BOTTOM_1
        elif hintLeft < 0:
            point = uiconst.POINT_TOP_3
        else:
            point = uiconst.POINT_TOP_1
        return ((hintLeft + cX - 15, hintTop + cY - 15, 30, 30), point)

    def OnDropData(self, dragObj, nodes):
        if self.controller.GetModule(
        ) is not None and not self.controller.SlotExists():
            return
        items = self.GetDroppedItems(nodes)
        chargeTypeID = None
        chargeItems = []
        for item in items:
            if not getattr(item, 'typeID', None):
                lg.Info('fittingUI', 'Dropped a non-item here', item)
                return
            if self.controller.IsChargeable() and self.IsCharge(item.typeID):
                if chargeTypeID is None:
                    chargeTypeID = item.typeID
                if chargeTypeID == item.typeID:
                    chargeItems.append(item)
            elif self.controller.IsInWeaponBank(item):
                ret = uicore.Message(
                    'CustomQuestion', {
                        'header':
                        localization.GetByLabel('UI/Common/Confirm'),
                        'question':
                        localization.GetByLabel('UI/Fitting/ClearGroupModule')
                    }, uiconst.YESNO)
                if ret == uiconst.ID_YES:
                    uthread.new(self.AddItem, item)
            else:
                uthread.new(self.AddItem, item)

        if len(chargeItems):
            self.controller.FitCharges(chargeItems)

    def _OnClose(self, *args):
        self.updateTimer = None
        moduleButtonHint = getattr(uicore.layer.hint, 'moduleButtonHint', None)
        if moduleButtonHint and not moduleButtonHint.destroyed:
            if moduleButtonHint.fromWhere == 'fitting':
                uicore.layer.hint.moduleButtonHint.FadeOpacity(0.0)
예제 #5
0
class OutcomeItemContainer(Container):
    default_state = uiconst.UI_NORMAL
    default_clipChildren = True
    __notifyevents__ = ['OnIndustryViewExpandCollapse']

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        sm.RegisterNotify(self)
        self.jobData = attributes.jobData
        self.videoThread = None
        self.iconCont = Container(name='iconCont', parent=self, align=CENTER, state=uiconst.UI_NORMAL, width=64, height=64)
        self.errorFrame = ErrorFrame(parent=self, align=uiconst.CENTER, pos=(0, 0, 64, 64), state=uiconst.UI_HIDDEN)
        self.qtyLabel = EveLabelLargeBold(parent=self, align=CENTER, top=42)
        FrameThemeColored(name='bgVignette', parent=self, texturePath='res:/UI/Texture/Classes/Industry/Output/bgVignette.png', cornerSize=30)
        self.videoCont = Container(name='videoCont', parent=self, align=uiconst.CENTER, width=324, height=199)
        self.previewContFill = FillThemeColored(parent=self)
        self.previewCont = PreviewContainer(parent=self, align=uiconst.TOALL, state=uiconst.UI_HIDDEN)
        self.leftProbabilityGradient = GradientSprite(name='leftProbabilityGradient', parent=self, align=uiconst.CENTERLEFT, state=uiconst.UI_HIDDEN, pos=(0, 0, 160, 64), rgbData=((0, (1.0, 1.0, 1.0)),), alphaData=((0.0, 0.5), (1.0, 0.0)))
        self.rightProbabilityGradient = GradientSprite(name='rightProbabilityGradient', parent=self, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, pos=(0, 0, 160, 64), rgbData=((0, (1.0, 1.0, 1.0)),), alphaData=((0.0, 0.0), (1.0, 0.5)))
        self.previewCont.navigation.LoadTooltipPanel = self.LoadIconContTooltipPanel
        self.previewCont.navigation.GetTooltipDelay = self.GetIconContTooltipDelay
        self.previewCont.navigation.GetMenu = self.GetMenu
        self.iconCont.LoadTooltipPanel = self.LoadIconContTooltipPanel
        self.iconCont.GetTooltipDelay = self.GetIconContTooltipDelay
        self.iconCont.OnMouseEnter = self.OnIconContMouseEnter
        self.iconCont.OnMouseExit = self.OnIconContMouseExit
        self.iconCont.OnClick = self.OnIconContClick
        self.iconCont.GetMenu = self.GetMenu
        self.iconCont.GetDragData = self.GetIconContDragData
        self.iconCont.isDragObject = True
        self.techIcon = Sprite(name='techIcon', parent=self.iconCont, width=16, height=16)
        self.icon = Icon(parent=self.iconCont, align=CENTER, state=uiconst.UI_DISABLED)
        self.bgCont = Container(name='bgCont', parent=self, align=uiconst.CENTER, width=201, height=192)
        self.bg = Sprite(bgParent=self.bgCont, texturePath='res:/UI/Texture/Classes/Industry/Output/itemBg.png')
        self.itemPattern = Sprite(bgParent=self.bgCont, texturePath='res:/UI/Texture/Classes/Industry/Output/itemBgColor.png')
        self.UpdateState()
        self.AnimEntry()

    def OnIndustryViewExpandCollapse(self):
        if not self.previewCont or self.jobData and self.jobData.activityID != industry.MANUFACTURING:
            return
        isCollapsed = settings.user.ui.Get('industryWndIsViewCollapsed', False)
        if not isCollapsed:
            self.AnimFadeSceneContIn()
        else:
            self.previewCont.Hide()
            self.previewContFill.opacity = 1.0

    def AnimFadeSceneContIn(self):
        self.previewCont.Hide()
        self.previewContFill.opacity = 1.0
        blue.synchro.SleepWallclock(250)
        self.previewCont.Show()
        uicore.animations.FadeTo(self.previewContFill, 1.0, 0.0, duration=0.6)

    def OnNewJobData(self, jobData):
        self.jobData = jobData
        self.UpdateState()
        if self.jobData:
            self.jobData.on_updated.connect(self.UpdateState)
        self.AnimEntry()

    def UpdateState(self, *args):
        if not self.jobData:
            self.previewCont.Hide()
            return
        typeID = self.jobData.GetProductTypeID()
        if IsPreviewable(typeID) and self.jobData.activityID == industry.MANUFACTURING:
            self.previewCont.Show()
            self.iconCont.Hide()
            newModel = self.previewCont.PreviewType(typeID)
            if newModel:
                self.previewContFill.Show()
                self.previewContFill.opacity = 1.0
                self.previewCont.AnimEntry(1.5, 0.0, 0.5, -0.3)
                self.previewCont.sceneContainer.scene.sunDirection = (-0.5, -1.0, -1.0)
            self.bg.Hide()
            self.qtyLabel.top = 86
            self.leftProbabilityGradient.Hide()
            self.rightProbabilityGradient.Hide()
        else:
            self.iconCont.Show()
            self.previewCont.Hide()
            self.bg.Show()
            self.qtyLabel.top = 42
            if self.jobData.activityID == industry.RESEARCH_MATERIAL:
                self.icon.LoadIcon('res:/UI/Texture/Classes/Industry/iconME.png')
                self.icon.width = self.icon.height = 17
                self.techIcon.texturePath = None
            elif self.jobData.activityID == industry.RESEARCH_TIME:
                self.icon.LoadIcon('res:/UI/Texture/Classes/Industry/iconTE.png')
                self.techIcon.texturePath = None
                self.icon.width = self.icon.height = 16
            else:
                isCopy = self.jobData.activityID in (industry.COPYING, industry.INVENTION)
                oldTypeID = self.icon.typeID
                self.icon.LoadIconByTypeID(typeID, ignoreSize=True, isCopy=isCopy)
                self.icon.width = self.icon.height = 64
                texturePath, hint = GetTechLevelIconPathAndHint(typeID)
                self.techIcon.texturePath = texturePath
                self.techIcon.hint = hint
                if oldTypeID != typeID:
                    uicore.animations.FadeTo(self.icon, 0.0, 1.0, duration=0.6)
            if self.jobData.activityID == industry.INVENTION:
                width = self.jobData.probability * 160
                color = GetJobColor(self.jobData)
                for gradient in (self.leftProbabilityGradient, self.rightProbabilityGradient):
                    gradient.Show()
                    gradient.SetRGBA(*color)
                    uicore.animations.MorphScalar(gradient, 'width', gradient.width, width, duration=0.6)

            else:
                self.leftProbabilityGradient.Hide()
                self.rightProbabilityGradient.Hide()
        if self.jobData and self.jobData.product:
            self.iconCont.opacity = 1.0
            uicore.animations.FadeTo(self.bgCont, self.bgCont.opacity, 1.0, duration=0.3)
            self.errorFrame.Hide()
        else:
            self.iconCont.opacity = 0.0
            uicore.animations.FadeTo(self.bgCont, 0.3, 1.0, duration=2.0, curveType=uiconst.ANIM_WAVE, loops=uiconst.ANIM_REPEAT)
            self.errorFrame.Show()
        self.UpdateOutputQty()
        self.StopVideo()
        if self.jobData.status == industry.STATUS_DELIVERED:
            self.PlayVideoDelivered()

    def PlayVideoDelivered(self):
        self.PlayVideo('res:/video/Industry/deliveredIntro.bk2', 'res:/video/Industry/deliveredOutro.bk2', industryUIConst.GetActivityColor(self.jobData.activityID))

    def PlayVideoFailed(self):
        self.PlayVideo('res:/video/Industry/failedIntro.bk2', 'res:/video/Industry/failedOutro.bk2', industryUIConst.COLOR_NOTREADY)

    def StopVideo(self):
        if self.videoThread:
            self.videoThread.kill()
            self.videoCont.Flush()

    def PlayVideo(self, introPath, outroPath, color):
        self.videoThread = uthread.new(self._PlayVideo, introPath, outroPath, color)

    def _PlayVideo(self, introPath, outroPath, color):
        self.videoCont.Flush()
        videoSprite = VideoSprite(parent=self.videoCont, align=uiconst.TOALL, spriteEffect=trinity.TR2_SFX_COPY, videoPath=introPath, color=color)
        while not videoSprite.isFinished:
            blue.synchro.Yield()

        blue.synchro.SleepWallclock(3000)
        videoSprite.Close()
        videoSprite = VideoSprite(parent=self.videoCont, align=uiconst.TOALL, spriteEffect=trinity.TR2_SFX_COPY, videoPath=outroPath, color=color)
        while not videoSprite.isFinished:
            blue.synchro.Yield()

        uicore.animations.FadeOut(videoSprite, callback=videoSprite.Close)

    def GetMenu(self):
        abstractInfo = KeyVal(bpData=self.GetBpData())
        return sm.GetService('menu').GetMenuFormItemIDTypeID(None, self.jobData.product.typeID, ignoreMarketDetails=False, abstractInfo=abstractInfo)

    def LoadIconContTooltipPanel(self, tooltipPanel, *args):
        if self.jobData.activityID in (industry.RESEARCH_TIME, industry.RESEARCH_MATERIAL):
            return
        self.tooltipPanel = OutcomeTooltipPanel(jobData=self.jobData, tooltipPanel=tooltipPanel)

    def GetIconContTooltipDelay(self):
        return TOOLTIP_DELAY_GAMEPLAY

    def GetIconContDragData(self, *args):
        typeID = self.jobData.GetProductTypeID()
        if not typeID:
            return
        if isinstance(self.jobData.product, industry.Blueprint):
            bpData = self.jobData.product.GetCopy()
        else:
            bpData = None
        return [KeyVal(__guid__='uicls.GenericDraggableForTypeID', typeID=typeID, label=cfg.invtypes.Get(typeID).name, bpData=bpData)]

    def UpdateOutputQty(self):
        if not self.jobData or not self.jobData.product:
            self.qtyLabel.text = ''
            return
        self.qtyLabel.text = self.jobData.GetProductAmountLabel()

    def AnimEntry(self):
        if not self.jobData:
            return
        uicore.animations.FadeTo(self.itemPattern, 0.0, 1.0, duration=0.6, timeOffset=1.35)
        uicore.animations.FadeTo(self.previewContFill, self.previewContFill.opacity, 0.0, duration=0.6, timeOffset=0, callback=self.previewContFill.Hide)

    def GetBpData(self):
        if not isinstance(self.jobData.product, industry.Blueprint):
            return None
        return self.jobData.product.GetCopy()

    def OnIconContClick(self, *args):
        if not self.jobData:
            return
        if self.jobData.activityID in (industry.RESEARCH_MATERIAL, industry.RESEARCH_TIME):
            return
        typeID = self.jobData.GetProductTypeID()
        if not typeID:
            return
        sm.GetService('info').ShowInfo(typeID, abstractinfo=KeyVal(bpData=self.GetBpData()))
        sm.GetService('audio').SendUIEvent('ind_click')

    def OnIconContMouseEnter(self, *args):
        uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.5, duration=0.15)
        sm.GetService('audio').SendUIEvent('ind_mouseEnter')

    def OnIconContMouseExit(self, *args):
        uicore.animations.FadeTo(self.bg, self.bg.opacity, 1.0, duration=0.3)
예제 #6
0
class SubmitButton(Button):
    def ApplyAttributes(self, attributes):
        Button.ApplyAttributes(self, attributes)
        self.tooltipErrors = None
        self.jobData = attributes.jobData
        self.isStopPending = False
        self.isArrowsAnimating = False
        self.func = self.ClickFunc
        self.sr.label.uppercase = True
        self.sr.label.fontsize = 13
        self.sr.label.bold = True
        self.pattern = Sprite(
            name='bgGradient',
            bgParent=self,
            texturePath=
            'res:/UI/Texture/Classes/Industry/CenterBar/buttonPattern.png',
            color=Color.GRAY2,
            idx=0)
        self.bg = Sprite(
            name='bg',
            bgParent=self,
            opacity=0.0,
            texturePath=
            'res:/UI/Texture/Classes/Industry/CenterBar/buttonBg.png',
            color=Color.GRAY2,
            idx=0,
            state=uiconst.UI_HIDDEN)
        self.arrows = Sprite(
            bgParent=self,
            texturePath=
            'res:/UI/Texture/Classes/Industry/CenterBar/arrowMask.png',
            textureSecondaryPath=
            'res:/UI/Texture/Classes/Industry/CenterBar/arrows.png',
            spriteEffect=trinity.TR2_SFX_MODULATE,
            color=Color.GRAY2,
            idx=0)
        self.arrows.translationSecondary = (-0.16, 0)
        self.errorFrame = ErrorFrame(bgParent=self)
        self.errorFrame.Hide()

    def OnNewJobData(self, jobData):
        self.oldJobData = self.jobData
        self.jobData = jobData
        self.isStopPending = False
        if self.jobData:
            self.jobData.on_updated.connect(self.OnJobUpdated)
            self.jobData.on_errors.connect(self.OnJobUpdated)
        self.UpdateState()

    def OnJobUpdated(self, *args):
        self.UpdateState()

    def GetColor(self):
        if not self.jobData or self.jobData.status == industry.STATUS_DELIVERED:
            return Color.GRAY2
        if self.jobData.errors or self.isStopPending:
            return industryUIConst.COLOR_RED
        color = industryUIConst.GetJobColor(self.jobData)
        if self.jobData and self.jobData.status == industry.STATUS_UNSUBMITTED:
            color = Color(*color).SetAlpha(0.5).GetRGBA()
        return color

    def AnimateArrows(self):
        self.arrows.Show()
        if self.isArrowsAnimating:
            return
        uicore.animations.MorphVector2(self.arrows,
                                       'translationSecondary', (0.16, 0.0),
                                       (-0.16, 0.0),
                                       duration=2.0,
                                       curveType=uiconst.ANIM_LINEAR,
                                       loops=uiconst.ANIM_REPEAT)
        self.isArrowsAnimating = True

    def StopAnimateArrows(self):
        if self.destroyed:
            return
        diff = math.fabs(-0.16 - self.arrows.translationSecondary[0])
        duration = diff / 0.16
        if diff:
            uicore.animations.MorphVector2(self.arrows,
                                           'translationSecondary',
                                           self.arrows.translationSecondary,
                                           (-0.16, 0.0),
                                           duration=duration,
                                           curveType=uiconst.ANIM_LINEAR)
        self.isArrowsAnimating = False

    def HideArrows(self):
        self.StopAnimateArrows()
        self.arrows.Hide()

    def UpdateState(self):
        uicore.animations.FadeIn(self.sr.label)
        color = self.GetColor()
        underlayColor = Color(*color).SetBrightness(0.4).GetRGBA()
        self.underlay.SetFixedColor(underlayColor)
        blinkColor = Color(
            *color).SetSaturation(0.5).SetBrightness(0.9).GetRGBA()
        self.sr.hilite.SetRGBA(*blinkColor)
        for obj in (self.pattern, self.bg, self.arrows):
            uicore.animations.SpColorMorphTo(obj,
                                             obj.GetRGBA(),
                                             color,
                                             duration=0.3)

        self.UpdateLabel()
        if not self.jobData:
            return
        if self.jobData.errors:
            self.errorFrame.Show()
            self.HideArrows()
        else:
            self.errorFrame.Hide()
            self.arrows.Show()
        if self.jobData.status == industry.STATUS_INSTALLED:
            if not self.oldJobData or self.oldJobData.status != industry.STATUS_INSTALLED:
                self.AnimateArrows()
        elif self.jobData.status == industry.STATUS_DELIVERED:
            self.HideArrows()
        else:
            self.StopAnimateArrows()
        if self.jobData.status == industry.STATUS_READY:
            self.Blink(time=3000)
        else:
            self.Blink(False)
        if self.jobData and self.jobData.status > industry.STATUS_READY:
            self.Disable()
        else:
            self.Enable()

    def UpdateLabel(self):
        if not self.jobData or self.jobData.status == industry.STATUS_UNSUBMITTED:
            label = 'UI/Industry/Start'
        elif self.jobData.status in (industry.STATUS_INSTALLED,
                                     industry.STATUS_PAUSED):
            if self.isStopPending:
                label = 'UI/Common/Confirm'
            else:
                label = 'UI/Industry/Stop'
        elif self.jobData.status == industry.STATUS_READY:
            label = 'UI/Industry/Deliver'
        else:
            label = None
        if label:
            text = localization.GetByLabel(label)
            if self.text != text:
                self.SetLabelAnimated(text)
        else:
            self.SetLabel('')

    def SetLabelAnimated(self, text):
        uthread.new(self._SetLabelAnimated, text)

    def _SetLabelAnimated(self, text):
        uicore.animations.FadeOut(self.sr.label, duration=0.15, sleep=True)
        self.SetLabel(text)
        uicore.animations.FadeIn(self.sr.label, duration=0.3)

    def LoadTooltipPanel(self, tooltipPanel, *args):
        if self.tooltipErrors is not None:
            errors = self.tooltipErrors
            self.tooltipErrors = None
        else:
            errors = self.jobData.errors
        SubmitButtonTooltipPanel(status=self.jobData.status,
                                 errors=errors,
                                 tooltipPanel=tooltipPanel)

    def GetTooltipDelay(self):
        return TOOLTIP_DELAY_GAMEPLAY

    def ClickFunc(self, *args):
        if self.jobData.IsInstalled():
            if self.jobData.status == industry.STATUS_READY:
                sm.GetService('industrySvc').CompleteJob(self.jobData.jobID)
                sm.GetService('audio').SendUIEvent('ind_jobDelivered')
            elif self.isStopPending:
                try:
                    sm.GetService('industrySvc').CancelJob(self.jobData.jobID)
                finally:
                    self.isStopPending = False
                    self.UpdateState()

            else:
                self.isStopPending = True
                self.UpdateState()
        else:
            try:
                self.Disable()
                if not self.jobData.errors:
                    self.AnimateArrows()
                sm.GetService('industrySvc').InstallJob(self.jobData)
                sm.GetService('audio').SendUIEvent('ind_jobStarted')
            except UserError as exception:
                if getattr(exception, 'msg',
                           None) == 'IndustryValidationError':
                    self.tooltipErrors = exception.args[1]['errors']
                    uicore.uilib.tooltipHandler.RefreshTooltipForOwner(self)
                raise
            finally:
                self.Enable()
                self.StopAnimateArrows()

    def OnMouseEnter(self, *args):
        Button.OnMouseEnter(self, *args)
        sm.GetService('audio').SendUIEvent('ind_mouseEnter')
예제 #7
0
 def Hide(self, *args):
     Sprite.Hide(self, *args)
     uicore.animations.FadeOut(self, duration=0.3)