766 if button.HitTest(x, y): |
766 if button.HitTest(x, y): |
767 button.ProcessCallback() |
767 button.ProcessCallback() |
768 return True |
768 return True |
769 return False |
769 return False |
770 |
770 |
771 def PopupContextualButtons(self, item, rect, style=wx.HORIZONTAL): |
771 def PopupContextualButtons(self, item, rect, style=wx.RIGHT): |
772 if self.ContextualButtonsItem is not None and item != self.ContextualButtonsItem: |
772 if self.ContextualButtonsItem is not None and item != self.ContextualButtonsItem: |
773 self.DismissContextualButtons() |
773 self.DismissContextualButtons() |
774 |
774 |
775 if self.ContextualButtonsItem is None: |
775 if self.ContextualButtonsItem is None: |
776 self.ContextualButtonsItem = item |
776 self.ContextualButtonsItem = item |
784 self.ContextualButtons.append( |
784 self.ContextualButtons.append( |
785 GraphButton(0, 0, GetBitmap("delete_graph"), self.OnRemoveItemButton)) |
785 GraphButton(0, 0, GetBitmap("delete_graph"), self.OnRemoveItemButton)) |
786 |
786 |
787 offset = 0 |
787 offset = 0 |
788 buttons = self.ContextualButtons[:] |
788 buttons = self.ContextualButtons[:] |
789 if style == wx.VERTICAL: |
789 if style in [wx.TOP, wx.LEFT]: |
790 buttons.reverse() |
790 buttons.reverse() |
791 for button in buttons: |
791 for button in buttons: |
792 w, h = button.GetSize() |
792 w, h = button.GetSize() |
793 if style == wx.HORIZONTAL: |
793 if style in [wx.LEFT, wx.RIGHT]: |
794 x = rect.x + rect.width + offset |
794 if style == wx.LEFT: |
|
795 x = rect.x - w - offset |
|
796 else: |
|
797 x = rect.x + rect.width + offset |
795 y = rect.y + (rect.height - h) / 2 |
798 y = rect.y + (rect.height - h) / 2 |
796 offset += w |
799 offset += w |
797 else: |
800 else: |
798 x = rect.x + (rect.width - w ) / 2 |
801 x = rect.x + (rect.width - w ) / 2 |
799 y = rect.y - h - offset |
802 if style == wx.TOP: |
|
803 y = rect.y - h - offset |
|
804 else: |
|
805 y = rect.y + rect.height + offset |
800 offset += h |
806 offset += h |
801 button.SetPosition(x, y) |
807 button.SetPosition(x, y) |
802 self.ParentWindow.ForceRefresh() |
808 self.ParentWindow.ForceRefresh() |
803 |
809 |
804 def DismissContextualButtons(self): |
810 def DismissContextualButtons(self): |
905 self.SetSizer(main_sizer) |
911 self.SetSizer(main_sizer) |
906 |
912 |
907 self.ResetGraphics() |
913 self.ResetGraphics() |
908 |
914 |
909 def RefreshLabelsPosition(self, ratio): |
915 def RefreshLabelsPosition(self, ratio): |
910 self.MaskLabel.set_position((0.05, 1.0 - 0.1 * ratio)) |
|
911 if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas(): |
916 if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas(): |
912 num_item = len(self.Items) |
917 num_item = len(self.Items) |
913 for idx in xrange(num_item): |
918 for idx in xrange(num_item): |
914 if not self.Is3DCanvas(): |
919 if not self.Is3DCanvas(): |
915 self.AxesLabels[idx].set_position((0.05, 1.0 - (0.1 + 0.075 * (idx + 1)) * ratio)) |
920 self.AxesLabels[idx].set_position((0.05, 1.0 - (0.1 + 0.075 * idx) * ratio)) |
916 self.Labels[idx].set_position((0.95, 0.1 + (num_item - idx - 1) * 0.1 * ratio)) |
921 self.Labels[idx].set_position((0.95, 0.1 + (num_item - idx - 1) * 0.1 * ratio)) |
917 else: |
922 else: |
918 self.AxesLabels[0].set_position((0.1, 0.05 * ratio)) |
923 self.AxesLabels[0].set_position((0.1, 0.05 * ratio)) |
919 self.Labels[0].set_position((0.95, 0.05 * ratio)) |
924 self.Labels[0].set_position((0.95, 0.05 * ratio)) |
920 self.AxesLabels[1].set_position((0.05, 0.1 * ratio)) |
925 self.AxesLabels[1].set_position((0.05, 0.1 * ratio)) |
948 if not self.Canvas.IsOverButton(x, y) and not self.Is3DCanvas(): |
953 if not self.Canvas.IsOverButton(x, y) and not self.Is3DCanvas(): |
949 rect = self.GetAxesBoundingBox() |
954 rect = self.GetAxesBoundingBox() |
950 if rect.InsideXY(x, y): |
955 if rect.InsideXY(x, y): |
951 self.MouseStartPos = wx.Point(x, y) |
956 self.MouseStartPos = wx.Point(x, y) |
952 item_idx = None |
957 item_idx = None |
953 for i, t in enumerate(self.AxesLabels): |
958 for i, t in ([pair for pair in enumerate(self.AxesLabels)] + |
|
959 [pair for pair in enumerate(self.Labels)]): |
954 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
960 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
955 rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0) |
961 rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0) |
956 if rect.InsideXY(x, y): |
962 if rect.InsideXY(x, y): |
957 item_idx = i |
963 item_idx = i |
958 break |
964 break |
973 def OnCanvasButtonReleased(self, event): |
979 def OnCanvasButtonReleased(self, event): |
974 if self.ParentWindow.IsDragging(): |
980 if self.ParentWindow.IsDragging(): |
975 width, height = self.Canvas.GetSize() |
981 width, height = self.Canvas.GetSize() |
976 xw, yw = self.GetPosition() |
982 xw, yw = self.GetPosition() |
977 self.ParentWindow.StopDragNDrop( |
983 self.ParentWindow.StopDragNDrop( |
978 self.Items[0].GetVariable(), |
984 self.ParentWindow.DraggingAxesPanel.Items[0].GetVariable(), |
979 xw + event.x, |
985 xw + event.x, |
980 yw + height - event.y) |
986 yw + height - event.y) |
981 else: |
987 else: |
982 self.MouseStartPos = None |
988 self.MouseStartPos = None |
983 self.StartCursorTick = None |
989 self.StartCursorTick = None |
1008 self.ParentWindow.SetCanvasPosition( |
1014 self.ParentWindow.SetCanvasPosition( |
1009 self.StartCursorTick + (self.MouseStartPos.x - event.x) * |
1015 self.StartCursorTick + (self.MouseStartPos.x - event.x) * |
1010 (end_tick - start_tick) / rect.width) |
1016 (end_tick - start_tick) / rect.width) |
1011 elif event.button is None: |
1017 elif event.button is None: |
1012 if self.GraphType == GRAPH_PARALLEL: |
1018 if self.GraphType == GRAPH_PARALLEL: |
1013 orientation = [wx.HORIZONTAL] * len(self.AxesLabels) |
1019 orientation = [wx.RIGHT] * len(self.AxesLabels) + [wx.LEFT] * len(self.Labels) |
1014 elif len(self.AxesLabels) > 0: |
1020 elif len(self.AxesLabels) > 0: |
1015 orientation = [wx.HORIZONTAL, wx.VERTICAL] |
1021 orientation = [wx.RIGHT, wx.TOP, wx.LEFT, wx.BOTTOM] |
1016 item_idx = None |
1022 item_idx = None |
1017 item_style = None |
1023 item_style = None |
1018 for i, (t, style) in enumerate(zip(self.AxesLabels, orientation)): |
1024 for (i, t), style in zip([pair for pair in enumerate(self.AxesLabels)] + |
|
1025 [pair for pair in enumerate(self.Labels)], |
|
1026 orientation): |
1019 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
1027 (x0, y0), (x1, y1) = t.get_window_extent().get_points() |
1020 rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0) |
1028 rect = wx.Rect(x0, height - y1, x1 - x0, y1 - y0) |
1021 if rect.InsideXY(event.x, height - event.y): |
1029 if rect.InsideXY(event.x, height - event.y): |
1022 item_idx = i |
1030 item_idx = i |
1023 item_style = style |
1031 item_style = style |
1115 self.AxesLabels = [] |
1123 self.AxesLabels = [] |
1116 if not self.Is3DCanvas(): |
1124 if not self.Is3DCanvas(): |
1117 text_func = self.Axes.text |
1125 text_func = self.Axes.text |
1118 else: |
1126 else: |
1119 text_func = self.Axes.text2D |
1127 text_func = self.Axes.text2D |
1120 self.MaskLabel = text_func(0, 0, "", size='small', |
|
1121 transform=self.Axes.transAxes) |
|
1122 if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas(): |
1128 if self.GraphType == GRAPH_PARALLEL or self.Is3DCanvas(): |
1123 num_item = len(self.Items) |
1129 num_item = len(self.Items) |
1124 for idx in xrange(num_item): |
1130 for idx in xrange(num_item): |
1125 if num_item == 1: |
1131 if num_item == 1: |
1126 color = 'k' |
1132 color = 'k' |
1298 values, forced = apply(zip, [item.GetValue(self.CursorTick) for item in self.Items]) |
1304 values, forced = apply(zip, [item.GetValue(self.CursorTick) for item in self.Items]) |
1299 else: |
1305 else: |
1300 values, forced = apply(zip, [(item.GetValue(), item.IsForced()) for item in self.Items]) |
1306 values, forced = apply(zip, [(item.GetValue(), item.IsForced()) for item in self.Items]) |
1301 labels = [item.GetVariable(variable_name_mask) for item in self.Items] |
1307 labels = [item.GetVariable(variable_name_mask) for item in self.Items] |
1302 styles = map(lambda x: {True: 'italic', False: 'normal'}[x], forced) |
1308 styles = map(lambda x: {True: 'italic', False: 'normal'}[x], forced) |
1303 self.MaskLabel.set_text('.'.join(variable_name_mask)) |
|
1304 if self.Is3DCanvas(): |
1309 if self.Is3DCanvas(): |
1305 for idx, label_func in enumerate([self.Axes.set_xlabel, |
1310 for idx, label_func in enumerate([self.Axes.set_xlabel, |
1306 self.Axes.set_ylabel, |
1311 self.Axes.set_ylabel, |
1307 self.Axes.set_zlabel]): |
1312 self.Axes.set_zlabel]): |
1308 label_func(labels[idx], fontdict={'size': 'small','color': color_cycle[idx]}) |
1313 label_func(labels[idx], fontdict={'size': 'small','color': color_cycle[idx]}) |
1310 for label, text in zip(self.AxesLabels, labels): |
1315 for label, text in zip(self.AxesLabels, labels): |
1311 label.set_text(text) |
1316 label.set_text(text) |
1312 for label, value, style in zip(self.Labels, values, styles): |
1317 for label, value, style in zip(self.Labels, values, styles): |
1313 label.set_text(value) |
1318 label.set_text(value) |
1314 label.set_style(style) |
1319 label.set_style(style) |
1315 |
1320 |
1316 self.Canvas.draw() |
1321 self.Canvas.draw() |
1317 |
1322 |
1318 class DebugVariablePanel(wx.Panel, DebugViewer): |
1323 class DebugVariablePanel(wx.Panel, DebugViewer): |
1319 |
1324 |
1320 def __init__(self, parent, producer, window): |
1325 def __init__(self, parent, producer, window): |
1337 self.Force = False |
1342 self.Force = False |
1338 self.CursorTick = None |
1343 self.CursorTick = None |
1339 self.DraggingAxesPanel = None |
1344 self.DraggingAxesPanel = None |
1340 self.DraggingAxesBoundingBox = None |
1345 self.DraggingAxesBoundingBox = None |
1341 self.DraggingAxesMousePos = None |
1346 self.DraggingAxesMousePos = None |
1342 self.VariableNameMask = None |
1347 self.VariableNameMask = [] |
1343 |
1348 |
1344 self.GraphicPanels = [] |
1349 self.GraphicPanels = [] |
1345 |
1350 |
1346 graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
1351 graphics_button_sizer = wx.BoxSizer(wx.HORIZONTAL) |
1347 main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW|wx.ALL) |
1352 main_sizer.AddSizer(graphics_button_sizer, border=5, flag=wx.GROW|wx.ALL) |
1353 self.Bind(wx.EVT_COMBOBOX, self.OnRangeChanged, self.CanvasRange) |
1358 self.Bind(wx.EVT_COMBOBOX, self.OnRangeChanged, self.CanvasRange) |
1354 graphics_button_sizer.AddWindow(self.CanvasRange, 1, |
1359 graphics_button_sizer.AddWindow(self.CanvasRange, 1, |
1355 border=5, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL) |
1360 border=5, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL) |
1356 |
1361 |
1357 for name, bitmap, help in [ |
1362 for name, bitmap, help in [ |
1358 ("ResetButton", "reset", _("Clear the graph values")), |
|
1359 ("CurrentButton", "current", _("Go to current value")), |
1363 ("CurrentButton", "current", _("Go to current value")), |
1360 ("ExportGraphButton", "export_graph", _("Export graph values to clipboard"))]: |
1364 ("ExportGraphButton", "export_graph", _("Export graph values to clipboard"))]: |
1361 button = wx.lib.buttons.GenBitmapButton(self, |
1365 button = wx.lib.buttons.GenBitmapButton(self, |
1362 bitmap=GetBitmap(bitmap), |
1366 bitmap=GetBitmap(bitmap), |
1363 size=wx.Size(28, 28), style=wx.NO_BORDER) |
1367 size=wx.Size(28, 28), style=wx.NO_BORDER) |
1382 |
1386 |
1383 self.TickSizer = wx.BoxSizer(wx.HORIZONTAL) |
1387 self.TickSizer = wx.BoxSizer(wx.HORIZONTAL) |
1384 main_sizer.AddSizer(self.TickSizer, border=5, flag=wx.ALL|wx.GROW) |
1388 main_sizer.AddSizer(self.TickSizer, border=5, flag=wx.ALL|wx.GROW) |
1385 |
1389 |
1386 self.TickLabel = wx.StaticText(self) |
1390 self.TickLabel = wx.StaticText(self) |
1387 self.TickSizer.AddWindow(self.TickLabel, 1, border=5, flag=wx.RIGHT|wx.GROW) |
1391 self.TickSizer.AddWindow(self.TickLabel, border=5, flag=wx.RIGHT) |
|
1392 |
|
1393 self.MaskLabel = wx.TextCtrl(self, style=wx.TE_READONLY|wx.TE_CENTER|wx.NO_BORDER) |
|
1394 self.TickSizer.AddWindow(self.MaskLabel, 1, border=5, flag=wx.RIGHT|wx.GROW) |
1388 |
1395 |
1389 self.TickTimeLabel = wx.StaticText(self) |
1396 self.TickTimeLabel = wx.StaticText(self) |
1390 self.TickSizer.AddWindow(self.TickTimeLabel) |
1397 self.TickSizer.AddWindow(self.TickTimeLabel) |
1391 |
1398 |
1392 self.GraphicsWindow = wx.ScrolledWindow(self, style=wx.HSCROLL|wx.VSCROLL) |
1399 self.GraphicsWindow = wx.ScrolledWindow(self, style=wx.HSCROLL|wx.VSCROLL) |
1844 except ValueError, e: |
1851 except ValueError, e: |
1845 self.CanvasRange.SetValue(str(self.CurrentRange)) |
1852 self.CanvasRange.SetValue(str(self.CurrentRange)) |
1846 wx.CallAfter(self.RefreshRange) |
1853 wx.CallAfter(self.RefreshRange) |
1847 event.Skip() |
1854 event.Skip() |
1848 |
1855 |
1849 def OnResetButton(self, event): |
|
1850 self.ResetGraphicsValues() |
|
1851 event.Skip() |
|
1852 |
|
1853 def OnCurrentButton(self, event): |
1856 def OnCurrentButton(self, event): |
1854 if len(self.Ticks) > 0: |
1857 if len(self.Ticks) > 0: |
1855 self.StartTick = max(self.Ticks[0], self.Ticks[-1] - self.CurrentRange) |
1858 self.StartTick = max(self.Ticks[0], self.Ticks[-1] - self.CurrentRange) |
1856 self.Fixed = False |
1859 self.Fixed = False |
1857 self.CursorTick = None |
1860 self.CursorTick = None |
1921 [item.GetVariable().split('.') for item in items]) |
1924 [item.GetVariable().split('.') for item in items]) |
1922 elif len(items) > 0: |
1925 elif len(items) > 0: |
1923 self.VariableNameMask = items[0].GetVariable().split('.')[:-1] + ['*'] |
1926 self.VariableNameMask = items[0].GetVariable().split('.')[:-1] + ['*'] |
1924 else: |
1927 else: |
1925 self.VariableNameMask = [] |
1928 self.VariableNameMask = [] |
|
1929 self.MaskLabel.ChangeValue(".".join(self.VariableNameMask)) |
|
1930 self.MaskLabel.SetInsertionPoint(self.MaskLabel.GetLastPosition()) |
1926 |
1931 |
1927 def GetVariableNameMask(self): |
1932 def GetVariableNameMask(self): |
1928 return self.VariableNameMask |
1933 return self.VariableNameMask |
1929 |
1934 |
1930 def InsertValue(self, iec_path, idx = None, force=False): |
1935 def InsertValue(self, iec_path, idx = None, force=False): |