default.py (12815B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\window\control\default.py 2 import eveicon 3 import localization 4 import signals 5 from carbonui import uiconst 6 from carbonui.button.menu import MenuButtonIcon 7 from carbonui.control.buttonIcon import ButtonIcon 8 from carbonui.control.contextMenu.menuData import MenuData 9 from carbonui.primitives.base import Base 10 from carbonui.primitives.containerAutoSize import ContainerAutoSize 11 from carbonui.window.control.action import WindowAction, WindowActionImportance, WindowMenuAction 12 13 class WindowControlsBase(Base): 14 15 def __init__(self, on_reserved_width_changed = None, *args, **kwargs): 16 self._on_reserved_width_changed = signals.Signal('{}.on_reserved_width_changed'.format(self.__class__.__name__)) 17 super(WindowControlsBase, self).__init__(*args, **kwargs) 18 self.layout() 19 if on_reserved_width_changed is not None: 20 self._on_reserved_width_changed.connect(on_reserved_width_changed) 21 22 def layout(self): 23 pass 24 25 @property 26 def reserved_width(self): 27 return self.width 28 29 @property 30 def on_reserved_width_changed(self): 31 return self._on_reserved_width_changed 32 33 def update(self): 34 pass 35 36 def _OnClose(self, *args, **kw): 37 self._on_reserved_width_changed.clear() 38 super(WindowControlsBase, self)._OnClose() 39 40 41 class DefaultWindowControls(WindowControlsBase, ContainerAutoSize): 42 OFFSET_LEFT = -4 43 44 def __init__(self, window, actions, get_menu = None, get_link_data = None, menu_unique_name = None, parent = None, align = uiconst.CENTERRIGHT, on_reserved_width_changed = None, display = True): 45 self._window = window 46 super(DefaultWindowControls, self).__init__(parent=parent, align=align, callback=self._on_size_changed, only_use_callback_when_size_changes=True, on_reserved_width_changed=on_reserved_width_changed) 47 self.display = display 48 _, _, content_pad_right, _ = window.content_padding 49 self._window_controls = WindowControls(parent=self, align=uiconst.TOPRIGHT, left=content_pad_right + self.OFFSET_LEFT, actions=actions, get_menu=get_menu, get_menu_title=self._get_menu_title, get_link_data=get_link_data, menu_unique_name=menu_unique_name) 50 window.on_content_padding_changed.connect(self._on_window_content_padding_changed) 51 52 def _get_menu_title(self): 53 if self._window.compact or self._window.is_stack: 54 return self._window.caption 55 56 @property 57 def reserved_width(self): 58 window_controls_width, _ = self._window_controls.GetAbsoluteSize() 59 return self._window_controls.left * 2 + window_controls_width 60 61 def update(self): 62 self._window_controls.update() 63 64 def _on_window_content_padding_changed(self, window): 65 _, _, content_pad_right, _ = window.content_padding 66 self._window_controls.left = content_pad_right + self.OFFSET_LEFT 67 68 def _on_size_changed(self): 69 self.on_reserved_width_changed() 70 71 def Close(self): 72 self._window.on_content_padding_changed.disconnect(self._on_window_content_padding_changed) 73 self._window = None 74 super(DefaultWindowControls, self).Close() 75 76 77 class WindowControls(ContainerAutoSize): 78 BUTTON_SIZE = 24 79 80 def __init__(self, actions, get_menu = None, get_menu_title = None, get_link_data = None, menu_unique_name = None, parent = None, align = uiconst.TOPLEFT, left = 0): 81 self._actions = actions 82 self._action_order = {} 83 self._get_menu = get_menu 84 self._get_menu_title = get_menu_title 85 self._get_link_data = get_link_data 86 self._menu_button = None 87 self._share_link_button = None 88 self._button_cont = None 89 self._menu_unique_name = menu_unique_name 90 super(WindowControls, self).__init__(parent=parent, align=align, alignMode=uiconst.TORIGHT, left=left, height=self.BUTTON_SIZE) 91 self._button_cont = ContainerAutoSize(parent=self, align=uiconst.TORIGHT, alignMode=uiconst.TORIGHT) 92 self._menu_cont = ContainerAutoSize(parent=self, align=uiconst.TORIGHT) 93 self._content_button_cont = ContainerAutoSize(parent=self, align=uiconst.TORIGHT, alignMode=uiconst.TORIGHT) 94 for i, action in enumerate(self._actions): 95 self._action_order[action] = i 96 if action.available and action.importance == WindowActionImportance.core: 97 self._create_action_button(action) 98 if action.available and action.importance == WindowActionImportance.content: 99 self._create_content_action_button(action) 100 action.on_available_changed.connect(self._on_available_changed) 101 action.on_importance_changed.connect(self._on_importance_changed) 102 103 self.update() 104 105 def update(self): 106 for action in self._actions: 107 action.update() 108 109 self._update_more_menu_button() 110 self._update_share_link_button() 111 112 def _update_more_menu_button(self): 113 if self._has_more_menu_options(): 114 self._show_menu_button() 115 else: 116 self._hide_menu_button() 117 118 def _has_more_menu_options(self): 119 for action in self._actions: 120 if action.importance == WindowActionImportance.extra and action.available: 121 return True 122 123 if self._get_menu is not None: 124 menu = self._get_menu() 125 return len(menu) > 0 126 return False 127 128 def _show_menu_button(self): 129 if self._menu_button is None: 130 self._create_menu_button() 131 else: 132 self._menu_button.display = True 133 134 def _hide_menu_button(self): 135 if self._menu_button is not None: 136 self._menu_button.display = False 137 138 def _create_menu_button(self): 139 if self._menu_button is None: 140 self._menu_button = MenuButtonIcon(parent=self._menu_cont, align=uiconst.CENTER, get_menu_func=self._get_menu_entries, hint=localization.GetByLabel('UI/Common/More'), uniqueUiName=self._menu_unique_name) 141 142 def _update_share_link_button(self): 143 if self._has_link_data(): 144 self._show_share_link() 145 else: 146 self._hide_share_link() 147 148 def _has_link_data(self): 149 if self._get_link_data is not None: 150 data = self._get_link_data() 151 return data is not None 152 return False 153 154 def _show_share_link(self): 155 if self._share_link_button is None: 156 self._create_share_link_button() 157 else: 158 self._share_link_button.display = True 159 160 def _hide_share_link(self): 161 if self._share_link_button is not None: 162 self._share_link_button.display = False 163 164 def _create_share_link_button(self): 165 if self._share_link_button is None: 166 self._share_link_button = ButtonIcon(name='link_button', parent=ContainerAutoSize(parent=self, align=uiconst.TORIGHT), align=uiconst.CENTER, width=24, height=24, iconSize=16, texturePath=eveicon.link, hint=localization.GetByLabel('UI/Common/DragToShareLinkWindow')) 167 self._share_link_button.isDragObject = True 168 self._share_link_button.GetDragData = self._get_link_data 169 170 def _create_action_button(self, action, index = -1): 171 WindowControlButton(parent=self._button_cont, align=uiconst.TORIGHT, index=index, action=action, size=self.BUTTON_SIZE) 172 173 def _create_content_action_button(self, action, index = -1): 174 WindowControlButton(parent=self._content_button_cont, align=uiconst.TORIGHT, index=index, action=action, size=self.BUTTON_SIZE) 175 176 def _add_action_button(self, action): 177 my_order = self._action_order[action] 178 for i, button in enumerate(self._button_cont.children): 179 if button.action == action: 180 break 181 order = self._action_order[button.action] 182 if my_order < order: 183 self._create_action_button(action, index=i) 184 break 185 else: 186 self._create_action_button(action) 187 188 def _remove_action_button(self, action): 189 for button in self._button_cont.children: 190 if button.action == action: 191 button.Close() 192 return 193 194 for button in self._content_button_cont.children: 195 if button.action == action: 196 button.Close() 197 return 198 199 def _add_content_action_button(self, action): 200 my_order = self._action_order[action] 201 for i, button in enumerate(self._content_button_cont.children): 202 if button.action == action: 203 break 204 order = self._action_order[button.action] 205 if my_order < order: 206 self._create_content_action_button(action, index=i) 207 break 208 else: 209 self._create_content_action_button(action) 210 211 def _get_menu_entries(self): 212 menu = MenuData() 213 if self._get_menu_title: 214 menu_title = self._get_menu_title() 215 if menu_title: 216 menu.AddCaption(menu_title) 217 for action in self._actions: 218 if isinstance(action, WindowAction): 219 self._add_action_to_menu(action, menu) 220 221 menu.AddSeparator() 222 for action in self._actions: 223 if not isinstance(action, WindowAction): 224 self._add_action_to_menu(action, menu) 225 226 extra_options = [] 227 if self._get_menu is not None: 228 extra_options = self._get_menu() 229 if len(menu) > 0 and len(extra_options) > 0: 230 menu.AddSeparator() 231 menu += extra_options 232 return menu 233 234 def _add_action_to_menu(self, action, menu): 235 if action.available and action.importance == WindowActionImportance.extra: 236 menu.AddEntry(text=action.label, func=action.execute, texturePath=action.icon) 237 238 def _on_available_changed(self, action): 239 if action.available and action.importance == WindowActionImportance.core: 240 self._add_action_button(action) 241 elif action.available and action.importance == WindowActionImportance.content: 242 self._add_content_action_button(action) 243 else: 244 self._remove_action_button(action) 245 self._update_more_menu_button() 246 247 def _on_importance_changed(self, action): 248 if action.importance == WindowActionImportance.core: 249 self._add_action_button(action) 250 elif action.importance == WindowActionImportance.content: 251 self._add_content_action_button(action) 252 else: 253 self._remove_action_button(action) 254 self._update_more_menu_button() 255 256 def _OnClose(self, *args, **kw): 257 for action in self._actions: 258 action.on_available_changed.disconnect(self._on_available_changed) 259 260 super(WindowControls, self)._OnClose() 261 262 263 class WindowControlButton(ContainerAutoSize): 264 265 def __init__(self, action, parent = None, align = uiconst.TOPLEFT, index = -1, size = 24, icon_size = 16): 266 self._action = action 267 self._size = size 268 self._icon_size = size 269 super(WindowControlButton, self).__init__(parent=parent, align=align, alignMode=uiconst.CENTER, idx=index) 270 if isinstance(action, WindowMenuAction): 271 self._button = MenuButtonIcon(name=action.ui_name, parent=self, align=uiconst.CENTER, width=size, height=size, texturePath=self._resolve_icon(action.icon), iconSize=icon_size, get_menu_func=action.execute, hint=action.label) 272 else: 273 self._button = ButtonIcon(name=action.ui_name, parent=self, align=uiconst.CENTER, width=size, height=size, texturePath=self._resolve_icon(action.icon), iconSize=icon_size, func=action.execute, hint=action.label) 274 self._on_enabled_changed(action) 275 action.on_enabled_changed.connect(self._on_enabled_changed) 276 action.on_icon_changed.connect(self._on_icon_changed) 277 action.on_label_changed.connect(self._on_label_changed) 278 279 @property 280 def action(self): 281 return self._action 282 283 def _on_enabled_changed(self, action): 284 if action.enabled: 285 self._button.Enable() 286 else: 287 self._button.Disable() 288 289 def _resolve_icon(self, icon): 290 if isinstance(icon, eveicon.IconData): 291 return icon.resolve(self._icon_size) 292 else: 293 return icon 294 295 def _on_icon_changed(self, action): 296 self._button.SetTexturePath(self._resolve_icon(action.icon)) 297 298 def _on_label_changed(self, action): 299 self._button.hint = action.label 300 301 def Close(self): 302 self._action.on_enabled_changed.disconnect(self._on_enabled_changed) 303 self._action.on_icon_changed.disconnect(self._on_icon_changed) 304 self._action.on_label_changed.disconnect(self._on_label_changed) 305 super(WindowControlButton, self).Close()