Commit 3d07ca3411f5f3ff484fd80ffc674478d0c7ade7
1 parent
9076ea01
Exists in
master
and in
68 other branches
ENH: Notebook page related to measurements / pubsub evt
Showing
2 changed files
with
324 additions
and
50 deletions
Show diff stats
invesalius/data/viewer_volume.py
| @@ -636,8 +636,18 @@ class Viewer(wx.Panel): | @@ -636,8 +636,18 @@ class Viewer(wx.Panel): | ||
| 636 | m = self.measures[-1] | 636 | m = self.measures[-1] |
| 637 | m.AddPoint(x, y, z) | 637 | m.AddPoint(x, y, z) |
| 638 | if m.IsComplete(): | 638 | if m.IsComplete(): |
| 639 | - ps.Publisher().sendMessage("Add measure to list", | ||
| 640 | - (u"3D", _(u"%.3f mm" % m.GetValue()))) | 639 | + index = len(self.measures) - 1 |
| 640 | + name = "M" | ||
| 641 | + colour = m.colour | ||
| 642 | + type_ = _("Linear") | ||
| 643 | + location = u"3D" | ||
| 644 | + value = u"%.2f mm"% m.GetValue() | ||
| 645 | + | ||
| 646 | + msg = 'Update measurement info in GUI', | ||
| 647 | + ps.Publisher().sendMessage(msg, | ||
| 648 | + (index, name, colour, | ||
| 649 | + type_, location, | ||
| 650 | + value)) | ||
| 641 | self.interactor.Render() | 651 | self.interactor.Render() |
| 642 | 652 | ||
| 643 | def OnInsertAngularMeasurePoint(self, obj, evt): | 653 | def OnInsertAngularMeasurePoint(self, obj, evt): |
| @@ -654,8 +664,17 @@ class Viewer(wx.Panel): | @@ -654,8 +664,17 @@ class Viewer(wx.Panel): | ||
| 654 | m = self.measures[-1] | 664 | m = self.measures[-1] |
| 655 | m.AddPoint(x, y, z) | 665 | m.AddPoint(x, y, z) |
| 656 | if m.IsComplete(): | 666 | if m.IsComplete(): |
| 657 | - ps.Publisher().sendMessage("Add measure to list", | ||
| 658 | - (u"3D", _(u"%.3fº" % m.GetValue()))) | 667 | + index = len(self.measures) - 1 |
| 668 | + name = "M" | ||
| 669 | + colour = m.colour | ||
| 670 | + type_ = _("Angular") | ||
| 671 | + location = u"3D" | ||
| 672 | + value = u"%.2f˚"% m.GetValue() | ||
| 673 | + msg = 'Update measurement info in GUI', | ||
| 674 | + ps.Publisher().sendMessage(msg, | ||
| 675 | + (index, name, colour, | ||
| 676 | + type_, location, | ||
| 677 | + value)) | ||
| 659 | self.interactor.Render() | 678 | self.interactor.Render() |
| 660 | 679 | ||
| 661 | 680 |
invesalius/gui/data_notebook.py
| @@ -48,12 +48,10 @@ class NotebookPanel(wx.Panel): | @@ -48,12 +48,10 @@ class NotebookPanel(wx.Panel): | ||
| 48 | if sys.platform != 'win32': | 48 | if sys.platform != 'win32': |
| 49 | book.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) | 49 | book.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) |
| 50 | 50 | ||
| 51 | - self.measures_list = MeasuresListCtrlPanel(book) | ||
| 52 | - | ||
| 53 | book.AddPage(MaskPage(book), _("Masks")) | 51 | book.AddPage(MaskPage(book), _("Masks")) |
| 54 | book.AddPage(SurfacePage(book), _("Surfaces")) | 52 | book.AddPage(SurfacePage(book), _("Surfaces")) |
| 55 | - book.AddPage(self.measures_list, _("Measures")) | ||
| 56 | - book.AddPage(AnnotationsListCtrlPanel(book), _("Annotations")) | 53 | + book.AddPage(MeasurePage(book), _("Measures")) |
| 54 | + #book.AddPage(AnnotationsListCtrlPanel(book), _("Annotations")) | ||
| 57 | 55 | ||
| 58 | book.SetSelection(0) | 56 | book.SetSelection(0) |
| 59 | 57 | ||
| @@ -63,19 +61,111 @@ class NotebookPanel(wx.Panel): | @@ -63,19 +61,111 @@ class NotebookPanel(wx.Panel): | ||
| 63 | 61 | ||
| 64 | book.Refresh() | 62 | book.Refresh() |
| 65 | 63 | ||
| 66 | - self.__bind_events() | 64 | + #def __bind_events(self): |
| 65 | + # ps.Publisher().subscribe(self._add_measure, | ||
| 66 | + # "Add measure to list") | ||
| 67 | + | ||
| 68 | + #def _add_measure(self, pubsub_evt): | ||
| 69 | + # type = pubsub_evt.data[0] | ||
| 70 | + # value = pubsub_evt.data[1] | ||
| 71 | + # self.measures_list.AddMeasure(type, value) | ||
| 72 | + | ||
| 73 | + | ||
| 74 | + | ||
| 75 | +class MeasurePage(wx.Panel): | ||
| 76 | + """ | ||
| 77 | + Page related to mask items. | ||
| 78 | + """ | ||
| 79 | + def __init__(self, parent): | ||
| 80 | + wx.Panel.__init__(self, parent, pos=wx.Point(0, 50), | ||
| 81 | + size=wx.Size(256, 140)) | ||
| 82 | + self.__init_gui() | ||
| 83 | + | ||
| 84 | + def __init_gui(self): | ||
| 85 | + # listctrl were existing masks will be listed | ||
| 86 | + self.listctrl = MeasuresListCtrlPanel(self, size=wx.Size(256, 100)) | ||
| 87 | + # button control with tools (eg. remove, add new, etc) | ||
| 88 | + self.buttonctrl = MeasureButtonControlPanel(self) | ||
| 89 | + | ||
| 90 | + sizer = wx.BoxSizer(wx.VERTICAL) | ||
| 91 | + sizer.Add(self.listctrl, 0, wx.EXPAND) | ||
| 92 | + sizer.Add(self.buttonctrl, 0, wx.EXPAND| wx.TOP, 2) | ||
| 93 | + self.SetSizer(sizer) | ||
| 94 | + self.Fit() | ||
| 95 | + | ||
| 96 | + | ||
| 97 | + | ||
| 98 | + | ||
| 99 | +class MeasureButtonControlPanel(wx.Panel): | ||
| 100 | + """ | ||
| 101 | + Button control panel that includes data notebook operations. | ||
| 102 | + TODO: Enhace interface with parent class - it is really messed up | ||
| 103 | + """ | ||
| 104 | + def __init__(self, parent): | ||
| 105 | + wx.Panel.__init__(self, parent, pos=wx.Point(0, 50), | ||
| 106 | + size=wx.Size(256, 22)) | ||
| 107 | + self.parent = parent | ||
| 108 | + self.__init_gui() | ||
| 109 | + | ||
| 110 | + def __init_gui(self): | ||
| 67 | 111 | ||
| 68 | - # TODO: insert icons bellow notebook | 112 | + # Bitmaps to be used in plate buttons |
| 113 | + BMP_NEW = wx.Bitmap("../icons/data_new.png", | ||
| 114 | + wx.BITMAP_TYPE_PNG) | ||
| 115 | + BMP_REMOVE = wx.Bitmap("../icons/data_remove.png", | ||
| 116 | + wx.BITMAP_TYPE_PNG) | ||
| 117 | + BMP_DUPLICATE = wx.Bitmap("../icons/data_duplicate.png", | ||
| 118 | + wx.BITMAP_TYPE_PNG) | ||
| 69 | 119 | ||
| 70 | - def __bind_events(self): | ||
| 71 | - ps.Publisher().subscribe(self._add_measure, | ||
| 72 | - "Add measure to list") | 120 | + # Plate buttons based on previous bitmaps |
| 121 | + button_style = pbtn.PB_STYLE_SQUARE | pbtn.PB_STYLE_DEFAULT | ||
| 122 | + button_new = pbtn.PlateButton(self, BTN_NEW, "", | ||
| 123 | + BMP_NEW, | ||
| 124 | + style=button_style, | ||
| 125 | + size = wx.Size(18, 18)) | ||
| 126 | + button_remove = pbtn.PlateButton(self, BTN_REMOVE, "", | ||
| 127 | + BMP_REMOVE, | ||
| 128 | + style=button_style, | ||
| 129 | + size = wx.Size(18, 18)) | ||
| 130 | + button_duplicate = pbtn.PlateButton(self, BTN_DUPLICATE, "", | ||
| 131 | + BMP_DUPLICATE, | ||
| 132 | + style=button_style, | ||
| 133 | + size = wx.Size(18, 18)) | ||
| 73 | 134 | ||
| 74 | - def _add_measure(self, pubsub_evt): | ||
| 75 | - type = pubsub_evt.data[0] | ||
| 76 | - value = pubsub_evt.data[1] | 135 | + # Add all controls to gui |
| 136 | + sizer = wx.BoxSizer(wx.HORIZONTAL) | ||
| 137 | + sizer.Add(button_new, 0, wx.GROW|wx.EXPAND|wx.LEFT) | ||
| 138 | + sizer.Add(button_remove, 0, wx.GROW|wx.EXPAND) | ||
| 139 | + sizer.Add(button_duplicate, 0, wx.GROW|wx.EXPAND) | ||
| 140 | + self.SetSizer(sizer) | ||
| 141 | + self.Fit() | ||
| 77 | 142 | ||
| 78 | - self.measures_list.AddMeasure(type, value) | 143 | + # Bindings |
| 144 | + self.Bind(wx.EVT_BUTTON, self.OnButton) | ||
| 145 | + | ||
| 146 | + def OnButton(self, evt): | ||
| 147 | + id = evt.GetId() | ||
| 148 | + if id == BTN_NEW: | ||
| 149 | + self.OnNew() | ||
| 150 | + elif id == BTN_REMOVE: | ||
| 151 | + self.OnRemove() | ||
| 152 | + elif id == BTN_DUPLICATE: | ||
| 153 | + self.OnDuplicate() | ||
| 154 | + | ||
| 155 | + def OnNew(self): | ||
| 156 | + mask_name = dlg.NewMask() | ||
| 157 | + if mask_name: | ||
| 158 | + ps.Publisher().sendMessage('Set measurement state', mask_name) | ||
| 159 | + | ||
| 160 | + def OnRemove(self): | ||
| 161 | + self.parent.listctrl.RemoveMasks() | ||
| 162 | + | ||
| 163 | + def OnDuplicate(self): | ||
| 164 | + selected_items = self.parent.listctrl.GetSelected() | ||
| 165 | + if selected_items: | ||
| 166 | + ps.Publisher().sendMessage('Duplicate measurement', selected_items) | ||
| 167 | + else: | ||
| 168 | + dlg.MaskSelectionRequiredForDuplication() | ||
| 79 | 169 | ||
| 80 | 170 | ||
| 81 | 171 | ||
| @@ -300,7 +390,8 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -300,7 +390,8 @@ class MasksListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
| 300 | self.image_gray = Image.open("../icons/object_colour.jpg") | 390 | self.image_gray = Image.open("../icons/object_colour.jpg") |
| 301 | 391 | ||
| 302 | def OnEditLabel(self, evt): | 392 | def OnEditLabel(self, evt): |
| 303 | - ps.Publisher().sendMessage('Change mask name', (evt.GetIndex(), evt.GetLabel())) | 393 | + ps.Publisher().sendMessage('Change mask name', |
| 394 | + (evt.GetIndex(), evt.GetLabel())) | ||
| 304 | evt.Skip() | 395 | evt.Skip() |
| 305 | 396 | ||
| 306 | def OnItemActivated(self, evt): | 397 | def OnItemActivated(self, evt): |
| @@ -641,7 +732,6 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -641,7 +732,6 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
| 641 | 732 | ||
| 642 | def OnItemActivated(self, evt): | 733 | def OnItemActivated(self, evt): |
| 643 | self.ToggleItem(evt.m_itemIndex) | 734 | self.ToggleItem(evt.m_itemIndex) |
| 644 | - #ps.Publisher().sendMessage('Change surface selected',index) | ||
| 645 | evt.Skip() | 735 | evt.Skip() |
| 646 | 736 | ||
| 647 | 737 | ||
| @@ -752,7 +842,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -752,7 +842,7 @@ class SurfacesListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
| 752 | #------------------------------------------------- | 842 | #------------------------------------------------- |
| 753 | 843 | ||
| 754 | class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | 844 | class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |
| 755 | - # TODO: Change edimixin to affect third column also | 845 | + |
| 756 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, | 846 | def __init__(self, parent, ID=-1, pos=wx.DefaultPosition, |
| 757 | size=wx.DefaultSize, style=wx.LC_REPORT): | 847 | size=wx.DefaultSize, style=wx.LC_REPORT): |
| 758 | 848 | ||
| @@ -766,66 +856,231 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | @@ -766,66 +856,231 @@ class MeasuresListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | ||
| 766 | self.__init_columns() | 856 | self.__init_columns() |
| 767 | self.__init_image_list() | 857 | self.__init_image_list() |
| 768 | self.__init_evt() | 858 | self.__init_evt() |
| 859 | + self.__bind_events_wx() | ||
| 860 | + self._list_index = {} | ||
| 861 | + self._bmp_idx_to_name = {} | ||
| 769 | 862 | ||
| 770 | - self._last_measure = 0 | ||
| 771 | - | ||
| 772 | def __init_evt(self): | 863 | def __init_evt(self): |
| 864 | + ps.Publisher().subscribe(self.AddItem_, | ||
| 865 | + 'Update measurement info in GUI') | ||
| 866 | + ps.Publisher().subscribe(self.EditItemColour, | ||
| 867 | + 'Set measurement colour') | ||
| 868 | + ps.Publisher().subscribe(self.OnCloseProject, 'Close project data') | ||
| 869 | + ps.Publisher().subscribe(self.OnShowSingle, 'Show single measurement') | ||
| 870 | + ps.Publisher().subscribe(self.OnShowMultiple, 'Show multiple measurements') | ||
| 871 | + | ||
| 872 | + def __bind_events_wx(self): | ||
| 773 | self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) | 873 | self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) |
| 874 | + self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEditLabel) | ||
| 875 | + self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected_) | ||
| 876 | + self.Bind(wx.EVT_KEY_UP, self.OnKeyEvent) | ||
| 877 | + | ||
| 878 | + | ||
| 879 | + def OnKeyEvent(self, event): | ||
| 880 | + keycode = event.GetKeyCode() | ||
| 881 | + # Delete key | ||
| 882 | + if (sys.platform == 'darwin') and (keycode == wx.WXK_BACK): | ||
| 883 | + self.RemoveMeasurements() | ||
| 884 | + elif (keycode == wx.WXK_DELETE): | ||
| 885 | + self.RemoveMeasurements() | ||
| 886 | + | ||
| 887 | + def RemoveMeasurements(self): | ||
| 888 | + """ | ||
| 889 | + Remove item given its index. | ||
| 890 | + """ | ||
| 891 | + # it is necessary to update internal dictionary | ||
| 892 | + # that maps bitmap given item index | ||
| 893 | + selected_items = self.GetSelected() | ||
| 894 | + old_dict = self._list_index | ||
| 895 | + new_dict = {} | ||
| 896 | + if selected_items: | ||
| 897 | + for index in selected_items: | ||
| 898 | + self.DeleteItem(index) | ||
| 899 | + for i in old_dict: | ||
| 900 | + if i < index: | ||
| 901 | + new_dict[i] = old_dict[i] | ||
| 902 | + if i > index: | ||
| 903 | + new_dict[i-1] = old_dict[i] | ||
| 904 | + old_dict = new_dict | ||
| 905 | + self._list_index = new_dict | ||
| 906 | + | ||
| 907 | + ps.Publisher().sendMessage('Remove measurements', selected_items) | ||
| 908 | + else: | ||
| 909 | + dlg.SurfaceSelectionRequiredForRemoval() | ||
| 910 | + | ||
| 911 | + | ||
| 912 | + def OnCloseProject(self, pubsub_evt): | ||
| 913 | + self.DeleteAllItems() | ||
| 914 | + self._list_index = {} | ||
| 915 | + self._bmp_idx_to_name = {} | ||
| 916 | + | ||
| 917 | + def OnItemSelected_(self, evt): | ||
| 918 | + # Note: DON'T rename to OnItemSelected!!! | ||
| 919 | + # Otherwise the parent's method will be overwritten and other | ||
| 920 | + # things will stop working, e.g.: OnCheckItem | ||
| 921 | + | ||
| 922 | + last_index = evt.m_itemIndex | ||
| 923 | + ps.Publisher().sendMessage('Change measurement selected', | ||
| 924 | + last_index) | ||
| 925 | + evt.Skip() | ||
| 926 | + | ||
| 927 | + def GetSelected(self): | ||
| 928 | + """ | ||
| 929 | + Return all items selected (highlighted). | ||
| 930 | + """ | ||
| 931 | + selected = [] | ||
| 932 | + for index in self._list_index: | ||
| 933 | + if self.IsSelected(index): | ||
| 934 | + selected.append(index) | ||
| 935 | + # it is important to revert items order, so | ||
| 936 | + # listctrl update is ok | ||
| 937 | + selected.sort(reverse=True) | ||
| 938 | + | ||
| 939 | + return selected | ||
| 774 | 940 | ||
| 775 | def __init_columns(self): | 941 | def __init_columns(self): |
| 776 | - | 942 | + |
| 777 | self.InsertColumn(0, "", wx.LIST_FORMAT_CENTER) | 943 | self.InsertColumn(0, "", wx.LIST_FORMAT_CENTER) |
| 778 | - self.InsertColumn(1, "Value") | ||
| 779 | - self.InsertColumn(2, "Type", wx.LIST_FORMAT_RIGHT) | ||
| 780 | - | ||
| 781 | - self.SetColumnWidth(0, 20) | ||
| 782 | - self.SetColumnWidth(1, 120) | ||
| 783 | - self.SetColumnWidth(2, 50) | 944 | + self.InsertColumn(1, _("Name")) |
| 945 | + self.InsertColumn(2, _("Location")) | ||
| 946 | + self.InsertColumn(3, _("Type")) | ||
| 947 | + self.InsertColumn(4, _("Value"), wx.LIST_FORMAT_RIGHT) | ||
| 784 | 948 | ||
| 949 | + self.SetColumnWidth(0, 15) | ||
| 950 | + self.SetColumnWidth(1, 70) | ||
| 951 | + self.SetColumnWidth(2, 55) | ||
| 952 | + self.SetColumnWidth(3, 50) | ||
| 953 | + self.SetColumnWidth(4, 75) | ||
| 954 | + | ||
| 785 | def __init_image_list(self): | 955 | def __init_image_list(self): |
| 786 | self.imagelist = wx.ImageList(16, 16) | 956 | self.imagelist = wx.ImageList(16, 16) |
| 787 | 957 | ||
| 788 | - image = wx.Image("../icons/object_visible.jpg") | ||
| 789 | - bitmap = wx.BitmapFromImage(image.Scale(16, 16)) | ||
| 790 | - bitmap.SetWidth(16) | ||
| 791 | - bitmap.SetHeight(16) | ||
| 792 | - img_check = self.imagelist.Add(bitmap) | ||
| 793 | - | ||
| 794 | image = wx.Image("../icons/object_invisible.jpg") | 958 | image = wx.Image("../icons/object_invisible.jpg") |
| 795 | bitmap = wx.BitmapFromImage(image.Scale(16, 16)) | 959 | bitmap = wx.BitmapFromImage(image.Scale(16, 16)) |
| 796 | bitmap.SetWidth(16) | 960 | bitmap.SetWidth(16) |
| 797 | bitmap.SetHeight(16) | 961 | bitmap.SetHeight(16) |
| 798 | img_null = self.imagelist.Add(bitmap) | 962 | img_null = self.imagelist.Add(bitmap) |
| 799 | 963 | ||
| 800 | - image = wx.Image("../icons/object_colour.jpg") | 964 | + image = wx.Image("../icons/object_visible.jpg") |
| 801 | bitmap = wx.BitmapFromImage(image.Scale(16, 16)) | 965 | bitmap = wx.BitmapFromImage(image.Scale(16, 16)) |
| 802 | bitmap.SetWidth(16) | 966 | bitmap.SetWidth(16) |
| 803 | bitmap.SetHeight(16) | 967 | bitmap.SetHeight(16) |
| 804 | - self.img_colour = self.imagelist.Add(bitmap) | 968 | + img_check = self.imagelist.Add(bitmap) |
| 805 | 969 | ||
| 806 | self.SetImageList(self.imagelist,wx.IMAGE_LIST_SMALL) | 970 | self.SetImageList(self.imagelist,wx.IMAGE_LIST_SMALL) |
| 807 | - | 971 | + |
| 972 | + self.image_gray = Image.open("../icons/object_colour.jpg") | ||
| 973 | + | ||
| 974 | + | ||
| 975 | + def OnEditLabel(self, evt): | ||
| 976 | + ps.Publisher().sendMessage('Change measurement name', (evt.GetIndex(), evt.GetLabel())) | ||
| 977 | + evt.Skip() | ||
| 808 | 978 | ||
| 809 | def OnItemActivated(self, evt): | 979 | def OnItemActivated(self, evt): |
| 810 | self.ToggleItem(evt.m_itemIndex) | 980 | self.ToggleItem(evt.m_itemIndex) |
| 981 | + evt.Skip() | ||
| 982 | + | ||
| 811 | 983 | ||
| 812 | def OnCheckItem(self, index, flag): | 984 | def OnCheckItem(self, index, flag): |
| 813 | - # TODO: use pubsub to communicate to models | ||
| 814 | - if flag: | ||
| 815 | - print "checked, ", index | ||
| 816 | - else: | ||
| 817 | - print "unchecked, ", index | 985 | + ps.Publisher().sendMessage('Show measurement', (index, flag)) |
| 818 | 986 | ||
| 819 | - def InsertNewItem(self, index=0, type_="", value="(1000, 4500)", | ||
| 820 | - colour=None): | 987 | + def OnShowSingle(self, pubsub_evt): |
| 988 | + index, visibility = pubsub_evt.data | ||
| 989 | + for key in self._list_index.keys(): | ||
| 990 | + if key != index: | ||
| 991 | + self.SetItemImage(key, not visibility) | ||
| 992 | + ps.Publisher().sendMessage('Show measurement', | ||
| 993 | + (key, not visibility)) | ||
| 994 | + self.SetItemImage(index, visibility) | ||
| 995 | + ps.Publisher().sendMessage('Show measurement', | ||
| 996 | + (index, visibility)) | ||
| 997 | + | ||
| 998 | + def OnShowMultiple(self, pubsub_evt): | ||
| 999 | + index_list, visibility = pubsub_evt.data | ||
| 1000 | + for key in self._list_index.keys(): | ||
| 1001 | + if key not in index_list: | ||
| 1002 | + self.SetItemImage(key, not visibility) | ||
| 1003 | + ps.Publisher().sendMessage('Show measurement', | ||
| 1004 | + (key, not visibility)) | ||
| 1005 | + for index in index_list: | ||
| 1006 | + self.SetItemImage(index, visibility) | ||
| 1007 | + ps.Publisher().sendMessage('Show measurement', | ||
| 1008 | + (index, visibility)) | ||
| 1009 | + | ||
| 1010 | + def AddItem_(self, pubsub_evt): | ||
| 1011 | + index = pubsub_evt.data[0] | ||
| 1012 | + name = pubsub_evt.data[1] | ||
| 1013 | + colour = pubsub_evt.data[2] | ||
| 1014 | + type_ = pubsub_evt.data[3] | ||
| 1015 | + location = pubsub_evt.data[4] | ||
| 1016 | + value = pubsub_evt.data[5] | ||
| 1017 | + | ||
| 1018 | + | ||
| 1019 | + if index not in self._list_index: | ||
| 1020 | + image = self.CreateColourBitmap(colour) | ||
| 1021 | + image_index = self.imagelist.Add(image) | ||
| 1022 | + | ||
| 1023 | + index_list = self._list_index.keys() | ||
| 1024 | + self._list_index[index] = image_index | ||
| 1025 | + | ||
| 1026 | + if (index in index_list) and index_list: | ||
| 1027 | + self.UpdateItemInfo(index, name, colour, type_, location, value) | ||
| 1028 | + else: | ||
| 1029 | + self.InsertNewItem(index, name, colour, type_, location, value) | ||
| 1030 | + | ||
| 1031 | + | ||
| 1032 | + | ||
| 1033 | + def InsertNewItem(self, index=0, label="Measurement 1", colour=None, | ||
| 1034 | + type_="LINEAR", location="SURFACE", value="0 mm"): | ||
| 821 | self.InsertStringItem(index, "") | 1035 | self.InsertStringItem(index, "") |
| 822 | - self.SetStringItem(index, 1, type_, imageId = self.img_colour) | ||
| 823 | - self.SetStringItem(index, 2, value) | 1036 | + self.SetStringItem(index, 1, label, |
| 1037 | + imageId = self._list_index[index]) | ||
| 1038 | + self.SetStringItem(index, 2, type_) | ||
| 1039 | + self.SetStringItem(index, 3, location) | ||
| 1040 | + self.SetStringItem(index, 4, value) | ||
| 1041 | + self.SetItemImage(index, 1) | ||
| 1042 | + | ||
| 1043 | + def UpdateItemInfo(self, index=0, label="Measurement 1", colour=None, | ||
| 1044 | + type_="LINEAR", location="SURFACE", value="0 mm"): | ||
| 1045 | + self.SetStringItem(index, 1, label, | ||
| 1046 | + imageId = self._list_index[index]) | ||
| 1047 | + self.SetStringItem(index, 2, type_) | ||
| 1048 | + self.SetStringItem(index, 3, location) | ||
| 1049 | + self.SetStringItem(index, 4, value) | ||
| 1050 | + self.SetItemImage(index, 1) | ||
| 1051 | + | ||
| 1052 | + | ||
| 1053 | + def CreateColourBitmap(self, colour): | ||
| 1054 | + """ | ||
| 1055 | + Create a wx Image with a mask colour. | ||
| 1056 | + colour: colour in rgb format(0 - 1) | ||
| 1057 | + """ | ||
| 1058 | + image = self.image_gray | ||
| 1059 | + new_image = Image.new("RGB", image.size) | ||
| 1060 | + for x in xrange(image.size[0]): | ||
| 1061 | + for y in xrange(image.size[1]): | ||
| 1062 | + pixel_colour = [int(i*image.getpixel((x,y))) | ||
| 1063 | + for i in colour] | ||
| 1064 | + new_image.putpixel((x,y), tuple(pixel_colour)) | ||
| 1065 | + | ||
| 1066 | + wx_image = wx.EmptyImage(new_image.size[0], | ||
| 1067 | + new_image.size[1]) | ||
| 1068 | + wx_image.SetData(new_image.tostring()) | ||
| 1069 | + return wx.BitmapFromImage(wx_image.Scale(16, 16)) | ||
| 1070 | + | ||
| 1071 | + def EditItemColour(self, pubsub_evt): | ||
| 1072 | + """ | ||
| 1073 | + """ | ||
| 1074 | + index, colour = pubsub_evt.data | ||
| 1075 | + image = self.CreateColourBitmap(colour) | ||
| 1076 | + image_index = self._list_index[index] | ||
| 1077 | + self.imagelist.Replace(image_index, image) | ||
| 1078 | + self.Refresh() | ||
| 1079 | + | ||
| 824 | 1080 | ||
| 825 | - def AddMeasure(self, type_, value, colour=None): | ||
| 826 | - self.InsertNewItem(self._last_measure, type_, value, colour) | ||
| 827 | - self._last_measure += 1 | ||
| 828 | 1081 | ||
| 1082 | +#******************************************************************* | ||
| 1083 | +#******************************************************************* | ||
| 829 | 1084 | ||
| 830 | 1085 | ||
| 831 | class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): | 1086 | class AnnotationsListCtrlPanel(wx.ListCtrl, listmix.TextEditMixin): |