charCreationOvalSlider.py (19410B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charcreation\charCreationOvalSlider.py 2 import math 3 from carbonui import uiconst 4 from carbon.common.script.util import timerstuff 5 from carbonui.primitives.container import Container 6 from carbonui.primitives.sprite import Sprite 7 from carbonui.uicore import uicore 8 from eve.client.script.ui.control import eveIcon 9 from eve.client.script.ui.login.charcreation.label import CCLabel 10 SMALLSLIDER = 1 11 TEXTURESIZE = 164 12 SETTINGS = {SMALLSLIDER: {'name': 'small', 13 'radius': 65, 14 'textureWidth': 56, 15 'textureHeight': 136, 16 'rotationRangeLeft': (5.0471258177, (math.pi * 2 - 5.0471258177) * 2), 17 'rotationRangeRight': (5.0471258177 - math.pi, (math.pi * 2 - 5.0471258177) * 2), 18 'centerOffsetLeft': (71, 136 / 2), 19 'centerOffsetRight': (-15, 136 / 2), 20 'comboSize': (142, 136)}} 21 22 class CharCreationSingleSlider(Container): 23 default_name = 'CharCreationSingleSlider' 24 default_align = uiconst.CENTER 25 default_state = uiconst.UI_PICKCHILDREN 26 default_pickRadius = 75 27 28 def ApplyAttributes(self, attributes): 29 for each in uicore.layer.main.children: 30 if each.name == self.default_name: 31 each.Close() 32 33 Container.ApplyAttributes(self, attributes) 34 if attributes.parent is None: 35 uicore.layer.main.children.append(self) 36 self.SetSize(TEXTURESIZE, TEXTURESIZE) 37 settings = {'radius': 72, 38 'textureWidth': 164, 39 'textureHeight': 164, 40 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_1.dds', 41 'rotationRange': (4.97, math.pi * 2 - 0.53), 42 'centerOffset': (82, 82)} 43 self.slider = CharCreationOvalSlider(parent=self, align=uiconst.CENTERLEFT, sliderSetting=settings, OnSetValue=attributes.get('OnSetValue', None), setValue=attributes.get('setValue', 0.0), invertSlider=attributes.get('invertSlider', False), modifierName=attributes.modifierName, increments=attributes.get('incrementsSlider', None)) 44 if attributes.label: 45 CCLabel(parent=self.slider, fontsize=13, align=uiconst.BOTTOMRIGHT, text=attributes.label, letterspace=2, top=-20, uppercase=True) 46 47 48 class CharCreationDoubleSlider(Container): 49 default_name = 'CharCreationDoubleSlider' 50 default_align = uiconst.CENTER 51 default_state = uiconst.UI_PICKCHILDREN 52 default_pickRadius = 75 53 54 def ApplyAttributes(self, attributes): 55 for each in uicore.layer.main.children: 56 if each.name == self.default_name: 57 each.Close() 58 59 Container.ApplyAttributes(self, attributes) 60 if attributes.parent is None: 61 uicore.layer.main.children.append(self) 62 self.SetSize(TEXTURESIZE, TEXTURESIZE) 63 settings1 = {'radius': 72, 64 'textureWidth': 82, 65 'textureHeight': 164, 66 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_2_1.dds', 67 'rotationRange': (4.97, math.pi - 0.53), 68 'centerOffset': (82, 82)} 69 self.slider1 = CharCreationOvalSlider(parent=self, align=uiconst.CENTERLEFT, sliderSetting=settings1, OnSetValue=attributes.get('OnSetValue1', None), setValue=attributes.get('setValue1', 0.0), invertSlider=attributes.get('invertSlider1', False), modifierName=attributes.modifierName1, increments=attributes.get('incrementsSlider1', None)) 70 if attributes.label1: 71 CCLabel(parent=self.slider1, fontsize=12, align=uiconst.BOTTOMRIGHT, text=attributes.label1, letterspace=2, top=-20, uppercase=True, left=13) 72 settings2 = {'radius': 72, 73 'textureWidth': 82, 74 'textureHeight': 164, 75 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_2_2.dds', 76 'rotationRange': (math.pi * 0.5 + 0.27, math.pi - 0.53), 77 'centerOffset': (0, 82)} 78 self.slider2 = CharCreationOvalSlider(parent=self, align=uiconst.CENTERRIGHT, sliderSetting=settings2, OnSetValue=attributes.get('OnSetValue2', None), setValue=attributes.get('setValue2', 0.0), invertSlider=attributes.get('invertSlider2', True), modifierName=attributes.modifierName2, increments=attributes.get('incrementsSlider2', None)) 79 if attributes.label2: 80 CCLabel(parent=self.slider2, fontsize=12, align=uiconst.BOTTOMLEFT, text=attributes.label2, letterspace=2, top=-20, uppercase=True, left=13) 81 82 83 class CharCreationTripleSlider(Container): 84 default_name = 'CharCreationTripleSlider' 85 default_align = uiconst.CENTER 86 default_state = uiconst.UI_PICKCHILDREN 87 default_pickRadius = 75 88 89 def ApplyAttributes(self, attributes): 90 for each in uicore.layer.main.children: 91 if each.name == self.default_name: 92 each.Close() 93 94 Container.ApplyAttributes(self, attributes) 95 if attributes.parent is None: 96 uicore.layer.main.children.append(self) 97 self.SetSize(TEXTURESIZE, TEXTURESIZE) 98 settings1 = {'radius': 72, 99 'textureWidth': 82, 100 'textureHeight': 117, 101 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_3_1.dds', 102 'rotationRange': (4.975, math.pi * 0.502), 103 'centerOffset': (82, 35)} 104 self.slider1 = CharCreationOvalSlider(parent=self, align=uiconst.BOTTOMLEFT, sliderSetting=settings1, OnSetValue=attributes.get('OnSetValue1', None), setValue=attributes.get('setValue1', 0.0), invertSlider=attributes.get('invertSlider1', False), modifierName=attributes.modifierName1, increments=attributes.get('incrementsSlider1', None)) 105 if attributes.label1: 106 CCLabel(parent=self.slider1, fontsize=12, align=uiconst.BOTTOMRIGHT, text=attributes.label1, letterspace=2, top=-10, uppercase=True, left=12) 107 settings2 = {'radius': 72, 108 'textureWidth': 82, 109 'textureHeight': 118, 110 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_3_2.dds', 111 'rotationRange': (2.88, math.pi * 0.502), 112 'centerOffset': (0, 36)} 113 self.slider2 = CharCreationOvalSlider(parent=self, align=uiconst.BOTTOMRIGHT, sliderSetting=settings2, OnSetValue=attributes.get('OnSetValue2', None), setValue=attributes.get('setValue2', 0.0), invertSlider=attributes.get('invertSlider2', True), modifierName=attributes.modifierName2, increments=attributes.get('incrementsSlider2', None)) 114 if attributes.label2: 115 CCLabel(parent=self.slider2, fontsize=12, align=uiconst.BOTTOMLEFT, text=attributes.label2, letterspace=2, top=-10, uppercase=True, left=12) 116 settings3 = {'radius': 72, 117 'textureWidth': 164, 118 'textureHeight': 48, 119 'texturePath': 'res:/UI/Texture/CharacterCreation/ovalSlider_3_3.dds', 120 'rotationRange': (0.78, math.pi * 0.502), 121 'centerOffset': (82, 82)} 122 self.slider3 = CharCreationOvalSlider(parent=self, align=uiconst.TOPLEFT, sliderSetting=settings3, OnSetValue=attributes.get('OnSetValue3', None), setValue=attributes.get('setValue3', 0.0), invertSlider=attributes.get('invertSlider3', False), modifierName=attributes.modifierName3, increments=attributes.get('incrementsSlider3', None)) 123 if attributes.label3: 124 CCLabel(parent=self.slider3, fontsize=12, align=uiconst.CENTERTOP, text=attributes.label3, letterspace=2, top=-20, uppercase=True) 125 126 127 class CharCreationOvalSlider(Container): 128 default_name = 'CharCreationOvalSlider' 129 default_align = uiconst.CENTER 130 default_state = uiconst.UI_NORMAL 131 132 def ApplyAttributes(self, attributes): 133 Container.ApplyAttributes(self, attributes) 134 self._invertedValue = False 135 self._lastCallbackValue = None 136 self.incrementStopToValue = {} 137 settings = attributes.sliderSetting 138 textureRadius = settings['radius'] 139 textureWidth = settings['textureWidth'] 140 textureHeight = settings['textureHeight'] 141 texturePath = settings['texturePath'] 142 centerOffset = settings['centerOffset'] 143 rotationRange = settings['rotationRange'] 144 texturePath = settings['texturePath'] 145 self.increments = attributes.increments 146 if self.increments is None: 147 self.increments = None 148 else: 149 self.increments.sort() 150 self.textureRadius = textureRadius 151 self.modifierName = attributes.modifierName 152 self.SetSize(textureWidth, textureHeight) 153 self.SetRotationCenterOffset(*centerOffset) 154 self.SetRotationRange(*rotationRange) 155 if attributes.get('invertSlider', False): 156 self.InvertSlider() 157 self.marker = Sprite(parent=self, align=uiconst.TOPLEFT, pos=(0, 0, 16, 16), texturePath='res:/UI/Texture/CharacterCreation/OvalSliderHandle.dds', ignoreSize=True) 158 self.marker.OnMouseDown = self.OnMarkerMouseDown 159 self.marker.OnMouseEnter = self.OnMarkerMouseEnter 160 self.marker.OnMouseExit = self.OnMarkerMouseExit 161 self.ghostMarker = Sprite(parent=self, align=uiconst.TOPLEFT, pos=(0, 0, 16, 16), texturePath='res:/UI/Texture/CharacterCreation/OvalSliderHandle.dds', ignoreSize=True, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 0.5)) 162 bg = Sprite(parent=self, align=uiconst.TOPLEFT, texturePath=texturePath, ignoreSize=True, state=uiconst.UI_DISABLED, color=(1.0, 1.0, 1.0, 1.0), pos=(0, 163 0, 164 textureWidth, 165 textureHeight)) 166 self.DrawIncrements() 167 self.DrawFill() 168 self.fill = Container(parent=self, align=uiconst.BOTTOMLEFT, clipChildren=True, pos=(0, 169 0, 170 textureWidth, 171 textureHeight)) 172 self.SetValue(attributes.get('setValue', 0.0)) 173 setvalueCallback = attributes.get('OnSetValue', None) 174 if setvalueCallback: 175 self.OnSetValue = setvalueCallback 176 177 def OnMarkerMouseDown(self, *args): 178 self.OnMouseDown() 179 180 def OnMarkerMouseEnter(self, *args): 181 self.marker.texture.resPath = 'res:/UI/Texture/CharacterCreation/OvalSliderHandle_MO.dds' 182 183 def OnMarkerMouseExit(self, *args): 184 self.marker.texture.resPath = 'res:/UI/Texture/CharacterCreation/OvalSliderHandle.dds' 185 186 def OnMouseDown(self, *args): 187 if uicore.uilib.leftbtn: 188 sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_down_play')) 189 self.UpdateMarkerPosition(jump=True) 190 self.updateTimer = timerstuff.AutoTimer(10, self.UpdateSlider) 191 192 def OnMouseWheel(self, *args): 193 delta = uicore.uilib.dz 194 if self.increments: 195 current = self.GetValue() 196 currentIndex = self.increments.index(current) 197 newIndex = max(0, min(len(self.increments) - 1, currentIndex + [-1, 1][delta > 0])) 198 newVal = self.increments[newIndex] 199 self.SetValue(newVal) 200 self._OnSetValue(self, self._value) 201 else: 202 self.SetValue(self.GetValue() + [-0.01, 0.01][delta > 0]) 203 self._OnSetValue(self, self._value) 204 205 def UpdateSlider(self, *args): 206 if not uicore.uilib.leftbtn: 207 self.updateTimer = None 208 self.ghostMarker.state = uiconst.UI_HIDDEN 209 self.marker.texture.resPath = 'res:/UI/Texture/CharacterCreation/OvalSliderHandle.dds' 210 sm.StartService('audio').SendUIEvent(unicode('ui_icc_button_mouse_down_play')) 211 self._OnSetValue(self, self._value) 212 return 213 self.marker.texture.resPath = 'res:/UI/Texture/CharacterCreation/OvalSliderHandle_MD.dds' 214 self.UpdateMarkerPosition() 215 216 def SetIncrements(self, increments): 217 self.increments = increments 218 self.DrawIncrements() 219 220 def DrawIncrements(self): 221 for each in self.children[:]: 222 if each.name == 'incrementMarker': 223 each.Close() 224 225 if not self.increments or len(self.increments) < 2: 226 return 227 fromAngle, toAngle, rotationRange = self.rotationRange 228 numberic = True 229 try: 230 for each in self.increments: 231 float(each) 232 233 except: 234 numberic = False 235 236 self.incrementStopToValue = {} 237 if numberic: 238 useIncrements = self.increments 239 else: 240 step = 1.0 / len(self.increments) - 1 241 useIncrements = [ i * step for i, each in enumerate(self.increments) ] 242 for i, step in enumerate(useIncrements): 243 radianAngle = fromAngle + rotationRange * step 244 l, t, w, h = self.GetAbsolute() 245 ox, oy = self.centerOffset 246 radius = self.textureRadius + 1 247 cos = math.cos(radianAngle + math.pi) 248 sin = math.sin(radianAngle + math.pi) 249 left = int(radius * cos) + ox - 4 250 top = int(radius * sin) + oy - 4 251 self.incrementStopToValue[step] = self.increments[i] 252 icon = eveIcon.Icon(parent=self, pos=(left, 253 top, 254 8, 255 8), icon='ui_3_8_1', color=(1.0, 256 1.0, 257 1.0, 258 step * 0.5), state=uiconst.UI_DISABLED, name='incrementMarker') 259 260 def DrawFill(self): 261 step = math.pi / 90.0 262 fromAngle, toAngle, rotationRange = self.rotationRange 263 l, t, w, h = self.GetAbsolute() 264 ox, oy = self.centerOffset 265 radius = self.textureRadius 266 startAngle = fromAngle + math.pi 267 while startAngle < fromAngle + rotationRange + math.pi: 268 cos = math.cos(startAngle) 269 sin = math.sin(startAngle) 270 left = int(radius * cos) + ox - 8 271 top = int(radius * sin) + oy - 8 272 fillDot = Sprite(parent=self, align=uiconst.TOPLEFT, pos=(left, 273 top, 274 16, 275 16), texturePath='res:/UI/Texture/CharacterCreation/ovalSlider_Filler.dds', ignoreSize=True, state=uiconst.UI_DISABLED, name='fillDot', color=(0.3, 0.3, 0.3, 1.0)) 276 startAngle += step 277 278 def UpdateFillByValue(self, value): 279 dots = [ each for each in self.children if each.name == 'fillDot' ] 280 if self._invertedValue: 281 totalVisible = len(dots) * (1.0 - value) 282 for i, dot in enumerate(dots): 283 if i > totalVisible: 284 dot.state = uiconst.UI_DISABLED 285 else: 286 dot.state = uiconst.UI_HIDDEN 287 288 else: 289 totalVisible = len(dots) * value 290 for i, dot in enumerate(dots): 291 if i < totalVisible: 292 dot.state = uiconst.UI_DISABLED 293 else: 294 dot.state = uiconst.UI_HIDDEN 295 296 def InvertSlider(self): 297 self._invertedValue = True 298 299 def SetRotationCenterOffset(self, x = 0, y = 0): 300 self.centerOffset = (x, y) 301 302 def SetRotationRange(self, fromAngle, rotationRange): 303 toAngle = self.ClampAngle(fromAngle + rotationRange) 304 self.rotationRange = (fromAngle, toAngle, rotationRange) 305 306 def GetRotationAngleFromCenterToMouse(self): 307 x, y = uicore.uilib.x, uicore.uilib.y 308 l, t, w, h = self.GetAbsolute() 309 ox, oy = self.centerOffset 310 px, py = l + ox, t + oy 311 tn = (abs(x - px) or 1e-07) / float(abs(y - py) or 1e-07) 312 if y < py: 313 if x > px: 314 rot = math.pi * 0.5 + math.atan(tn) 315 else: 316 rot = math.pi * 0.5 - math.atan(tn) 317 elif x > px: 318 rot = math.pi * 1.5 - math.atan(tn) 319 else: 320 rot = math.pi * 1.5 + math.atan(tn) 321 return rot 322 323 def UpdateMarkerPosition(self, jump = False): 324 angle = self.GetRotationAngleFromCenterToMouse() 325 fromAngle, toAngle, rotationRange = self.rotationRange 326 if angle < fromAngle and toAngle < angle: 327 fromDiff = abs(angle - fromAngle) 328 toDiff = abs(angle - toAngle) 329 if fromDiff < toDiff: 330 angle = fromAngle 331 else: 332 angle = toAngle 333 if fromAngle + rotationRange > math.pi * 2 and 0.0 < angle <= toAngle: 334 angle += math.pi * 2 335 portion = (angle - fromAngle) / rotationRange 336 if self._invertedValue: 337 portion = 1.0 - portion 338 nonIncrementedValue = None 339 if self.increments: 340 nonIncrementedValue = portion 341 portion = self.FindIncrementValue(portion) 342 self.SetValue(portion, jump, nonIncrementedValue) 343 344 def FindIncrementValue(self, fromValue): 345 if fromValue < 0: 346 return self.increments[0] 347 if fromValue > 1.0: 348 return self.increments[-1] 349 nextStep = 0.0 350 for i, step in enumerate(self.increments): 351 if i != len(self.increments) - 1: 352 nextStep = self.increments[i + 1] 353 if step <= fromValue <= nextStep: 354 if abs(step - fromValue) < abs(nextStep - fromValue): 355 return step 356 else: 357 return nextStep 358 359 return nextStep 360 361 def ClampAngle(self, angle): 362 if angle > math.pi * 2: 363 angle -= math.pi * 2 364 elif angle < 0: 365 angle += math.pi * 2 366 return angle 367 368 def GetValue(self): 369 return self._value 370 371 def SetValue(self, value, jump = False, nonIncrementedValue = None): 372 value = min(1.0, max(0.0, value)) 373 if nonIncrementedValue is not None: 374 nonIncrementedValue = min(1.0, max(0.0, nonIncrementedValue)) 375 self._value = value 376 niSetAngle = None 377 fromAngle, toAngle, rotationRange = self.rotationRange 378 if self._invertedValue: 379 setAngle = self.ClampAngle(fromAngle + rotationRange - rotationRange * value) 380 if nonIncrementedValue: 381 niSetAngle = self.ClampAngle(fromAngle + rotationRange - rotationRange * nonIncrementedValue) 382 else: 383 setAngle = self.ClampAngle(fromAngle + rotationRange * value) 384 if nonIncrementedValue: 385 niSetAngle = self.ClampAngle(fromAngle + rotationRange * nonIncrementedValue) 386 self.MoveMarkerByAngle(setAngle, niSetAngle) 387 if self._lastCallbackValue != value: 388 self._lastCallbackValue = value 389 self.UpdateFillByValue(value) 390 391 def _OnSetValue(self, ctrl, stopvalue): 392 if stopvalue in self.incrementStopToValue: 393 self.OnSetValue(self, self.incrementStopToValue[stopvalue]) 394 else: 395 self.OnSetValue(self, stopvalue) 396 397 def OnSetValue(self, ctrl, value): 398 pass 399 400 def MoveMarkerByAngle(self, radianAngle, nonIncrementAngle = None): 401 l, t, w, h = self.GetAbsolute() 402 ox, oy = self.centerOffset 403 radius = self.textureRadius 404 cos = math.cos(radianAngle + math.pi) 405 sin = math.sin(radianAngle + math.pi) 406 left = int(radius * cos) + ox - self.marker.width / 2 407 top = int(radius * sin) + oy - self.marker.height / 2 408 self.marker.SetPosition(left, top) 409 if nonIncrementAngle is not None: 410 cos = math.cos(nonIncrementAngle + math.pi) 411 sin = math.sin(nonIncrementAngle + math.pi) 412 left = int(radius * cos) + ox - self.ghostMarker.width / 2 413 top = int(radius * sin) + oy - self.ghostMarker.height / 2 414 self.ghostMarker.SetPosition(left, top) 415 self.ghostMarker.state = uiconst.UI_DISABLED 416 else: 417 self.ghostMarker.state = uiconst.UI_HIDDEN