materialGroup.py (7745B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\industry\views\materialGroup.py 2 from collections import defaultdict 3 from math import ceil, cos, asin 4 import carbonui.const as uiconst 5 from carbon.client.script.environment.AudioUtil import PlaySound 6 from carbonui.primitives.container import Container 7 from carbonui.primitives.containerAutoSize import ContainerAutoSize 8 from carbonui.primitives.sprite import Sprite 9 from eve.client.script.ui.shared.industry import industryUIConst 10 from eve.client.script.ui.shared.industry.industryUIConst import RADIUS_CONNECTOR_SMALL, RADIUS_CENTERCIRCLE_OUTER 11 import geo2 12 from eve.client.script.ui.shared.industry.views.industryLine import IndustryLineTrace 13 from eve.client.script.ui.shared.industry.views.material import Material, OptionalMaterial 14 from eve.client.script.ui.shared.industry.views.materialGroupDashedCircle import MaterialGroupDashedCircle 15 import localization 16 from carbonui.uicore import uicore 17 OFFSET_CONNECTIONPOINT = 8 18 ICONCOLUMN_WIDTH = 38 19 MAX_MATERIAL_PER_ROW = 5 20 21 class MaterialGroup(Container): 22 default_name = 'MaterialGroup' 23 default_height = 60 24 default_alignMode = uiconst.TOPLEFT 25 default_align = uiconst.TOPLEFT 26 27 def ApplyAttributes(self, attributes): 28 Container.ApplyAttributes(self, attributes) 29 self.jobData = attributes.jobData 30 self.materialsData = attributes.materialsData 31 self.numRows = attributes.numRows 32 self.industryGroupID = attributes.industryGroupID 33 self.perRow = self.GetNumPerRow() 34 self.materials = [] 35 self.lines = [] 36 self.connectorCircle = None 37 self.pCircleIntersect = None 38 self.materialsCont = ContainerAutoSize(name='materialsCont', parent=self, align=uiconst.TOPLEFT, alignMode=uiconst.TOPLEFT) 39 self.icon = GroupIconSprite(name='icon', parent=self, align=uiconst.CENTERLEFT, pos=(7, 0, 22, 22), industryGroupID=self.industryGroupID) 40 self.ConstructMaterials() 41 self.ConstructLines() 42 43 def AnimEntry(self, timeOffset, animate = True): 44 for i, material in enumerate(self.materials): 45 if animate: 46 uicore.animations.FadeTo(material, 0.0, 1.0, duration=0.3, timeOffset=timeOffset + i * 0.02) 47 else: 48 material.opacity = 1.0 49 50 for i, line in enumerate(self.lines): 51 line.AnimEntry(timeOffset, i, animate) 52 53 if animate: 54 uicore.animations.FadeTo(self.connectorCircle, 0.0, 1.0, duration=0.3, timeOffset=timeOffset) 55 else: 56 self.connectorCircle.opacity = 1.0 57 58 def ConstructLines(self): 59 if self.parent is None: 60 return 61 for line in self.lines: 62 line.Close() 63 64 self.lines = [] 65 usedRows = int(ceil(len(self.materialsData) / float(self.perRow))) 66 pointsStart = self.GetLineStartingPoints() 67 pConnect = self.GetLineConnectionPoint(pointsStart) 68 y = self.top + self.materialsCont.top + self.materialsCont.height / 2 69 x = self.GetLineCirceOffset(y) 70 width, height = self.parent.GetCurrentAbsoluteSize() 71 self.pCircleIntersect = (width / 2 - x, pConnect[1]) 72 pEnd = geo2.Vec2Subtract(self.pCircleIntersect, (1 * RADIUS_CONNECTOR_SMALL, 0)) 73 if len(pointsStart) == 1: 74 self.DrawLine((pointsStart[0], pEnd)) 75 else: 76 for point in pointsStart: 77 if point[1] == pEnd[1]: 78 self.DrawLine((point, geo2.Vec2Subtract(pConnect, (3, 0)))) 79 else: 80 self.DrawLine((point, (pConnect[0], point[1]), pConnect)) 81 82 self.DrawLine((geo2.Vec2Add(pConnect, (3, 0)), pEnd)) 83 if not self.connectorCircle: 84 self.connectorCircle = MaterialGroupDashedCircle(parent=self.materialsCont, numSegments=len(self.materialsData), radius=RADIUS_CONNECTOR_SMALL, materialsByGroupID=((self.industryGroupID, self.materialsData),), jobData=self.jobData) 85 self.connectorCircle.left = pEnd[0] 86 self.connectorCircle.top = pEnd[1] - RADIUS_CONNECTOR_SMALL 87 self.UpdateState(animate=False) 88 89 def DrawLine(self, points): 90 line = IndustryLineTrace(parent=self.materialsCont) 91 line.AddPoints(points) 92 self.lines.append(line) 93 94 def GetEndPoint(self): 95 return self.pCircleIntersect 96 97 def ConstructMaterials(self): 98 for i, materialData in enumerate(self.materialsData): 99 top = 66 * (i / self.perRow) 100 cls = self.GetMaterialClass() 101 material = cls(parent=self.materialsCont, jobData=self.jobData, materialData=materialData, align=uiconst.TOPLEFT, left=ICONCOLUMN_WIDTH + i % self.perRow * 48, top=top) 102 self.materials.append(material) 103 104 self.materialsCont.SetSizeAutomatically() 105 self.materialsCont.top = (self.height - self.materialsCont.height) / 2 106 107 def GetMaterialClass(self): 108 if self.IsOptional(): 109 return OptionalMaterial 110 else: 111 return Material 112 113 def IsOptional(self): 114 for materialData in self.materialsData: 115 if not materialData.IsOptional(): 116 return False 117 118 return True 119 120 def IsOptionSelected(self): 121 for materialData in self.materialsData: 122 if materialData.IsOptionSelected(): 123 return True 124 125 return False 126 127 def GetLineStartingPoints(self): 128 ret = defaultdict(int) 129 for material in self.materials: 130 x = material.left + Material.default_width 131 y = material.top + Material.default_height / 2 132 ret[y] = max(ret[y], x) 133 134 ret = zip(ret.values(), ret.keys()) 135 return ret 136 137 def OnRunsChanged(self): 138 self.UpdateState() 139 140 def UpdateState(self, animate = True): 141 for line in self.lines: 142 line.UpdateColor(self.IsReady(), self.IsOptional(), self.IsOptionSelected(), animate) 143 144 numReadySegments = sum([ materialData.valid for materialData in self.materialsData ]) 145 self.connectorCircle.UpdateState(numReadySegments, self.IsReady(), self.IsOptionSelected(), animate=animate) 146 147 def GetNumPerRow(self): 148 numMaterials = len(self.materialsData) 149 if self.numRows >= 2: 150 if numMaterials > 3: 151 return min(MAX_MATERIAL_PER_ROW, int(ceil(numMaterials / 2.0))) 152 return numMaterials 153 154 def GetLineConnectionPoint(self, points): 155 x = max((x for x, _ in points)) 156 x += OFFSET_CONNECTIONPOINT 157 y = sum((y for _, y in points)) / len(points) 158 return (x, y) 159 160 def GetLineCirceOffset(self, y): 161 r = RADIUS_CENTERCIRCLE_OUTER 162 y = float(y) 163 return r * cos(asin((r - y) / r)) 164 165 def IsReady(self): 166 for materialData in self.materialsData: 167 if not materialData.valid: 168 return False 169 170 return True 171 172 173 class GroupIconSprite(Sprite): 174 default_opacity = 0.25 175 176 def ApplyAttributes(self, attributes): 177 Sprite.ApplyAttributes(self, attributes) 178 self.industryGroupID = attributes.industryGroupID 179 self.texturePath = industryUIConst.ICON_BY_INDUSTRYGROUP[self.industryGroupID] 180 181 def LoadTooltipPanel(self, tooltipPanel, *args): 182 tooltipPanel.LoadGeneric1ColumnTemplate() 183 groupName = industryUIConst.LABEL_BY_INDUSTRYGROUP[self.industryGroupID] 184 groupHint = industryUIConst.HINT_BY_INDUSTRYGROUP[self.industryGroupID] 185 tooltipPanel.AddLabelMedium(text=localization.GetByLabel(groupName), bold=True) 186 tooltipPanel.AddLabelMedium(text=localization.GetByLabel(groupHint), wrapWidth=200) 187 188 def OnMouseEnter(self, *args): 189 PlaySound(uiconst.SOUND_BUTTON_HOVER)