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

registry.py (22350B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\services\registry.py
      2 from __future__ import print_function
      3 import weakref
      4 import uthread
      5 import carbonui.const as uiconst
      6 from carbonui.primitives.container import Container
      7 from carbonui.util.various_unsorted import SortListOfTuples, GetDesktopObject
      8 import log
      9 import blue
     10 import localization
     11 from carbonui.uicore import uicore
     12 from carbonui.window.settings import GetRegisteredState
     13 
     14 class RegistryHandler(object):
     15     _focus = None
     16     toggleState = None
     17 
     18     def __init__(self, *args, **kwds):
     19         self.PrimeHandler()
     20 
     21     def PrimeHandler(self):
     22         self.modals = []
     23         self.windows = []
     24         self.stacks = []
     25         self.control_blockers = set()
     26         self._blockConfirm = 0
     27         self.windowsActiveTimes = {}
     28         self._activeWindow = None
     29 
     30     def RequestControl(self, requester):
     31         self.control_blockers.add(requester)
     32 
     33     def ReleaseControl(self, requester):
     34         if requester in self.control_blockers:
     35             self.control_blockers.remove(requester)
     36 
     37     def HasControl(self):
     38         return not self.control_blockers
     39 
     40     def RegisterWindow(self, wnd):
     41         if wnd not in self.windows:
     42             self.windows.append(wnd)
     43 
     44     def UnregisterWindow(self, wnd):
     45         if wnd in self.windows:
     46             self.windows.remove(wnd)
     47             self.windowsActiveTimes.pop(wnd.windowID, None)
     48 
     49     def GetWindows(self):
     50         return self.windows
     51 
     52     def GetWindow(self, windowID, windowInstanceID = None):
     53         if not windowID or isinstance(windowID, tuple):
     54             return
     55         for wnd in self.GetWindows():
     56             windowIDMatches = str(getattr(wnd, 'windowID', wnd.name)).lower() == windowID.lower()
     57             if not windowInstanceID and windowIDMatches:
     58                 return wnd
     59             if windowInstanceID:
     60                 windowInstanceIDMatches = wnd.windowInstanceID == windowInstanceID
     61                 if windowIDMatches and windowInstanceIDMatches:
     62                     return wnd
     63                 continue
     64 
     65     def GetWindowByClass(self, windowClass):
     66         for window in self.GetWindows():
     67             if isinstance(window, windowClass) and not window.destroyed:
     68                 return window
     69 
     70     def GetWindowsByClass(self, windowClass):
     71         return [ wnd for wnd in self.GetWindows() if isinstance(wnd, windowClass) and not wnd.destroyed ]
     72 
     73     def GetWindowByClassAndName(self, windowClass, windowName):
     74         for window in self.GetWindows():
     75             if isinstance(window, windowClass) and not window.destroyed and window.name == windowName:
     76                 return window
     77 
     78     def GetStack(self, stackID, stackClass = None, useDefaultPos = False):
     79         if stackID.startswith('windowStack_'):
     80             stackName = stackID
     81         else:
     82             stackName = 'windowStack_%s' % stackID
     83         stack = self.GetWindow(stackName)
     84         if stack is not None and not stack.closing:
     85             return stack
     86         return stackClass.Open(windowID=stackID, parent=uicore.layer.main, useDefaultPos=useDefaultPos)
     87 
     88     def GetTopLevelWindowAboveItem(self, item):
     89         checkPar = item.parent
     90         while checkPar:
     91             if self.IsTopLevelWindow(checkPar):
     92                 return checkPar
     93             if checkPar.parent:
     94                 checkPar = checkPar.parent
     95             else:
     96                 break
     97 
     98         return uicore.desktop
     99 
    100     def IsTopLevelWindow(self, item):
    101         return getattr(item, 'isTopLevelWindow', False)
    102 
    103     def IsWindow(self, item):
    104         from carbonui.control.window import Window
    105         return isinstance(item, Window)
    106 
    107     def IsWindowStack(self, item):
    108         from carbonui.window.stack import WindowStack
    109         return isinstance(item, WindowStack)
    110 
    111     def GetValidWindows(self, getModals = 0, floatingOnly = False, getHidden = 0):
    112         validWnds = []
    113         for wnd in self.GetWindows():
    114             if not self.IsWindow(wnd) or wnd.stacked or getattr(wnd, '_changing', 0):
    115                 continue
    116             if not getHidden and not wnd.IsVisible():
    117                 continue
    118             if not getModals and (getattr(wnd, 'isModal', 0) or getattr(wnd, 'isDialog', 0)):
    119                 continue
    120             if floatingOnly and wnd.GetAlign() != uiconst.RELATIVE:
    121                 continue
    122             if getattr(wnd, 'parent', None) is None:
    123                 log.LogError("Window without parent!; that shouldn't be possible. Window: %s" % repr(wnd))
    124                 print("Window without parent!; that shouldn't be possible. Window: %s" % repr(wnd), wnd.name)
    125                 continue
    126             validWnds.append(wnd)
    127 
    128         return validWnds
    129 
    130     def GetModalWindow(self, exclude = None):
    131         if self.modals:
    132             mdl = self.modals[-1]
    133             if mdl is None or mdl.destroyed or exclude and mdl == exclude:
    134                 self.modals.remove(mdl)
    135                 return self.GetModalWindow()
    136             return mdl
    137         else:
    138             return
    139 
    140     def IsModalWindowOpen(self):
    141         return bool(self.GetModalWindow())
    142 
    143     def AddModalWindow(self, wnd, fillOpacity = uiconst.DEFAULT_MODAL_OPACITY, sceneSaturation = uiconst.DEFAULT_MODAL_SCENE_SATURATION):
    144         sceneMan = sm.GetService('sceneManager')
    145         sceneMan.Saturate(duration=0.3, saturateLevel=sceneSaturation)
    146         sm.GetService('loading').FadeIn(time=300.0, color=(0,
    147          0,
    148          0,
    149          fillOpacity), sleep=False, owner=wnd)
    150         if wnd in self.modals:
    151             self.RemoveModalWindow(wnd)
    152         self.modals.append(wnd)
    153 
    154     def RemoveModalWindow(self, wnd):
    155         if wnd in self.modals:
    156             self.modals.remove(wnd)
    157         sceneMan = sm.GetService('sceneManager')
    158         sm.GetService('loading').FadeOut(time=300.0, sleep=False, owner=wnd)
    159         if not self.modals:
    160             sceneMan.Saturate(0.3, 1.0)
    161 
    162     def GetActiveStackOrWindow(self, *args):
    163         all = self.GetValidWindows()
    164         active = self.GetActive()
    165         if active:
    166             for each in all:
    167                 if each is active:
    168                     return each
    169                 if active.IsUnder(each):
    170                     return each
    171 
    172     def _GetDerivedFocusItem(self, item):
    173         while item and not getattr(item, 'isTabStop', False):
    174             if self.IsTopLevelWindow(item):
    175                 stackWnd = None
    176                 current, tabstops = None, []
    177                 if self.IsWindowStack(item):
    178                     stackWnd = item.GetActiveWindow()
    179                 current, tabstops = self.CrawlForTabstops(stackWnd or item)
    180                 if current:
    181                     item = current
    182                     break
    183                 elif tabstops:
    184                     item = tabstops[0]
    185                     break
    186             if self.IsTopLevelWindow(item):
    187                 break
    188             if not hasattr(item, 'parent') or item == uicore.desktop:
    189                 break
    190             item = item.parent
    191 
    192         return item
    193 
    194     def SetFocus(self, item):
    195         if item:
    196             desktop = GetDesktopObject(item)
    197             if desktop and not getattr(desktop, 'doesTakeFocus', True):
    198                 return
    199         focus = self._GetDerivedFocusItem(item)
    200         oldFocus = self.GetFocus()
    201         if focus:
    202             if self.IsTopLevelWindow(focus):
    203                 wndAbove = focus
    204             else:
    205                 wndAbove = self.GetTopLevelWindowAboveItem(focus)
    206             focus.SetFocus()
    207             self._SetActiveWindow(wndAbove)
    208             self._focus = focus
    209             self.RegisterFocusItem(focus)
    210         else:
    211             self._focus = None
    212             self._SetActiveWindow(uicore.desktop)
    213         if oldFocus != focus and hasattr(oldFocus, 'OnKillFocus'):
    214             oldFocus.OnKillFocus()
    215         if hasattr(focus, 'OnSetFocus') and not focus.destroyed:
    216             focus.OnSetFocus()
    217 
    218     def _SetActiveWindow(self, wnd = None):
    219         while not self.IsTopLevelWindow(wnd):
    220             if wnd == uicore.desktop:
    221                 break
    222             wnd = wnd.parent
    223 
    224         if wnd == self.GetActive():
    225             return
    226         self._TriggerInactiveEvents()
    227         wnd = self._GetDerivedWindowToActivate(wnd)
    228         self._activeWindow = weakref.ref(wnd)
    229         if self.IsWindow(wnd):
    230             self.windowsActiveTimes[wnd.windowID] = blue.os.GetWallclockTime()
    231             if wnd.stacked:
    232                 wnd.stack.SetOrder(0)
    233             elif wnd.parent and wnd.align == uiconst.TOPLEFT:
    234                 wnd.SetOrder(0)
    235         if hasattr(wnd, 'SetActive'):
    236             wnd.SetActive()
    237             sm.ScatterEvent('OnWindowSetActive', wnd)
    238 
    239     def _GetDerivedWindowToActivate(self, wnd):
    240         if self.IsWindowStack(wnd):
    241             wnd = wnd.GetActiveWindow()
    242         if not wnd or wnd.destroyed:
    243             return uicore.desktop
    244         else:
    245             return wnd
    246 
    247     def _TriggerInactiveEvents(self):
    248         activeWnd = self.GetActive()
    249         if not activeWnd:
    250             return
    251         if hasattr(activeWnd, 'OnSetInactive'):
    252             activeWnd.OnSetInactive()
    253         sm.ScatterEvent('OnWindowSetInactive', activeWnd)
    254 
    255     def RegisterFocusItem(self, item):
    256         if item and not item.destroyed and item != uicore.desktop:
    257             wndAbove = self.GetTopLevelWindowAboveItem(item)
    258             if wndAbove and wndAbove is not uicore.desktop:
    259                 tabstopGroupsFromTop, tabstopsFromTop = FindTabStopGroupsAndTabstops(wndAbove)
    260                 for tabstop in tabstopsFromTop:
    261                     setattr(tabstop, 'hasFocus', 0)
    262 
    263                 setattr(item, 'hasFocus', 1)
    264 
    265     def GetFocus(self, active = None):
    266         focus = self._focus
    267         if focus and not focus.destroyed:
    268             return focus
    269 
    270     def GetActive(self):
    271         activeWnd = self._activeWindow() if self._activeWindow else None
    272         if activeWnd and not activeWnd.destroyed:
    273             return activeWnd
    274 
    275     def FindFocus(self, browse = 0):
    276         modal = self.GetModalWindow()
    277         if modal:
    278             active = modal
    279         else:
    280             active = self.GetActive()
    281         focus = self.GetFocus()
    282         if active is None:
    283             active = uicore.desktop
    284         if focus and hasattr(focus, 'CheckFocusChange'):
    285             usedFocusChange = focus.CheckFocusChange(browse)
    286             if usedFocusChange:
    287                 return
    288         if focus and focus.IsUnder(active) and focus.IsVisible() and not browse:
    289             uthread.new(self.SetFocus, focus)
    290             return
    291         tabstops = []
    292         if active:
    293             current, tabstops = self.CrawlForTabstops(active)
    294         if browse and len(tabstops) > 1:
    295             current = current or focus
    296             idx = 0
    297             if current in tabstops:
    298                 idx = browse + tabstops.index(current)
    299             if idx < 0:
    300                 idx = len(tabstops) - 1
    301             elif idx >= len(tabstops):
    302                 idx = 0
    303             self.SetFocus(tabstops[idx])
    304             return
    305         if len(tabstops) and focus != tabstops[0]:
    306             self.SetFocus(tabstops[0])
    307             return
    308 
    309     def CrawlForTabstops(self, fromwhere):
    310         sorted = []
    311         current = []
    312         done = []
    313         tabstopGroupsFromTop, tabstopsFromTop = FindTabStopGroupsAndTabstops(fromwhere)
    314         for tabstopgroup in tabstopGroupsFromTop:
    315             tabstops = [ wnd for wnd in tabstopgroup.FindByInstance(Container) if getattr(wnd, 'isTabStop', False) ]
    316             gAbs = tabstopgroup.GetAbsolute()
    317             for tabstop in tabstops:
    318                 if tabstop.IsClickable():
    319                     if getattr(tabstop, 'hasFocus', None):
    320                         current.append(tabstop)
    321                     tAbs = tabstop.GetAbsolute()
    322                     sorted.append(([gAbs[1],
    323                       gAbs[0],
    324                       tAbs[1],
    325                       tAbs[0]], tabstop))
    326                     done.append(tabstop)
    327 
    328         for tabstop in tabstopsFromTop:
    329             if tabstop not in done and tabstop.IsClickable():
    330                 if getattr(tabstop, 'hasFocus', None) == 1:
    331                     current.append(tabstop)
    332                 tAbs = tabstop.GetAbsolute()
    333                 sorted.append(([tAbs[1],
    334                   tAbs[0],
    335                   tAbs[1],
    336                   tAbs[0]], tabstop))
    337                 done.append(tabstop)
    338 
    339         if current:
    340             current = current[0]
    341         return (current, SortListOfTuples(sorted))
    342 
    343     def GetModalResult(self, default, funcname = 'btn_default'):
    344         result = None
    345         modal = self.GetModalWindow()
    346         if modal:
    347             result = default
    348             for wndType in ('trinity.Tr2Sprite2dContainer', 'trinity.Tr2Sprite2d'):
    349                 for c in modal.Find(wndType):
    350                     if getattr(c, funcname, 0):
    351                         result = c.btn_modalresult
    352                         break
    353 
    354         return result
    355 
    356     def BlockConfirm(self):
    357         self._blockConfirm = 1
    358 
    359     def Confirm(self, starter = None):
    360         if self._blockConfirm:
    361             self._blockConfirm = 0
    362             return False
    363         if uicore.imeHandler and uicore.imeHandler.IsVisible():
    364             return
    365         focus = self.GetFocus()
    366         active = self.GetActive()
    367         modal = self.GetModalWindow()
    368         if modal:
    369             if focus and focus.IsUnder(modal):
    370                 if hasattr(focus, 'Confirm') and focus != starter:
    371                     return uthread.new(focus.Confirm)
    372             if hasattr(modal, 'Confirm') and modal != starter:
    373                 if not getattr(modal, 'blockconfirmonreturn', 0) or uicore.uilib.Key(uiconst.VK_CONTROL):
    374                     modal.Confirm()
    375                     return True
    376             else:
    377                 result = self.GetModalResult(uiconst.ID_OK)
    378                 modal.SetModalResult(result)
    379                 return True
    380             return False
    381         if getattr(focus, 'Confirm', None) and focus != starter:
    382             uthread.new(focus.Confirm)
    383             return True
    384         if hasattr(active, 'IsCurrentDialog') and active.IsCurrentDialog():
    385             active.SetModalResult(uiconst.ID_OK)
    386             return True
    387         if getattr(active, 'Confirm', None) and active != starter:
    388             uthread.new(active.Confirm)
    389             return True
    390         if focus and focus.HasEventHandler('OnClick'):
    391             uthread.new(focus.OnClick, focus)
    392             return True
    393         if focus:
    394             searchFrom = self.GetTopLevelWindowAboveItem(focus)
    395         else:
    396             searchFrom = uicore.desktop
    397         if searchFrom:
    398             wnds = [ w for w in searchFrom.Find('trinity.Tr2Sprite2dContainer') + searchFrom.Find('trinity.Tr2Sprite2d') if getattr(w, 'btn_default', 0) == 1 ]
    399             if len(wnds):
    400                 for wnd in wnds:
    401                     if starter and starter == wnd:
    402                         continue
    403                     if wnd.IsVisible():
    404                         if wnd.HasEventHandler('OnClick'):
    405                             uthread.new(wnd.OnClick, wnd)
    406                         return True
    407 
    408         return False
    409 
    410     def AddToListGroup(self, listID_groupID, add):
    411         listID = unicode(listID_groupID[0])
    412         groupID = unicode(listID_groupID[1])
    413         groups = self.GetAllGroups()
    414         if listID in groups and groupID in groups[listID] and 'groupItems' in groups[listID][groupID] and add not in groups[listID][groupID]['groupItems']:
    415             groups[listID][groupID]['groupItems'].append(add)
    416         try:
    417             if hasattr(settings, 'char'):
    418                 settings.char.WriteToDisk()
    419         except:
    420             print('Failed to write settings.char to disk')
    421 
    422     def RemoveFromListGroup(self, listID_groupID, rem):
    423         listID = unicode(listID_groupID[0])
    424         groupID = unicode(listID_groupID[1])
    425         groups = self.GetAllGroups()
    426         if listID in groups and groupID in groups[listID] and 'groupItems' in groups[listID][groupID] and rem in groups[listID][groupID]['groupItems']:
    427             groups[listID][groupID]['groupItems'].remove(rem)
    428         self.ReloadGroupWindow(listID_groupID)
    429         try:
    430             if hasattr(settings, 'char'):
    431                 settings.char.WriteToDisk()
    432         except:
    433             print('Failed to write settings.char to disk')
    434 
    435     def ReloadGroupWindow(self, listID_groupID):
    436         wnd = self.GetWindow(unicode(listID_groupID))
    437         if wnd:
    438             wnd.LoadContent()
    439 
    440     def AddListGroup(self, listID, listgroupName = None):
    441         from eve.client.script.ui.util.utilWindows import NamePopup
    442         groupname = NamePopup(localization.GetByLabel('/Carbon/UI/Common/TypeName'), localization.GetByLabel('/Carbon/UI/Common/TypeNameForFolder'))
    443         if not groupname:
    444             return
    445         if isinstance(groupname, dict):
    446             groupname = groupname['name']
    447         id = (listID, listgroupName or str(blue.os.GetWallclockTime()))
    448         group = self.GetListGroup(id)
    449         group['label'] = groupname
    450         group['id'] = id
    451         group['groupItems'] = []
    452         group['open'] = 0
    453         return group
    454 
    455     def GetLockedGroup(self, listID, listgroupName, label, openState = 0):
    456         id = (listID, listgroupName)
    457         group = self.GetListGroup(id)
    458         group['label'] = label
    459         group['id'] = id
    460         group['groupItems'] = []
    461         group['open'] = openState
    462         group['state'] = 'locked'
    463         return group
    464 
    465     def GetListGroup(self, listID_groupID):
    466         listID = unicode(listID_groupID[0])
    467         groupID = unicode(listID_groupID[1])
    468         if groupID in self.GetListGroups(listID):
    469             return self.GetListGroups(listID)[groupID]
    470         self.GetListGroups(listID)[groupID] = {}
    471         return self.GetListGroup(listID_groupID)
    472 
    473     def GetListGroups(self, listID):
    474         listID = unicode(listID)
    475         groups = self.GetAllGroups()
    476         if listID in groups:
    477             return groups[listID]
    478         groups[listID] = {}
    479         return self.GetListGroups(listID)
    480 
    481     def ChangeListGroupLabel(self, listID_groupID, newlabel):
    482         group = self.GetListGroup(listID_groupID)
    483         group['label'] = newlabel
    484         try:
    485             if hasattr(settings, 'char'):
    486                 settings.char.WriteToDisk()
    487         except:
    488             print('Failed to write settings.char to disk')
    489 
    490     def GetAllGroups(self):
    491         try:
    492             if hasattr(settings, 'char'):
    493                 if settings.char.ui.Get('listgroups', None) is None:
    494                     settings.char.ui.Set('listgroups', {})
    495                 return settings.char.ui.Get('listgroups', {})
    496         except:
    497             print('Failed to fetch group settings')
    498 
    499         return {}
    500 
    501     def DeleteListGroup(self, listID_groupID):
    502         listID = unicode(listID_groupID[0])
    503         groupID = unicode(listID_groupID[1])
    504         groups = self.GetAllGroups()
    505         if listID in groups and groupID in groups[listID]:
    506             del groups[listID][groupID]
    507         try:
    508             if hasattr(settings, 'char'):
    509                 settings.char.WriteToDisk()
    510         except:
    511             print('Failed to write settings.char to disk')
    512 
    513     def GetGroupIDFromItemID(self, listID, itemID):
    514         groups = self.GetAllGroups()
    515         if listID in groups:
    516             for groupID in groups[listID].iterkeys():
    517                 if itemID in groups[listID][groupID]['groupItems']:
    518                     return (listID, groupID)
    519 
    520     def GetListGroupOpenState(self, listID_groupID, default = False):
    521         listID = unicode(listID_groupID[0])
    522         groupID = unicode(listID_groupID[1])
    523         groups = self.GetAllGroups()
    524         return groups.get(listID, {}).get(groupID, {}).get('open', default)
    525 
    526     def SetListGroupOpenState(self, listID_groupID, state):
    527         listID = unicode(listID_groupID[0])
    528         groupID = unicode(listID_groupID[1])
    529         groups = self.GetAllGroups()
    530         if listID not in groups:
    531             groups[listID] = {}
    532         if groupID not in groups[listID]:
    533             groups[listID][groupID] = {}
    534         if listID in groups and groupID in groups[listID]:
    535             groups[listID][groupID]['open'] = state
    536         try:
    537             if hasattr(settings, 'char'):
    538                 settings.char.WriteToDisk()
    539         except:
    540             print('Failed to write settings.char to disk')
    541 
    542     def ToggleCollapseAllWindows(self):
    543         if self.toggleState is None:
    544             self.toggleState = settings.char.windows.Get('windowToggleState', [])
    545         if self.toggleState:
    546 
    547             def RegisterAsNotCollapsed(myWndID):
    548                 allWnds = settings.char.windows.Get('collapsedWindows', {})
    549                 allWnds[myWndID] = False
    550                 settings.char.windows.Set('collapsedWindows', allWnds)
    551 
    552             for windowID in self.toggleState:
    553                 wnd = self.GetWindow(windowID)
    554                 if wnd and wnd.IsCollapsed():
    555                     wnd.Expand()
    556                 else:
    557                     wID = windowID
    558                     if GetRegisteredState(wID, 'collapsed'):
    559                         RegisterAsNotCollapsed(wID)
    560 
    561             self.toggleState = []
    562             settings.char.windows.Set('windowToggleState', self.toggleState)
    563             return
    564         state = []
    565         wnds = self.GetValidWindows(floatingOnly=True)
    566         for wnd in wnds:
    567             if not getattr(wnd, 'windowID', None):
    568                 continue
    569             windowID = wnd.windowID
    570             if not wnd.IsCollapsed():
    571                 wnd.Collapse()
    572                 state.append(windowID)
    573 
    574         if not state:
    575             for wnd in wnds:
    576                 if wnd.IsCollapsed():
    577                     wnd.Expand()
    578 
    579         self.toggleState = state
    580         settings.char.windows.Set('windowToggleState', self.toggleState)
    581 
    582     def ResetToggleStateForWnd(self, windowID):
    583         if self.toggleState and windowID in self.toggleState:
    584             self.toggleState.remove(windowID)
    585             settings.char.windows.Set('windowToggleState', self.toggleState)
    586 
    587 
    588 def FindTabStopGroupsAndTabstops(fromwhere):
    589     tabstopgroups = set()
    590     tabstops = set()
    591     for wnd in fromwhere.FindByInstance(Container):
    592         if getattr(wnd, 'isTabOrderGroup', None) and wnd.IsVisible():
    593             tabstopgroups.add(wnd)
    594         if getattr(wnd, 'isTabStop', False):
    595             tabstops.add(wnd)
    596 
    597     return (tabstopgroups, tabstops)