Skip to content

Commit

Permalink
New fix for Issue #101
Browse files Browse the repository at this point in the history
Back off previous "fix" for issue #101 which completely broke the tabs in the Preferences dialog.

This one actually fixes the problem - almost.  It turns out that removing the call to the resizable() method makes the problem disappear. By default tk.Toplevel widgets are resizable, so we just need to find a differen way to make non-resizable dialogs. This is done by setting both the minimum and maximum size to the current size.

Unfortunately, this solution has problems with the standalone version of the simulator dialog. But it works ok for the simulator dialog running under the IVS2 GUI.
  • Loading branch information
csatt committed Jun 9, 2020
1 parent 26a20fa commit c44fa41
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 74 deletions.
60 changes: 32 additions & 28 deletions python/IV_Swinger2_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,6 @@
SPI_CLOCK_DIV64: "DIV64 (250 KHz)",
SPI_CLOCK_DIV128: "DIV128 (125 kHz)"}
SPI_COMBO_VALS_INV = {v: k for k, v in SPI_COMBO_VALS.items()}
ISSUE_26340_MSG = """
Sorry. Minimization is not supported.
This is Python issue 26340, which is
closed, but was never fixed :-(
The app will probably crash when you
click OK.
"""

# Default plotting config
FANCY_LABELS_DEFAULT = "Fancy"
Expand Down Expand Up @@ -371,13 +364,14 @@ def handle_early_exception():
IV_Swinger2.sys_view_file(tmp_file.name)


def get_dialog_width(dialog):
"""Global function to parse the width of a dialog from its current
geometry
def get_dialog_width_and_height(dialog):
"""Global function to parse the width and height of a dialog from its
current geometry
"""
m = re.match(r"(\d+)x(\d+)", dialog.geometry())
width = int(m.group(1))
return width
height = int(m.group(2))
return width, height


def pdf_permission_denied(e):
Expand Down Expand Up @@ -454,6 +448,7 @@ def __init__(self, app_data_dir=None):
self.plot_power_cb = None
self.preferences_button = None
self.prefs_results_bb = None
self.prefs_dialog_active = False
self.range_lock_cb = None
self.results_button = None
self.results_wiz = None
Expand Down Expand Up @@ -579,6 +574,7 @@ def init_instance_vars(self):
self.label_all_vocs = tk.StringVar()
self.version = "UNKNOWN"
self.grid_args = {}
self.prefs_dialog_active = False
self.results_wiz = None
self.img_file = None
self._cfg_filename = None
Expand Down Expand Up @@ -680,6 +676,24 @@ def mac_grayed_menu_workaround(self):
if self.win_sys == "aqua": # Mac
self.create_menu_bar()

# -------------------------------------------------------------------------
def pseudo_dialog_resize_disable(self, dialog):
"""Method to effectively disable resizing by setting the minimimum and
maximum size to the current values. This is a hack that is
part of the fix for Issue #101.
"""
# Run update_idletasks to get the geometry manager to size the
# window to fit the widgets
self.update_idletasks()

# Get current window width and height
width, height = get_dialog_width_and_height(dialog)

# Set the minimum and maximum to the current width and height,
# effectively disabling resizing
dialog.minsize(width, height)
dialog.maxsize(width, height)

# -------------------------------------------------------------------------
def set_dialog_geometry(self, dialog, min_height=None, max_height=None):
"""Method to set the size and position of a dialog. If min_height is
Expand All @@ -695,7 +709,7 @@ def set_dialog_geometry(self, dialog, min_height=None, max_height=None):
self.update_idletasks()

# Get current window width
width = get_dialog_width(dialog)
width, _ = get_dialog_width_and_height(dialog)

