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

contextMenu.py (9491B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\control\contextMenu\contextMenu.py
      2 import logging
      3 import types
      4 import weakref
      5 from collections import defaultdict
      6 import log
      7 from carbon.client.script.environment.AudioUtil import PlaySound
      8 from carbonui import const as uiconst
      9 from carbonui.control.contextMenu.contextMenuMixin import ContextMenuMixin
     10 from carbonui.control.contextMenu.menuData import MenuData
     11 from carbonui.control.contextMenu.menuDataFactory import CreateMenuDataFromRawTuples
     12 from carbonui.control.contextMenu.menuEntryData import MenuEntryDataCaption, MenuEntryDataLabel, MenuEntryDataCheckbox, MenuEntryDataRadioButton, MenuEntryDataSlider
     13 from carbonui.control.contextMenu.menuEntryView import MenuEntryView, MenuEntryViewCaption, MenuEntryViewLabel, MenuEntryViewCheckbox, MenuEntryViewRadioButton, MenuEntryViewSlider
     14 from carbonui.control.contextMenu.menuUtil import CloseContextMenus
     15 from carbonui.primitives.container import Container
     16 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     17 from carbonui.primitives.line import Line
     18 from carbonui.uicore import uicore
     19 from carbonui.util.mouseTargetObject import MouseTargetObject
     20 from carbonui.decorative.menuUnderlay import MenuUnderlay
     21 from uihider import CommandBlockerService
     22 logger = logging.getLogger(__name__)
     23 
     24 class ContextMenu(ContainerAutoSize, ContextMenuMixin):
     25     default_alignMode = uiconst.TOTOP
     26     default_align = uiconst.TOPLEFT
     27     default_state = uiconst.UI_NORMAL
     28     __notifyevents__ = ['OnMenuHighlightActivated', 'OnMenuHighlightsCleared']
     29 
     30     def ApplyAttributes(self, attributes):
     31         ContainerAutoSize.ApplyAttributes(self, attributes)
     32         sm.RegisterNotify(self)
     33         self.menuData = attributes.menuData
     34         minWidth = attributes.minWidth
     35         self.entries = []
     36         self.entries_by_internal_name = defaultdict(list)
     37         self.highlights_svc = sm.GetService('uiHighlightingService')
     38         self.mainCont = ContainerAutoSize(parent=self, name='mainCont', align=uiconst.TOTOP, padding=8)
     39         self.Prepare_Background_()
     40         self.ConstructEntries()
     41         self.UpdateSize(minWidth)
     42         self.SetupHighlights()
     43         log.LogInfo('Menu.Setup Completed', id(self))
     44         MouseTargetObject(self)
     45 
     46     def UpdateSize(self, minWidth):
     47         if len(self.mainCont.children):
     48             maxChildWidth = max([ entry.GetRequiredWidth() for entry in self.entries ])
     49             self.width = max(maxChildWidth + 8, minWidth or 0) + self.mainCont.padLeft + self.mainCont.padRight
     50         else:
     51             self.width = 100
     52         self.mainCont.SetSizeAutomatically()
     53         self.SetSizeAutomatically()
     54 
     55     def ConstructEntries(self):
     56         entries = self.menuData.GetEntries()
     57         wasLine = 0
     58         while len(entries):
     59             if entries[-1] is None:
     60                 entries.pop(-1)
     61             else:
     62                 break
     63 
     64         for i, menuEntryData in enumerate(entries):
     65             if menuEntryData is None:
     66                 if not len(self.mainCont.children) or i == len(entries) - 1 or wasLine:
     67                     continue
     68                 self._ConstructLine()
     69                 wasLine = 1
     70             else:
     71                 self._ConstructMenuEntry(menuEntryData)
     72                 wasLine = 0
     73 
     74     def _ConstructMenuEntry(self, menuEntryData):
     75         menuEntryViewClass = self._GetMenuEntryViewClass(menuEntryData)
     76         menuEntry = menuEntryViewClass(name=u'context_menu_{}'.format(menuEntryData.internalName or menuEntryData.text), align=uiconst.TOTOP, state=uiconst.UI_NORMAL, parent=self.mainCont, menuEntryData=menuEntryData, iconSize=self.menuData.GetIconSize(), uniqueUiName=getattr(menuEntryData, 'uniqueUiName', None))
     77         self.entries.append(menuEntry)
     78         if menuEntryData.internalName:
     79             self.entries_by_internal_name[menuEntryData.internalName, menuEntryData.typeID].append(menuEntry)
     80 
     81     def _ConstructLine(self):
     82         Line(align=uiconst.TOTOP, parent=self.mainCont, opacity=0.1, padding=(0, 6, 0, 6))
     83 
     84     def _GetMenuEntryViewClass(self, menuEntryData):
     85         if menuEntryData.menuClass:
     86             return menuEntryData.menuClass
     87         elif isinstance(menuEntryData, MenuEntryDataCaption):
     88             return MenuEntryViewCaption
     89         elif isinstance(menuEntryData, MenuEntryDataLabel):
     90             return MenuEntryViewLabel
     91         elif isinstance(menuEntryData, MenuEntryDataRadioButton):
     92             return MenuEntryViewRadioButton
     93         elif isinstance(menuEntryData, MenuEntryDataCheckbox):
     94             return MenuEntryViewCheckbox
     95         elif isinstance(menuEntryData, MenuEntryDataSlider):
     96             return MenuEntryViewSlider
     97         else:
     98             return MenuEntryView
     99 
    100     def Prepare_Background_(self, *args):
    101         self.underlay = MenuUnderlay(bgParent=self)
    102 
    103     def _OnClose(self):
    104         Container._OnClose(self)
    105         for each in self.mainCont.children[:]:
    106             if hasattr(each, 'Collapse'):
    107                 each.Collapse()
    108 
    109         self.menuData = None
    110 
    111     def SetupHighlights(self):
    112         for restriction, entryViews in self.entries_by_internal_name.iteritems():
    113             internalName, typeID = restriction
    114             if self.highlights_svc.is_menu_highlighted(internalName, typeID):
    115                 for entryView in entryViews:
    116                     entryView.Highlight()
    117 
    118     def OnMenuHighlightActivated(self, menuName, menuTypeID):
    119         self.HighlightEntries(menuName, menuTypeID)
    120 
    121     def OnMenuHighlightsCleared(self):
    122         self.ClearHighlights()
    123 
    124     def HighlightEntries(self, menuName, menuTypeID):
    125         for restriction, entryViews in self.entries_by_internal_name.iteritems():
    126             if restriction == (menuName, menuTypeID):
    127                 for entryView in entryViews:
    128                     entryView.Highlight()
    129 
    130     def ClearHighlights(self):
    131         for entryViews in self.entries_by_internal_name.values():
    132             for entryView in entryViews:
    133                 entryView.ClearHighlight()
    134 
    135     def Collapse(self):
    136         if not self.destroyed:
    137             for each in self.mainCont.children:
    138                 if hasattr(each, 'Collapse'):
    139                     each.Collapse()
    140 
    141             self.Close()
    142 
    143 
    144 class ContextSubMenu(ContextMenu):
    145 
    146     def ApplyAttributes(self, attributes):
    147         self.parentEntry = attributes.parentEntry
    148         super(ContextSubMenu, self).ApplyAttributes(attributes)
    149 
    150     def SetSizeAutomatically(self):
    151         super(ContextSubMenu, self).SetSizeAutomatically()
    152         self._UpdatePosition()
    153 
    154     def _UpdatePosition(self):
    155         aL, aT, aW, aH = self.parentEntry.GetAbsolute()
    156         if aL + aW + self.width <= uicore.desktop.width:
    157             self.left = aL + aW + 2
    158         else:
    159             self.left = aL - self.width + -2
    160         self.top = max(0, min(uicore.desktop.height - self.height, aT)) - 8
    161 
    162 
    163 def CreateMenuView(menuData, parent = None, minwidth = None):
    164     if menuData is None:
    165         return
    166     if not parent:
    167         CloseContextMenus()
    168     return ContextMenu(name='menuview', align=uiconst.TOPLEFT, menuData=menuData, minWidth=minwidth)
    169 
    170 
    171 def ShowMenu(object, auxObject = None):
    172     command_blocker = CommandBlockerService.instance()
    173     if command_blocker.is_blocked(['menucore', 'menucore.expand']) and not getattr(object, 'ignore_command_blocker', False):
    174         logger.info('ShowMenu: Menus disabled')
    175         return
    176     CloseContextMenus()
    177     m = None
    178     menuFunc = getattr(object, 'GetMenu', None)
    179     if menuFunc:
    180         if type(menuFunc) == types.TupleType:
    181             func, args = menuFunc
    182             m = func(args)
    183         else:
    184             m = menuFunc()
    185     hasAuxOptions = auxObject and hasattr(auxObject, 'GetAuxiliaryMenuOptions')
    186     if _IsEmptyList(m):
    187         if hasAuxOptions:
    188             m = auxObject.GetAuxiliaryMenuOptions()
    189         else:
    190             logger.info('ShowMenu: No Menu!')
    191             return
    192     elif hasAuxOptions:
    193         m = m + auxObject.GetAuxiliaryMenuOptions()
    194     if getattr(object, 'showingMenu', 0):
    195         logger.info('ShowMenu: Already showing a menu')
    196         return
    197     object.showingMenu = 1
    198     uicore.contextMenuOwner = weakref.ref(object)
    199     try:
    200         menuData = CreateMenuDataFromRawTuples(m)
    201         if not menuData or not menuData.GetEntries():
    202             return
    203         mv = CreateMenuView(menuData=menuData, minwidth=getattr(object, 'minwidth', None))
    204         if mv is not None:
    205             object.menuObject_weakref = weakref.ref(mv)
    206             uicore.layer.menu.children.insert(0, mv)
    207             width, height = mv.GetAbsoluteSize()
    208             mv.left, mv.top = _GetMenuViewPosition(width, height, object)
    209             PlaySound(uiconst.SOUND_EXPAND)
    210             sm.ScatterEvent('OnMenuShown')
    211     finally:
    212         object.showingMenu = 0
    213 
    214     logger.info('ShowMenu finished OK')
    215 
    216 
    217 def _IsEmptyList(m):
    218     if isinstance(m, MenuData):
    219         return False
    220     return not m or not filter(None, m)
    221 
    222 
    223 def _GetMenuViewPosition(width, height, object):
    224     topLeft = 1
    225     func = getattr(object, 'GetMenuPosition', None)
    226     if func is not None:
    227         ret = func(object)
    228         if len(ret) == 2:
    229             x, y = ret
    230         else:
    231             x, y, topLeft = ret
    232     else:
    233         x, y = uicore.uilib.x + 10, uicore.uilib.y
    234     d = uicore.desktop
    235     if topLeft:
    236         x, y = min(d.width - width, x), min(d.height - height, y)
    237     else:
    238         x, y = min(d.width - width, x - width), min(d.height - height, y)
    239     return (x, y)