From 0adabebda9a745966faba8bce987375d992c3528 Mon Sep 17 00:00:00 2001 From: Wurschdhaud Date: Sun, 30 Nov 2025 17:49:17 +0100 Subject: [PATCH 1/3] add store and restore window pos functions --- pyrevitlib/pyrevit/script.py | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pyrevitlib/pyrevit/script.py b/pyrevitlib/pyrevit/script.py index 89f2fcc01..94e114666 100644 --- a/pyrevitlib/pyrevit/script.py +++ b/pyrevitlib/pyrevit/script.py @@ -48,6 +48,7 @@ ICON_MEDIUM = 24 ICON_LARGE = 32 + def get_info(): """Return info on current pyRevit command. @@ -799,3 +800,60 @@ def data_exists(slot_name, this_project=True): file_ext=DATAFEXT, add_cmd_name=False) return os.path.exists(data_file) + + +def restore_window_position(window, command_name=EXEC_PARAMS.command_name): + """ + Restore window position from saved data. + + Args: + window: WPF window instance + command_name: Unique identifier for this window + + Returns: + bool: True if position was restored, False if centered to screen + """ + storage_key = "last_window_position_" + command_name + + try: + pos = load_data(storage_key, this_project=False) + if not pos: + raise Exception("No saved position") + + # Get all screen working areas + all_bounds = [s.WorkingArea for s in framework.Forms.Screen.AllScreens] + x, y = pos.get("Left", 0), pos.get("Top", 0) + + # Check if position is visible on any screen + visible = any( + (b.Left <= x <= b.Right and b.Top <= y <= b.Bottom) for b in all_bounds + ) + + if visible: + window.WindowStartupLocation = ( + framework.Windows.WindowStartupLocation.Manual + ) + window.Left = x + window.Top = y + return True + else: + raise Exception("Position not visible on any screen") + + except Exception: + window.WindowStartupLocation = ( + framework.Windows.WindowStartupLocation.CenterScreen + ) + return False + + +def save_window_position(window, command_name=EXEC_PARAMS.command_name): + """ + Save window position to persistent storage. + + Args: + window: WPF window instance + command_name: Unique identifier for this window + """ + storage_key = "last_window_position_" + command_name + position_data = {"Left": window.Left, "Top": window.Top} + store_data(storage_key, position_data, this_project=False) From 9d43e7cef55d0d9dbe3e09e21130d83a94634981 Mon Sep 17 00:00:00 2001 From: Wurschdhaud Date: Sun, 30 Nov 2025 17:49:34 +0100 Subject: [PATCH 2/3] implement new functions available in lib --- .../3D.pulldown/Measure.pushbutton/script.py | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/3D.pulldown/Measure.pushbutton/script.py b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/3D.pulldown/Measure.pushbutton/script.py index e7403dea6..8c81ecbfc 100644 --- a/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/3D.pulldown/Measure.pushbutton/script.py +++ b/extensions/pyRevitTools.extension/pyRevit.tab/Modify.panel/3D.pulldown/Measure.pushbutton/script.py @@ -3,7 +3,6 @@ from math import pi, atan, sqrt from pyrevit import HOST_APP, revit, forms, script from pyrevit import UI, DB -from pyrevit.framework import System from Autodesk.Revit.Exceptions import InvalidOperationException logger = script.get_logger() @@ -42,8 +41,6 @@ LINE_COLOR_DIAG = DB.ColorWithTransparency(200, 200, 0, 0) # Dark Yellow CUBE_COLOR = DB.ColorWithTransparency(255, 165, 0, 50) # Orange -WINDOW_POSITION = "measure_window_pos" - def calculate_distances(point1, point2): """Calculate dx, dy, dz, diagonal distance, and slope angle between two points. @@ -306,24 +303,7 @@ def __init__(self, xaml_file_name): # Handle window close event self.Closed += self.window_closed - - try: - pos = script.load_data(WINDOW_POSITION, this_project=False) - all_bounds = [s.WorkingArea for s in System.Windows.Forms.Screen.AllScreens] - x, y = pos["Left"], pos["Top"] - visible = any( - (b.Left <= x <= b.Right and b.Top <= y <= b.Bottom) for b in all_bounds - ) - if not visible: - raise Exception - self.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual - self.Left = pos.get("Left", 200) - self.Top = pos.get("Top", 150) - except Exception: - self.WindowStartupLocation = ( - System.Windows.WindowStartupLocation.CenterScreen - ) - + script.restore_window_position(self) self.Show() # Automatically start the first measurement @@ -332,9 +312,7 @@ def __init__(self, xaml_file_name): def window_closed(self, sender, args): """Handle window close event - copy history to clipboard, cleanup DC3D server and visual aids.""" global dc3d_server - new_pos = {"Left": self.Left, "Top": self.Top} - script.store_data(WINDOW_POSITION, new_pos, this_project=False) - + script.save_window_position(self) # Copy measurement history to clipboard before cleanup try: if measurement_history: From 4747b8cd56e590420a9609bca51f03ae84f782a9 Mon Sep 17 00:00:00 2001 From: Wurschdhaud Date: Sun, 30 Nov 2025 18:31:09 +0100 Subject: [PATCH 3/3] - improved docstring - store width+height - reuse coreutils function --- pyrevitlib/pyrevit/script.py | 42 ++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/pyrevitlib/pyrevit/script.py b/pyrevitlib/pyrevit/script.py index 94e114666..0205f2585 100644 --- a/pyrevitlib/pyrevit/script.py +++ b/pyrevitlib/pyrevit/script.py @@ -8,7 +8,7 @@ script.exit() ``` """ -#pylint: disable=consider-using-f-string +# pylint: disable=consider-using-f-string import sys import os @@ -38,7 +38,7 @@ # suppress any warning generated by native or third-party modules warnings.filterwarnings("ignore") -#pylint: disable=W0703,C0302,C0103,W0614 +# pylint: disable=W0703,C0302,C0103,W0614 mlogger = logger.get_logger(__name__) @@ -807,8 +807,8 @@ def restore_window_position(window, command_name=EXEC_PARAMS.command_name): Restore window position from saved data. Args: - window: WPF window instance - command_name: Unique identifier for this window + window (System.Windows.Window): WPF window instance + command_name (str): Unique identifier for this window Returns: bool: True if position was restored, False if centered to screen @@ -820,26 +820,27 @@ def restore_window_position(window, command_name=EXEC_PARAMS.command_name): if not pos: raise Exception("No saved position") - # Get all screen working areas - all_bounds = [s.WorkingArea for s in framework.Forms.Screen.AllScreens] - x, y = pos.get("Left", 0), pos.get("Top", 0) - - # Check if position is visible on any screen - visible = any( - (b.Left <= x <= b.Right and b.Top <= y <= b.Bottom) for b in all_bounds + left, top, width, height = ( + pos.get("Left", 0), + pos.get("Top", 0), + pos.get("Width", window.Width), + pos.get("Height", window.Height), ) - if visible: + if coreutils.is_box_visible_on_screens(left, top, width, height): window.WindowStartupLocation = ( framework.Windows.WindowStartupLocation.Manual ) - window.Left = x - window.Top = y + window.Left = left + window.Top = top + window.Width = width + window.Height = height return True else: raise Exception("Position not visible on any screen") - except Exception: + except Exception as ex: + mlogger.debug("Could not restore window position: %s", ex) window.WindowStartupLocation = ( framework.Windows.WindowStartupLocation.CenterScreen ) @@ -851,9 +852,14 @@ def save_window_position(window, command_name=EXEC_PARAMS.command_name): Save window position to persistent storage. Args: - window: WPF window instance - command_name: Unique identifier for this window + window (System.Windows.Window): WPF window instance + command_name (str): Unique identifier for this window """ storage_key = "last_window_position_" + command_name - position_data = {"Left": window.Left, "Top": window.Top} + position_data = { + "Left": window.Left, + "Top": window.Top, + "Width": window.ActualWidth, + "Height": window.ActualHeight + } store_data(storage_key, position_data, this_project=False)