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)