if min_height is not None:
# Disable width resizing by setting min and max width to
Expand Down Expand Up @@ -2228,7 +2242,7 @@ def change_min_height(self, min_height):
value
"""
# Get current window width
width = get_dialog_width(self)
width, _ = get_dialog_width_and_height(self)

# Set minimum size using current width and requested height
self.minsize(width, min_height)
Expand Down Expand Up @@ -4552,7 +4566,6 @@ def __init__(self, master=None, title=None, has_ok_button=True,
self.has_cancel_button = has_cancel_button
self.return_ok = return_ok
self.ok_label = ok_label
self.resizable(width=resizable, height=resizable)
self.transient(self.master) # tie this window to master
if title is not None:
self.title(title)
Expand All @@ -4564,9 +4577,6 @@ def __init__(self, master=None, title=None, has_ok_button=True,
self.min_height = min_height
self.max_height = max_height

# Catch attempt to minimize
self.bind("<Unmap>", self.unmap_action)

# Snapshot current values for revert
self.snapshot()

Expand All @@ -4586,6 +4596,11 @@ def __init__(self, master=None, title=None, has_ok_button=True,
min_height=self.min_height,
max_height=self.max_height)

# If dialog is not resizable, constrain its width and height to
# their current values
if not resizable:
self.master.pseudo_dialog_resize_disable(self)

# Map Ctrl-A and Cmd-A (Mac) to select-all for Text widgets
# (which includes ScrolledText)
self.master.bind_class("Text", "<Control-a>", selectall)
Expand All @@ -4594,17 +4609,6 @@ def __init__(self, master=None, title=None, has_ok_button=True,
# Wait for dialog to be closed before returning control
self.wait_window(self)

# -------------------------------------------------------------------------
def unmap_action(self, event=None):
"""Method to display error message when user attempts to minimize
the dialog, which would leave the app in limbo due to Python
issue 26340. The dialog is then destroyed, which crashes the
whole app, but at least we've told the user what happened.
"""
# pylint: disable=unused-argument
tkmsg.showerror(message=ISSUE_26340_MSG)
self.destroy()

# -------------------------------------------------------------------------
def body(self, master):
"""Method to create the dialog body. This method should be
Expand Down
88 changes: 42 additions & 46 deletions python/IV_Swinger2_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,6 @@
# Simulator GUI
SLIDER_LENGTH = 200
MFG_PN_ENTRY_WIDTH = 20
ISSUE_26340_MSG = """
Sorry. Minimization is not supported.
This is Python issue 26340, which is
closed, but was never fixed :-(
The app will probably crash when you
click OK.
"""

# From IV_Swinger2
INFINITE_VAL = IV_Swinger2.INFINITE_VAL
Expand Down Expand Up @@ -331,25 +324,45 @@ def selectall(event):
event.widget.tag_add("sel", "1.0", "end")


def get_dialog_width_and_height(dialog):
"""Global function to parse the width and height of a dialog from its
current geometry
"""
m = re.match(r"(\d+)x(\d+)", dialog.geometry())
width = int(m.group(1))
height = int(m.group(2))
return width, height


def pseudo_dialog_resize_disable(dialog):
"""Function to effectively disable resizing by setting the minimimum and
maximum size to the current values. This is a hack that is part
of the fix for Issue #101.
"""
dialog.update_idletasks()
width, height = get_dialog_width_and_height(dialog)
dialog.minsize(width, height)
dialog.maxsize(width, height)


