Commit 1384e482373b3b34b0238f2fc6233324abbf2cea
1 parent
dcdef93b
Exists in
master
and in
6 other branches
STL: Improving source code style
Showing
1 changed file
with
177 additions
and
130 deletions
Show diff stats
invesalius/gui/frame.py
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | import math |
21 | 21 | import os.path |
22 | 22 | import sys |
23 | +import webbrowser | |
23 | 24 | |
24 | 25 | import wx |
25 | 26 | import wx.aui |
... | ... | @@ -34,25 +35,18 @@ import project as prj |
34 | 35 | import session as ses |
35 | 36 | import utils |
36 | 37 | |
37 | -# Object toolbar | |
38 | -#OBJ_TOOLS = [ID_ZOOM, ID_ZOOM_SELECT, ID_ROTATE, ID_MOVE, | |
39 | -#ID_CONTRAST] = [wx.NewId() for number in range(5)] | |
40 | -#MODE_BY_ID = {ID_ZOOM: const.STATE_ZOOM, | |
41 | -# ID_ZOOM_SELECT: const.STATE_ZOOM_SL, | |
42 | -# ID_ROTATE: const.STATE_SPIN, | |
43 | -# ID_MOVE: const.STATE_PAN, | |
44 | -# ID_CONTRAST: const.STATE_WL} | |
45 | - | |
46 | -# Slice toolbar | |
47 | -#SLICE_TOOLS = [ID_SLICE_SCROLL, ID_CROSS] = [wx.NewId() for number in range(2)] | |
48 | -#SLICE_MODE_BY_ID = {ID_SLICE_SCROLL: const.SLICE_STATE_SCROLL, | |
49 | -# ID_CROSS: const.SLICE_STATE_CROSS} | |
50 | 38 | |
51 | 39 | # Layout toolbar |
52 | 40 | VIEW_TOOLS = [ID_LAYOUT, ID_TEXT] = [wx.NewId() for number in range(2)] |
53 | 41 | |
54 | 42 | class Frame(wx.Frame): |
43 | + """ | |
44 | + Main frame of the whole software. | |
45 | + """ | |
55 | 46 | def __init__(self, prnt): |
47 | + """ | |
48 | + Initialize frame, given its parent. | |
49 | + """ | |
56 | 50 | wx.Frame.__init__(self, id=-1, name='', parent=prnt, |
57 | 51 | pos=wx.Point(0, 0), |
58 | 52 | size=wx.Size(1024, 748), #size = wx.DisplaySize(), |
... | ... | @@ -60,18 +54,16 @@ class Frame(wx.Frame): |
60 | 54 | self.Center(wx.BOTH) |
61 | 55 | self.SetIcon(wx.Icon(os.path.join(const.ICON_DIR, "invesalius.ico"), |
62 | 56 | wx.BITMAP_TYPE_ICO)) |
63 | - | |
64 | 57 | self.Maximize() |
65 | - #self.MacSetMetalAppearance(True) | |
58 | + | |
66 | 59 | # Set menus, status and task bar |
67 | 60 | self.SetMenuBar(MenuBar(self)) |
68 | 61 | self.SetStatusBar(StatusBar(self)) |
69 | 62 | |
70 | - # TEST: Check what happens in each OS when starting widget bellow | |
71 | - # win32: Show icon at "Notification Area" on "Task Bar" | |
63 | + # win32: Show icon on "Notification Area" at "Task Bar" | |
72 | 64 | # darwin: Show icon on Dock |
73 | 65 | # linux2: ? - TODO: find what it does |
74 | - #TaskBarIcon(self) | |
66 | + TaskBarIcon(self) | |
75 | 67 | |
76 | 68 | # Create aui manager and insert content in it |
77 | 69 | self.__init_aui() |
... | ... | @@ -80,78 +72,59 @@ class Frame(wx.Frame): |
80 | 72 | self.__bind_events() |
81 | 73 | self.__bind_events_wx() |
82 | 74 | |
83 | - | |
84 | 75 | def __bind_events(self): |
85 | - ps.Publisher().subscribe(self.ShowContentPanel, 'Show content panel') | |
86 | - ps.Publisher().subscribe(self.ShowImportPanel, 'Show import panel in frame') | |
87 | - ps.Publisher().subscribe(self.UpdateAui, 'Update AUI') | |
88 | - ps.Publisher().subscribe(self.ShowTask, 'Show task panel') | |
89 | - ps.Publisher().subscribe(self.HideTask, 'Hide task panel') | |
90 | - ps.Publisher().subscribe(self.SetProjectName, 'Set project name') | |
91 | - ps.Publisher().subscribe(self.ShowContentPanel, 'Cancel DICOM load') | |
92 | - ps.Publisher().subscribe(self.HideImportPanel, 'Hide import panel') | |
93 | - ps.Publisher().subscribe(self.BeginBusyCursor, 'Begin busy cursor') | |
94 | - ps.Publisher().subscribe(self.EndBusyCursor, 'End busy cursor') | |
95 | - ps.Publisher().subscribe(self.HideContentPanel, 'Hide content panel') | |
96 | - ps.Publisher().subscribe(self.CloseProgram, 'Close Window') | |
97 | - | |
98 | - def EndBusyCursor(self, pubsub_evt=None): | |
99 | - try: | |
100 | - wx.EndBusyCursor() | |
101 | - except wx._core.PyAssertionError: | |
102 | - #xEndBusyCursor(): no matching wxBeginBusyCursor() for wxEndBusyCursor() | |
103 | - pass | |
104 | - | |
105 | - def BeginBusyCursor(self, pubsub_evt=None): | |
106 | - wx.BeginBusyCursor() | |
107 | - | |
108 | - def SetProjectName(self, pubsub_evt): | |
109 | - proj_name = pubsub_evt.data | |
110 | - | |
111 | - if not(proj_name): | |
112 | - self.SetTitle("InVesalius 3") | |
113 | - else: | |
114 | - if sys.platform != 'darwin': | |
115 | - self.SetTitle("%s - InVesalius 3"%(proj_name)) | |
116 | - else: | |
117 | - self.SetTitle("%s"%(proj_name)) | |
118 | - | |
119 | - def UpdateAui(self, pubsub_evt): | |
120 | - self.aui_manager.Update() | |
76 | + """ | |
77 | + Bind events related to pubsub. | |
78 | + """ | |
79 | + ps.Publisher().subscribe(self._BeginBusyCursor, 'Begin busy cursor') | |
80 | + ps.Publisher().subscribe(self._ShowContentPanel, 'Cancel DICOM load') | |
81 | + ps.Publisher().subscribe(self._Exit, 'Close Window') | |
82 | + ps.Publisher().subscribe(self._EndBusyCursor, 'End busy cursor') | |
83 | + ps.Publisher().subscribe(self._HideContentPanel, 'Hide content panel') | |
84 | + ps.Publisher().subscribe(self._HideImportPanel, 'Hide import panel') | |
85 | + ps.Publisher().subscribe(self._HideTask, 'Hide task panel') | |
86 | + ps.Publisher().subscribe(self._SetProjectName, 'Set project name') | |
87 | + ps.Publisher().subscribe(self._ShowContentPanel, 'Show content panel') | |
88 | + ps.Publisher().subscribe(self._ShowImportPanel, 'Show import panel in frame') | |
89 | + ps.Publisher().subscribe(self._ShowTask, 'Show task panel') | |
90 | + ps.Publisher().subscribe(self._UpdateAUI, 'Update AUI') | |
121 | 91 | |
122 | 92 | def __bind_events_wx(self): |
93 | + """ | |
94 | + Bind normal events from wx (except pubsub related). | |
95 | + """ | |
123 | 96 | self.Bind(wx.EVT_SIZE, self.OnSize) |
124 | 97 | self.Bind(wx.EVT_MENU, self.OnMenuClick) |
125 | 98 | self.Bind(wx.EVT_CLOSE, self.OnClose) |
126 | - #self.Bind(wx.EVT_CLOSE, self.OnExit) | |
127 | - | |
128 | - def OnClose(self, evt): | |
129 | - ps.Publisher().sendMessage('Close Project') | |
130 | 99 | |
131 | 100 | def __init_aui(self): |
101 | + """ | |
102 | + Build AUI manager and all panels inside InVesalius frame. | |
103 | + """ | |
132 | 104 | |
133 | 105 | # Tell aui_manager to manage this frame |
134 | 106 | aui_manager = self.aui_manager = wx.aui.AuiManager() |
135 | 107 | aui_manager.SetManagedWindow(self) |
136 | 108 | |
137 | 109 | # Add panels to manager |
110 | + | |
111 | + # First, the task panel, to be on the left fo the frame | |
112 | + # This will be specific according to InVesalius application | |
138 | 113 | aui_manager.AddPane(tasks.Panel(self), wx.aui.AuiPaneInfo(). |
139 | 114 | Name("Tasks").CaptionVisible(False)) |
140 | - # TEST: Check if above works well in all supported OS | |
141 | - # or if we nwwd to insert information bellow | |
142 | - #Caption("Task panel").CaptionVisible(False)). | |
143 | - #CloseButton(False).Floatable(False). | |
144 | - #Layer(1).Left().MaximizeButton(False).Name("Task"). | |
145 | - #Position(0)) | |
146 | - | |
147 | 115 | |
116 | + # Then, add the viewers panel, which will contain slices and | |
117 | + # volume panels. In future this might also be specific | |
118 | + # according to InVesalius application (e.g. panoramic | |
119 | + # visualization, in odontology) | |
148 | 120 | aui_manager.AddPane(viewers.Panel(self), wx.aui.AuiPaneInfo(). |
149 | 121 | Caption(_("Data panel")).CaptionVisible(False). |
150 | 122 | Centre().CloseButton(False).Floatable(False). |
151 | 123 | Hide().Layer(1).MaximizeButton(True).Name("Data"). |
152 | 124 | Position(1)) |
153 | - | |
154 | - | |
125 | + | |
126 | + # This is the DICOM import panel. When the two panels above | |
127 | + # are shown, this should be hiden | |
155 | 128 | aui_manager.AddPane(imp.Panel(self), wx.aui.AuiPaneInfo(). |
156 | 129 | Name("Import").Centre().Hide(). |
157 | 130 | MaximizeButton(True).Floatable(True). |
... | ... | @@ -160,7 +133,8 @@ class Frame(wx.Frame): |
160 | 133 | |
161 | 134 | |
162 | 135 | # Add toolbars to manager |
163 | - | |
136 | + # This is pretty tricky -- order on win32 is inverted when | |
137 | + # compared to linux2 & darwin | |
164 | 138 | if sys.platform == 'win32': |
165 | 139 | t1 = ProjectToolBar(self) |
166 | 140 | t2 = LayoutToolBar(self) |
... | ... | @@ -194,28 +168,77 @@ class Frame(wx.Frame): |
194 | 168 | |
195 | 169 | aui_manager.Update() |
196 | 170 | |
171 | + # TODO: Allow saving and restoring perspectives | |
197 | 172 | self.perspective_all = aui_manager.SavePerspective() |
198 | 173 | |
199 | 174 | self.aui_manager = aui_manager |
200 | 175 | |
201 | - def ShowImportPanel(self, evt_pubsub): | |
202 | - ps.Publisher().sendMessage("Set layout button data only") | |
176 | + def _BeginBusyCursor(self, pubsub_evt): | |
177 | + """ | |
178 | + Start busy cursor. | |
179 | + Note: _EndBusyCursor should be called after. | |
180 | + """ | |
181 | + wx.BeginBusyCursor() | |
182 | + | |
183 | + def _EndBusyCursor(self, pubsub_evt): | |
184 | + """ | |
185 | + End busy cursor. | |
186 | + Note: _BeginBusyCursor should have been called previously. | |
187 | + """ | |
188 | + try: | |
189 | + wx.EndBusyCursor() | |
190 | + except wx._core.PyAssertionError: | |
191 | + #xEndBusyCursor(): no matching wxBeginBusyCursor() for wxEndBusyCursor() | |
192 | + pass | |
193 | + | |
194 | + def _Exit(self, pubsub_evt): | |
195 | + """ | |
196 | + Exit InVesalius. | |
197 | + """ | |
198 | + self.Destroy() | |
199 | + | |
200 | + def _HideContentPanel(self, pubsub_evt): | |
201 | + """ | |
202 | + Hide data and tasks panels. | |
203 | + """ | |
203 | 204 | aui_manager = self.aui_manager |
204 | - aui_manager.GetPane("Import").Show(1) | |
205 | 205 | aui_manager.GetPane("Data").Show(0) |
206 | - aui_manager.GetPane("Tasks").Show(0) | |
206 | + aui_manager.GetPane("Tasks").Show(1) | |
207 | 207 | aui_manager.Update() |
208 | 208 | |
209 | - def HideImportPanel(self, evt_pubsub): | |
210 | - utils.debug("HideImportPanel") | |
209 | + def _HideImportPanel(self, evt_pubsub): | |
210 | + """ | |
211 | + Hide import panel and show tasks. | |
212 | + """ | |
211 | 213 | aui_manager = self.aui_manager |
212 | 214 | aui_manager.GetPane("Import").Show(0) |
213 | 215 | aui_manager.GetPane("Data").Show(0) |
214 | 216 | aui_manager.GetPane("Tasks").Show(1) |
215 | 217 | aui_manager.Update() |
216 | 218 | |
217 | - def ShowContentPanel(self, evt_pubsub): | |
218 | - utils.debug("ShowContentPanel") | |
219 | + | |
220 | + def _HideTask(self, pubsub_evt): | |
221 | + """ | |
222 | + Hide task panel. | |
223 | + """ | |
224 | + self.aui_manager.GetPane("Tasks").Hide() | |
225 | + self.aui_manager.Update() | |
226 | + | |
227 | + def _SetProjectName(self, pubsub_evt): | |
228 | + """ | |
229 | + Set project name into frame's title. | |
230 | + """ | |
231 | + proj_name = pubsub_evt.data | |
232 | + | |
233 | + if not(proj_name): | |
234 | + self.SetTitle("InVesalius 3") | |
235 | + else: | |
236 | + self.SetTitle("%s - InVesalius 3"%(proj_name)) | |
237 | + | |
238 | + def _ShowContentPanel(self, evt_pubsub): | |
239 | + """ | |
240 | + Show viewers and task, hide import panel. | |
241 | + """ | |
219 | 242 | ps.Publisher().sendMessage("Set layout button full") |
220 | 243 | aui_manager = self.aui_manager |
221 | 244 | aui_manager.GetPane("Import").Show(0) |
... | ... | @@ -223,92 +246,116 @@ class Frame(wx.Frame): |
223 | 246 | aui_manager.GetPane("Tasks").Show(1) |
224 | 247 | aui_manager.Update() |
225 | 248 | |
226 | - def HideContentPanel(self, pubsub_evt): | |
249 | + def _ShowImportPanel(self, evt_pubsub): | |
250 | + """ | |
251 | + Show only DICOM import panel. | |
252 | + """ | |
253 | + ps.Publisher().sendMessage("Set layout button data only") | |
227 | 254 | aui_manager = self.aui_manager |
255 | + aui_manager.GetPane("Import").Show(1) | |
228 | 256 | aui_manager.GetPane("Data").Show(0) |
229 | - aui_manager.GetPane("Tasks").Show(1) | |
257 | + aui_manager.GetPane("Tasks").Show(0) | |
230 | 258 | aui_manager.Update() |
231 | 259 | |
232 | - def OnSize(self, evt): | |
233 | - ps.Publisher().sendMessage(('ProgressBar Reposition')) | |
234 | - evt.Skip() | |
260 | + def _ShowTask(self, pubsub_evt): | |
261 | + """ | |
262 | + Show task panel. | |
263 | + """ | |
264 | + self.aui_manager.GetPane("Tasks").Show() | |
265 | + self.aui_manager.Update() | |
266 | + | |
267 | + | |
268 | + def _UpdateAUI(self, pubsub_evt): | |
269 | + """ | |
270 | + Refresh AUI panels/data. | |
271 | + """ | |
272 | + self.aui_manager.Update() | |
273 | + | |
274 | + | |
275 | + def CloseProject(self): | |
276 | + ps.Publisher().sendMessage('Close Project') | |
277 | + | |
278 | + def OnClose(self, evt): | |
279 | + """ | |
280 | + Close all project data. | |
281 | + """ | |
282 | + ps.Publisher().sendMessage('Close Project') | |
235 | 283 | |
236 | 284 | def OnMenuClick(self, evt): |
285 | + """ | |
286 | + Capture event from mouse click on menu / toolbar (as both use | |
287 | + the same ID's) | |
288 | + """ | |
237 | 289 | id = evt.GetId() |
238 | - session = ses.Session() | |
290 | + | |
239 | 291 | if id == const.ID_DICOM_IMPORT: |
240 | - self.ImportDicom() | |
292 | + self.ShowImportDicomPanel() | |
241 | 293 | elif id == const.ID_PROJECT_OPEN: |
242 | - self.OpenProject() | |
294 | + self.ShowOpenProject() | |
243 | 295 | elif id == const.ID_PROJECT_SAVE: |
244 | - #if proj.save_as: | |
296 | + session = ses.Session() | |
245 | 297 | if session.temp_item: |
246 | - self.SaveAsProject() | |
298 | + self.ShowSaveAsProject() | |
247 | 299 | else: |
248 | 300 | self.SaveProject() |
249 | 301 | elif id == const.ID_PROJECT_SAVE_AS: |
250 | - self.SaveAsProject() | |
302 | + self.ShowSaveAsProject() | |
251 | 303 | elif id == const.ID_PROJECT_CLOSE: |
252 | 304 | self.CloseProject() |
253 | 305 | elif id == const.ID_EXIT: |
254 | - self.OnExit() | |
306 | + self.CloseProject() | |
255 | 307 | elif id == const.ID_ABOUT: |
256 | 308 | self.ShowAbout() |
257 | 309 | elif id == const.ID_START: |
258 | - self.GettingStarted() | |
259 | - | |
260 | - def GettingStarted(self): | |
261 | - #if sys.platform == 'win32': | |
262 | - # os.filestart() | |
263 | - #else: | |
264 | - # os.system("/usr/bin/xdg-open %s" % nome_file) | |
265 | - | |
266 | - import webbrowser | |
267 | - path = os.path.join(const.DOC_DIR, "user_guide_invesalius3a.pdf") | |
268 | - webbrowser.open(path) | |
269 | - | |
310 | + self.ShowGettingStarted() | |
270 | 311 | |
312 | + def OnSize(self, evt): | |
313 | + """ | |
314 | + Refresh GUI when frame is resized. | |
315 | + """ | |
316 | + ps.Publisher().sendMessage(('ProgressBar Reposition')) | |
317 | + evt.Skip() | |
271 | 318 | |
272 | 319 | def ShowAbout(self): |
320 | + """ | |
321 | + Shows about dialog. | |
322 | + """ | |
273 | 323 | dlg.ShowAboutDialog(self) |
274 | 324 | |
275 | - def ImportDicom(self): | |
276 | - ps.Publisher().sendMessage('Show import directory dialog') | |
277 | - | |
278 | - def OpenProject(self): | |
279 | - ps.Publisher().sendMessage('Show open project dialog') | |
280 | - | |
281 | - def SaveAsProject(self): | |
282 | - ps.Publisher().sendMessage('Show save dialog', True) | |
283 | - | |
284 | 325 | def SaveProject(self): |
326 | + """ | |
327 | + Save project. | |
328 | + """ | |
285 | 329 | ps.Publisher().sendMessage('Show save dialog', False) |
286 | 330 | |
287 | - def CloseProject(self): | |
288 | - utils.debug("CloseProject") | |
289 | - ps.Publisher().sendMessage('Close Project') | |
331 | + def ShowGettingStarted(self): | |
332 | + """ | |
333 | + Show getting started window. | |
334 | + """ | |
335 | + path = os.path.join(const.DOC_DIR, "user_guide_invesalius3a.pdf") | |
336 | + webbrowser.open(path) | |
290 | 337 | |
291 | - def OnExit(self): | |
292 | - ps.Publisher().sendMessage('Close Project') | |
338 | + def ShowImportDicomPanel(self): | |
339 | + """ | |
340 | + Show import DICOM panel. | |
341 | + """ | |
342 | + ps.Publisher().sendMessage('Show import directory dialog') | |
293 | 343 | |
294 | - def CloseProgram(self, pubsub_evt): | |
295 | - self.Destroy() | |
344 | + def ShowOpenProject(self): | |
345 | + """ | |
346 | + Show open project dialog. | |
347 | + """ | |
348 | + ps.Publisher().sendMessage('Show open project dialog') | |
296 | 349 | |
297 | - def Exit(self): | |
298 | - utils.debug("Exit") | |
299 | - ps.Publisher().sendMessage('Close Project') | |
350 | + def ShowSaveAsProject(self): | |
351 | + """ | |
352 | + Show save as dialog. | |
353 | + """ | |
354 | + ps.Publisher().sendMessage('Show save dialog', True) | |
300 | 355 | |
301 | - def ShowTask(self, pubsub_evt): | |
302 | - self.aui_manager.GetPane("Tasks").Show() | |
303 | - self.aui_manager.Update() | |
304 | 356 | |
305 | - def HideTask(self, pubsub_evt): | |
306 | - self.aui_manager.GetPane("Tasks").Hide() | |
307 | - self.aui_manager.Update() | |
308 | 357 | |
309 | - #def OnClose(self): | |
310 | - # TODO: implement this, based on wx.Demo | |
311 | - #pass | |
358 | +# ------------------------------------------------------------------------------ | |
312 | 359 | # ------------------------------------------------------------------------------ |
313 | 360 | # TODO: what will appear on ivMenuBar? |
314 | 361 | # Menu items ID's, necessary to bind events on them |
... | ... | @@ -512,7 +559,7 @@ class TaskBarIcon(wx.TaskBarIcon): |
512 | 559 | self.imgidx = 1 |
513 | 560 | |
514 | 561 | # bind some events |
515 | - self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActive) | |
562 | + self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate) | |
516 | 563 | |
517 | 564 | def OnTaskBarActivate(self): |
518 | 565 | pass | ... | ... |