25
25
import tkinter
26
26
import traceback
27
27
from logger import Logger
28
- from tkinter import ttk
28
+ from tkinter import filedialog , ttk
29
29
from typing import List , Optional , Tuple
30
30
31
31
@@ -70,29 +70,39 @@ def _setup_window(self):
70
70
).grid (column = 1 , row = 1 , sticky = tkinter .E )
71
71
ttk .Label (
72
72
self ._mainframe ,
73
- text = "open heatmap in a browser window using current zoom settings" ,
73
+ text = "open heatmap in a browser window, using current zoom settings" ,
74
74
).grid (column = 2 , row = 1 , sticky = tkinter .W )
75
- # 2. Interstitial
75
+ # 2. Save
76
+ ttk .Button (
77
+ self ._mainframe ,
78
+ text = "Save" ,
79
+ command = functools .partial (self ._handle_long_op , self ._handle_save ),
80
+ ).grid (column = 1 , row = 2 , sticky = tkinter .E )
81
+ ttk .Label (
82
+ self ._mainframe ,
83
+ text = "save heatmap to a file, using current zoom settings" ,
84
+ ).grid (column = 2 , row = 2 , sticky = tkinter .W )
85
+ # 3. Interstitial
76
86
ttk .Label (
77
87
self ._mainframe ,
78
- text = "NOTE: Zoom in/out are effective at the next 'Display'" ,
79
- ).grid (column = 1 , row = 2 , columnspan = 2 , sticky = tkinter .W )
80
- # 3 . Zoom In
88
+ text = "NOTE: Zoom in/out are effective at the next 'Display' or 'Save' " ,
89
+ ).grid (column = 1 , row = 3 , columnspan = 2 , sticky = tkinter .W )
90
+ # 4 . Zoom In
81
91
ttk .Button (
82
92
self ._mainframe ,
83
93
text = "Zoom In" ,
84
94
command = functools .partial (self ._handle_long_op , self ._handle_zoom_in ),
85
- ).grid (column = 1 , row = 3 , sticky = tkinter .E )
95
+ ).grid (column = 1 , row = 4 , sticky = tkinter .E )
86
96
zoomin_data_frame = self ._build_zoomin_data_frame (self ._mainframe )
87
97
zoomin_data_frame .grid (
88
- column = 2 , row = 3 , sticky = (tkinter .N , tkinter .W , tkinter .E , tkinter .S )
98
+ column = 2 , row = 4 , sticky = (tkinter .N , tkinter .W , tkinter .E , tkinter .S )
89
99
)
90
- # 4 . Zoom Out
100
+ # 5 . Zoom Out
91
101
ttk .Button (
92
102
self ._mainframe , text = "Zoom Out" , command = self ._handle_zoom_out
93
- ).grid (column = 1 , row = 4 , sticky = tkinter .E )
103
+ ).grid (column = 1 , row = 5 , sticky = tkinter .E )
94
104
ttk .Label (self ._mainframe , text = "zoom out to the initial state" ).grid (
95
- column = 2 , row = 4 , sticky = tkinter .W
105
+ column = 2 , row = 5 , sticky = tkinter .W
96
106
)
97
107
98
108
# Add a progress bar for long operations; this will be created on-demand
@@ -104,7 +114,7 @@ def _setup_window(self):
104
114
self ._mainframe ,
105
115
textvariable = self ._status_text ,
106
116
relief = "sunken" ,
107
- ).grid (column = 1 , row = 6 , columnspan = 2 , sticky = (tkinter .W , tkinter .E ))
117
+ ).grid (column = 1 , row = 7 , columnspan = 2 , sticky = (tkinter .W , tkinter .E ))
108
118
109
119
# Setup padding for all children of the mainframe
110
120
for child in self ._mainframe .winfo_children ():
@@ -122,6 +132,12 @@ def log(self, s: str):
122
132
def _handle_display (self , * args ):
123
133
self ._systems .display ()
124
134
135
+ def _handle_save (self , * args ):
136
+ filename = filedialog .asksaveasfilename (
137
+ defaultextension = ".html" , filetypes = [("HTML file" , ".html" )]
138
+ )
139
+ self ._systems .save (filename )
140
+
125
141
def _handle_zoom_in (self , * args ):
126
142
try :
127
143
coord0 = (int (self .x0 .get ()), int (self .z0 .get ()))
@@ -180,7 +196,7 @@ def _progressbar_start(self):
180
196
)
181
197
self ._progressbar .grid_configure (padx = 5 , pady = 5 )
182
198
self ._progressbar .grid (
183
- column = 1 , row = 5 , columnspan = 2 , sticky = (tkinter .W , tkinter .E )
199
+ column = 1 , row = 6 , columnspan = 2 , sticky = (tkinter .W , tkinter .E )
184
200
)
185
201
self ._progressbar .start ()
186
202
0 commit comments