# HG changeset patch # User lbessard # Date 1237561557 -3600 # Node ID 555124c752ecf0dbfbe96baa3192b8404102abe2 # Parent 9106d66bd20469610b3deb5529bc9d5ca8f53efd Adding Display menu with Zoom item In place element copy in Viewer fixed diff -r 9106d66bd204 -r 555124c752ec PLCOpenEditor.py --- a/PLCOpenEditor.py Thu Mar 19 18:10:12 2009 +0100 +++ b/PLCOpenEditor.py Fri Mar 20 16:05:57 2009 +0100 @@ -188,7 +188,9 @@ def _init_coll_MenuBar_Menus(self, parent): parent.Append(menu=self.FileMenu, title=u'File') - parent.Append(menu=self.EditMenu, title=u'Edit') + if not self.Debug: + parent.Append(menu=self.EditMenu, title=u'Edit') + parent.Append(menu=self.DisplayMenu, title=u'Display') parent.Append(menu=self.HelpMenu, title=u'Help') def _init_coll_FileMenu_Items(self, parent): @@ -253,61 +255,69 @@ self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_STOP) def _init_coll_EditMenu_Items(self, parent): + AppendMenu(parent, help='', id=wx.ID_UNDO, + kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z') + AppendMenu(parent, help='', id=wx.ID_REDO, + kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y') + parent.AppendSeparator() + AppendMenu(parent, help='', id=wx.ID_CUT, + kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X') + AppendMenu(parent, help='', id=wx.ID_COPY, + kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C') + AppendMenu(parent, help='', id=wx.ID_PASTE, + kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V') + parent.AppendSeparator() + addmenu = wx.Menu(title='') + parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu) + AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, + kind=wx.ITEM_NORMAL, text=u'Data Type') + AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, + kind=wx.ITEM_NORMAL, text=u'Function') + AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, + kind=wx.ITEM_NORMAL, text=u'Function Block') + AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, + kind=wx.ITEM_NORMAL, text=u'Program') + AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, + kind=wx.ITEM_NORMAL, text=u'Configuration') + AppendMenu(parent, help='', id=wx.ID_SELECTALL, + kind=wx.ITEM_NORMAL, text=u'Select All\tCTRL+A') + AppendMenu(parent, help='', id=wx.ID_DELETE, + kind=wx.ITEM_NORMAL, text=u'Delete') + self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) + self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) + self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT) + self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY) + self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE) + self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, + id=ID_PLCOPENEDITOREDITMENUADDDATATYPE) + self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"), + id=ID_PLCOPENEDITOREDITMENUADDFUNCTION) + self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"), + id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK) + self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"), + id=ID_PLCOPENEDITOREDITMENUADDPROGRAM) + self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, + id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION) + self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL) + self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE) + + def _init_coll_DisplayMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_REFRESH, - kind=wx.ITEM_NORMAL, text=u'Refresh\tCTRL+R') - if not self.Debug: - if not self.ModeSolo: - AppendMenu(parent, help='', id=wx.ID_CLEAR, - kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K') - AppendMenu(parent, help='', id=wx.ID_UNDO, - kind=wx.ITEM_NORMAL, text=u'Undo\tCTRL+Z') - AppendMenu(parent, help='', id=wx.ID_REDO, - kind=wx.ITEM_NORMAL, text=u'Redo\tCTRL+Y') - parent.AppendSeparator() - AppendMenu(parent, help='', id=wx.ID_CUT, - kind=wx.ITEM_NORMAL, text=u'Cut\tCTRL+X') - AppendMenu(parent, help='', id=wx.ID_COPY, - kind=wx.ITEM_NORMAL, text=u'Copy\tCTRL+C') - AppendMenu(parent, help='', id=wx.ID_PASTE, - kind=wx.ITEM_NORMAL, text=u'Paste\tCTRL+V') - parent.AppendSeparator() - addmenu = wx.Menu(title='') - parent.AppendMenu(wx.ID_ADD, "Add Element", addmenu) - AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDDATATYPE, - kind=wx.ITEM_NORMAL, text=u'Data Type') - AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTION, - kind=wx.ITEM_NORMAL, text=u'Function') - AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK, - kind=wx.ITEM_NORMAL, text=u'Function Block') - AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDPROGRAM, - kind=wx.ITEM_NORMAL, text=u'Program') - AppendMenu(addmenu, help='', id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION, - kind=wx.ITEM_NORMAL, text=u'Configuration') - AppendMenu(parent, help='', id=wx.ID_SELECTALL, - kind=wx.ITEM_NORMAL, text=u'Select All\tCTRL+A') - AppendMenu(parent, help='', id=wx.ID_DELETE, - kind=wx.ITEM_NORMAL, text=u'Delete') + kind=wx.ITEM_NORMAL, text=u'Refresh\tF5') + if not self.Debug and not self.ModeSolo: + AppendMenu(parent, help='', id=wx.ID_CLEAR, + kind=wx.ITEM_NORMAL, text=u'Clear Errors\tCTRL+K') + parent.AppendSeparator() + zoommenu = wx.Menu(title='') + parent.AppendMenu(wx.ID_ZOOM_FIT, "ZOOM", zoommenu) + for idx, value in enumerate(ZOOM_FACTORS): + new_id = wx.NewId() + AppendMenu(zoommenu, help='', id=new_id, + kind=wx.ITEM_RADIO, text=str(int(round(value * 100))) + "%") + self.Bind(wx.EVT_MENU, self.GenerateZoomFunction(idx), id=new_id) self.Bind(wx.EVT_MENU, self.OnRefreshMenu, id=wx.ID_REFRESH) - if not self.Debug: - if not self.ModeSolo: - self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) - self.Bind(wx.EVT_MENU, self.OnUndoMenu, id=wx.ID_UNDO) - self.Bind(wx.EVT_MENU, self.OnRedoMenu, id=wx.ID_REDO) - self.Bind(wx.EVT_MENU, self.OnCutMenu, id=wx.ID_CUT) - self.Bind(wx.EVT_MENU, self.OnCopyMenu, id=wx.ID_COPY) - self.Bind(wx.EVT_MENU, self.OnPasteMenu, id=wx.ID_PASTE) - self.Bind(wx.EVT_MENU, self.OnAddDataTypeMenu, - id=ID_PLCOPENEDITOREDITMENUADDDATATYPE) - self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("function"), - id=ID_PLCOPENEDITOREDITMENUADDFUNCTION) - self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("functionBlock"), - id=ID_PLCOPENEDITOREDITMENUADDFUNCTIONBLOCK) - self.Bind(wx.EVT_MENU, self.GenerateAddPouFunction("program"), - id=ID_PLCOPENEDITOREDITMENUADDPROGRAM) - self.Bind(wx.EVT_MENU, self.OnAddConfigurationMenu, - id=ID_PLCOPENEDITOREDITMENUADDCONFIGURATION) - self.Bind(wx.EVT_MENU, self.OnSelectAllMenu, id=wx.ID_SELECTALL) - self.Bind(wx.EVT_MENU, self.OnDeleteMenu, id=wx.ID_DELETE) + if not self.Debug and not self.ModeSolo: + self.Bind(wx.EVT_MENU, self.OnClearErrorsMenu, id=wx.ID_CLEAR) def _init_coll_HelpMenu_Items(self, parent): AppendMenu(parent, help='', id=wx.ID_HELP, @@ -327,12 +337,16 @@ self.MenuBar = wx.MenuBar() self.FileMenu = wx.Menu(title='') - self.EditMenu = wx.Menu(title='') + if not self.Debug: + self.EditMenu = wx.Menu(title='') + self.DisplayMenu = wx.Menu(title='') self.HelpMenu = wx.Menu(title='') self._init_coll_MenuBar_Menus(self.MenuBar) self._init_coll_FileMenu_Items(self.FileMenu) - self._init_coll_EditMenu_Items(self.EditMenu) + if not self.Debug: + self._init_coll_EditMenu_Items(self.EditMenu) + self._init_coll_DisplayMenu_Items(self.DisplayMenu) self._init_coll_HelpMenu_Items(self.HelpMenu) def _init_coll_MainLibrarySizer_Items(self, parent): @@ -622,6 +636,7 @@ self.RefreshFileMenu() self.RefreshEditMenu() + self.RefreshDisplayMenu() self.RefreshTitle() self.RefreshToolBar() @@ -643,6 +658,7 @@ self.RefreshTitle() self.RefreshFileMenu() self.RefreshEditMenu() + self.RefreshDisplayMenu() self.RefreshToolBar() event.Skip() @@ -682,6 +698,7 @@ self.RefreshTitle() self.RefreshFileMenu() self.RefreshEditMenu() + self.RefreshDisplayMenu() self.RefreshTypesTree() self.RefreshScaling() dialog.Destroy() @@ -993,16 +1010,12 @@ #------------------------------------------------------------------------------- -# Edit Project Menu Functions +# Edit Menu Functions #------------------------------------------------------------------------------- def RefreshEditMenu(self): - if self.Controler.HasOpenedProject(): - if self.TabsOpened.GetPageCount() > 0: - self.EditMenu.Enable(wx.ID_REFRESH, True) - else: - self.EditMenu.Enable(wx.ID_REFRESH, False) - if not self.Debug: + if not self.Debug: + if self.Controler.HasOpenedProject(): undo, redo = self.Controler.GetBufferState() self.EditMenu.Enable(wx.ID_UNDO, undo) self.EditMenu.Enable(wx.ID_REDO, redo) @@ -1021,9 +1034,7 @@ self.EditMenu.Enable(wx.ID_COPY, False) self.EditMenu.Enable(wx.ID_PASTE, False) self.EditMenu.Enable(wx.ID_SELECTALL, False) - else: - self.EditMenu.Enable(wx.ID_REFRESH, False) - if not self.Debug: + else: self.EditMenu.Enable(wx.ID_UNDO, False) self.EditMenu.Enable(wx.ID_REDO, False) self.EditMenu.Enable(wx.ID_CUT, False) @@ -1033,19 +1044,6 @@ self.EditMenu.Enable(wx.ID_ADD, False) self.EditMenu.Enable(wx.ID_DELETE, False) - def OnRefreshMenu(self, event): - selected = self.TabsOpened.GetSelection() - if selected != -1: - window = self.TabsOpened.GetPage(selected) - window.RefreshView() - if not self.Debug: - self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName()) - event.Skip() - - def OnClearErrorsMenu(self, event): - self.ClearErrors() - event.Skip() - def OnUndoMenu(self, event): self.Controler.LoadPrevious() idxs = range(self.TabsOpened.GetPageCount()) @@ -1193,6 +1191,58 @@ #------------------------------------------------------------------------------- +# Display Menu Functions +#------------------------------------------------------------------------------- + + def RefreshDisplayMenu(self): + if self.Controler.HasOpenedProject(): + if self.TabsOpened.GetPageCount() > 0: + self.DisplayMenu.Enable(wx.ID_REFRESH, True) + selected = self.TabsOpened.GetSelection() + if selected != -1: + window = self.TabsOpened.GetPage(selected) + if isinstance(window, Viewer): + self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, True) + zoommenu = self.DisplayMenu.FindItemById(wx.ID_ZOOM_FIT).GetSubMenu() + zoomitem = zoommenu.FindItemByPosition(window.GetScale()) + zoomitem.Check(True) + else: + self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) + else: + self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) + else: + self.DisplayMenu.Enable(wx.ID_REFRESH, False) + self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) + self.DisplayMenu.Enable(wx.ID_CLEAR, True) + else: + self.DisplayMenu.Enable(wx.ID_REFRESH, False) + self.DisplayMenu.Enable(wx.ID_CLEAR, False) + self.DisplayMenu.Enable(wx.ID_ZOOM_FIT, False) + + def OnRefreshMenu(self, event): + selected = self.TabsOpened.GetSelection() + if selected != -1: + window = self.TabsOpened.GetPage(selected) + window.RefreshView() + if not self.Debug: + self.VariablePanelIndexer.RefreshVariablePanel(window.GetTagName()) + event.Skip() + + def OnClearErrorsMenu(self, event): + self.ClearErrors() + event.Skip() + + def GenerateZoomFunction(self, idx): + def ZoomFunction(event): + selected = self.TabsOpened.GetSelection() + if selected != -1: + window = self.TabsOpened.GetPage(selected) + window.SetScale(idx) + event.Skip() + return ZoomFunction + + +#------------------------------------------------------------------------------- # Project Editor Panels Management Functions #------------------------------------------------------------------------------- @@ -1215,6 +1265,7 @@ self.VariablePanelIndexer.ChangeVariablePanel(window.GetTagName()) self.RefreshFileMenu() self.RefreshEditMenu() + self.RefreshDisplayMenu() self.RefreshToolBar() event.Skip() @@ -4214,9 +4265,14 @@ new_row["Class"] = self.DefaultTypes[self.Filter] else: new_row["Class"] = self.Filter - self.Values.append(new_row) + if self.Filter == "All" and len(self.Values) > 0: + row_index = self.VariablesGrid.GetGridCursorRow() + 1 + self.Values.insert(row_index, new_row) + else: + row_index = -1 + self.Values.append(new_row) self.SaveValues() - self.RefreshValues() + self.RefreshValues(row_index) self.RefreshButtons() event.Skip() @@ -4353,7 +4409,7 @@ self.RefreshValues() self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol()) - def RefreshValues(self): + def RefreshValues(self, select=0): if len(self.Table.data) > 0: self.VariablesGrid.SetGridCursor(0, 1) data = [] @@ -4362,6 +4418,11 @@ variable["Number"] = num + 1 data.append(variable) self.Table.SetData(data) + if len(self.Table.data) > 0: + if select == -1: + select = len(self.Table.data) - 1 + self.VariablesGrid.SetGridCursor(select, 1) + self.VariablesGrid.MakeCellVisible(select, 1) self.Table.ResetView(self.VariablesGrid) def SaveValues(self, buffer = True): diff -r 9106d66bd204 -r 555124c752ec Viewer.py --- a/Viewer.py Thu Mar 19 18:10:12 2009 +0100 +++ b/Viewer.py Fri Mar 20 16:05:57 2009 +0100 @@ -22,6 +22,8 @@ #License along with this library; if not, write to the Free Software #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import math + import wx if wx.VERSION >= (2, 8, 0): USE_AUI = True @@ -60,6 +62,8 @@ 'size' : 20, } +ZOOM_FACTORS = [math.sqrt(2) ** x for x in xrange(-6, 7)] + #------------------------------------------------------------------------------- # Graphic elements Viewer base class #------------------------------------------------------------------------------- @@ -350,7 +354,6 @@ self.DrawGrid = True self.GridBrush = wx.TRANSPARENT_BRUSH self.PageSize = None - self.ViewScale = (1.0, 1.0) self.PagePen = wx.TRANSPARENT_PEN self.DrawingWire = False self.current_id = 0 @@ -386,6 +389,8 @@ width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") self.SetFont(font) + self.SetScale(len(ZOOM_FACTORS) / 2) + self.ResetView() # Link Viewer event to corresponding methods @@ -440,10 +445,14 @@ self.Flush() self.ResetView() - def SetScale(self, scalex, scaley): - self.ViewScale = (scalex, scaley) + def SetScale(self, scale_number): + self.CurrentScale = max(0, min(scale_number, len(ZOOM_FACTORS) - 1)) + self.ViewScale = (ZOOM_FACTORS[self.CurrentScale], ZOOM_FACTORS[self.CurrentScale]) self.RefreshScaling() + def GetScale(self): + return self.CurrentScale + def GetLogicalDC(self, buffered=False): if buffered: dc = wx.AutoBufferedPaintDC(self) @@ -1661,12 +1670,17 @@ self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(0, scaling[1])), False) elif not self.Debug and keycode == wx.WXK_SPACE and self.SelectedElement is not None and self.SelectedElement.Dragging: if self.IsBlock(self.SelectedElement) or self.IsComment(self.SelectedElement): - self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition())) - self.RefreshBuffer() - self.RefreshScrollBars() + block = self.CopyBlock(self.SelectedElement, wx.Point(*self.SelectedElement.GetPosition())) + event = wx.MouseEvent() + event.m_x, event.m_y = self.ScreenToClient(wx.GetMousePosition()) + dc = self.GetLogicalDC() + self.SelectedElement.OnLeftUp(event, dc, self.Scaling) + self.SelectedElement.SetSelected(False) + block.OnLeftDown(event, dc, self.Scaling) + self.SelectedElement = block + self.SelectedElement.SetSelected(True) self.ParentWindow.RefreshVariablePanel(self.TagName) self.RefreshVisibleElements() - self.SelectedElement.Refresh() else: event.Skip() else: @@ -1681,7 +1695,7 @@ width = round(float(width) / float(self.Scaling[0]) + 0.4) * self.Scaling[0] height = round(float(height) / float(self.Scaling[1]) + 0.4) * self.Scaling[1] return width, height - + def AddNewBlock(self, bbox): dialog = BlockPropertiesDialog(self.ParentWindow, self.Controler) dialog.SetPreviewFont(self.GetFont()) @@ -2565,7 +2579,24 @@ def Paste(self): element = self.ParentWindow.GetCopyBuffer() if not self.Debug and element is not None and self.CanAddElement(element): - block = self.CopyBlock(element, wx.Point(*self.CalcUnscrolledPosition(30, 30))) + mouse_pos = self.ScreenToClient(wx.GetMousePosition()) + if wx.Rect(0, 0, *self.GetClientSize()).InsideXY(mouse_pos.x, mouse_pos.y): + x, y = self.CalcUnscrolledPosition(mouse_pos.x, mouse_pos.y) + block_size = element.GetSize() + x = int(float(x) / self.ViewScale[0]) - block_size[0] / 2 + y = int(float(y) / self.ViewScale[1]) - block_size[1] / 2 + else: + x, y = self.CalcUnscrolledPosition(0, 0) + x = int(x / self.ViewScale[0]) + 30 + y = int(y / self.ViewScale[1]) + 30 + if self.Scaling is not None: + new_pos = wx.Point(max(round_scaling(30, self.Scaling[0], 1), + round_scaling(x, self.Scaling[0])), + max(round_scaling(30, self.Scaling[1], 1), + round_scaling(y, self.Scaling[1]))) + else: + new_pos = wx.Point(max(30, x), max(30, y)) + block = self.CopyBlock(element, new_pos) if self.SelectedElement is not None: self.SelectedElement.SetSelected(False) self.SelectedElement = block @@ -2707,15 +2738,13 @@ dc = self.GetLogicalDC() pos = event.GetLogicalPosition(dc) mouse_pos = event.GetPosition() - factor = 1.414 ** rotation - xscale = max(0.125, min(self.ViewScale[0] * factor, 8)) - yscale = max(0.125, min(self.ViewScale[0] * factor, 8)) - self.SetScale(xscale, yscale) + self.SetScale(self.CurrentScale + rotation) self.Scroll(round(pos.x * self.ViewScale[0] - mouse_pos.x) / SCROLLBAR_UNIT, round(pos.y * self.ViewScale[1] - mouse_pos.y) / SCROLLBAR_UNIT) self.RefreshScrollBars() self.RefreshVisibleElements() self.Refresh() + self.ParentWindow.RefreshDisplayMenu() else: x, y = self.GetViewStart() yp = max(0, min(y - rotation * 3, self.GetVirtualSize()[1] / self.GetScrollPixelsPerUnit()[1]))