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

utilMenu.py (24146B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\utilMenu.py
      2 import weakref
      3 import carbonui.const as uiconst
      4 from carbon.client.script.environment.AudioUtil import PlaySound
      5 from carbon.common.script.util.timerstuff import AutoTimer
      6 from carbonui.primitives.container import Container
      7 from carbonui.primitives.containerAutoSize import ContainerAutoSize
      8 from carbonui.primitives.fill import Fill
      9 from carbonui.primitives.layoutGrid import LayoutGrid
     10 from carbonui.primitives.line import Line
     11 from carbonui.primitives.sprite import Sprite
     12 from carbonui.util.various_unsorted import IsUnder
     13 from carbonui.control.buttonIcon import ButtonIcon
     14 from eve.client.script.ui.control.eveIcon import Icon
     15 from eve.client.script.ui.control.eveLabel import EveLabelMedium
     16 from carbonui.decorative.menuUnderlay import MenuUnderlay
     17 from eve.client.script.ui.control.themeColored import FillThemeColored, FrameThemeColored, LineThemeColored, SpriteThemeColored
     18 from eve.client.script.ui.services.tutoriallib import TutorialColor
     19 from eve.common.lib.appConst import defaultPadding
     20 import uthread
     21 from carbonui.uicore import uicore
     22 IDLE_OPACITY = 0.8
     23 MOUSEOVER_OPACITY = 1.0
     24 TOGGLEACTIVE_OPACITY = 0.8
     25 TOGGLEINACTIVE_OPACITY = 0.6
     26 DISABLED_OPACITY = 0.2
     27 OPACITY_LINES = 0.2
     28 OPACITY_BG = 0.8
     29 
     30 class UtilMenu(ButtonIcon):
     31     default_name = 'UtilMenu'
     32     default_align = uiconst.TOPLEFT
     33     default_state = uiconst.UI_NORMAL
     34     default_texturePath = 'res:/UI/Texture/Icons/77_32_30.png'
     35     default_iconSize = 16
     36     default_width = 24
     37     default_height = 24
     38     default_maxWidth = None
     39     default_menuAlign = uiconst.TOPLEFT
     40     default_bgOpacityExpandedIcon = OPACITY_BG
     41     default_opacityExpandedLines = OPACITY_LINES
     42     default_labelAlign = uiconst.CENTERLEFT
     43     _getMenuFunction = None
     44     _expanded = False
     45     _menu = None
     46     _label = None
     47     _menuButton = None
     48 
     49     def Close(self, *args):
     50         if self.destroyed:
     51             return
     52         self._getMenuFunction = None
     53         ButtonIcon.Close(self, *args)
     54         if self.IsExpanded():
     55             self.CloseMenu()
     56 
     57     def CloseMenu(self, *args):
     58         if self._menu:
     59             menu = self._menu()
     60             if menu:
     61                 menu.Close()
     62 
     63     def OnMenuClosed(self, *args):
     64         if self._menuButton:
     65             menuButton = self._menuButton()
     66             if menuButton:
     67                 menuButton.Close()
     68 
     69     def ApplyAttributes(self, attributes):
     70         ButtonIcon.ApplyAttributes(self, attributes)
     71         self._label = None
     72         self._menu = None
     73         self._menuButton = None
     74         if attributes.GetUtilMenu:
     75             self._getMenuFunction = attributes.GetUtilMenu
     76         else:
     77             raise RuntimeError('GetUtilMenu has to be provided in order to use UtilMenu')
     78         texturePath = attributes.get('texturePath', self.default_texturePath)
     79         closeTexturePath = attributes.get('closeTexturePath', None)
     80         iconSize = attributes.get('iconSize', self.default_iconSize)
     81         self.texturePath = texturePath
     82         self.iconSize = iconSize
     83         self.menuAlign = attributes.get('menuAlign', self.default_menuAlign)
     84         self.closeTexturePath = closeTexturePath or texturePath
     85         self.maxWidth = attributes.get('maxWidth', self.default_maxWidth)
     86         self.bgOpacityExpandedIcon = attributes.get('bgOpacityExpandedIcon', self.default_bgOpacityExpandedIcon)
     87         self.opacityExpandedLines = attributes.get('opacityExpandedLines', self.default_opacityExpandedLines)
     88         self.labelAlign = attributes.get('labelAlign', self.default_labelAlign)
     89         if attributes.label:
     90             self.SetLabel(attributes.label, self.labelAlign)
     91 
     92     def SetLabel(self, label, labelAlign = None):
     93         if labelAlign is None:
     94             labelAlign = self.labelAlign
     95         if labelAlign not in (uiconst.CENTERLEFT, uiconst.CENTERRIGHT):
     96             raise RuntimeError('SetLabel labelAlign has to be CENTERLEFT or CENTERRIGHT')
     97         if labelAlign == uiconst.CENTERLEFT:
     98             iconAlign = uiconst.CENTERRIGHT
     99         else:
    100             iconAlign = uiconst.CENTERLEFT
    101         if self._label is None:
    102             self._label = EveLabelMedium(parent=self, text=label, align=labelAlign, left=const.defaultPadding * 2)
    103         else:
    104             self._label.text = label
    105         margin = int((self.height - self.iconSize) / 2.0)
    106         self.width = self.GetFullWidth()
    107         if self.maxWidth:
    108             self.width = min(self.maxWidth, self.width)
    109             self._label.SetRightAlphaFade(self.maxWidth - defaultPadding * 6, 10)
    110         icon = self.icon
    111         icon.align = iconAlign
    112         icon.left = margin
    113         background = self.bgContainer
    114         background.align = uiconst.CENTERLEFT
    115         background.width = self.width
    116         if self._menuButton:
    117             buttonCopy = self._menuButton()
    118             if buttonCopy:
    119                 if not hasattr(buttonCopy, 'label'):
    120                     buttonCopy.label = EveLabelMedium(parent=buttonCopy, text=label, align=labelAlign, left=self._label.left)
    121                 else:
    122                     buttonCopy.label.SetText(label)
    123                     buttonCopy.label.SetAlign(labelAlign)
    124                 buttonCopy.width = self.GetFullWidth()
    125 
    126     def GetFullWidth(self):
    127         margin = int((self.height - self.iconSize) / 2.0)
    128         if self._label:
    129             width = self._label.left + self._label.width + self.iconSize + 2 * margin
    130         else:
    131             width = self.iconSize + 2 * margin
    132         if self.align == uiconst.TOTOP:
    133             absWidth, _ = self.GetAbsoluteSize()
    134             width = max(width, absWidth)
    135         return width
    136 
    137     def GetHint(self):
    138         if self._label and self._label.text:
    139             if self.maxWidth and self.maxWidth < self.GetFullWidth():
    140                 return self._label.text
    141         return self.hint
    142 
    143     def OnClick(self, *args):
    144         if not self.enabled:
    145             return
    146         PlaySound(uiconst.SOUND_EXPAND)
    147         self.ExpandMenu()
    148 
    149     def IsExpanded(self):
    150         return bool(self._menu and self._menu() and not self._menu().destroyed)
    151 
    152     def ExpandMenu(self, *args):
    153         if self.destroyed:
    154             return
    155         if self.IsExpanded():
    156             self.CloseMenu()
    157             return
    158         background = self.bgContainer
    159         icon = self.icon
    160         l, t, w, h = background.GetAbsolute()
    161         buttonCopy = Container(name='buttonCopy', parent=uicore.layer.utilmenu, align=uiconst.TOPLEFT, pos=(l,
    162          t,
    163          self.GetFullWidth(),
    164          h), state=uiconst.UI_NORMAL, idx=0)
    165         buttonCopy.OnMouseDown = self.CloseMenu
    166         if self._label is not None:
    167             buttonCopy.label = EveLabelMedium(parent=buttonCopy, text=self._label.text, align=self._label.align, left=self._label.left)
    168         try:
    169             expandedPadding = 0 if self.align == uiconst.TOTOP else 16
    170             menuParent = ExpandedUtilMenu(parent=uicore.layer.utilmenu, controller=self, GetUtilMenu=self._getMenuFunction, minWidth=self.GetFullWidth() + expandedPadding, idx=1, menuAlign=self.menuAlign)
    171         except Exception:
    172             buttonCopy.Close()
    173             raise
    174 
    175         self._menu = weakref.ref(menuParent)
    176         self._menuButton = weakref.ref(buttonCopy)
    177         uicore.animations.MorphScalar(buttonCopy, 'opacity', startVal=0.5, endVal=1.0, duration=0.2)
    178         uthread.new(uicore.registry.SetFocus, menuParent)
    179         sm.ScatterEvent('OnUtilMenuOpened')
    180 
    181 
    182 class ExpandedUtilMenu(ContainerAutoSize):
    183     __guid__ = 'ExpandedUtilMenu'
    184     default_name = 'ExpandedUtilMenu'
    185     default_state = uiconst.UI_NORMAL
    186     default_opacity = 0
    187     default_bgOpacity = OPACITY_BG
    188     default_menuAlign = uiconst.TOPLEFT
    189     minWidth = 0
    190 
    191     def ApplyAttributes(self, attributes):
    192         attributes.align = uiconst.TOPLEFT
    193         attributes.width = 128
    194         attributes.height = 128
    195         ContainerAutoSize.ApplyAttributes(self, attributes)
    196         if attributes.GetUtilMenu:
    197             self._getMenuFunction = attributes.GetUtilMenu
    198         else:
    199             raise RuntimeError('GetUtilMenu has to be provided in order to use UtilMenu')
    200         self.controller = attributes.controller
    201         self.isTopLevelWindow = True
    202         self.menuAlign = attributes.Get('menuAlign', self.default_menuAlign)
    203         self.minWidth = attributes.minWidth or 0
    204         self.bgOpacity = attributes.Get('bgOpacity', self.default_bgOpacity)
    205         MenuUnderlay(bgParent=self, padding=-8)
    206         uicore.uilib.RegisterForTriuiEvents([uiconst.UI_MOUSEDOWN], self.OnGlobalMouseDown)
    207         self.ReloadMenu()
    208         self.AnimFadeIn()
    209         self.UpdateMenuPosition()
    210 
    211     def OnGlobalMouseDown(self, *args):
    212         if self.destroyed:
    213             return False
    214         for layer in (uicore.layer.utilmenu, uicore.layer.modal, uicore.layer.menu):
    215             if IsUnder(uicore.uilib.mouseOver, layer):
    216                 return True
    217 
    218         self.Close()
    219         return False
    220 
    221     def AnimFadeIn(self):
    222         uicore.animations.FadeIn(self, duration=0.2)
    223 
    224     def Close(self, *args):
    225         if self.controller and hasattr(self.controller, 'OnMenuClosed'):
    226             self.controller.OnMenuClosed()
    227         ContainerAutoSize.Close(self, *args)
    228 
    229     def _OnSizeChange_NoBlock(self, *args, **kwds):
    230         ContainerAutoSize._OnSizeChange_NoBlock(self, *args, **kwds)
    231         self.OnSizeChanged()
    232 
    233     def OnSizeChanged(self, *args):
    234         self.UpdateMenuPosition()
    235 
    236     def SetSizeAutomatically(self):
    237         width = self.minWidth
    238         for each in self.children:
    239             if hasattr(each, 'GetEntryWidth'):
    240                 width = max(width, each.GetEntryWidth())
    241 
    242         self.width = width
    243         ContainerAutoSize.SetSizeAutomatically(self)
    244 
    245     def ReloadMenu(self):
    246         self.Flush()
    247         getMenuFunction = self._getMenuFunction
    248         if callable(getMenuFunction):
    249             getMenuFunction(self)
    250         elif isinstance(getMenuFunction, tuple):
    251             func = getMenuFunction[0]
    252             if callable(func):
    253                 func(self, *getMenuFunction[1:])
    254 
    255     def UpdateMenuPosition(self, *args):
    256         if self.controller.destroyed:
    257             return
    258         l, t, w, h = self.controller.GetAbsolute()
    259         shiftAmount = 0
    260         if self.menuAlign in (uiconst.TOPRIGHT, uiconst.BOTTOMRIGHT):
    261             self.left = l - self.width + w - 8
    262             shiftAmount = -w
    263         else:
    264             self.left = l + 8
    265             shiftAmount = w
    266         if self.menuAlign in (uiconst.BOTTOMLEFT, uiconst.BOTTOMRIGHT):
    267             self.top = t - self.height - 8
    268         else:
    269             self.top = t + h + 8
    270         shiftToSide = False
    271         if self.top < 0:
    272             self.top = 0
    273             shiftToSide = True
    274         elif self.top + self.height > uicore.desktop.height:
    275             self.top = uicore.desktop.height - self.height
    276             shiftToSide = True
    277         if shiftToSide:
    278             if self.left + self.width + shiftAmount < uicore.desktop.width:
    279                 self.left += shiftAmount
    280             else:
    281                 self.left = self.left - self.width
    282         if self.left < 0:
    283             self.left = l + w
    284         elif self.left + self.width > uicore.desktop.width:
    285             self.left = l - self.width
    286 
    287     def VerifyCallback(self, callback):
    288         if callable(callback):
    289             return True
    290         if isinstance(callback, tuple):
    291             func = callback[0]
    292             if callable(func):
    293                 return True
    294         raise RuntimeError('Callback has to be callable or tuple with callable as first argument')
    295 
    296     def AddHeader(self, text, callback = None, hint = None, icon = None):
    297         if callback:
    298             self.VerifyCallback(callback)
    299         return UtilMenuHeader(parent=self, text=text, callback=callback, hint=hint, icon=icon)
    300 
    301     def AddIconEntry(self, icon, text, callback = None, hint = None, toggleMode = None, name = 'UtilMenuIconEntry'):
    302         if callback:
    303             self.VerifyCallback(callback)
    304         return UtilMenuIconEntry(parent=self, icon=icon, text=text, callback=callback, hint=hint, toggleMode=toggleMode, name=name)
    305 
    306     def AddButton(self, text, callback = None, hint = None, toggleMode = None):
    307         if callback:
    308             self.VerifyCallback(callback)
    309         return UtilMenuButton(parent=self, text=text, callback=callback, hint=hint, toggleMode=toggleMode)
    310 
    311     def AddCheckBox(self, text, checked, callback = None, icon = None, hint = None, indentation = None, state = uiconst.UI_NORMAL, uniqueUiName = None):
    312         if callback:
    313             self.VerifyCallback(callback)
    314         return UtilMenuCheckBox(parent=self, text=text, checked=checked, icon=icon, hint=hint, callback=callback, indentation=indentation, state=state, uniqueUiName=uniqueUiName)
    315 
    316     def AddCheckBoxWithSubIcon(self, text, checked, subIcon, callback = None, subIconCallback = None, icon = None, subIconHint = None, hint = None):
    317         if callback:
    318             self.VerifyCallback(callback)
    319         UtilMenuCheckBoxWithButton(parent=self, text=text, checked=checked, icon=icon, hint=hint, callback=callback, subIcon=subIcon, subIconCallback=subIconCallback, subIconHint=subIconHint)
    320 
    321     def AddRadioButton(self, text, checked, callback = None, icon = None, hint = None, uniqueUiName = None):
    322         if callback:
    323             self.VerifyCallback(callback)
    324         return UtilMenuRadioBox(parent=self, text=text, checked=checked, icon=icon, hint=hint, callback=callback, uniqueUiName=uniqueUiName)
    325 
    326     def AddText(self, text, minTextWidth = 100):
    327         return UtilMenuText(parent=self, text=text, minTextWidth=minTextWidth)
    328 
    329     def AddSpace(self, height = 5):
    330         return UtilMenuSpace(parent=self, height=height)
    331 
    332     def AddDivider(self, padding = 0):
    333         return UtilMenuDivider(parent=self, padding=padding)
    334 
    335     def AddContainer(self, *args, **kwargs):
    336         return UtilMenuContainer(parent=self, *args, **kwargs)
    337 
    338     def AddLayoutGrid(self, *args, **kwargs):
    339         return UtilMenuLayoutGrid(parent=self, *args, **kwargs)
    340 
    341 
    342 class UtilMenuEntryBase(Container):
    343     __guid__ = 'UtilMenuEntryBase'
    344     default_align = uiconst.TOTOP
    345     default_state = uiconst.UI_NORMAL
    346     default_icon = None
    347     _hiliteSprite = None
    348     callback = None
    349     isToggleEntry = False
    350     uniqueUiName = None
    351 
    352     def ApplyAttributes(self, attributes):
    353         Container.ApplyAttributes(self, attributes)
    354         labelLeft = 22
    355         iconLeft = 3
    356         if attributes.indentation:
    357             labelLeft += attributes.indentation
    358             iconLeft += attributes.indentation
    359         self.label = EveLabelMedium(parent=self, text=attributes.text, align=uiconst.CENTERLEFT, left=labelLeft, state=uiconst.UI_DISABLED)
    360         icon = attributes.Get('icon', self.default_icon)
    361         if icon is not None:
    362             self.icon = SpriteThemeColored(parent=self, texturePath=icon, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW, state=uiconst.UI_DISABLED, left=iconLeft, width=16, height=16, align=uiconst.CENTERLEFT, ignoreSize=True)
    363         self.ResetOpacity()
    364         self.TryAddHighlighting()
    365         self.UpdateEntryHeight()
    366 
    367     def TryAddHighlighting(self):
    368         if self.uniqueUiName is None:
    369             return
    370         isHighlighted = sm.GetService('helpPointer').IsUtilMenuEntryHighlighted(self.uniqueUiName)
    371         if not isHighlighted:
    372             return
    373         self.highlightFrame = Fill(bgParent=self, color=TutorialColor.HINT_FRAME, opacity=0.0)
    374         uicore.animations.FadeTo(self.highlightFrame, 0.0, 0.4, duration=1.6, curveType=uiconst.ANIM_WAVE, loops=uiconst.ANIM_REPEAT)
    375 
    376     def UpdateEntryHeight(self):
    377         self.height = self.label.textheight + 4
    378 
    379     def GetEntryWidth(self):
    380         return self.label.width + self.label.left + 12
    381 
    382     def ResetOpacity(self):
    383         if not self.callback:
    384             self.opacity = DISABLED_OPACITY
    385         elif self.isToggleEntry:
    386             if self.isChecked:
    387                 self.opacity = TOGGLEACTIVE_OPACITY
    388             else:
    389                 self.opacity = TOGGLEINACTIVE_OPACITY
    390         else:
    391             self.opacity = IDLE_OPACITY
    392 
    393     def OnClick(self, *args):
    394         callback = self.callback
    395         if callback:
    396             PlaySound(uiconst.SOUND_BUTTON_CLICK)
    397             if callable(callback):
    398                 callback()
    399             elif isinstance(callback, tuple):
    400                 func = callback[0]
    401                 if callable(func):
    402                     func(*callback[1:])
    403         if self.parent:
    404             if self.isToggleEntry:
    405                 self.parent.ReloadMenu()
    406             else:
    407                 self.parent.Close()
    408 
    409     def OnMouseEnter(self, *args):
    410         if not self.callback:
    411             self.opacity = DISABLED_OPACITY
    412         else:
    413             self.opacity = MOUSEOVER_OPACITY
    414             PlaySound(uiconst.SOUND_ENTRY_HOVER)
    415             if not self._hiliteSprite:
    416                 self._hiliteSprite = SpriteThemeColored(parent=self, name='hiliteSprite', texturePath='res:/UI/Texture/classes/UtilMenu/entryHilite.png', opacity=0.0, padding=(1, 0, 1, 0), align=uiconst.TOALL, state=uiconst.UI_DISABLED)
    417             uicore.animations.FadeIn(self._hiliteSprite, 0.2, duration=uiconst.TIME_ENTRY)
    418             self.hiliteTimer = AutoTimer(1, self._CheckIfStillHilited)
    419 
    420     def OnMouseExit(self, *args):
    421         if not (IsUnder(uicore.uilib.mouseOver, self) or uicore.uilib.mouseOver is self):
    422             self.ShowNotHilited()
    423 
    424     def ShowNotHilited(self):
    425         self.ResetOpacity()
    426         self.hiliteTimer = None
    427         if self._hiliteSprite and self._hiliteSprite.display:
    428             uicore.animations.FadeOut(self._hiliteSprite, duration=uiconst.TIME_EXIT)
    429 
    430     def _CheckIfStillHilited(self):
    431         if IsUnder(uicore.uilib.mouseOver, self) or uicore.uilib.mouseOver is self:
    432             return
    433         self.ShowNotHilited()
    434 
    435 
    436 class UtilMenuIconEntry(UtilMenuEntryBase):
    437     __guid__ = 'UtilMenuIconEntry'
    438 
    439     def ApplyAttributes(self, attributes):
    440         self.callback = attributes.callback
    441         if self.callback and attributes.toggleMode:
    442             self.isToggleEntry = True
    443             self.isChecked = True
    444         UtilMenuEntryBase.ApplyAttributes(self, attributes)
    445 
    446 
    447 class UtilMenuButton(UtilMenuIconEntry):
    448     __guid__ = 'UtilMenuButton'
    449     default_icon = 'res:/UI/Texture/classes/UtilMenu/BulletIcon.png'
    450 
    451 
    452 class UtilMenuCheckBox(UtilMenuEntryBase):
    453     __guid__ = 'UtilMenuCheckBox'
    454     isToggleEntry = True
    455     isChecked = False
    456 
    457     def ApplyAttributes(self, attributes):
    458         self.callback = attributes.callback
    459         self.isChecked = attributes.checked
    460         self.isToggleEntry = True
    461         if attributes.icon is None:
    462             if attributes.checked:
    463                 attributes.icon = 'res:/UI/Texture/classes/UtilMenu/checkBoxActive.png'
    464             else:
    465                 attributes.icon = 'res:/UI/Texture/classes/UtilMenu/checkBoxInactive.png'
    466         UtilMenuEntryBase.ApplyAttributes(self, attributes)
    467 
    468 
    469 class UtilMenuCheckBoxWithButton(UtilMenuCheckBox):
    470     __guid__ = 'UtilMenuCheckBoxWithButton'
    471 
    472     def ApplyAttributes(self, attributes):
    473         UtilMenuCheckBox.ApplyAttributes(self, attributes)
    474         self.subIcon = Icon(parent=self, icon=attributes.subIcon, state=uiconst.UI_DISABLED, left=3, width=16, height=16, align=uiconst.CENTERRIGHT, ignoreSize=True)
    475         if attributes.subIconCallback:
    476             self.subIcon.hint = attributes.subIconHint
    477             self.subIcon.state = uiconst.UI_NORMAL
    478             self.subIcon.OnClick = self.OnSubIconClick
    479             self.subIcon.OnMouseEnter = self.OnMouseEnter
    480             self.subIconCallback = attributes.subIconCallback
    481 
    482     def OnSubIconClick(self, *args):
    483         callback = self.subIconCallback
    484         if callback:
    485             if callable(callback):
    486                 callback()
    487             elif isinstance(callback, tuple):
    488                 func = callback[0]
    489                 if callable(func):
    490                     func(*callback[1:])
    491         if self.parent:
    492             if self.isToggleEntry:
    493                 self.parent.ReloadMenu()
    494             else:
    495                 self.parent.Close()
    496 
    497     def GetEntryWidth(self):
    498         width = UtilMenuCheckBox.GetEntryWidth(self)
    499         return (width + 20) / 16 * 16 + 16
    500 
    501 
    502 class UtilMenuRadioBox(UtilMenuEntryBase):
    503     __guid__ = 'UtilMenuRadioBox'
    504 
    505     def ApplyAttributes(self, attributes):
    506         self.callback = attributes.callback
    507         self.isChecked = attributes.checked
    508         self.isToggleEntry = True
    509         if attributes.icon is None:
    510             if attributes.checked:
    511                 attributes.icon = 'res:/UI/Texture/classes/UtilMenu/radioButtonActive.png'
    512             else:
    513                 attributes.icon = 'res:/UI/Texture/classes/UtilMenu/radioButtonInactive.png'
    514         UtilMenuEntryBase.ApplyAttributes(self, attributes)
    515 
    516 
    517 class UtilMenuHeader(UtilMenuEntryBase):
    518     __guid__ = 'UtilMenuHeader'
    519     default_align = uiconst.TOTOP
    520     default_state = uiconst.UI_DISABLED
    521 
    522     def ApplyAttributes(self, attributes):
    523         self.callback = attributes.callback
    524         if self.callback:
    525             attributes.state = uiconst.UI_NORMAL
    526             self.isToggleEntry = True
    527         UtilMenuEntryBase.ApplyAttributes(self, attributes)
    528         iconLeft = 0
    529         if attributes.icon:
    530             self.label.left = 22
    531         else:
    532             self.label.left = 6
    533         self.label.bold = True
    534         self.label.letterspace = 1
    535         Sprite(parent=self, align=uiconst.TOALL, texturePath='res:/UI/Texture/classes/UtilMenu/headerGradient.png', color=(1, 1, 1, 0.1), padLeft=1, padRight=1, state=uiconst.UI_DISABLED)
    536         self.UpdateEntryHeight()
    537 
    538     def ResetOpacity(self):
    539         pass
    540 
    541     def GetEntryWidth(self):
    542         return self.label.width + self.label.left * 2
    543 
    544 
    545 class UtilMenuText(Container):
    546     __guid__ = 'UtilMenuText'
    547     default_align = uiconst.TOTOP
    548     default_height = 22
    549     default_minTextWidth = 100
    550 
    551     def ApplyAttributes(self, attributes):
    552         Container.ApplyAttributes(self, attributes)
    553         self.minTextWidth = attributes.get('minTextWidth', self.default_minTextWidth)
    554         self.text = EveLabelMedium(parent=self, text=attributes.text, align=uiconst.TOTOP, padding=6, color=(1, 1, 1, 0.8), state=uiconst.UI_DISABLED)
    555         self.text._OnSizeChange_NoBlock = self.OnTextSizeChange
    556         self.height = self.text.textheight + 12
    557 
    558     def GetEntryWidth(self):
    559         return self.minTextWidth + 12
    560 
    561     def OnTextSizeChange(self, newWidth, newHeight):
    562         EveLabelMedium._OnSizeChange_NoBlock(self.text, newWidth, newHeight)
    563         self.height = self.text.textheight + 12
    564 
    565 
    566 class UtilMenuSpace(Container):
    567     __guid__ = 'UtilMenuSpace'
    568     default_align = uiconst.TOTOP
    569 
    570     def ApplyAttributes(self, attributes):
    571         Container.ApplyAttributes(self, attributes)
    572 
    573     def GetEntryWidth(self):
    574         return 0
    575 
    576 
    577 class UtilMenuDivider(ContainerAutoSize):
    578     __guid__ = 'UtilMenuDivider'
    579     default_align = uiconst.TOTOP
    580 
    581     def ApplyAttributes(self, attributes):
    582         padding = attributes.padding or 0
    583         super(UtilMenuDivider, self).ApplyAttributes(attributes)
    584         Line(align=uiconst.TOTOP, parent=self, opacity=0.1, padding=(0, 6, 0, 6))
    585 
    586     def GetEntryWidth(self):
    587         return 0
    588 
    589 
    590 class UtilMenuLayoutGrid(UtilMenuEntryBase, LayoutGrid):
    591 
    592     def ApplyAttributes(self, attributes):
    593         LayoutGrid.ApplyAttributes(self, attributes)
    594 
    595     def GetEntryWidth(self):
    596         return self.gridSize[0]
    597 
    598     def UpdateEntryHeight(self):
    599         pass
    600 
    601     def ResetOpacity(self):
    602         pass
    603 
    604     def OnClick(self, *args):
    605         pass
    606 
    607     def OnMouseEnter(self, *args):
    608         pass
    609 
    610 
    611 class UtilMenuContainer(UtilMenuEntryBase, ContainerAutoSize):
    612     __guid__ = 'UtilMenuContainer'
    613 
    614     def ApplyAttributes(self, attributes):
    615         ContainerAutoSize.ApplyAttributes(self, attributes)
    616         self.ResetOpacity()
    617         self.UpdateEntryHeight()
    618 
    619     def GetEntryWidth(self):
    620         return 100
    621 
    622     def UpdateEntryHeight(self):
    623         pass
    624 
    625     def ResetOpacity(self):
    626         pass
    627 
    628     def OnClick(self, *args):
    629         pass
    630 
    631     def OnMouseEnter(self, *args):
    632         pass