NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

checkbox.py (14407B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\control\checkbox.py
      2 import logging
      3 import math
      4 import uthread
      5 from carbon.client.script.environment.AudioUtil import PlaySound
      6 from carbonui import fontconst, uiconst
      7 from carbonui.primitives.container import Container
      8 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      9 from carbonui.primitives.fill import Fill
     10 from carbonui.primitives.frame import Frame
     11 from carbonui.primitives.sprite import Sprite
     12 from carbonui.text.color import TextColor
     13 from carbonui.uianimations import animations
     14 from carbonui.util.various_unsorted import GetAttrs, GetBrowser
     15 from eve.client.script.ui import eveThemeColor
     16 from eve.client.script.ui.control.eveLabel import EveLabelMedium
     17 logger = logging.getLogger(__name__)
     18 
     19 class Checkbox(ContainerAutoSize):
     20     default_enabled = True
     21     DIODE_SIZE = 16
     22     DIODE_TEXT_GAP_SIZE = 8
     23     LABEL_COLOR_IDLE = TextColor.NORMAL
     24     LABEL_COLOR_HOVER = TextColor.HIGHLIGHT
     25     LABEL_COLOR_DISABLED = TextColor.DISABLED
     26     CHECK_MARK_COLOR_DISABLED = TextColor.DISABLED
     27     CHECK_MARK_COLOR_IDLE = eveThemeColor.THEME_FOCUS
     28     default_alignMode = uiconst.TOPLEFT
     29     default_fontsize = fontconst.EVE_MEDIUM_FONTSIZE
     30     default_width = 0
     31     default_height = 24
     32     default_minWidth = 24
     33     default_minHeight = 24
     34     default_checkedTexture = 'res:/UI/Texture/classes/checkbox/checked.png'
     35     default_align = uiconst.TOTOP
     36     default_text = ''
     37     default_checked = 0
     38     default_callback = None
     39     default_state = uiconst.UI_NORMAL
     40     default_wrapLabel = True
     41     default_cursor = uiconst.UICURSOR_SELECT
     42     default_fontStyle = None
     43     default_fontFamily = None
     44     default_fontPath = None
     45     default_setting = None
     46     default_settingsPath = ('user', 'ui')
     47     default_settingsKey = None
     48 
     49     def ApplyAttributes(self, attributes):
     50         self._callback = None
     51         if 'callback' in attributes:
     52             self._callback = attributes.pop('callback')
     53         super(Checkbox, self).ApplyAttributes(attributes)
     54         text = attributes.get('text', self.default_text)
     55         self.checkedTexture = attributes.get('checkedTexture', self.default_checkedTexture)
     56         self._enabled = attributes.get('enabled', self.default_enabled)
     57         self.wrapLabel = attributes.get('wrapLabel', self.default_wrapLabel)
     58         self.fontStyle = attributes.get('fontStyle', self.default_fontStyle)
     59         self.fontFamily = attributes.get('fontFamily', self.default_fontFamily)
     60         self.fontPath = attributes.get('fontPath', self.default_fontPath)
     61         self.fontsize = attributes.get('fontsize', self.default_fontsize)
     62         isChecked = attributes.get('checked', self.default_checked)
     63         self.setting = attributes.get('setting', self.default_setting)
     64         self.settingsKey = attributes.get('settingsKey', self.default_settingsKey)
     65         self.settingsPath = attributes.get('settingsPath', self.default_settingsPath)
     66         self.underlay = None
     67         self._hovered = False
     68         self._checked = False
     69         self.isTabStop = 1
     70         self.checkboxCont = None
     71         if self.settingsKey is not None:
     72             self.name = self.settingsKey if isinstance(self.settingsKey, (str, unicode)) else repr(self.settingsKey)
     73         self.ConstructLayout()
     74         if self.setting is not None:
     75             isChecked = self._GetIsCheckedSettingValue()
     76             self.setting.on_change.connect(self._on_setting_changed)
     77         self.SetChecked(isChecked, 0)
     78         self.SetLabelText(text)
     79         self._update_enabled(animate=False)
     80         self._update_checkmark_color()
     81 
     82     def Close(self):
     83         super(Checkbox, self).Close()
     84         try:
     85             if self.setting:
     86                 self.setting.on_change.disconnect(self._on_setting_changed)
     87         except Exception as e:
     88             logger.exception(e)
     89 
     90     def _on_setting_changed(self, value, *args):
     91         self.SetChecked(value, report=False)
     92 
     93     @property
     94     def checked(self):
     95         return self._checked
     96 
     97     @checked.setter
     98     def checked(self, value):
     99         if self._checked != value:
    100             self.SetChecked(value)
    101 
    102     def ConstructLayout(self):
    103         self.ConstructLabel()
    104         self.ConstructCheckboxCont()
    105 
    106     def ConstructLabel(self):
    107         self.label = EveLabelMedium(name='text', parent=self, align=uiconst.TOPLEFT, state=uiconst.UI_DISABLED, left=self.DIODE_SIZE + self.DIODE_TEXT_GAP_SIZE, maxLines=1 if not self.wrapLabel else None, color=self._get_label_color())
    108 
    109     def _get_label_color(self):
    110         if self.hovered:
    111             return self.LABEL_COLOR_HOVER
    112         elif self.enabled:
    113             return self.LABEL_COLOR_IDLE
    114         else:
    115             return self.LABEL_COLOR_DISABLED
    116 
    117     def _update_label_color(self, animate = True):
    118         if self.label:
    119             if animate:
    120                 duration = uiconst.TIME_ENTRY if self.hovered else uiconst.TIME_EXIT
    121                 animations.SpColorMorphTo(self.label, endColor=self._get_label_color(), duration=duration)
    122             else:
    123                 self.label.SetRGBA(*self._get_label_color())
    124 
    125     def OnColorThemeChanged(self):
    126         super(Checkbox, self).OnColorThemeChanged()
    127         self._update_checkmark_color()
    128 
    129     def Enable(self):
    130         self.enabled = True
    131 
    132     def Disable(self):
    133         self.enabled = False
    134 
    135     @property
    136     def enabled(self):
    137         return self._enabled
    138 
    139     @enabled.setter
    140     def enabled(self, value):
    141         if self._enabled != value:
    142             self._enabled = value
    143             self._update_enabled()
    144 
    145     @property
    146     def disabled(self):
    147         return not self._enabled
    148 
    149     @disabled.setter
    150     def disabled(self, value):
    151         self.enabled = not value
    152 
    153     @property
    154     def hovered(self):
    155         return self._hovered
    156 
    157     def _update_enabled(self, animate = True):
    158         if self.enabled:
    159             self.underlay.Enable()
    160         else:
    161             self.underlay.Disable()
    162         self._update_checkmark_color()
    163         self._update_label_color(animate)
    164 
    165     def ToggleState(self):
    166         self.SetChecked(not self._checked)
    167 
    168     def OnChar(self, char, flag):
    169         if char == uiconst.VK_SPACE:
    170             uthread.pool('checkbox::OnChar', self.ToggleState)
    171             return 1
    172 
    173     def OnSetFocus(self, *args):
    174         if self and not self.destroyed and self.parent and self.parent.name == 'inlines':
    175             if self.parent.parent and self.parent.parent.sr.node:
    176                 browser = GetBrowser(self)
    177                 if browser:
    178                     uthread.new(browser.ShowObject, self)
    179 
    180     def SetValue(self, value):
    181         self.SetChecked(value)
    182 
    183     def GetValue(self):
    184         return self._checked
    185 
    186     def SetLabelText(self, labeltext):
    187         self.label.text = labeltext
    188         if self.align not in (uiconst.TOTOP, uiconst.TOBOTTOM):
    189             self.ChangeWidth()
    190 
    191     def ChangeWidth(self, *args):
    192         self.width = max(20, self.label.padLeft + self.label.left + self.label.textwidth + self.label.padRight) + 1
    193 
    194     def UpdateUIScaling(self, value, oldValue):
    195         super(Checkbox, self).UpdateUIScaling(value, oldValue)
    196         self.ChangeWidth()
    197 
    198     def GetLabelText(self):
    199         return self.label.GetText()
    200 
    201     def SetTextColor(self, color):
    202         self.label.SetTextColor(color)
    203 
    204     def GetSettingsKey(self):
    205         if self.setting:
    206             return self.setting.settings_key
    207         else:
    208             return self.settingsKey
    209 
    210     def SetSettingsKey(self, settingsKey):
    211         self.settingsKey = settingsKey
    212 
    213     def GetSettingsPath(self):
    214         return self.settingsPath
    215 
    216     def UpdateSettings(self):
    217         if self.setting:
    218             if self._checked:
    219                 self.setting.enable()
    220             else:
    221                 self.setting.disable()
    222         elif self.settingsPath:
    223             self._ApplySettingOld(self._checked)
    224 
    225     def _ApplySettingOld(self, value):
    226         setting = GetAttrs(settings, *self.settingsPath)
    227         try:
    228             setting.Set(self.settingsKey, value)
    229         except:
    230             logger.error('Failed to assign setting to: %s, %s' % (self.settingsPath, self.settingsKey))
    231 
    232     def _GetSettingValue(self):
    233         return self.setting.is_enabled()
    234 
    235     def _GetIsCheckedSettingValue(self):
    236         return self._GetSettingValue()
    237 
    238     def ConstructCheckboxCont(self):
    239         if self.checkboxCont:
    240             self.checkboxCont.Close()
    241         diodeAlign = uiconst.TOPLEFT
    242         self.checkboxCont = Container(name='diode', parent=self, align=diodeAlign, state=uiconst.UI_DISABLED, pos=(0,
    243          (self.minHeight - self.DIODE_SIZE) / 2,
    244          16,
    245          16))
    246         self._ConstructCheckmark()
    247 
    248     def _ConstructCheckmark(self):
    249         self.checkMark = Sprite(name='self_ok', parent=self.checkboxCont, align=uiconst.CENTER, state=uiconst.UI_HIDDEN, pos=(0, 0, 16, 16), texturePath=self.checkedTexture)
    250         self.underlay = CheckboxUnderlay(parent=self.checkboxCont, enabled=self._enabled)
    251 
    252     def _update_checkmark_color(self):
    253         color = self.CHECK_MARK_COLOR_IDLE if self._enabled else self.CHECK_MARK_COLOR_DISABLED
    254         self.checkMark.SetRGBA(*color)
    255 
    256     def IsRightAligned(self):
    257         return self.GetAlign() in (uiconst.TOPRIGHT, uiconst.CENTERRIGHT)
    258 
    259     def SetChecked(self, isChecked, report = 1):
    260         isChecked = isChecked or 0
    261         self._checked = int(isChecked)
    262         self.checkMark.state = uiconst.UI_DISABLED if self._checked else uiconst.UI_HIDDEN
    263         if report:
    264             if isChecked:
    265                 PlaySound(uiconst.SOUND_SETDESELECTED)
    266             else:
    267                 PlaySound(uiconst.SOUND_SETSELECTED)
    268             self.UpdateSettings()
    269             self.OnChange()
    270         if isChecked:
    271             self.underlay.Select(animate=report)
    272         else:
    273             self.underlay.Deselect(animate=report)
    274 
    275     def OnChange(self):
    276         if self._callback:
    277             self._callback(self)
    278 
    279     def SetCallback(self, callback):
    280         self._callback = callback
    281 
    282     def SetLabel(self, labeltext):
    283         self.SetLabelText(labeltext)
    284 
    285     def GetTooltipPosition(self, *args, **kwds):
    286         l, t, w, h = self.GetAbsolute()
    287         label = self.label
    288         if label.text:
    289             return (l,
    290              t,
    291              label.padLeft + label.left + label.textwidth,
    292              h)
    293         else:
    294             return (l,
    295              t,
    296              w,
    297              h)
    298 
    299     def OnClick(self, *args):
    300         if not self.disabled:
    301             self.ToggleState()
    302 
    303     def OnMouseEnter(self, *args):
    304         self._hovered = True
    305         if self.disabled:
    306             return
    307         PlaySound(uiconst.SOUND_BUTTON_HOVER)
    308         self._update_label_color()
    309         if self.underlay:
    310             self.underlay.OnMouseEnter()
    311 
    312     def OnMouseExit(self, *args):
    313         self._hovered = False
    314         if self.disabled:
    315             return
    316         self._update_label_color()
    317         if self.underlay:
    318             self.underlay.OnMouseExit()
    319 
    320     def OnMouseDown(self, mouseBtn = None):
    321         if self.disabled or mouseBtn != uiconst.MOUSELEFT:
    322             return
    323         if self.underlay:
    324             self.underlay.OnMouseDown()
    325 
    326     def OnMouseUp(self, mouseBtn = None):
    327         super(Checkbox, self).OnMouseUp(mouseBtn)
    328         if self.disabled or mouseBtn != uiconst.MOUSELEFT:
    329             return
    330         if self.underlay:
    331             self.underlay.OnMouseUp()
    332 
    333     def UpdateAlignment(self, budgetLeft = 0, budgetTop = 0, budgetWidth = 0, budgetHeight = 0, updateChildrenOnly = False):
    334         budget = super(Checkbox, self).UpdateAlignment(budgetLeft, budgetTop, budgetWidth, budgetHeight, updateChildrenOnly)
    335         if self.align in uiconst.ALIGNMENTS_WITH_RELEVANT_WIDTH:
    336             self.label.clear_set_width()
    337         else:
    338             width, _ = self.GetCurrentAbsoluteSize()
    339             self.label.width = width - self.label.left
    340         measurer = self.label.measurer
    341         approximateGlyphHeight = int(math.ceil(9.0 / 13.0 * self.ReverseScaleDpi(measurer.fontSize)))
    342         glyphDistanceFromTop = self.ReverseScaleDpi(measurer.ascender) - approximateGlyphHeight
    343         self.label.top = round((self.minHeight - approximateGlyphHeight) / 2.0 - glyphDistanceFromTop)
    344         if self.label._alignmentDirty:
    345             size_changed = budget[4]
    346             budget = super(Checkbox, self).UpdateAlignment(budgetLeft, budgetTop, budgetWidth, budgetHeight, updateChildrenOnly=False)
    347             budget = budget[:4] + (size_changed or budget[4],)
    348         return budget
    349 
    350 
    351 class CheckboxUnderlay(Container):
    352     UNDERLAY_OPACITY_NORMAL = 1.0
    353     UNDERLAY_OPACITY_DISABLED = 0.5
    354 
    355     def __init__(self, parent = None, bgParent = None, align = uiconst.TOALL, padding = 0, enabled = True):
    356         self._hover = None
    357         self._highlight = None
    358         self._underlay = None
    359         super(CheckboxUnderlay, self).__init__(parent=parent, bgParent=bgParent, align=align, padding=padding)
    360         self._hover = Frame(parent=self, align=uiconst.TOALL, texturePath='res:/UI/Texture/classes/checkbox/underlay_hover.png', color=eveThemeColor.THEME_FOCUS, outputMode=uiconst.OUTPUT_COLOR_AND_GLOW, glowBrightness=0.3, cornerSize=8, opacity=0.0)
    361         self._highlight = Fill(parent=self, align=uiconst.TOALL, padding=1, opacity=0.0)
    362         self._underlay = Frame(parent=self, align=uiconst.TOALL, texturePath='res:/UI/Texture/classes/checkbox/underlay.png', cornerSize=3, opacity=self.UNDERLAY_OPACITY_NORMAL if enabled else self.UNDERLAY_OPACITY_DISABLED)
    363 
    364     def OnColorThemeChanged(self):
    365         super(CheckboxUnderlay, self).OnColorThemeChanged()
    366         self._hover.SetRGBA(*(eveThemeColor.THEME_FOCUS[:3] + (self._hover.opacity,)))
    367 
    368     def Enable(self):
    369         self._underlay.opacity = self.UNDERLAY_OPACITY_NORMAL
    370 
    371     def Disable(self):
    372         self._underlay.opacity = self.UNDERLAY_OPACITY_DISABLED
    373 
    374     def Select(self, animate = True):
    375         pass
    376 
    377     def Deselect(self, animate = True):
    378         pass
    379 
    380     def OnMouseEnter(self, *args):
    381         if self._hover is not None:
    382             animations.FadeIn(self._hover, duration=0.1)
    383 
    384     def OnMouseExit(self, *args):
    385         if self._hover is not None:
    386             animations.FadeOut(self._hover, duration=0.3)
    387 
    388     def OnMouseDown(self, *args):
    389         animations.FadeIn(self._highlight, duration=uiconst.TIME_ENTRY)
    390 
    391     def OnMouseUp(self, *args):
    392         animations.FadeOut(self._highlight, duration=uiconst.TIME_MOUSEUP)