Commit 241070c61f28e4eb224b7647f2071fb684446b96
Committed by
GitHub
1 parent
1f878946
Exists in
master
Go to slice dialog tool (#167)
Adds to the user the possibility of go to a slice typing the slice number
Showing
4 changed files
with
93 additions
and
2 deletions
Show diff stats
invesalius/constants.py
@@ -98,6 +98,10 @@ SAGITAL = 3 | @@ -98,6 +98,10 @@ SAGITAL = 3 | ||
98 | VOLUME = 4 | 98 | VOLUME = 4 |
99 | SURFACE = 5 | 99 | SURFACE = 5 |
100 | 100 | ||
101 | +AXIAL_STR="AXIAL" | ||
102 | +CORONAL_STR="CORONAL" | ||
103 | +SAGITAL_STR="SAGITAL" | ||
104 | + | ||
101 | # Measure type | 105 | # Measure type |
102 | LINEAR = 6 | 106 | LINEAR = 6 |
103 | ANGULAR = 7 | 107 | ANGULAR = 7 |
@@ -550,6 +554,8 @@ ID_CROP_MASK = wx.NewId() | @@ -550,6 +554,8 @@ ID_CROP_MASK = wx.NewId() | ||
550 | ID_CREATE_SURFACE = wx.NewId() | 554 | ID_CREATE_SURFACE = wx.NewId() |
551 | ID_CREATE_MASK = wx.NewId() | 555 | ID_CREATE_MASK = wx.NewId() |
552 | 556 | ||
557 | +ID_GOTO_SLICE = wx.NewId() | ||
558 | + | ||
553 | #--------------------------------------------------------- | 559 | #--------------------------------------------------------- |
554 | STATE_DEFAULT = 1000 | 560 | STATE_DEFAULT = 1000 |
555 | STATE_WL = 1001 | 561 | STATE_WL = 1001 |
invesalius/data/viewer_slice.py
@@ -1263,6 +1263,11 @@ class Viewer(wx.Panel): | @@ -1263,6 +1263,11 @@ class Viewer(wx.Panel): | ||
1263 | else: | 1263 | else: |
1264 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZING)) | 1264 | self.interactor.SetCursor(wx.StockCursor(wx.CURSOR_SIZING)) |
1265 | 1265 | ||
1266 | + def SetFocus(self): | ||
1267 | + Publisher.sendMessage('Set viewer orientation focus', | ||
1268 | + orientation=self.orientation) | ||
1269 | + super().SetFocus() | ||
1270 | + | ||
1266 | def OnExportPicture(self, orientation, filename, filetype): | 1271 | def OnExportPicture(self, orientation, filename, filetype): |
1267 | dict = {"AXIAL": const.AXIAL, | 1272 | dict = {"AXIAL": const.AXIAL, |
1268 | "CORONAL": const.CORONAL, | 1273 | "CORONAL": const.CORONAL, |
invesalius/gui/dialogs.py
@@ -3590,3 +3590,68 @@ class SurfaceProgressWindow(object): | @@ -3590,3 +3590,68 @@ class SurfaceProgressWindow(object): | ||
3590 | 3590 | ||
3591 | def Close(self): | 3591 | def Close(self): |
3592 | self.dlg.Destroy() | 3592 | self.dlg.Destroy() |
3593 | + | ||
3594 | + | ||
3595 | +class GoToDialog(wx.Dialog): | ||
3596 | + def __init__(self, title=_("Go to slice ..."), init_orientation=const.AXIAL_STR): | ||
3597 | + wx.Dialog.__init__(self, wx.GetApp().GetTopWindow(), -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.FRAME_FLOAT_ON_PARENT|wx.STAY_ON_TOP) | ||
3598 | + self._init_gui(init_orientation) | ||
3599 | + | ||
3600 | + def _init_gui(self, init_orientation): | ||
3601 | + orientations = ( | ||
3602 | + (_("Axial"), const.AXIAL_STR), | ||
3603 | + (_("Coronal"), const.CORONAL_STR), | ||
3604 | + (_("Sagital"), const.SAGITAL_STR), | ||
3605 | + ) | ||
3606 | + self.goto_slice = wx.TextCtrl(self, -1, "") | ||
3607 | + self.goto_orientation = wx.ComboBox(self, -1, style=wx.CB_DROPDOWN|wx.CB_READONLY) | ||
3608 | + cb_init = 0 | ||
3609 | + for n, orientation in enumerate(orientations): | ||
3610 | + self.goto_orientation.Append(*orientation) | ||
3611 | + if orientation[1] == init_orientation: | ||
3612 | + cb_init = n | ||
3613 | + self.goto_orientation.SetSelection(cb_init) | ||
3614 | + | ||
3615 | + btn_ok = wx.Button(self, wx.ID_OK) | ||
3616 | + btn_ok.SetHelpText("") | ||
3617 | + btn_ok.SetDefault() | ||
3618 | + | ||
3619 | + btn_cancel = wx.Button(self, wx.ID_CANCEL) | ||
3620 | + btn_cancel.SetHelpText("") | ||
3621 | + | ||
3622 | + btnsizer = wx.StdDialogButtonSizer() | ||
3623 | + btnsizer.AddButton(btn_ok) | ||
3624 | + btnsizer.AddButton(btn_cancel) | ||
3625 | + btnsizer.Realize() | ||
3626 | + | ||
3627 | + main_sizer = wx.BoxSizer(wx.VERTICAL) | ||
3628 | + | ||
3629 | + slice_sizer = wx.BoxSizer(wx.HORIZONTAL) | ||
3630 | + slice_sizer.Add(wx.StaticText(self, -1, _("Slice number"), style=wx.ALIGN_CENTER), 0, wx.ALIGN_CENTER|wx.RIGHT, 5) | ||
3631 | + slice_sizer.Add(self.goto_slice, 1, wx.EXPAND) | ||
3632 | + | ||
3633 | + main_sizer.Add((5, 5)) | ||
3634 | + main_sizer.Add(slice_sizer, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5) | ||
3635 | + main_sizer.Add((5, 5)) | ||
3636 | + main_sizer.Add(self.goto_orientation, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 5) | ||
3637 | + main_sizer.Add((5, 5)) | ||
3638 | + main_sizer.Add(btnsizer, 0, wx.EXPAND) | ||
3639 | + main_sizer.Add((5, 5)) | ||
3640 | + | ||
3641 | + self.SetSizer(main_sizer) | ||
3642 | + main_sizer.Fit(self) | ||
3643 | + | ||
3644 | + btn_ok.Bind(wx.EVT_BUTTON, self.OnOk) | ||
3645 | + | ||
3646 | + def OnOk(self, evt): | ||
3647 | + try: | ||
3648 | + slice_number = int(self.goto_slice.GetValue()) | ||
3649 | + orientation = self.goto_orientation.GetClientData(self.goto_orientation.GetSelection()) | ||
3650 | + Publisher.sendMessage(("Set scroll position", orientation), index=slice_number) | ||
3651 | + except ValueError: | ||
3652 | + pass | ||
3653 | + self.Close() | ||
3654 | + | ||
3655 | + def Close(self): | ||
3656 | + wx.Dialog.Close(self) | ||
3657 | + self.Destroy() |
invesalius/gui/frame.py
@@ -98,7 +98,7 @@ class Frame(wx.Frame): | @@ -98,7 +98,7 @@ class Frame(wx.Frame): | ||
98 | self.SetIcon(wx.Icon(icon_path, wx.BITMAP_TYPE_ICO)) | 98 | self.SetIcon(wx.Icon(icon_path, wx.BITMAP_TYPE_ICO)) |
99 | 99 | ||
100 | self.mw = None | 100 | self.mw = None |
101 | - | 101 | + self._last_viewer_orientation_focus = const.AXIAL_STR |
102 | 102 | ||
103 | if sys.platform != 'darwin': | 103 | if sys.platform != 'darwin': |
104 | self.Maximize() | 104 | self.Maximize() |
@@ -153,6 +153,7 @@ class Frame(wx.Frame): | @@ -153,6 +153,7 @@ class Frame(wx.Frame): | ||
153 | sub(self._ShowImportBitmap, 'Show import bitmap panel in frame') | 153 | sub(self._ShowImportBitmap, 'Show import bitmap panel in frame') |
154 | sub(self._ShowTask, 'Show task panel') | 154 | sub(self._ShowTask, 'Show task panel') |
155 | sub(self._UpdateAUI, 'Update AUI') | 155 | sub(self._UpdateAUI, 'Update AUI') |
156 | + sub(self._UpdateViewerFocus, 'Set viewer orientation focus') | ||
156 | sub(self._Exit, 'Exit') | 157 | sub(self._Exit, 'Exit') |
157 | 158 | ||
158 | def __bind_events_wx(self): | 159 | def __bind_events_wx(self): |
@@ -388,6 +389,10 @@ class Frame(wx.Frame): | @@ -388,6 +389,10 @@ class Frame(wx.Frame): | ||
388 | """ | 389 | """ |
389 | self.aui_manager.Update() | 390 | self.aui_manager.Update() |
390 | 391 | ||
392 | + def _UpdateViewerFocus(self, orientation): | ||
393 | + if orientation in (const.AXIAL_STR, const.CORONAL_STR, const.SAGITAL_STR): | ||
394 | + self._last_viewer_orientation_focus = orientation | ||
395 | + | ||
391 | def CloseProject(self): | 396 | def CloseProject(self): |
392 | Publisher.sendMessage('Close Project') | 397 | Publisher.sendMessage('Close Project') |
393 | 398 | ||
@@ -456,6 +461,8 @@ class Frame(wx.Frame): | @@ -456,6 +461,8 @@ class Frame(wx.Frame): | ||
456 | self.OnUndo() | 461 | self.OnUndo() |
457 | elif id == wx.ID_REDO: | 462 | elif id == wx.ID_REDO: |
458 | self.OnRedo() | 463 | self.OnRedo() |
464 | + elif id == const.ID_GOTO_SLICE: | ||
465 | + self.OnGotoSlice() | ||
459 | 466 | ||
460 | elif id == const.ID_BOOLEAN_MASK: | 467 | elif id == const.ID_BOOLEAN_MASK: |
461 | self.OnMaskBoolean() | 468 | self.OnMaskBoolean() |
@@ -683,6 +690,12 @@ class Frame(wx.Frame): | @@ -683,6 +690,12 @@ class Frame(wx.Frame): | ||
683 | def OnRedo(self): | 690 | def OnRedo(self): |
684 | Publisher.sendMessage('Redo edition') | 691 | Publisher.sendMessage('Redo edition') |
685 | 692 | ||
693 | + def OnGotoSlice(self): | ||
694 | + gt_dialog = dlg.GoToDialog(init_orientation=self._last_viewer_orientation_focus) | ||
695 | + gt_dialog.CenterOnParent() | ||
696 | + gt_dialog.ShowModal() | ||
697 | + self.Refresh() | ||
698 | + | ||
686 | def OnMaskBoolean(self): | 699 | def OnMaskBoolean(self): |
687 | Publisher.sendMessage('Show boolean dialog') | 700 | Publisher.sendMessage('Show boolean dialog') |
688 | 701 | ||
@@ -755,7 +768,8 @@ class MenuBar(wx.MenuBar): | @@ -755,7 +768,8 @@ class MenuBar(wx.MenuBar): | ||
755 | const.ID_THRESHOLD_SEGMENTATION, | 768 | const.ID_THRESHOLD_SEGMENTATION, |
756 | const.ID_FLOODFILL_SEGMENTATION, | 769 | const.ID_FLOODFILL_SEGMENTATION, |
757 | const.ID_CREATE_SURFACE, | 770 | const.ID_CREATE_SURFACE, |
758 | - const.ID_CREATE_MASK] | 771 | + const.ID_CREATE_MASK, |
772 | + const.ID_GOTO_SLICE] | ||
759 | self.__init_items() | 773 | self.__init_items() |
760 | self.__bind_events() | 774 | self.__bind_events() |
761 | 775 | ||
@@ -839,6 +853,7 @@ class MenuBar(wx.MenuBar): | @@ -839,6 +853,7 @@ class MenuBar(wx.MenuBar): | ||
839 | else: | 853 | else: |
840 | file_edit.Append(wx.ID_UNDO, _("Undo\tCtrl+Z")).Enable(False) | 854 | file_edit.Append(wx.ID_UNDO, _("Undo\tCtrl+Z")).Enable(False) |
841 | file_edit.Append(wx.ID_REDO, _("Redo\tCtrl+Y")).Enable(False) | 855 | file_edit.Append(wx.ID_REDO, _("Redo\tCtrl+Y")).Enable(False) |
856 | + file_edit.Append(const.ID_GOTO_SLICE, _("Go to slice ...\tCtrl+G")) | ||
842 | #app(const.ID_EDIT_LIST, "Show Undo List...") | 857 | #app(const.ID_EDIT_LIST, "Show Undo List...") |
843 | ################################################################# | 858 | ################################################################# |
844 | 859 |