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

layout.py (6122B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\window\layout.py
      2 import mathext
      3 from carbonui.uicore import uicore
      4 from carbonui.window.snap import SNAP_DISTANCE
      5 from functools import reduce
      6 
      7 class AnchorSide(object):
      8     LEFT = 1
      9     TOP = 2
     10     RIGHT = 3
     11     BOTTOM = 4
     12     HORIZONTAL = 5
     13     VERTICAL = 6
     14 
     15 
     16 class Anchor(object):
     17 
     18     def __init__(self, side, offset):
     19         self.side = side
     20         self.offset = offset
     21 
     22 
     23 class Rect(object):
     24 
     25     def __init__(self, x, y, width, height):
     26         self.x = x
     27         self.y = y
     28         self.width = width
     29         self.height = height
     30 
     31     @property
     32     def left(self):
     33         return self.x
     34 
     35     @property
     36     def top(self):
     37         return self.y
     38 
     39     @property
     40     def right(self):
     41         return self.x + self.width
     42 
     43     @property
     44     def bottom(self):
     45         return self.y + self.height
     46 
     47     @classmethod
     48     def from_element(cls, element):
     49         left, top, width, height = element.GetAbsolute()
     50         return cls(left, top, width, height)
     51 
     52     @classmethod
     53     def from_elements(cls, elements):
     54         return reduce(lambda a, b: a.merge(b), [ cls.from_element(e) for e in elements ])
     55 
     56     def merge(self, other):
     57         left = min(self.x, other.x)
     58         top = min(self.y, other.y)
     59         right = max(self.right, other.right)
     60         bottom = max(self.bottom, other.bottom)
     61         return Rect(x=left, y=top, width=right - left, height=bottom - top)
     62 
     63 
     64 class AnchoredWindowGroup(object):
     65 
     66     def __init__(self, anchors, windows, boundaries):
     67         self.anchors = anchors
     68         self.windows = windows
     69         self.boundaries = boundaries
     70 
     71 
     72 def capture_desktop_window_layout():
     73     all_windows = uicore.registry.GetValidWindows(getModals=True, floatingOnly=True, getHidden=True)
     74     desktop_rect = Rect.from_element(uicore.desktop)
     75     window_groups = []
     76     processed_windows = set()
     77     for window in all_windows:
     78         if window in processed_windows:
     79             continue
     80         connected_windows = window.FindConnectingWindows(validWnds=all_windows, fullSideOnly=False)
     81         group_rect = Rect.from_elements(connected_windows)
     82         group = AnchoredWindowGroup(anchors=_get_window_desktop_anchors(window_group_rect=group_rect, desktop_rect=desktop_rect), windows=connected_windows, boundaries=group_rect)
     83         window_groups.append(group)
     84         processed_windows.update(connected_windows)
     85 
     86     return window_groups
     87 
     88 
     89 CENTER_THRESHOLD = 32
     90 
     91 def _get_window_desktop_anchors(window_group_rect, desktop_rect):
     92     anchors = []
     93     left_offset, right_offset = _get_side_offset()
     94     margin_left = window_group_rect.left - desktop_rect.left
     95     margin_right = desktop_rect.right - window_group_rect.right
     96     if margin_left in (0, left_offset, left_offset + SNAP_DISTANCE):
     97         anchors.append(Anchor(side=AnchorSide.LEFT, offset=margin_left))
     98     elif margin_right in (0, right_offset, right_offset + SNAP_DISTANCE):
     99         anchors.append(Anchor(side=AnchorSide.RIGHT, offset=margin_right))
    100     elif abs(margin_left - margin_right) < CENTER_THRESHOLD:
    101         anchors.append(Anchor(AnchorSide.HORIZONTAL, offset=0.5))
    102     elif margin_left < margin_right:
    103         anchors.append(Anchor(side=AnchorSide.LEFT, offset=margin_left))
    104     else:
    105         anchors.append(Anchor(side=AnchorSide.RIGHT, offset=margin_right))
    106     margin_top = window_group_rect.top - desktop_rect.top
    107     margin_bottom = desktop_rect.bottom - window_group_rect.bottom
    108     if margin_top in (0, SNAP_DISTANCE):
    109         anchors.append(Anchor(side=AnchorSide.TOP, offset=margin_top))
    110     elif margin_bottom in (0, SNAP_DISTANCE):
    111         anchors.append(Anchor(side=AnchorSide.BOTTOM, offset=margin_bottom))
    112     elif abs(margin_top - margin_bottom) < CENTER_THRESHOLD:
    113         anchors.append(Anchor(AnchorSide.VERTICAL, offset=0.5))
    114     elif margin_top < margin_bottom:
    115         anchors.append(Anchor(side=AnchorSide.TOP, offset=margin_top))
    116     else:
    117         anchors.append(Anchor(side=AnchorSide.BOTTOM, offset=margin_bottom))
    118     return anchors
    119 
    120 
    121 def apply_desktop_window_layout(anchored_window_groups):
    122     for anchored_window_group in anchored_window_groups:
    123         group_rect = anchored_window_group.boundaries
    124         for anchor in anchored_window_group.anchors:
    125             for window in anchored_window_group.windows:
    126                 if anchor.side == AnchorSide.LEFT:
    127                     window.left = min(max(0, uicore.desktop.width - window.width), anchor.offset + (window.left - group_rect.left))
    128                 elif anchor.side == AnchorSide.TOP:
    129                     window.top = min(max(0, uicore.desktop.height - window.height), anchor.offset + (window.top - group_rect.top))
    130                 elif anchor.side == AnchorSide.RIGHT:
    131                     window.left = min(max(0, uicore.desktop.width - window.width), uicore.desktop.width - (anchor.offset + group_rect.width) + (window.left - group_rect.left))
    132                 elif anchor.side == AnchorSide.BOTTOM:
    133                     window.top = max(0, uicore.desktop.height - (anchor.offset + group_rect.height) + (window.top - group_rect.top))
    134                 elif anchor.side == AnchorSide.HORIZONTAL:
    135                     group_half_width = int(round(group_rect.width / 2.0))
    136                     group_center = uicore.desktop.width * anchor.offset
    137                     offset_in_group = window.left - group_rect.left
    138                     window.left = mathext.clamp(value=group_center - group_half_width + offset_in_group, low=0, high=uicore.desktop.width - window.width)
    139                 elif anchor.side == AnchorSide.VERTICAL:
    140                     group_half_height = int(round(group_rect.height / 2.0))
    141                     group_center = uicore.desktop.height * anchor.offset
    142                     offset_in_group = window.top - group_rect.top
    143                     window.top = mathext.clamp(value=group_center - group_half_height + offset_in_group, low=0, high=uicore.desktop.height - window.height)
    144 
    145 
    146 def _get_side_offset():
    147     side_panel_layer = uicore.layer.sidePanels
    148     if side_panel_layer:
    149         return side_panel_layer.GetSideOffset()
    150     return (0, 0)