From a3aa0f292d468cd3885b6716905282080405f492 Mon Sep 17 00:00:00 2001 From: zcy <290198252@qq.com> Date: Sun, 24 Mar 2024 23:41:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpin=20=E8=BF=9E=E6=8E=A5?= =?UTF-8?q?=E7=82=B9=E4=B8=8D=E9=9A=8F=E7=9D=80=E8=BD=AC=E5=8A=A8=E8=80=8C?= =?UTF-8?q?=E5=8F=98=E5=8A=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- altium_sch.html | 12 +- altium_sch_renderer.js | 489 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 436 insertions(+), 65 deletions(-) diff --git a/altium_sch.html b/altium_sch.html index e47849d..8a12e28 100644 --- a/altium_sch.html +++ b/altium_sch.html @@ -20,6 +20,11 @@ style="overflow:auto;position:relative;width:1500px;height:600px;border:1px soli

 
+ + + 0) + { + // FIXME: First segment not movable + hint = state.view.transformControlPoint(state, hints[0]); + mxLog.show(); + mxLog.debug(hints.length,'hints0.y='+hint.y, pt.y) + + if (horizontal && Math.floor(hint.y) != Math.floor(pt.y)) + { + mxLog.show(); + mxLog.debug('add waypoint'); + + pt = new mxPoint(pt.x, hint.y); + result.push(pt); + pt = pt.clone(); + //horizontal = !horizontal; + } + + for (var i = 0; i < hints.length; i++) + { + horizontal = !horizontal; + hint = state.view.transformControlPoint(state, hints[i]); + + if (horizontal) + { + if (pt.y != hint.y) + { + pt.y = hint.y; + result.push(pt.clone()); + } + } + else if (pt.x != hint.x) + { + pt.x = hint.x; + result.push(pt.clone()); + } + } + } + else + { + hint = pt; + } + + // Adds the last point + pt = pts[pts.length - 1]; + + // TODO: Should move along connected segment + if (pt == null && target != null) + { + pt = new mxPoint(state.view.getRoutingCenterX(target), state.view.getRoutingCenterY(target)); + } + + if (horizontal) + { + if (pt.y != hint.y && first.x != pt.x) + { + // result.push(new mxPoint(pt.x, hint.y)); + } + } + else if (pt.x != hint.x && first.y != pt.y) + { + // result.push(new mxPoint(hint.x, pt.y)); + } + }; + + mxStyleRegistry.putValue('wireEdgeStyle', mxEdgeStyle.WireConnector); + + + + let mxGraphGetCellStyle = mxGraph.prototype.getCellStyle; + mxGraph.prototype.getCellStyle = function(cell) + { + var style = mxGraphGetCellStyle.apply(this, arguments); + + if (style != null && this.model.isEdge(cell)) + { + style = mxUtils.clone(style); + + if (this.model.isEdge(this.model.getTerminal(cell, true))) + { + style['startArrow'] = 'oval'; + } + + if (this.model.isEdge(this.model.getTerminal(cell, false))) + { + style['endArrow'] = 'oval'; + } + } + + return style; + }; + + let mxConnectionHandlerCreateMarker = mxConnectionHandler.prototype.createMarker; + mxConnectionHandler.prototype.createMarker = function() { + var marker = mxConnectionHandlerCreateMarker.apply(this, arguments); + + // Uses complete area of cell for new connections (no hotspot) + marker.intersects = function(state, evt) + { + return true; + }; + + // Adds in-place highlighting + mxCellHighlightHighlight = mxCellHighlight.prototype.highlight; + marker.highlight.highlight = function(state) + { + if (this.state != state) + { + if (this.state != null) + { + this.state.style = this.lastStyle; + + // Workaround for shape using current stroke width if no strokewidth defined + this.state.style['strokeWidth'] = this.state.style['strokeWidth'] || '1'; + this.state.style['strokeColor'] = this.state.style['strokeColor'] || 'none'; + + if (this.state.shape != null) + { + this.state.view.graph.cellRenderer.configureShape(this.state); + this.state.shape.redraw(); + } + } + + if (state != null) + { + this.lastStyle = state.style; + state.style = mxUtils.clone(state.style); + state.style['strokeColor'] = '#00ff00'; + state.style['strokeWidth'] = '3'; + + if (state.shape != null) + { + state.view.graph.cellRenderer.configureShape(state); + state.shape.redraw(); + } + } + + this.state = state; + } + }; + + return marker; + }; + + let mxEdgeHandlerCreateMarker = mxEdgeHandler.prototype.createMarker; + mxEdgeHandler.prototype.createMarker = function() + { + var marker = mxEdgeHandlerCreateMarker.apply(this, arguments); + marker.highlight.highlight = this.graph.connectionHandler.marker.highlight.highlight; + return marker; + } + // Sets source terminal point for edge-to-edge connections. + mxConnectionHandler.prototype.createEdgeState = function(me) + { + var edge = this.graph.createEdge(); + + if (this.sourceConstraint != null && this.previous != null) + { + edge.style = mxConstants.STYLE_EXIT_X+'='+this.sourceConstraint.point.x+';'+ + mxConstants.STYLE_EXIT_Y+'='+this.sourceConstraint.point.y+';'; + } + else if (this.graph.model.isEdge(me.getCell())) + { + var scale = this.graph.view.scale; + var tr = this.graph.view.translate; + var pt = new mxPoint(this.graph.snap(me.getGraphX() / scale) - tr.x, + this.graph.snap(me.getGraphY() / scale) - tr.y); + edge.geometry.setTerminalPoint(pt, true); + } + + return this.graph.view.createState(edge); + }; + + // Uses right mouse button to create edges on background (see also: lines 67 ff) + mxConnectionHandler.prototype.isStopEvent = function(me) + { + return me.getState() != null || mxEvent.isRightMouseButton(me.getEvent()); + }; + + // Updates target terminal point for edge-to-edge connections. + let mxConnectionHandlerUpdateCurrentState = mxConnectionHandler.prototype.updateCurrentState; + mxConnectionHandler.prototype.updateCurrentState = function(me) + { + mxConnectionHandlerUpdateCurrentState.apply(this, arguments); + + if (this.edgeState != null) + { + this.edgeState.cell.geometry.setTerminalPoint(null, false); + + if (this.shape != null && this.currentState != null && + this.currentState.view.graph.model.isEdge(this.currentState.cell)) + { + var scale = this.graph.view.scale; + var tr = this.graph.view.translate; + var pt = new mxPoint(this.graph.snap(me.getGraphX() / scale) - tr.x, + this.graph.snap(me.getGraphY() / scale) - tr.y); + this.edgeState.cell.geometry.setTerminalPoint(pt, false); + } + } + }; + + // Updates the terminal and control points in the cloned preview. + mxEdgeSegmentHandler.prototype.clonePreviewState = function(point, terminal) { + var clone = mxEdgeHandler.prototype.clonePreviewState.apply(this, arguments); + clone.cell = clone.cell.clone(); + + if (this.isSource || this.isTarget) + { + clone.cell.geometry = clone.cell.geometry.clone(); + + // Sets the terminal point of an edge if we're moving one of the endpoints + if (this.graph.getModel().isEdge(clone.cell)) + { + // TODO: Only set this if the target or source terminal is an edge + clone.cell.geometry.setTerminalPoint(point, this.isSource); + } + else + { + clone.cell.geometry.setTerminalPoint(null, this.isSource); + } + } + + return clone; + }; + + var mxEdgeHandlerConnect = mxEdgeHandler.prototype.connect; + mxEdgeHandler.prototype.connect = function(edge, terminal, isSource, isClone, me) + { + var result = null; + var model = this.graph.getModel(); + var parent = model.getParent(edge); + + model.beginUpdate(); + try + { + result = mxEdgeHandlerConnect.apply(this, arguments); + var geo = model.getGeometry(result); + + if (geo != null) + { + geo = geo.clone(); + var pt = null; + + if (model.isEdge(terminal)) + { + pt = this.abspoints[(this.isSource) ? 0 : this.abspoints.length - 1]; + pt.x = pt.x / this.graph.view.scale - this.graph.view.translate.x; + pt.y = pt.y / this.graph.view.scale - this.graph.view.translate.y; + + var pstate = this.graph.getView().getState( + this.graph.getModel().getParent(edge)); + + if (pstate != null) + { + pt.x -= pstate.origin.x; + pt.y -= pstate.origin.y; + } + + pt.x -= this.graph.panDx / this.graph.view.scale; + pt.y -= this.graph.panDy / this.graph.view.scale; + } + + geo.setTerminalPoint(pt, isSource); + model.setGeometry(edge, geo); + } + } + finally + { + model.endUpdate(); + } + + return result; + }; // https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L1036 mxGraphHandler.prototype.updatePreview = function(remote) { if (this.livePreviewUsed && !remote) { @@ -76,31 +414,30 @@ class AltiumSchematicRenderer this.updatePreviewShape(); } }; - - this.graph = new mxGraph(document.getElementById('graphContainer')); - let oldMove = mxGraphHandler.prototype.mouseMove mxGraphHandler.prototype.mouseMove = function(sender, me){ - console.log("mouse move",sender,me) + // mxLog.debug("mouse move",sender,me) // https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901 if (!this.livePreviewUsed && this.shape == null) { this.shape = this.createPreviewShape(this.bounds); }else if(this.shape != null){ - console.log("mouseMove",this) + // mxLog.debug("mouseMove",this) } oldMove.call(this, sender, me); } let oldClick = mxGraphHandler.prototype.mouseDown - mxGraphHandler.prototype.mouseDown = function(sender, me){ - console.log("mouse down",sender,me) + mxGraphHandler.prototype.mouseDown = function(sender, me){ + mxLog.debug("mouse down",sender,me,this.graph.getSelectionCells()) + if(this.graph.getSelectionCells().length > 0) + this.graph.clearSelection() // https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901 if(me.state != undefined){ if(me.state.cell.children != undefined){ oldClick.call(this, sender, me); }else{ - console.log(me.state.cell) + mxLog.debug(me.state.cell) if(me.state.cell.parent != undefined){ this.graph.addSelectionCell(me.state.cell.parent) oldClick.call(this, sender, me); @@ -108,12 +445,11 @@ class AltiumSchematicRenderer // oldClick.call(this, sender, me); } } - } let oldMouseUp = mxGraphHandler.prototype.mouseUp - mxGraphHandler.prototype.mouseUp = function(sender, me){ - console.log("mouse up",sender,me) + mxGraphHandler.prototype.mouseUp = function(sender, me) { + mxLog.debug("mouse up",sender,me) // https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/handler/mxGraphHandler.js#L901 if(me.state != undefined){ if(me.state.cell.children != undefined){ @@ -121,15 +457,15 @@ class AltiumSchematicRenderer }else{ if(me.state.cell.parent != undefined){ this.graph.addSelectionCell(me.state.cell.parent) - oldMouseUp.call(this, sender, me); + // oldMouseUp.call(this, sender, me); } // oldClick.call(this, sender, me); } } oldMouseUp.call(this, sender, me); - } + this.graph.setPanning(true); this.graph.setConnectable(true); this.graph.setConnectableEdges(true); @@ -152,8 +488,7 @@ class AltiumSchematicRenderer // Adds rubberband selection new mxRubberband(this.graph); - this.graph.addListener(mxEvent.CLICK, function(sender, evt) - { + this.graph.addListener(mxEvent.CLICK, function(sender, evt) { var e = evt.getProperty('event'); // mouse event var cell = evt.getProperty('cell'); // cell may be null @@ -165,8 +500,7 @@ class AltiumSchematicRenderer }); var connectionHandlerMouseUp = this.graph.connectionHandler.mouseUp; - this.graph.connectionHandler.mouseUp = function(sender, me) - { + this.graph.connectionHandler.mouseUp = function(sender, me) { if (this.first != null && this.previous != null) { var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY()); @@ -177,7 +511,7 @@ class AltiumSchematicRenderer { // Selects edges in non-wire mode for single clicks, but starts // connecting for non-edges regardless of wire-mode - console.log("sss") + mxLog.debug("sss") return; } @@ -192,13 +526,26 @@ class AltiumSchematicRenderer // incoming/outgoing direction. this.graph.getAllConnectionConstraints = function(terminal) { var geo = (terminal != null) ? this.getCellGeometry(terminal.cell) : null; - console.log("getAllConnectionConstraints ",terminal) if ((geo != null ? !geo.relative : false) && this.getModel().isVertex(terminal.cell) && this.getModel().getChildCount(terminal.cell) == 0) { - return [ - new mxConnectionConstraint(new mxPoint(1, 0.5), false)]; + if(terminal.cell.Pin == true){ // a pin + mxLog.debug("getAllConnectionConstraints ",terminal.cell.angle) + if(terminal.cell.angle == 90){ + return [new mxConnectionConstraint(new mxPoint(0,0), false)]; + }else if(terminal.cell.angle == 180){ + return [new mxConnectionConstraint(new mxPoint(0,0), false)]; + }else if(terminal.cell.angle == 270){ + return [new mxConnectionConstraint(new mxPoint(1, 0), false)]; + }else{ + return [new mxConnectionConstraint(new mxPoint(1, 0), false)]; + } + + } + } + if((geo != null) && (this.getModel.isEdge(terminal.cell))){ + console.log(terminal.cell) } return null; }; @@ -215,6 +562,8 @@ class AltiumSchematicRenderer return (geo != null) ? geo.relative : false; } }; + + var parent = this.graph.getDefaultParent(); mxVertexHandler.prototype.livePreview = true; @@ -358,7 +707,7 @@ class AltiumSchematicRenderer // var obj2 = this.graph.getCellAt(obj.points[obj.points.length - 1].x, // obj.points[obj.points.length - 1].y,parent) - // console.log(obj1,obj2) + // mxLog.debug(obj1,obj2) // // if (!this.#shouldShow(obj)) continue; // // ctx.strokeStyle = this.#altiumColourToHex(obj.colour); @@ -425,7 +774,7 @@ class AltiumSchematicRenderer obj.top = 840 - obj.top obj.bottom = 840 - obj.bottom if(!obj.transparent){ - console.log('verticalLabelPosition=top;verticalAlign=bottom;fillColor=' + mxLog.debug('verticalLabelPosition=top;verticalAlign=bottom;fillColor=' + this.#altiumColourToHex(obj.attributes.areacolor)) let v1 = this.graph.insertVertex(parent, null, '', obj.left, obj.top, @@ -516,7 +865,7 @@ class AltiumSchematicRenderer } obj.y = 840 - obj.y - // console.log(style) + // mxLog.debug(style) var v11 = this.graph.insertVertex(parent, null, name, obj.x, obj.y, obj.length, 1, style); @@ -525,7 +874,10 @@ class AltiumSchematicRenderer if(chips[obj.owner_record_index] == undefined){ chips[obj.owner_record_index] = [] } - console.log(v11.geometry.getTerminalPoint (true)) + v11.Pin = true + v11.angle = obj.angle + v11.length = obj.length + mxLog.debug(v11.geometry.getTerminalPoint (true)) chips[obj.owner_record_index].push(v11) // v11.geometry.offset = new mxPoint(-v11.geometry.width, 2); // ctx.strokeStyle = "#000000"; @@ -569,7 +921,7 @@ class AltiumSchematicRenderer obj.x2 = 840 - obj.x2 obj.y2 = 840 - obj.y2 style = 'shape=polyline;strokeColor=#0000ff;' - // console.log(style) + // mxLog.debug(style) var v11 = this.graph.insertVertex(parent, null, '', obj.x1, obj.x2, 1,1,style); v11.points = [new mxPoint(obj.y1 - obj.x1,obj.y2 - obj.x2)] @@ -629,7 +981,7 @@ class AltiumSchematicRenderer obj.x2 = 840 - obj.x2 obj.y2 = 840 - obj.y2 style = 'shape=polygon;strokeColor=#0000ff;' - // console.log(style) + // mxLog.debug(style) var v11 = this.graph.insertVertex(parent, null, '', obj.points[0], obj.points[0], 1,1,style); @@ -661,17 +1013,6 @@ class AltiumSchematicRenderer // ctx.lineWidth = 1; } - for (let obj of doc.objects.filter((o) => o instanceof AltiumJunction)) - { - obj = obj - - // if (!this.#shouldShow(obj)) continue; - - // ctx.fillStyle = this.#altiumColourToHex(obj.colour); - // ctx.beginPath(); - // ctx.ellipse(obj.x, obj.y, 5, 4, 0, 0, 2*Math.PI); - // ctx.fill(); - } for (let obj of doc.objects.filter((o) => o instanceof AltiumPowerPort)) { @@ -771,10 +1112,10 @@ class AltiumSchematicRenderer { obj.y = 840 - obj.y if(obj.text != undefined){ - console.log(obj.text.length) + mxLog.debug(obj.text.length) var v11 = this.graph.insertVertex(parent, null, obj.text, obj.x, obj.y - 4, obj.text.length*9/2, 0, - "shape=label;fontSize=9;"); + "shape=label;fontSize=6;"); v11.geometry.relative = false; v11.setConnectable(false); if(obj.owner_record_index != 1) @@ -803,8 +1144,8 @@ class AltiumSchematicRenderer obj = obj obj.y = 840 - obj.y if(obj.text != undefined){ - console.log(obj.text.length) - var v11 = this.graph.insertVertex(parent, null, obj.text, obj.x, obj.y - 4, + mxLog.debug(obj.text.length) + var v11 = this.graph.insertVertex(parent, null, obj.text, obj.x, obj.y - 5, obj.text.length*9/2, 0, "shape=label;fontSize=9;"); v11.geometry.relative = false; @@ -812,14 +1153,7 @@ class AltiumSchematicRenderer if(obj.owner_record_index != 1) chips[obj.owner_record_index].push(v11) } - // if (!this.#shouldShow(obj)) continue; - - // if (obj.hidden) - // continue; - // ctx.textAlign = ["left", "left", "right", "right"][obj.orientation]; - // ctx.textBaseline = ["bottom", "bottom", "top", "top"][obj.orientation]; - // ctx.fillStyle = this.#altiumColourToHex(obj.colour); - // ctx.fillText(obj.full_designator, obj.x, canvas.height - obj.y); + } // ctx.textAlign = "left"; // ctx.textBaseline = "bottom"; @@ -1000,14 +1334,22 @@ class AltiumSchematicRenderer } } - var e6 = this.graph.insertEdge(parent, null, '') + var e6 = this.graph.insertEdge(parent, null, '',null,null,'fillColor=fff2ff,startArrow=oval') e6.geometry.points = poi e6.geometry.setTerminalPoint(new mxPoint(obj.points[0].x, obj.points[0].y), true) e6.geometry.setTerminalPoint(new mxPoint(obj.points[obj.points.length - 1].x, obj.points[obj.points.length - 1].y), false) + + if(this.wires == undefined){ + this.wires = [] + this.wires.push(e6) + }else{ + this.wires.push(e6) } + + // if (!this.#shouldShow(obj)) continue; // ctx.strokeStyle = this.#altiumColourToHex(obj.colour); @@ -1020,9 +1362,34 @@ class AltiumSchematicRenderer // } // ctx.stroke(); } - for (let i in chips){ - let chip = this.graph.groupCells(null,0,chips[i]) - chip.setStyle("border=0;strokeColor=none") + + // find the junction on the wire + for (let obj of doc.objects.filter((o) => o instanceof AltiumJunction)) + { + obj.y = 840 - obj.y + let found = false + for(let i = 0;i < this.wires.length;i++){ + for(let j = 0;j < this.wires[i].geometry.points.length;j++){ + if((this.wires[i].geometry.points[j].x == obj.x) + &&(this.wires[i].geometry.points[j].y == obj.y)){ + found = true + // this.wires[i].geometry.points.push(new mxPoint(obj.x,obj.y)) + // this.wires[i].geometry.points.push(obj.x,obj.y) + } + } + } + // obj = obj + // obj.y = 840 - obj.y + // let edge = this.graph.getCellsBeyond(obj.x,obj.y) + // mxLog.debug(edge) + + var v11 = this.graph.insertVertex(parent, null, '', obj.x - 1, obj.y - 1, + 1,1,''); + + for (let i in chips){ + let chip = this.graph.groupCells(null,0,chips[i]) + chip.setStyle("border=0;strokeColor=none") + } } } finally{