# HG changeset patch # User Laurent Bessard # Date 1350380064 -7200 # Node ID 1009f956d2ee709471cbb9a6fd5afa6eeebe9c2c # Parent 666f5bdad3010b0f31ada00b3a8b8aa69183bb0d Fix support for adjusting block size to block minimum size and to Viewer scaling diff -r 666f5bdad301 -r 1009f956d2ee editors/Viewer.py --- a/editors/Viewer.py Mon Oct 15 17:05:19 2012 +0200 +++ b/editors/Viewer.py Tue Oct 16 11:34:24 2012 +0200 @@ -501,11 +501,12 @@ # Add Default Menu items to the given menu def AddDefaultMenuItems(self, menu, edit=False, block=False): if block: - [ID_EDIT_BLOCK, ID_DELETE] = [wx.NewId() for i in xrange(2)] + [ID_EDIT_BLOCK, ID_DELETE, ID_ADJUST_BLOCK_SIZE] = [wx.NewId() for i in xrange(3)] # Create menu items self.AddMenuItems(menu, [ (ID_EDIT_BLOCK, wx.ITEM_NORMAL, _(u'Edit Block'), '', self.OnEditBlockMenu), + (ID_ADJUST_BLOCK_SIZE, wx.ITEM_NORMAL, _(u'Adjust Block Size'), '', self.OnAdjustBlockSizeMenu), (ID_DELETE, wx.ITEM_NORMAL, _(u'Delete'), '', self.OnDeleteMenu)]) menu.Enable(ID_EDIT_BLOCK, edit) @@ -790,13 +791,17 @@ self.Comments[comment.GetId()] = comment def IsBlock(self, block): - return self.Blocks.get(block.GetId(), False) + if block is not None: + return self.Blocks.get(block.GetId(), False) + return False def IsWire(self, wire): return self.Wires.get(wire, False) def IsComment(self, comment): - return self.Comments.get(comment.GetId(), False) + if comment is not None: + return self.Comments.get(comment.GetId(), False) + return False def RemoveBlock(self, block): self.Blocks.pop(block.GetId()) @@ -1237,8 +1242,7 @@ self.AddBlock(element) connectors = element.GetConnectors() element.SetPosition(instance["x"], instance["y"]) - if isinstance(element, SFC_Divergence): - element.SetSize(instance["width"], instance["height"]) + element.SetSize(instance["width"], instance["height"]) for i, output_connector in enumerate(instance["outputs"]): if i < len(connectors["outputs"]): connector = connectors["outputs"][i] @@ -1256,8 +1260,6 @@ if input_connector.get("edge", "none") != "none": connector.SetEdge(input_connector["edge"]) self.CreateWires(connector, instance["id"], input_connector["links"], ids, selection) - if not isinstance(element, SFC_Divergence): - element.SetSize(instance["width"], instance["height"]) if selection is not None and selection[0].get(instance["id"], False): self.SelectInGroup(element) @@ -1521,6 +1523,14 @@ if self.SelectedElement is not None: self.ParentWindow.EditProjectElement(ITEM_POU, "P::%s"%self.SelectedElement.GetType()) + def OnAdjustBlockSizeMenu(self, event): + if self.SelectedElement is not None: + movex, movey = self.SelectedElement.SetBestSize(self.Scaling) + self.SelectedElement.RefreshModel() + self.RefreshBuffer() + if movex != 0 or movey != 0: + self.RefreshRect(self.GetScrolledRect(self.SelectedElement.GetRedrawRect(movex, movey)), False) + def OnDeleteMenu(self, event): if self.SelectedElement is not None: self.SelectedElement.Delete() @@ -1836,14 +1846,15 @@ else: self.ParentWindow.OpenGraphicViewer(iec_path) elif event.ControlDown() and not event.ShiftDown(): - instance_type = self.SelectedElement.GetType() - if self.IsBlock(self.SelectedElement) and instance_type in self.Controler.GetProjectPouNames(self.Debug): - self.ParentWindow.EditProjectElement(ITEM_POU, - self.Controler.ComputePouName(instance_type)) - else: - self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling) + if not isinstance(self.SelectedElement, Group_Element): + instance_type = self.SelectedElement.GetType() + if self.IsBlock(self.SelectedElement) and instance_type in self.Controler.GetProjectPouNames(self.Debug): + self.ParentWindow.EditProjectElement(ITEM_POU, + self.Controler.ComputePouName(instance_type)) + else: + self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling) elif event.ControlDown() and event.ShiftDown(): - movex, movey = self.SelectedElement.AdjustToScaling(self.Scaling) + movex, movey = self.SelectedElement.SetBestSize(self.Scaling) self.SelectedElement.RefreshModel() self.RefreshBuffer() if movex != 0 or movey != 0: @@ -2468,6 +2479,7 @@ self.RefreshBuffer() if old_name != values["name"]: self.Controler.UpdateEditedElementUsedVariable(self.TagName, old_name, values["name"]) + self.RefreshBuffer() self.RefreshView(selection=({connection.GetId(): True}, {})) else: self.RefreshScrollBars() diff -r 666f5bdad301 -r 1009f956d2ee graphics/FBD_Objects.py --- a/graphics/FBD_Objects.py Mon Oct 15 17:05:19 2012 +0200 +++ b/graphics/FBD_Objects.py Tue Oct 16 11:34:24 2012 +0200 @@ -690,38 +690,19 @@ def GetExecutionOrder(self): return self.ExecutionOrder - # Changes the element size - def SetSize(self, width, height): - scaling = self.Parent.GetScaling() - min_width, min_height = self.GetMinSize() - if width < min_width: - if self.Type == INPUT: - posx = max(0, self.Pos.x + width - min_width) - if scaling is not None: - posx = round_scaling(posx, scaling[0]) - self.Pos.x = posx - elif self.Type == OUTPUT: - posx = max(0, self.Pos.x + (width - min_width) / 2) - if scaling is not None: - posx = round_scaling(posx, scaling[0]) - self.Pos.x = posx - width = min_width - if scaling is not None: - width = round_scaling(width, scaling[0], 1) - if height < min_height: - posy = max(0, self.Pos.y + (height - min_height) / 2) - if scaling is not None: - posy = round_scaling(posy, scaling[1]) - self.Pos.y = posy - height = min_height - if scaling is not None: - height = round_scaling(height, scaling[1], 1) - Graphic_Element.SetSize(self, width, height) - # Returns the variable minimum size def GetMinSize(self): return self.NameSize[0] + 10, self.NameSize[1] + 10 + # Set size of the variable to the minimum size + def SetBestSize(self, scaling): + if self.Type == INPUT: + return Graphic_Element.SetBestSize(self, scaling, x_factor=1.) + elif self.Type == OUTPUT: + return Graphic_Element.SetBestSize(self, scaling, x_factor=0.) + else: + return Graphic_Element.SetBestSize(self, scaling) + # Method called when a LeftDClick event have been generated def OnLeftDClick(self, event, dc, scaling): # Edit the variable properties @@ -930,28 +911,12 @@ def GetName(self): return self.Name - # Changes the element size - def SetSize(self, width, height): - scaling = self.Parent.GetScaling() - min_width, min_height = self.GetMinSize() - if width < min_width: - if self.Type == CONTINUATION: - posx = max(0, self.Pos.x + width - min_width) - if scaling is not None: - posx = round_scaling(posx, scaling[0]) - self.Pos.x = posx - width = min_width - if scaling is not None: - width = round_scaling(width, scaling[0], 1) - if height < min_height: - posy = max(0, self.Pos.y + (height - min_height) / 2) - if scaling is not None: - posy = round_scaling(posy, scaling[1]) - self.Pos.y = posy - height = min_height - if scaling is not None: - height = round_scaling(height, scaling[1], 1) - Graphic_Element.SetSize(self, width, height) + # Set size of the variable to the minimum size + def SetBestSize(self, scaling): + if self.Type == CONTINUATION: + return Graphic_Element.SetBestSize(self, scaling, x_factor=1.) + else: + return Graphic_Element.SetBestSize(self, scaling, x_factor=0.) # Returns the connection minimum size def GetMinSize(self): diff -r 666f5bdad301 -r 1009f956d2ee graphics/GraphicCommons.py --- a/graphics/GraphicCommons.py Mon Oct 15 17:05:19 2012 +0200 +++ b/graphics/GraphicCommons.py Tue Oct 16 11:34:24 2012 +0200 @@ -118,13 +118,13 @@ def round_scaling(x, n, constraint=0): fraction = float(x) / float(n) - if constraint == - 1: + if constraint == -1: xround = int(fraction) else: xround = round(fraction) - if constraint == 1 and int(fraction) == xround: - xround += 1 - return xround * n + if constraint == 1 and xround < fraction: + xround += 1 + return int(xround * n) """ Basic vector operations for calculate wire points @@ -675,7 +675,7 @@ return [self.Id], [] def TestVisible(self, screen): - self.Visible = self.GetRedrawRect().Intersects(screen) + self.Visible = self.Selected or self.GetRedrawRect().Intersects(screen) def IsVisible(self): return self.Visible @@ -737,6 +737,25 @@ def GetMinSize(self): return 0, 0 + # Set size of the element to the minimum size + def SetBestSize(self, scaling, x_factor=0.5, y_factor=0.5): + width, height = self.GetSize() + posx, posy = self.GetPosition() + min_width, min_height = self.GetMinSize() + if width < min_width: + self.Pos.x = max(0, self.Pos.x - (width - min_width) * x_factor) + width = min_width + if height < min_height: + self.Pos.y = max(0, self.Pos.y - (height - min_height) * y_factor) + height = min_height + if scaling is not None: + self.Pos.x = round_scaling(self.Pos.x, scaling[0]) + self.Pos.y = round_scaling(self.Pos.y, scaling[1]) + width = round_scaling(width, scaling[0], 1) + height = round_scaling(height, scaling[1], 1) + self.SetSize(width, height) + return self.Pos.x - posx, self.Pos.y - posy + # Refresh the element Bounding Box def RefreshBoundingBox(self): self.BoundingBox = wx.Rect(self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]) @@ -943,20 +962,6 @@ self.Move(x, y) self.SetSize(width, height) - # Moves and Resizes the element for fitting scaling - def AdjustToScaling(self, scaling): - if scaling is not None: - movex = round_scaling(self.Pos.x, scaling[0]) - self.Pos.x - movey = round_scaling(self.Pos.y, scaling[1]) - self.Pos.y - min_width, min_height = self.GetMinSize() - width = max(round_scaling(min_width, scaling[0], 1), - round_scaling(self.Size.width, scaling[0])) - height = max(round_scaling(min_height, scaling[1], 1), - round_scaling(self.Size.height, scaling[1])) - self.Resize(movex, movey, width, height) - return movex, movey - return 0, 0 - # Refreshes the element state according to move defined and handle selected def ProcessDragging(self, movex, movey, event, scaling, width_fac = 1, height_fac = 1): handle_type, handle = self.Handle @@ -1176,7 +1181,7 @@ new_element = element.Clone(parent, newid, name, pos = new_pos) else: new_element = element.Clone(parent, newid, pos = new_pos) - new_element.AdjustToScaling(parent.Scaling) + new_element.SetBestSize(parent.Scaling) else: new_element = element.Clone(parent) connectors.update(element.GetConnectorTranslation(new_element)) @@ -1368,15 +1373,15 @@ # Returns the size of this group def GetSize(self): return self.BoundingBox.width, self.BoundingBox.height - - # Moves and Resizes the group elements for fitting scaling - def AdjustToScaling(self, scaling): - movex_max = movey_max = 0 + + # Set size of the group elements to their minimum size + def SetBestSize(self, scaling): + max_movex = max_movey = 0 for element in self.Elements: - movex, movey = element.AdjustToScaling(scaling) - movex_max = max(movex_max, abs(movex)) - movey_max = max(movey_max, abs(movey)) - return movex_max, movey_max + movex, movey = element.SetBestSize(scaling) + max_movex = max(max_movex, movex) + max_movey = max(max_movey, movey) + return max_movex, max_movey # Refreshes the group elements to move defined and handle selected def ProcessDragging(self, movex, movey, event, scaling): @@ -1986,8 +1991,11 @@ def SetSize(width, height): pass + # Forbids to et size of the group elements to their minimum size + pass + # Moves and Resizes the element for fitting scaling - def AdjustToScaling(self, scaling): + def SetBestSize(self, scaling): if scaling is not None: movex_max = movey_max = 0 for idx, point in enumerate(self.Points):