def UpdateState(self, numFilledSegments, isReady = True, isOptional = False, isOptionSelected = True, animate = True):
        isEverythingReady = numFilledSegments == self.numSegments
        baseColor = IndustryLineTrace.GetLineColor(isReady, isOptionSelected)
        for i, segment in enumerate(self.segments):
            if isEverythingReady:
                opacity = OPACITY_LINES
            else:
                isFilled = i < numFilledSegments
                opacity = OPACITY_LINES if not isFilled else OPACITY_SEGMENTINCOMPLETE
            color = Color(*baseColor).SetAlpha(opacity).GetRGBA()
            if animate:
                uicore.animations.SpColorMorphTo(segment, segment.GetRGBA(), color, duration=0.3)
            else:
                segment.SetRGBA(*color)

        self.UpdateIcon(isReady, isOptional)
class MaterialGroups(Container):
    default_name = 'MaterialGroups'
    __notifyevents__ = ['OnMultipleItemChange', 'OnUIScalingChange']

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes)
        sm.RegisterNotify(self)
        self.jobData = attributes.jobData
        self.materialGroups = []
        self.lines = []
        self.fromLine = None
        self.bigConnectorCircle = None
        self.animateTextThread = None
        noItemsLabelCont = Container(
            parent=self,
            align=uiconst.TOPLEFT_PROP,
            pos=(0.0, 0.5, 0.5, 500),
            padRight=industryUIConst.RADIUS_CENTERCIRCLE_OUTER)
        self.noItemsRequiredLabel = EveCaptionMedium(
            name='noItemsRequiredLabel',
            parent=noItemsLabelCont,
            align=uiconst.CENTER,
            opacity=0.0)
        self.bg = StretchSpriteHorizontal(name='groupBackground',
                                          parent=self,
                                          align=uiconst.TOLEFT_PROP,
                                          state=uiconst.UI_DISABLED,
                                          width=0.5,
                                          height=402,
                                          leftEdgeSize=10,
                                          rightEdgeSize=400)
        groupsData = self.GetMaterialGroups()
        self.ConstructGroups(groupsData)
        self.ConstructLines(groupsData)
        self.UpdateState()
        self.AnimEntry()

    def DrawBigConnectorCircle(self, groupsData):
        x, y = self.GetPointBigCircleLeft()
        if not self.bigConnectorCircle:
            self.bigConnectorCircle = MaterialGroupDashedCircle(
                name='bigConnectorCircle',
                parent=self,
                radius=industryUIConst.RADIUS_CONNECTOR_LARGE,
                color=industryUIConst.COLOR_READY,
                numSegments=len(groupsData),
                lineWidth=3.0,
                materialsByGroupID=groupsData,
                jobData=self.jobData)
            self.bigConnectorCircle.UpdateState(1)
        self.bigConnectorCircle.left = x
        self.bigConnectorCircle.top = y - industryUIConst.RADIUS_CONNECTOR_LARGE

    def ConstructLines(self, groupsData):
        for line in self.lines:
            line.Close()

        if self.fromLine:
            self.fromLine.Close()
        self.lines = []
        if self.materialGroups:
            self.DrawBigConnectorCircle(groupsData)
            self.DrawLines()
        if self.jobData:
            self.DrawLineFromCenter()

    def GetStatusText(self):
        if self.jobData:
            status = self.jobData.status
            if status == industry.STATUS_UNSUBMITTED:
                text = GetByLabel('UI/Industry/NoInputItemsRequired')
            elif status == industry.STATUS_INSTALLED:
                text = GetByLabel('UI/Industry/JobActive')
            elif status == industry.STATUS_READY:
                text = GetByLabel('UI/Industry/JobReadyForDelivery')
            else:
                text = self.jobData.GetJobStateLabel()
        else:
            text = GetByLabel('UI/Industry/NoBlueprintSelectedCaption')
        return text

    def ConstructGroups(self, groupsData):
        for group in self.materialGroups:
            group.Close()

        self.materialGroups = []
        numGroups = max(len(groupsData) - 1, 0)
        numRowsByGroupIdx = GROUP_NUMROWS[numGroups]
        if groupsData:
            top = 1
            for i, (industryGroupID, materialsData) in enumerate(groupsData):
                numRows = numRowsByGroupIdx[i]
                height = 60 * numRows + 8 * max(0, numRows - 1)
                materialGroup = MaterialGroup(parent=self,
                                              industryGroupID=industryGroupID,
                                              jobData=self.jobData,
                                              materialsData=materialsData,
                                              pos=(0, top, 400, height),
                                              numRows=numRows,
                                              opacity=0.0)
                top += height + 8
                self.materialGroups.append(materialGroup)

            statusText = ''
        else:
            statusText = self.GetStatusText()
        self.AnimateStateText(statusText)
        self.bg.SetTexturePath(GROUP_BACKGROUNDS[numGroups])

    def AnimateStateText(self, text):
        if self.animateTextThread:
            self.animateTextThread.kill()
        self.animateTextThread = uthread.new(self._AnimateStateText, text)

    def _AnimateStateText(self, text):
        if self.noItemsRequiredLabel.text:
            uicore.animations.FadeOut(self.noItemsRequiredLabel,
                                      duration=0.3,
                                      sleep=True)
        self.noItemsRequiredLabel.text = text
        uicore.animations.FadeTo(self.noItemsRequiredLabel,
                                 0.0,
                                 0.9,
                                 duration=0.6)
        self.animateTextThread = None

    def GetInnerCircleIntersectPoint(self, y):
        """
        Returns inner circle intersection point and angle (in radians)
        of line coming from a group, given y-coordinate of that line
        """
        pCenter = self.GetPointCenter()
        y = pCenter[1] - y
        th = asin(y / industryUIConst.RADIUS_CENTERCIRCLE_OUTER) + pi
        r = industryUIConst.RADIUS_CENTERCIRCLE_INNER
        p = (r * cos(th), r * sin(th))
        p = geo2.Vec2Add(p, pCenter)
        return (p, th)

    def GetOuterCirclePoint(self, p, p1):
        """
        Offset point by radius of connector circle
        """
        l = industryUIConst.RADIUS_CENTERCIRCLE_OUTER - industryUIConst.RADIUS_CENTERCIRCLE_INNER
        t = 1.0 - (l - industryUIConst.RADIUS_CONNECTOR_SMALL) / l
        return geo2.Vec2Lerp(p, p1, t)

    def DrawLine(self, points):
        line = IndustryLineTrace(parent=self, opacity=0.0)
        line.AddPoints(points)
        self.lines.append(line)

    def DrawLineFromCenter(self):
        self.fromLine = IndustryLineTrace(name='fromLine',
                                          parent=self,
                                          opacity=0.0)
        self.fromLine.AddPoints(
            (self.GetPointCenter(), self.GetPointCenterRight()))

    def DrawLineToCenter(self, p):
        self.DrawLine((p, self.GetPointBigCircleLeft()))
        self.DrawLine((self.GetPointBigCircleRight(), self.GetPointCenter()))

    def GetPointCenter(self):
        width, height = self.GetAbsoluteSize()
        return (width / 2, height / 2 + 1)

    def GetPointBigCircleLeft(self):
        x, y = self.GetPointCenter()
        return (x - BIGCIRCLE_OFFSET - industryUIConst.RADIUS_CONNECTOR_LARGE,
                y)

    def GetPointBigCircleRight(self):
        x, y = self.GetPointCenter()
        return (x - BIGCIRCLE_OFFSET + industryUIConst.RADIUS_CONNECTOR_LARGE,
                y)

    def GetPointCenterLeft(self):
        x, y = self.GetPointCenter()
        return (x - industryUIConst.RADIUS_CENTERCIRCLE_INNER, y)

    def GetPointCenterRight(self):
        w, h = self.GetCurrentAbsoluteSize()
        return (w - 334, h / 2.0)

    def DrawLines(self):
        """
        Draw lines connecting materialGroups to center circle
        """
        x1, y1 = self.GetAbsolutePosition()
        linePoints = []
        thetas = []
        for materialGroup in self.materialGroups:
            x0, y0 = materialGroup.GetEndPoint()
            p = (x0, materialGroup.top + materialGroup.height / 2.0)
            p1, theta = self.GetInnerCircleIntersectPoint(p[1])
            thetas.append(theta)
            p0 = self.GetOuterCirclePoint(p, p1)
            linePoints.append((p0, p1))

        if len(linePoints) == 1:
            p = linePoints[0][0]
            self.DrawLineToCenter(p)
            return
        thetaFirst = thetas[0]
        thetaLast = thetas[-1]
        numPoints = int(fabs((thetaFirst - thetaLast) * 8))
        stepSize = (thetaLast - thetaFirst) / numPoints
        lineStart = linePoints.pop(0)
        arcPoints = [lineStart[0]]
        r = industryUIConst.RADIUS_CENTERCIRCLE_INNER
        for i in xrange(numPoints):
            th = thetaFirst + float(i) * stepSize
            p = (r * cos(th), r * sin(th))
            p = geo2.Vec2Add(self.GetPointCenter(), p)
            arcPoints.append(p)

        lineEnd = linePoints.pop()
        arcPoints.extend([lineEnd[1], lineEnd[0]])
        self.DrawLine(arcPoints)
        for p0, p1 in linePoints:
            self.DrawLine((p0, p1))

        self.DrawLineToCenter(self.GetPointCenterLeft())

    def AnimEntry(self, animate=True):
        k = 0.05
        for i, materialGroup in enumerate(self.materialGroups):
            if animate:
                uicore.animations.FadeTo(materialGroup,
                                         0.0,
                                         1.0,
                                         duration=0.3,
                                         timeOffset=k * i)
            else:
                materialGroup.opacity = 1.0
            materialGroup.AnimEntry(k * i, animate=animate)

        i = 0
        for i, line in enumerate(self.lines):
            line.AnimEntry(0.2, i, animate=animate)

        if self.fromLine:
            self.fromLine.AnimEntry(0.8, i + 1, animate=animate)
        if self.jobData and animate:
            uicore.animations.FadeTo(self.bg, 0.0, 1.0, duration=0.6)

    def GetMaterialGroups(self):
        if not self.jobData:
            return []
        else:
            return self.jobData.GetMaterialsByGroups()

    def OnMultipleItemChange(self, items, change):
        self.OnRunsChanged()

    def OnRunsChanged(self):
        for materialGroup in self.materialGroups:
            materialGroup.OnRunsChanged()

        self.UpdateState()

    def OnNewJobData(self, jobData):
        self.jobData = jobData
        groupsData = self.GetMaterialGroups()
        if self.bigConnectorCircle:
            self.bigConnectorCircle.Close()
            self.bigConnectorCircle = None
        self.ConstructGroups(groupsData)
        self.ConstructLines(groupsData)
        self.UpdateState(animate=False)
        self.AnimEntry()

    def UpdateState(self, animate=True):
        isReady = self.IsAllGroupsReady()
        for i, line in enumerate(self.lines):
            line.UpdateColor(isReady, animate=animate)

        if self.fromLine:
            self.fromLine.UpdateColor(isReady, animate=animate)
        if self.bigConnectorCircle:
            self.bigConnectorCircle.UpdateState(self.GetNumGroupsReady(),
                                                self.IsAllGroupsReady())

    def IsAllGroupsReady(self):
        for group in self.materialGroups:
            if not group.IsReady():
                return False

        return True

    def GetNumGroupsReady(self):
        return sum(
            [materialGroup.IsReady() for materialGroup in self.materialGroups])

    def OnUIScalingChange(self, *args):
        self.OnNewJobData(self.jobData)

    def _OnResize(self, *args):
        if not self.jobData:
            return
        for group in self.materialGroups:
            group.ConstructLines()

        self.ConstructLines(self.GetMaterialGroups())
        self.UpdateState(animate=False)
        self.AnimEntry(animate=False)
 def DrawLine(self, points):
     line = IndustryLineTrace(parent=self, opacity=0.0)
     line.AddPoints(points)
     self.lines.append(line)
 def DrawLineFromCenter(self):
     self.fromLine = IndustryLineTrace(name='fromLine',
                                       parent=self,
                                       opacity=0.0)
     self.fromLine.AddPoints(
         (self.GetPointCenter(), self.GetPointCenterRight()))
示例#5
0
 def DrawLine(self, points):
     line = IndustryLineTrace(parent=self.materialsCont)
     line.AddPoints(points)
     self.lines.append(line)