color_picker.py (25142B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\control\color_picker.py 2 from __future__ import division 3 import math 4 import carbonui 5 import localization 6 import mathext 7 import signals 8 from carbonui import Align, Axis, Density, uiconst, PickState 9 from carbonui.button import styling 10 from carbonui.control.forms.formFields import IntegerEditField 11 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 12 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText 13 from carbonui.decorative.inputUnderlay import InputUnderlay 14 from carbonui.primitives.container import Container 15 from carbonui.primitives.fill import Fill 16 from carbonui.primitives.gradientSprite import GradientSprite 17 from carbonui.primitives.sprite import Sprite 18 from carbonui.uicore import uicore 19 from chroma import Color 20 from eve.client.script.ui import eveColor 21 from eve.client.script.ui.control.tooltips import TooltipPersistentPanel 22 DEFAULT_COLOR = carbonui.Color.from_hex('#000000') 23 24 class ColorFill(Container): 25 default_clipChildren = True 26 27 def __init__(self, color = DEFAULT_COLOR, on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), ignore_color_blind_mode = False, **kwargs): 28 self._color = color 29 self._brightness_range = brightness_range 30 self._saturation_range = saturation_range 31 self._on_color_changed = signals.Signal() 32 self._ignore_color_blind_mode = ignore_color_blind_mode 33 self._on_color_changed = signals.Signal() 34 super(ColorFill, self).__init__(**kwargs) 35 self._layout() 36 self._update_color_fill() 37 if on_color_changed: 38 self._on_color_changed.connect(on_color_changed) 39 40 @property 41 def color(self): 42 return self._color 43 44 @color.setter 45 def color(self, value): 46 value = carbonui.Color.from_any(value) if value else None 47 if self._color != value: 48 self._color = value 49 self._update_color_fill() 50 51 def _layout(self): 52 self._color_fill = Fill(name='color_fill', parent=self, padding=1, color=self._color, ignoreColorBlindMode=self._ignore_color_blind_mode, hint=localization.GetByLabel('UI/SystemMenu/GeneralSettings/ColorTheme/ColorPickerEditColorHint')) 53 InputUnderlay(bgParent=self) 54 55 def OnClick(self, *args): 56 self.show_popover() 57 58 def show_popover(self): 59 show_color_picker_popover(owner=self._color_fill, color=self.color or DEFAULT_COLOR, on_color_changed=self._on_popover_picker_color_changed, brightness_range=self._brightness_range, saturation_range=self._saturation_range, ignore_color_blind_mode=self._ignore_color_blind_mode) 60 61 def _on_popover_picker_color_changed(self, picker): 62 self.color = picker.color 63 self._on_color_changed(self) 64 65 def _update_color_fill(self): 66 if self._color_fill: 67 color = self.color or DEFAULT_COLOR 68 self._color_fill.SetRGB(*color.rgb) 69 70 71 class ColorHexInputField(SingleLineEditText): 72 _color_cont = None 73 default_displayHistory = False 74 75 def __init__(self, color = DEFAULT_COLOR, density = Density.NORMAL, width = 160, on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), ignore_color_blind_mode = False, **kwargs): 76 self._color = color 77 self._brightness_range = brightness_range 78 self._saturation_range = saturation_range 79 self._density = density 80 self._on_color_changed = signals.Signal() 81 self._ignore_color_blind_mode = ignore_color_blind_mode 82 kwargs['setvalue'] = (self._get_color_text(),) 83 kwargs['OnChange'] = self.on_text_field_change 84 kwargs['OnFocusLost'] = self._on_text_field_focus_lost 85 super(ColorHexInputField, self).__init__(width=width, height=self._get_height(), **kwargs) 86 self._update_field_text() 87 if on_color_changed: 88 self._on_color_changed.connect(on_color_changed) 89 90 @property 91 def color(self): 92 return self._color 93 94 @color.setter 95 def color(self, value): 96 value = carbonui.Color.from_any(value) if value else None 97 if self._color != value: 98 self._color = value 99 self._update_field_text() 100 101 def _get_color_text(self): 102 if self._color: 103 return self._color.hex_rgb.upper() 104 return '#' 105 106 def _get_height(self): 107 return styling.get_height(self._density) 108 109 def _update_field_text(self): 110 focused = uicore.registry.GetFocus() == self 111 if not focused: 112 self.SetValue(self._get_color_text(), docallback=False) 113 114 def _on_text_field_focus_lost(self, input): 115 try: 116 color = carbonui.Color.from_hex(self.GetValue().strip()) 117 color = color.with_capped_brightness(*self._brightness_range) 118 except Exception: 119 pass 120 else: 121 self.color = color 122 self._on_color_changed(self) 123 124 self._update_field_text() 125 126 def on_text_field_change(self, text): 127 try: 128 color = carbonui.Color.from_hex(self.GetValue().strip()) 129 color = color.with_capped_brightness(*self._brightness_range) 130 except Exception: 131 pass 132 else: 133 self.color = color 134 self._on_color_changed(self) 135 136 def Confirm(self, *args): 137 uicore.registry.SetFocus(None) 138 139 140 class ColorField(Container): 141 _color_fill = None 142 _color_cont = None 143 144 def __init__(self, color = DEFAULT_COLOR, density = Density.NORMAL, width = 160, on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), ignore_color_blind_mode = False, **kwargs): 145 self._color = color 146 self._brightness_range = brightness_range 147 self._saturation_range = saturation_range 148 self._density = density 149 self._on_color_changed = signals.Signal() 150 self._ignore_color_blind_mode = ignore_color_blind_mode 151 super(ColorField, self).__init__(width=width, height=self._get_height(), **kwargs) 152 self._layout() 153 if on_color_changed: 154 self._on_color_changed.connect(on_color_changed) 155 156 @property 157 def color(self): 158 return self._color 159 160 @color.setter 161 def color(self, value): 162 value = carbonui.Color.from_any(value) if value else None 163 if self._color != value: 164 self._color = value 165 self._color_fill.color = value 166 self._hex_input_field.color = value 167 168 def _layout(self): 169 self._color_fill = ColorFill(parent=self, align=Align.TOLEFT, pickState=PickState.ON, width=self._get_height(), color=self.color, brightness_range=self._brightness_range, saturation_range=self._saturation_range, ignore_color_blind_mode=self._ignore_color_blind_mode, on_color_changed=self.on_color_fill_color_changed, padRight=1) 170 self._hex_input_field = ColorHexInputField(parent=self, align=Align.TOTOP, autoselect=True, on_color_changed=self.on_text_field_color_change) 171 172 def on_color_fill_color_changed(self, color_fill): 173 self.color = color_fill.color 174 self._on_color_changed(self) 175 176 def _get_height(self): 177 return styling.get_height(self._density) 178 179 def on_text_field_color_change(self, text_field): 180 self.color = self._hex_input_field.color 181 self._on_color_changed(self) 182 183 def show_popover(self): 184 self._color_fill.show_popover() 185 186 187 class _ColorPickerPopoverArguments(object): 188 189 def __init__(self, color, on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), show_text_fields = False, ignore_color_blind_mode = False): 190 self.brightness_range = brightness_range 191 self.saturation_range = saturation_range 192 self.color = color 193 self.on_color_changed = on_color_changed 194 self.show_text_fields = show_text_fields 195 self.ignore_color_blind_mode = ignore_color_blind_mode 196 197 198 def show_color_picker_popover(owner, color, on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), show_text_fields = False, ignore_color_blind_mode = False): 199 arguments = _ColorPickerPopoverArguments(color=color, on_color_changed=on_color_changed, brightness_range=brightness_range, saturation_range=saturation_range, show_text_fields=show_text_fields, ignore_color_blind_mode=ignore_color_blind_mode) 200 return uicore.uilib.tooltipHandler.LoadPersistentTooltip(owner=owner, customTooltipClass=_ColorFieldPickerPopover, loadArguments=(arguments,), parent=uicore.layer.hint) 201 202 203 class _ColorFieldPickerPopover(TooltipPersistentPanel): 204 default_pointerDirection = uiconst.POINT_BOTTOM_2 205 default_columns = 1 206 default_state = uiconst.UI_NORMAL 207 default_margin = 16 208 isTopLevelWindow = True 209 _picker = None 210 211 def __init__(self, **kwargs): 212 self.on_color_changed = signals.Signal() 213 super(_ColorFieldPickerPopover, self).__init__(**kwargs) 214 self.pickState = uiconst.TR2_SPS_ON 215 uicore.registry.SetFocus(self) 216 uicore.uilib.RegisterForTriuiEvents(uiconst.UI_MOUSEDOWN, self._on_global_mouse_down) 217 218 @property 219 def color(self): 220 return self._picker.color 221 222 def LoadTooltip(self, arguments): 223 ColorPicker(parent=self, align=Align.TOPLEFT, color=arguments.color, on_color_changed=arguments.on_color_changed, brightness_range=arguments.brightness_range, saturation_range=arguments.saturation_range, show_text_fields=arguments.show_text_fields, ignore_color_blind_mode=arguments.ignore_color_blind_mode) 224 225 def _on_global_mouse_down(self, *args): 226 if uicore.uilib.mouseOver is self or uicore.uilib.mouseOver.IsUnder(self): 227 return True 228 else: 229 self.Close() 230 return False 231 232 233 class ColorTextInputFields(Container): 234 default_height = 32 235 236 def __init__(self, color = carbonui.Color.from_hsb(h=0.0, s=0.0, b=1.0), on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), ignore_color_blind_mode = False, **kwargs): 237 super(ColorTextInputFields, self).__init__(**kwargs) 238 self._color = color 239 self.on_color_changed = signals.Signal() 240 self._construct_rgb_fields() 241 self._hex_input_field = ColorHexInputField(parent=self, color=color, align=Align.TORIGHT, width=80, brightness_range=brightness_range, saturation_range=saturation_range, ignore_color_blind_mode=ignore_color_blind_mode, on_color_changed=self.on_hex_input_field_color_changed) 242 self._update_rgb_input_fields() 243 if on_color_changed: 244 self.on_color_changed.connect(on_color_changed) 245 246 def _construct_rgb_fields(self): 247 self._r_input_field = SingleLineEditInteger(parent=self, align=Align.TOLEFT, width=48, minValue=0, maxValue=255, showNumericControls=False, OnChange=self.on_rgb_field_change, OnFocusLost=self.on_rgb_field_change) 248 self._g_input_field = SingleLineEditInteger(parent=self, align=Align.TOLEFT, width=48, minValue=0, maxValue=255, showNumericControls=False, OnChange=self.on_rgb_field_change, OnFocusLost=self.on_rgb_field_change) 249 self._b_input_field = SingleLineEditInteger(parent=self, align=Align.TOLEFT, width=48, minValue=0, maxValue=255, showNumericControls=False, OnChange=self.on_rgb_field_change, OnFocusLost=self.on_rgb_field_change) 250 251 def on_rgb_field_change(self, *args): 252 self.color = Color.from_rgba_8bit(self._r_input_field.GetValue(), self._g_input_field.GetValue(), self._b_input_field.GetValue()) 253 self.on_color_changed(self) 254 255 def on_hex_input_field_color_changed(self, *args): 256 self.color = self._hex_input_field.color 257 self.on_color_changed(self) 258 259 @property 260 def color(self): 261 return self._color 262 263 @color.setter 264 def color(self, value): 265 if self._color != value: 266 self._color = value 267 self._hex_input_field.color = value 268 self._update_rgb_input_fields() 269 270 def _update_rgb_input_fields(self): 271 r, g, b = self.color.rgb_8bit 272 self._r_input_field.SetValue(r, docallback=False) 273 self._g_input_field.SetValue(g, docallback=False) 274 self._b_input_field.SetValue(b, docallback=False) 275 276 277 class ColorPicker(Container): 278 isTabStop = True 279 280 def __init__(self, width = 236, height = 200, color = carbonui.Color.from_hsb(h=0.0, s=0.0, b=1.0), on_color_changed = None, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), show_text_fields = False, ignore_color_blind_mode = False, **kwargs): 281 self._hue = color.hue 282 self._saturation = color.saturation 283 self._brightness = color.brightness 284 self.on_color_changed = signals.Signal() 285 super(ColorPicker, self).__init__(width=width, height=height, **kwargs) 286 if show_text_fields: 287 self._text_input_fields = ColorTextInputFields(parent=self, align=Align.TOBOTTOM, padTop=4, on_color_changed=self.on_text_input_fields_color_changed, color=self.color) 288 self.height += 36 289 else: 290 self._text_input_fields = None 291 self._hue_slider = HueSlider(parent=self, align=Align.TORIGHT, width=20, padLeft=16, hue=self._hue, on_hue_changed=self._on_hue_changed, ignore_color_blind_mode=ignore_color_blind_mode) 292 self._picker = Picker2D(parent=self, align=Align.TOALL, position=(self._saturation, 1.0 - self._brightness), on_position_changed=self._on_picker_position_changed, brightness_range=brightness_range, saturation_range=saturation_range, ignore_color_blind_mode=ignore_color_blind_mode) 293 self._gradient = ColorSaturationBrightnessGradient(parent=self, align=Align.TOALL, hue=self._hue, ignore_color_blind_mode=ignore_color_blind_mode) 294 if on_color_changed is not None: 295 self.on_color_changed.connect(on_color_changed) 296 297 def on_text_input_fields_color_changed(self, *args): 298 self.color = self._text_input_fields.color 299 self._hue_slider.hue = self._hue 300 301 @property 302 def color(self): 303 return carbonui.Color.from_hsb(h=self._hue, s=self._saturation, b=self._brightness) 304 305 @color.setter 306 def color(self, value): 307 if self.color != value: 308 self._hue = value.hue 309 self._saturation = value.saturation 310 self._brightness = value.brightness 311 self._update_color() 312 self.on_color_changed(self) 313 314 def _update_color(self): 315 self._gradient.hue = self._hue 316 if self._text_input_fields: 317 self._text_input_fields.color = self.color 318 self._picker.position = (self._saturation, 1.0 - self._brightness) 319 320 def _on_hue_changed(self, picker): 321 self._hue = picker.hue 322 self._update_color() 323 self.on_color_changed(self) 324 325 def _on_picker_position_changed(self, picker): 326 x, y = picker.position 327 saturation = x 328 brightness = 1.0 - y 329 if not mathext.is_close(saturation, self._saturation) or not mathext.is_close(brightness, self._brightness): 330 self._saturation = saturation 331 self._brightness = brightness 332 self._update_color() 333 self.on_color_changed(self) 334 335 336 class HueSlider(Container): 337 _dragging = False 338 _on_hue_changed = None 339 _STEPS = 10 340 _INDICATOR_THICKNESS = 2 341 342 def __init__(self, hue = 0.0, orientation = Axis.VERTICAL, enabled = True, on_hue_changed = None, state = uiconst.UI_NORMAL, ignore_color_blind_mode = False, **kwargs): 343 self._enabled = enabled 344 self._hue = hue 345 self._orientation = orientation 346 super(HueSlider, self).__init__(state=state, **kwargs) 347 self._indicator = Fill(parent=self, align=Align.TOTOP_NOPUSH if self._orientation == Axis.VERTICAL else Align.TOLEFT_NOPUSH, pos=self._get_indicator_position(), color=carbonui.Color.from_rgba(1.0, 1.0, 1.0, 1.0)) 348 GradientSprite(parent=self, align=Align.TOALL, state=uiconst.UI_DISABLED, rgbData=[ (float(i) / self._STEPS, carbonui.Color.from_hsb(h=float(i) / self._STEPS, s=1.0, b=1.0).rgb) for i in range(self._STEPS + 1) ], rotation=0.0 if self._orientation == Axis.HORIZONTAL else -math.pi / 2.0, ignoreColorBlindMode=ignore_color_blind_mode) 349 if on_hue_changed: 350 self.on_hue_changed.connect(on_hue_changed) 351 352 @property 353 def enabled(self): 354 return self._enabled 355 356 @enabled.setter 357 def enabled(self, value): 358 if self._enabled != value: 359 self._enabled = bool(value) 360 if self._dragging: 361 self._stop_dragging() 362 363 @property 364 def hue(self): 365 return self._hue 366 367 @hue.setter 368 def hue(self, value): 369 value = mathext.clamp(float(value), 0.0, 1.0) 370 if not mathext.is_close(self._hue, value): 371 self._hue = value 372 self._update_indicator_position() 373 if self._on_hue_changed is not None: 374 self._on_hue_changed(self) 375 376 @property 377 def on_hue_changed(self): 378 if self._on_hue_changed is None: 379 self._on_hue_changed = signals.Signal('{}.on_hue_changed'.format(self.__class__.__name__)) 380 return self._on_hue_changed 381 382 def _get_indicator_position(self): 383 width, height = self.GetCurrentAbsoluteSize() 384 if self._orientation == Axis.VERTICAL: 385 return (0, 386 self._hue * (height - self._INDICATOR_THICKNESS), 387 0, 388 self._INDICATOR_THICKNESS) 389 else: 390 return (self._hue * (width - self._INDICATOR_THICKNESS), 391 0, 392 self._INDICATOR_THICKNESS, 393 0) 394 395 def _update_indicator_position(self): 396 if self._indicator: 397 self._indicator.pos = self._get_indicator_position() 398 399 def _stop_dragging(self): 400 if self._dragging: 401 self._dragging = False 402 403 def _pick_at_mouse(self): 404 left, top = self.GetCurrentAbsolutePosition() 405 width, height = self.GetCurrentAbsoluteSize() 406 if self._orientation == Axis.HORIZONTAL: 407 self.hue = mathext.clamp((uicore.uilib.x - left) / width, 0.0, 1.0) 408 else: 409 self.hue = mathext.clamp((uicore.uilib.y - top) / height, 0.0, 1.0) 410 411 def OnMouseDown(self, button, *args): 412 if not self._dragging and button == uiconst.MOUSELEFT and self.enabled: 413 self._dragging = True 414 self._pick_at_mouse() 415 416 def OnMouseMove(self, *args): 417 if self._dragging: 418 self._pick_at_mouse() 419 420 def OnMouseUp(self, button, *args): 421 if self._dragging and button == uiconst.MOUSELEFT: 422 self._pick_at_mouse() 423 self._stop_dragging() 424 425 def UpdateAlignment(self, budgetLeft = 0, budgetTop = 0, budgetWidth = 0, budgetHeight = 0, updateChildrenOnly = False): 426 result = super(HueSlider, self).UpdateAlignment(budgetLeft, budgetTop, budgetWidth, budgetHeight, updateChildrenOnly) 427 _, _, _, _, size_changed = result 428 if size_changed: 429 self._update_indicator_position() 430 return result 431 432 433 class _HatchesSprite(Sprite): 434 default_texturePath = 'res:/UI/Texture/Classes/Industry/Output/hatchPattern.png' 435 default_tileX = True 436 default_tileY = True 437 default_state = uiconst.UI_DISABLED 438 default_color = eveColor.BLACK 439 default_opacity = 0.5 440 441 442 class Picker2D(Container): 443 _dragging = False 444 _on_position_changed = None 445 446 def __init__(self, position = (0.0, 0.0), indicator = None, indicator_hotspot = (0.5, 0.5), enabled = True, on_position_changed = None, state = uiconst.UI_NORMAL, cursor = uiconst.UICORSOR_FINGER, brightness_range = (0.0, 1.0), saturation_range = (0.0, 1.0), **kwargs): 447 self._enabled = enabled 448 self._position = position 449 self._indicator = indicator 450 self._indicator_hotspot = indicator_hotspot 451 self._brightness_range = brightness_range 452 self._saturation_range = saturation_range 453 super(Picker2D, self).__init__(state=state, cursor=cursor, **kwargs) 454 if self._indicator is None: 455 self._indicator = CircleIndicator() 456 self._indicator.align = Align.TOPLEFT 457 self._indicator.SetParent(self) 458 self._check_construct_limitation_hatches() 459 if on_position_changed: 460 self.on_position_changed.connect(on_position_changed) 461 462 def _check_construct_limitation_hatches(self): 463 x_min, x_max = self._saturation_range 464 y_min, y_max = 1.0 - self._brightness_range[1], 1.0 - self._brightness_range[0] 465 hatchesCont = Container(name='hatcesCont', parent=self, state=uiconst.UI_DISABLED) 466 if x_min != 0: 467 _HatchesSprite(parent=hatchesCont, align=uiconst.TOLEFT_PROP, width=x_min) 468 if x_max != 1.0: 469 _HatchesSprite(parent=hatchesCont, align=uiconst.TORIGHT_PROP, width=1.0 - x_max) 470 if y_min != 0: 471 _HatchesSprite(parent=hatchesCont, align=uiconst.TOTOP_PROP, height=y_min) 472 if y_max != 1.0: 473 _HatchesSprite(parent=hatchesCont, align=uiconst.TOBOTTOM_PROP, height=1.0 - y_max) 474 475 @property 476 def enabled(self): 477 return self._enabled 478 479 @enabled.setter 480 def enabled(self, value): 481 if self._enabled != value: 482 self._enabled = value 483 if self._dragging: 484 self._stop_dragging() 485 486 @property 487 def position(self): 488 return self._position 489 490 @position.setter 491 def position(self, value): 492 if self._position != value: 493 self._position = value 494 self._update_indicator_position() 495 496 @property 497 def on_position_changed(self): 498 if self._on_position_changed is None: 499 self._on_position_changed = signals.Signal('{}.on_position_changed'.format(self.__class__.__name__)) 500 return self._on_position_changed 501 502 def _update_indicator_position(self): 503 width, height = self.GetCurrentAbsoluteSize() 504 x, y = self._position 505 offset_x, offset_y = self._get_indicator_offset() 506 self._indicator.left = math.floor(width * x + offset_x) 507 self._indicator.top = math.floor(height * y + offset_y) 508 509 def _get_indicator_offset(self): 510 width, height = self._indicator.GetCurrentAbsoluteSize() 511 hotspot_x, hotspot_y = self._indicator_hotspot 512 return (width * -hotspot_x, height * -hotspot_y) 513 514 def _stop_dragging(self): 515 if self._dragging: 516 self._dragging = False 517 518 def _update_selected_position(self): 519 left, top = self.GetCurrentAbsolutePosition() 520 width, height = self.GetCurrentAbsoluteSize() 521 sat_min, sat_max = self._saturation_range 522 bri_min, bri_max = self._brightness_range 523 x = mathext.clamp((uicore.uilib.x - left) / width, sat_min, sat_max) 524 y = mathext.clamp((uicore.uilib.y - top) / height, 1.0 - bri_max, 1.0 - bri_min) 525 self.position = (x, y) 526 if self._on_position_changed is not None: 527 self._on_position_changed(self) 528 529 def OnMouseDown(self, button, *args): 530 if not self._dragging and button == uiconst.MOUSELEFT and self.enabled: 531 self._dragging = True 532 self._update_selected_position() 533 534 def OnMouseMove(self, *args): 535 if self._dragging: 536 self._update_selected_position() 537 538 def OnMouseUp(self, button, *args): 539 if self._dragging and button == uiconst.MOUSELEFT: 540 self._update_selected_position() 541 self._stop_dragging() 542 543 def UpdateAlignment(self, budgetLeft = 0, budgetTop = 0, budgetWidth = 0, budgetHeight = 0, updateChildrenOnly = False): 544 result = super(Picker2D, self).UpdateAlignment(budgetLeft, budgetTop, budgetWidth, budgetHeight, updateChildrenOnly) 545 _, _, _, _, size_changed = result 546 if size_changed: 547 self._update_indicator_position() 548 return result 549 550 551 class CircleIndicator(Sprite): 552 553 def __init__(self, width = 15, height = 15, texturePath = 'res:/UI/Texture/classes/ColorPicker/color_selection_indicator.png', state = uiconst.UI_DISABLED, **kwargs): 554 super(CircleIndicator, self).__init__(width=width, height=height, texturePath=texturePath, state=state, **kwargs) 555 556 557 class ColorSaturationBrightnessGradient(Container): 558 _hue_fill = None 559 560 def __init__(self, hue, ignore_color_blind_mode = False, **kwargs): 561 self._hue = hue 562 super(ColorSaturationBrightnessGradient, self).__init__(**kwargs) 563 GradientSprite(parent=self, align=Align.TOALL, rgbData=[(0.0, (0.0, 0.0, 0.0)), (1.0, (0.0, 0.0, 0.0))], alphaData=[(0.0, 0.0), (1.0, 1.0)], rotation=-math.pi / 2.0) 564 GradientSprite(parent=self, align=Align.TOALL, rgbData=[(0.0, (1.0, 1.0, 1.0)), (1.0, (1.0, 1.0, 1.0))], alphaData=[(0.0, 1.0), (1.0, 0.0)]) 565 self._hue_fill = Fill(parent=self, align=Align.TOALL, color=self._get_color(), ignoreColorBlindMode=ignore_color_blind_mode) 566 567 @property 568 def hue(self): 569 return self._hue 570 571 @hue.setter 572 def hue(self, value): 573 self._hue = value 574 if self._hue_fill: 575 self._hue_fill.color = self._get_color() 576 577 def _get_color(self): 578 return carbonui.Color.from_hsb(self._hue, 1.0, 1.0)