-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathtransformations_GUI.py
More file actions
145 lines (113 loc) · 5.28 KB
/
transformations_GUI.py
File metadata and controls
145 lines (113 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import sys
import matplotlib
import tkinter as tk
from contextlib import suppress
matplotlib.use("Agg")
matplotlib.rcParams["toolbar"] = "toolbar2"
matplotlib.rcParams["interactive"] = False
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from tkinter import BOTH, Frame, Tk, TOP, Toplevel
from notebook import notebook # window with tabs
from stftMorph_GUI_frame import *
from sineTransformations_GUI_frame import *
from harmonicTransformations_GUI_frame import *
from stochasticTransformations_GUI_frame import *
from hpsTransformations_GUI_frame import *
from hpsMorph_GUI_frame import *
def fit_window_to_screen(root, margin_x=80, margin_y=120):
root.update_idletasks()
width = min(root.winfo_reqwidth(), root.winfo_screenwidth() - margin_x)
height = min(root.winfo_reqheight(), root.winfo_screenheight() - margin_y)
root.geometry(f"{width}x{height}+0+0")
root.minsize(640, 480)
root.resizable(True, True)
def install_embedded_plot_viewer(root):
def embedded_show(*args, **kwargs):
block = kwargs.pop("block", True)
figures = [plt.figure(num) for num in plt.get_fignums()]
last_window = None
for fig in figures:
manager = getattr(getattr(fig, "canvas", None), "manager", None)
native_window = getattr(manager, "window", None)
if native_window is not None:
with suppress(Exception):
native_window.withdraw()
existing_window = getattr(fig, "_sms_plot_window", None)
if existing_window is not None and existing_window.winfo_exists():
existing_window.deiconify()
existing_window.lift()
canvas = getattr(fig, "_sms_plot_canvas", None)
if canvas is not None:
canvas.draw_idle()
last_window = existing_window
continue
window = Toplevel(root)
window.title(fig._suptitle.get_text() if fig._suptitle else f"Plot {fig.number}")
window.minsize(640, 480)
container = Frame(window)
container.pack(fill=BOTH, expand=1)
canvas = FigureCanvasTkAgg(fig, master=container)
toolbar = NavigationToolbar2Tk(canvas, container, pack_toolbar=False)
toolbar.update()
toolbar.pack(fill="x")
canvas.get_tk_widget().pack(fill=BOTH, expand=1)
canvas.draw()
fig._sms_plot_window = window
fig._sms_plot_canvas = canvas
def close_window(current_fig=fig, current_window=window):
current_fig._sms_plot_window = None
current_fig._sms_plot_canvas = None
plt.close(current_fig)
current_window.destroy()
window.protocol("WM_DELETE_WINDOW", close_window)
last_window = window
if block and last_window is not None:
last_window.wait_visibility()
plt.show = embedded_show
plt.ioff()
def install_audio_button_style():
if getattr(tk.Button, "_sms_audio_style_installed", False):
return
original_init = tk.Button.__init__
def styled_init(self, master=None, cnf=None, **kw):
cnf = {} if cnf is None else dict(cnf)
text = kw.get("text", cnf.get("text"))
if isinstance(text, str) and (text == ">" or text.startswith("> ")):
styled_text = "▶ Play" if text == ">" else f"▶{text[1:]}"
if "text" in kw:
kw["text"] = styled_text
kw.setdefault("width", max(10, len(styled_text)))
kw.setdefault("font", ("TkDefaultFont", 11, "bold"))
kw.setdefault("padx", 6)
kw.setdefault("pady", 2)
else:
cnf["text"] = styled_text
cnf.setdefault("width", max(10, len(styled_text)))
cnf.setdefault("font", ("TkDefaultFont", 11, "bold"))
cnf.setdefault("padx", 6)
cnf.setdefault("pady", 2)
original_init(self, master, cnf, **kw)
tk.Button.__init__ = styled_init
tk.Button._sms_audio_style_installed = True
root = Tk()
root.title("sms-tools transformations GUI")
# Set larger default window size
root.geometry("1200x800")
root.minsize(900, 600)
install_audio_button_style()
install_embedded_plot_viewer(root)
# Create a single notebook instance and pack its frames
nb = notebook(root, TOP)
nb.rb_fr.pack(side=TOP, fill=X)
nb.screen_container.pack(fill=BOTH, expand=1)
# Frames are built lazily: only when the tab is first selected.
f1 = Frame(nb()); nb.add_screen(f1, "STFT Morph", build_func=lambda f: StftMorph_frame(f).pack(fill=BOTH, expand=True))
f2 = Frame(nb()); nb.add_screen(f2, "Sine", build_func=lambda f: SineTransformations_frame(f).pack(fill=BOTH, expand=True))
f3 = Frame(nb()); nb.add_screen(f3, "Harmonic", build_func=lambda f: HarmonicTransformations_frame(f))
f4 = Frame(nb()); nb.add_screen(f4, "Stochastic", build_func=lambda f: StochasticTransformations_frame(f))
f5 = Frame(nb()); nb.add_screen(f5, "HPS", build_func=lambda f: HpsTransformations_frame(f))
f6 = Frame(nb()); nb.add_screen(f6, "HPS Morph", build_func=lambda f: HpsMorph_frame(f))
nb.display(f1)
fit_window_to_screen(root)
root.mainloop()