diff --git a/web/app/canvas.js b/web/app/canvas.js index 53563264..3487b4ba 100644 --- a/web/app/canvas.js +++ b/web/app/canvas.js @@ -19,7 +19,14 @@ TCAD.TWO.Styles = { lineWidth : 2, strokeStyle : "#ff0000", fillStyle : "#FF0000" + }, + + SNAP : { + lineWidth : 2, + strokeStyle : "#00FF00", + fillStyle : "#00FF00" } + }; TCAD.TWO.utils = {}; @@ -62,8 +69,8 @@ TCAD.TWO.Viewer = function(canvas) { this.translate = {x : 0.0, y : 0.0}; this.scale = 1.0; - this.segments = []; this.selected = []; + this.snapped = []; this._setupServiceLayer(); this.refresh(); @@ -77,7 +84,7 @@ TCAD.TWO.Viewer.prototype.addSegment = function(x1, y1, x2, y2, layer) { return line; }; -TCAD.TWO.Viewer.prototype.searchSegment = function(x, y, buffer, deep) { +TCAD.TWO.Viewer.prototype.search = function(x, y, buffer, deep, onlyPoints) { buffer *= 0.5; @@ -93,6 +100,9 @@ TCAD.TWO.Viewer.prototype.searchSegment = function(x, y, buffer, deep) { for (var j = 0; j < objs.length; j++) { var l = unreachable + 1; var hit = !objs[j].visit(true, function(o) { + if (onlyPoints && o._class !== 'TCAD.TWO.EndPoint') { + return false; + } l = o.normalDistance(aim); if (l > 0 && l <= buffer) { pickResult.push(o); @@ -102,7 +112,7 @@ TCAD.TWO.Viewer.prototype.searchSegment = function(x, y, buffer, deep) { }); if (hit) { - if (!deep && pickResult.length != 0) return; + if (!deep && pickResult.length != 0) return pickResult; if (l < heroLength) { heroLength = l; heroIdx = pickResult.length - 1; @@ -165,6 +175,29 @@ TCAD.TWO.Viewer.prototype.repaint = function() { } }; +TCAD.TWO.Viewer.prototype.snap = function(x, y, excl) { + this.cleanSnap(); + var snapTo = this.search(x, y, 20 / this.scale, false, true); + if (snapTo.length > 0) { + snapTo = snapTo[0]; + for (var i = 0; i < excl.length; i++) { + if (excl[i] === snapTo) { + return; + } + } + this.mark(snapTo, TCAD.TWO.Styles.SNAP); + this.snapped.push(snapTo); + return snapTo; + } + return null; +}; + +TCAD.TWO.Viewer.prototype.cleanSnap = function() { + while(this.snapped.length > 0) { + this.snapped.pop().marked = null; + } +}; + TCAD.TWO.Viewer.prototype.showBounds = function(x1, y1, x2, y2) { this.translate.x = -x1; this.translate.y = -y1; @@ -202,18 +235,20 @@ TCAD.TWO.Viewer.prototype.select = function(objs, exclusive) { TCAD.TWO.Viewer.prototype.pick = function(e) { var m = this.screenToModel(e); - return this.searchSegment(m.x, m.y, 20 / this.scale, true); + return this.search(m.x, m.y, 20 / this.scale, true, false); }; -TCAD.TWO.Viewer.prototype.mark = function(obj) { - obj.marked = true; +TCAD.TWO.Viewer.prototype.mark = function(obj, style) { + if (style === undefined) { + style = TCAD.TWO.Styles.MARK; + } + obj.marked = style; this.selected.push(obj); }; TCAD.TWO.Viewer.prototype.deselectAll = function() { for (var i = 0; i < this.selected.length; i++) { - var obj = this.selected[i]; - obj.marked = false; + this.selected[i].marked = null; } while(this.selected.length > 0) this.selected.pop(); }; @@ -275,7 +310,7 @@ TCAD.TWO.utils.genID = function() { TCAD.TWO.SketchObject = function() { this.id = TCAD.TWO.utils.genID(); this.aux = false; - this.marked = false; + this.marked = null; this.visible = true; this.children = []; this.linked = []; @@ -313,12 +348,12 @@ TCAD.TWO.SketchObject.prototype.translate = function(dx, dy) { TCAD.TWO.SketchObject.prototype.draw = function(ctx, scale) { if (!this.visible) return; - if (this.marked) { + if (this.marked != null) { ctx.save(); - TCAD.TWO.utils.setStyle(TCAD.TWO.Styles.MARK, ctx, scale); + TCAD.TWO.utils.setStyle(this.marked, ctx, scale); } this.drawImpl(ctx, scale); - if (this.marked) ctx.restore(); + if (this.marked != null) ctx.restore(); for (var i = 0; i < this.children.length; i++) { this.children[i].draw(ctx, scale); } @@ -355,7 +390,6 @@ TCAD.TWO.EndPoint = function(x, y) { TCAD.TWO.SketchObject.call(this); this.x = x; this.y = y; - this.marked = false; this.parent = null; this._x = new TCAD.TWO.Param(this, 'x'); this._y = new TCAD.TWO.Param(this, 'y'); @@ -478,6 +512,16 @@ TCAD.TWO.ToolManager = function(viewer, defaultTool) { e.stopPropagation(); tm.getTool().mousewheel(e); }, false); + + window.addEventListener("keydown", function (e) { + tm.getTool().mousewheel(e); + }, false); + window.addEventListener("keypress", function (e) { + tm.getTool().mousewheel(e); + }, false); + window.addEventListener("keyup", function (e) { + tm.getTool().mousewheel(e); + }, false); }; TCAD.TWO.ToolManager.prototype.takeControl = function(tool) { @@ -488,7 +532,7 @@ TCAD.TWO.ToolManager.prototype.releaseControl = function() { if (this.stack.length == 1) { return; } - this.stack.pop(); + this.stack.pop().cleanup();; }; TCAD.TWO.ToolManager.prototype.getTool = function() { @@ -502,6 +546,11 @@ TCAD.TWO.PanTool = function(viewer) { this.y = 0.0; }; +TCAD.TWO.PanTool.prototype.keydown = function(e) {}; +TCAD.TWO.PanTool.prototype.keypress = function(e) {}; +TCAD.TWO.PanTool.prototype.keyup = function(e) {}; +TCAD.TWO.PanTool.prototype.cleanup = function(e) {}; + TCAD.TWO.PanTool.prototype.mousemove = function(e) { if (!this.dragging) { return; @@ -588,6 +637,11 @@ TCAD.TWO.DragTool = function(obj, viewer) { this.errorY = 0; }; +TCAD.TWO.DragTool.prototype.keydown = function(e) {}; +TCAD.TWO.DragTool.prototype.keypress = function(e) {}; +TCAD.TWO.DragTool.prototype.keyup = function(e) {}; +TCAD.TWO.DragTool.prototype.cleanup = function(e) {}; + TCAD.TWO.DragTool.prototype.mousemove = function(e) { var x = this._point.x; var y = this._point.y; diff --git a/web/app/parametric.js b/web/app/parametric.js index a9a737fe..b7b8e3c0 100644 --- a/web/app/parametric.js +++ b/web/app/parametric.js @@ -115,8 +115,7 @@ TCAD.TWO.ParametricManager.prototype.radius = function(objs, promptCallback) { } }; -TCAD.TWO.ParametricManager.prototype.coincident = function(objs) { - if (objs.length == 0) return; +TCAD.TWO.ParametricManager.prototype.linkObjects = function(objs) { var i; var last = objs.length - 1; for (i = 0; i < objs.length - 1; ++i) { @@ -133,7 +132,11 @@ TCAD.TWO.ParametricManager.prototype.coincident = function(objs) { } } } - +}; + +TCAD.TWO.ParametricManager.prototype.coincident = function(objs) { + if (objs.length == 0) return; + this.linkObjects(objs); this.solve(); this.viewer.refresh(); }; diff --git a/web/app/tools/arc.js b/web/app/tools/arc.js index baa4cc1b..3cbe49fb 100644 --- a/web/app/tools/arc.js +++ b/web/app/tools/arc.js @@ -74,6 +74,11 @@ TCAD.TWO.AddArcTool = function(viewer, layer) { this._v = new TCAD.Vector(0, 0, 0); }; +TCAD.TWO.AddArcTool.prototype.keydown = function(e) {}; +TCAD.TWO.AddArcTool.prototype.keypress = function(e) {}; +TCAD.TWO.AddArcTool.prototype.keyup = function(e) {}; +TCAD.TWO.AddArcTool.prototype.cleanup = function(e) {}; + TCAD.TWO.AddArcTool.prototype.mousemove = function(e) { if (this.point != null) { var p = this.viewer.screenToModel(e); diff --git a/web/app/tools/circle.js b/web/app/tools/circle.js index 3a425085..ec9e46d7 100644 --- a/web/app/tools/circle.js +++ b/web/app/tools/circle.js @@ -47,6 +47,11 @@ TCAD.TWO.EditCircleTool = function(viewer, layer) { this.circle = null; }; +TCAD.TWO.EditCircleTool.prototype.keydown = function(e) {}; +TCAD.TWO.EditCircleTool.prototype.keypress = function(e) {}; +TCAD.TWO.EditCircleTool.prototype.keyup = function(e) {}; +TCAD.TWO.EditCircleTool.prototype.cleanup = function(e) {}; + TCAD.TWO.EditCircleTool.prototype.mousemove = function(e) { if (this.circle != null) { var p = this.viewer.screenToModel(e); diff --git a/web/app/tools/segment.js b/web/app/tools/segment.js index 720b4ec8..1e47a60a 100644 --- a/web/app/tools/segment.js +++ b/web/app/tools/segment.js @@ -1,32 +1,74 @@ -TCAD.TWO.AddSegmentTool = function(viewer, layer) { +TCAD.TWO.AddSegmentTool = function(viewer, layer, multi) { this.viewer = viewer; this.layer = layer; this.line = null; + this.multi = multi; }; TCAD.TWO.AddSegmentTool.prototype.mousemove = function(e) { + var p = this.viewer.screenToModel(e); if (this.line != null) { - var p = this.viewer.screenToModel(e); + this.viewer.snap(p.x, p.y, [this.line.a, this.line.b]); this.line.b.x = p.x; this.line.b.y = p.y; this.viewer.refresh(); + } else { + this.viewer.snap(p.x, p.y, []); + this.viewer.refresh(); } }; -TCAD.TWO.AddSegmentTool.prototype.mousedown = function(e) { +TCAD.TWO.AddSegmentTool.prototype.cleanup = function(e) { + this.viewer.cleanSnap(); +}; +TCAD.TWO.AddSegmentTool.prototype.mousedown = function(e) { + }; TCAD.TWO.AddSegmentTool.prototype.mouseup = function(e) { if (this.line == null) { - var p = this.viewer.screenToModel(e); - this.line = this.viewer.addSegment(p.x, p.y, p.x, p.y, this.layer); + var b = this.viewer.screenToModel(e); + var a = b; + var needSnap = false; + if (this.viewer.snapped.length != 0) { + a = this.viewer.snapped.pop(); + this.viewer.cleanSnap(); + needSnap = true; + } + this.line = this.viewer.addSegment(a.x, a.y, b.x, b.y, this.layer); + if (needSnap) { + this.viewer.parametricManager.linkObjects([this.line.a, a]); + } this.viewer.refresh(); } else { - this.line = null; + if (this.viewer.snapped.length != 0) { + var p = this.viewer.snapped.pop(); + this.viewer.cleanSnap(); + this.line.b.x = p.x; + this.line.b.y = p.y; + this.viewer.parametricManager.linkObjects([this.line.b, p]); + this.viewer.refresh(); + } + if (this.multi) { + var b = this.line.b; + this.line = this.viewer.addSegment(b.x, b.y, b.x, b.y, this.layer); + this.viewer.parametricManager.linkObjects([this.line.a, b]); + } else { + this.line = null; + } } }; TCAD.TWO.AddSegmentTool.prototype.mousewheel = function(e) { }; + +TCAD.TWO.AddSegmentTool.prototype.keydown = function(e) { + if (this.multi && e.keyCode == 13) { + this.line = null; + } +}; + +TCAD.TWO.AddSegmentTool.prototype.keypress = function(e) {}; +TCAD.TWO.AddSegmentTool.prototype.keyup = function(e) {};