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 | 98 | VOLUME = 4 |
99 | 99 | SURFACE = 5 |
100 | 100 | |
101 | +AXIAL_STR="AXIAL" | |
102 | +CORONAL_STR="CORONAL" | |
103 | +SAGITAL_STR="SAGITAL" | |
104 | + | |
101 | 105 | # Measure type |
102 | 106 | LINEAR = 6 |
103 | 107 | ANGULAR = 7 |
... | ... | @@ -550,6 +554,8 @@ ID_CROP_MASK = wx.NewId() |
550 | 554 | ID_CREATE_SURFACE = wx.NewId() |
551 | 555 | ID_CREATE_MASK = wx.NewId() |
552 | 556 | |
557 | +ID_GOTO_SLICE = wx.NewId() | |
558 | + | |
553 | 559 | #--------------------------------------------------------- |
554 | 560 | STATE_DEFAULT = 1000 |
555 | 561 | STATE_WL = 1001 | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -1263,6 +1263,11 @@ class Viewer(wx.Panel): |
1263 | 1263 | else: |
1264 | 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 | 1271 | def OnExportPicture(self, orientation, filename, filetype): |
1267 | 1272 | dict = {"AXIAL": const.AXIAL, |
1268 | 1273 | "CORONAL": const.CORONAL, | ... | ... |
invesalius/gui/dialogs.py
... | ... | @@ -3590,3 +3590,68 @@ class SurfaceProgressWindow(object): |
3590 | 3590 | |
3591 | 3591 | def Close(self): |
3592 | 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 | 98 | self.SetIcon(wx.Icon(icon_path, wx.BITMAP_TYPE_ICO)) |
99 | 99 | |
100 | 100 | self.mw = None |
101 | - | |
101 | + self._last_viewer_orientation_focus = const.AXIAL_STR | |
102 | 102 | |
103 | 103 | if sys.platform != 'darwin': |
104 | 104 | self.Maximize() |
... | ... | @@ -153,6 +153,7 @@ class Frame(wx.Frame): |
153 | 153 | sub(self._ShowImportBitmap, 'Show import bitmap panel in frame') |
154 | 154 | sub(self._ShowTask, 'Show task panel') |
155 | 155 | sub(self._UpdateAUI, 'Update AUI') |
156 | + sub(self._UpdateViewerFocus, 'Set viewer orientation focus') | |
156 | 157 | sub(self._Exit, 'Exit') |
157 | 158 | |
158 | 159 | def __bind_events_wx(self): |
... | ... | @@ -388,6 +389,10 @@ class Frame(wx.Frame): |
388 | 389 | """ |
389 | 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 | 396 | def CloseProject(self): |
392 | 397 | Publisher.sendMessage('Close Project') |
393 | 398 | |
... | ... | @@ -456,6 +461,8 @@ class Frame(wx.Frame): |
456 | 461 | self.OnUndo() |
457 | 462 | elif id == wx.ID_REDO: |
458 | 463 | self.OnRedo() |
464 | + elif id == const.ID_GOTO_SLICE: | |
465 | + self.OnGotoSlice() | |
459 | 466 | |
460 | 467 | elif id == const.ID_BOOLEAN_MASK: |
461 | 468 | self.OnMaskBoolean() |
... | ... | @@ -683,6 +690,12 @@ class Frame(wx.Frame): |
683 | 690 | def OnRedo(self): |
684 | 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 | 699 | def OnMaskBoolean(self): |
687 | 700 | Publisher.sendMessage('Show boolean dialog') |
688 | 701 | |
... | ... | @@ -755,7 +768,8 @@ class MenuBar(wx.MenuBar): |
755 | 768 | const.ID_THRESHOLD_SEGMENTATION, |
756 | 769 | const.ID_FLOODFILL_SEGMENTATION, |
757 | 770 | const.ID_CREATE_SURFACE, |
758 | - const.ID_CREATE_MASK] | |
771 | + const.ID_CREATE_MASK, | |
772 | + const.ID_GOTO_SLICE] | |
759 | 773 | self.__init_items() |
760 | 774 | self.__bind_events() |
761 | 775 | |
... | ... | @@ -839,6 +853,7 @@ class MenuBar(wx.MenuBar): |
839 | 853 | else: |
840 | 854 | file_edit.Append(wx.ID_UNDO, _("Undo\tCtrl+Z")).Enable(False) |
841 | 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 | 857 | #app(const.ID_EDIT_LIST, "Show Undo List...") |
843 | 858 | ################################################################# |
844 | 859 | ... | ... |