def set_dialog_geometry(dialog, min_height=None, max_height=None):
"""Function to set the dialog geometry if the master doesn't have a
set_dialog_geometry method. Place the dialog at the top of the
screen, in the middle, on top of other windows.
"""
dialog.update_idletasks()
m = re.match(r"(\d+)x(\d+)", dialog.geometry())
dialog_width = int(m.group(1))
width, _ = get_dialog_width_and_height(dialog)
if min_height is not None:
if max_height is None:
max_height = dialog.winfo_height()
dialog.minsize(dialog_width, min_height)
dialog.maxsize(dialog_width, max_height)
dialog.geometry("{}x{}+{}+5".format(dialog_width, min_height,
dialog.minsize(width, min_height)
dialog.maxsize(width, max_height)
dialog.geometry("{}x{}+{}+5".format(width, min_height,
(dialog.winfo_screenwidth()/2 -
dialog_width/2)))
width/2)))
else:
dialog.geometry("+{}+5".format(dialog.winfo_screenwidth()/2 -
dialog_width/2))
width/2))
dialog.lift()
dialog.attributes("-topmost", True)
dialog.after_idle(dialog.attributes, "-topmost", False)
Expand Down Expand Up @@ -1507,18 +1520,24 @@ class SimulatorDialog(tk.Toplevel):
def __init__(self, master=None):
tk.Toplevel.__init__(self, master=master)
self.master = master
# Hack: determine if we're running under the IVS2 GUI or
# standalone
self.running_under_ivs2_gui = True
try:
if self.master.version:
pass
except AttributeError:
self.running_under_ivs2_gui = False
self.win_sys = self.master.tk.call("tk", "windowingsystem")
self.resizable(width=False, height=False)
self.update_idletasks()
if not self.running_under_ivs2_gui:
# Doesn't start on top without this (but it breaks mimimize)
self.update_idletasks()
self.transient(self.master) # tie this window to master
title = "IV Swinger 2 Simulator"
self.title(title)
self.grab_set() # block change of focus to master
self.focus_set()

# Catch attempt to minimize
self.bind("<Unmap>", self.unmap_action)

# Initialize the widget handles that need to be accessed by
# callback methods
self.isc_amps_slider = None
Expand Down Expand Up @@ -1552,6 +1571,10 @@ def __init__(self, master=None):
except (AttributeError, TypeError):
set_dialog_geometry(self)

# The dialog is not resizable, so constrain its width and height
# to their current values.
pseudo_dialog_resize_disable(self)

# Register callback for when the dialog is closed
self.protocol("WM_DELETE_WINDOW", self.done)

Expand All @@ -1563,17 +1586,6 @@ def __init__(self, master=None):
# Wait for dialog to be closed before returning control
self.wait_window(self)

# -------------------------------------------------------------------------
def unmap_action(self, event=None):
"""Method to display error message when user attempts to minimize
the dialog, which would leave the app in limbo due to Python
issue 26340. The dialog is then destroyed, which crashes the
whole app, but at least we've told the user what happened.
"""
# pylint: disable=unused-argument
tkmsg.showerror(message=ISSUE_26340_MSG)
self.destroy()

# -------------------------------------------------------------------------
def create_widget_vars(self):
"""Method to create the widgets' tk StringVar objects
Expand Down Expand Up @@ -3107,17 +3119,12 @@ def __init__(self, master=None):
tk.Toplevel.__init__(self, master=master)
self.master = master
self.win_sys = self.master.tk.call("tk", "windowingsystem")
self.resizable(width=True, height=True)
self.update_idletasks()
self.transient(self.master) # tie this window to master
title = "IV Swinger 2 Simulator Help"
self.title(title)
self.grab_set() # block change of focus to master
self.focus_set()

# Catch attempt to minimize
self.bind("<Unmap>", self.unmap_action)

# Create body frame
body = ttk.Frame(self)

Expand All @@ -3136,17 +3143,6 @@ def __init__(self, master=None):
# Wait for dialog to be closed before returning control
self.wait_window(self)

# -------------------------------------------------------------------------
def unmap_action(self, event=None):
"""Method to display error message when user attempts to minimize
the dialog, which would leave the app in limbo due to Python
issue 26340. The dialog is then destroyed, which crashes the
whole app, but at least we've told the user what happened.
"""
# pylint: disable=unused-argument
tkmsg.showerror(message=ISSUE_26340_MSG)
self.destroy()

# -------------------------------------------------------------------------
def body(self, master):
"""Method to create the dialog body, which is just a ScrolledText
Expand Down

0 comments on commit c44fa41

Please sign in to comment.