LineRelativeAngle.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /**
  2. * Copyright (c) 2011-2018 by Andrew Mustun. All rights reserved.
  3. *
  4. * This file is part of the QCAD project.
  5. *
  6. * QCAD is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * QCAD is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with QCAD.
  18. */
  19. include("scripts/Draw/Line/Line.js");
  20. /**
  21. * \class LineRelativeAngle
  22. * \brief Line with relative angle to existing line, position and length.
  23. * \ingroup ecma_draw_line
  24. */
  25. function LineRelativeAngle(guiAction) {
  26. Line.call(this, guiAction);
  27. this.entity = undefined;
  28. this.shape = undefined;
  29. this.pos = undefined;
  30. this.angle = Math.PI/2.0;
  31. this.len = 100.0;
  32. this.referencePoint = undefined;
  33. if (!isNull(guiAction)) {
  34. this.setUiOptions(["../Line.ui", "LineRelativeAngle.ui"]);
  35. }
  36. }
  37. LineRelativeAngle.prototype = new Line();
  38. LineRelativeAngle.State = {
  39. ChoosingEntity : 0,
  40. SettingPos : 1
  41. };
  42. LineRelativeAngle.ReferencePoint = {
  43. Start : 0,
  44. Middle : 1,
  45. End : 2
  46. };
  47. LineRelativeAngle.prototype.beginEvent = function() {
  48. Line.prototype.beginEvent.call(this);
  49. this.setState(LineRelativeAngle.State.ChoosingEntity);
  50. };
  51. LineRelativeAngle.prototype.setState = function(state) {
  52. Line.prototype.setState.call(this, state);
  53. this.setCrosshairCursor();
  54. var tr;
  55. var appWin = RMainWindowQt.getMainWindow();
  56. switch (this.state) {
  57. case LineRelativeAngle.State.ChoosingEntity:
  58. this.getDocumentInterface().setClickMode(RAction.PickEntity);
  59. tr = qsTr("Choose base line, arc, circle, ellipse or polyline");
  60. this.setCommandPrompt(tr);
  61. this.setLeftMouseTip(tr);
  62. this.setRightMouseTip(EAction.trCancel);
  63. this.entity = undefined;
  64. this.shape = undefined;
  65. this.pos = undefined;
  66. break;
  67. case LineRelativeAngle.State.SettingPos:
  68. this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
  69. tr = qsTr("Set position");
  70. this.setCommandPrompt(tr);
  71. this.setLeftMouseTip(tr);
  72. this.setRightMouseTip(EAction.trBack);
  73. EAction.showSnapTools();
  74. break;
  75. }
  76. this.typeChanged();
  77. };
  78. LineRelativeAngle.prototype.escapeEvent = function() {
  79. switch (this.state) {
  80. case LineRelativeAngle.State.ChoosingEntity:
  81. EAction.prototype.escapeEvent.call(this);
  82. break;
  83. case LineRelativeAngle.State.SettingPos:
  84. this.setState(LineRelativeAngle.State.ChoosingEntity);
  85. break;
  86. }
  87. };
  88. LineRelativeAngle.prototype.pickEntity = function(event, preview) {
  89. var di = this.getDocumentInterface();
  90. var doc = this.getDocument();
  91. var entityId = this.getEntityId(event, preview);
  92. var entity = doc.queryEntity(entityId);
  93. var pos = event.getModelPosition();
  94. if (isNull(entity)) {
  95. return;
  96. }
  97. if (!this.isEntitySnappable(entity)) {
  98. // entity not on a snappable layer:
  99. return;
  100. }
  101. var shape = entity.getClosestSimpleShape(pos);
  102. //if (preview) {
  103. // di.highlightEntity(entityId);
  104. //}
  105. switch (this.state) {
  106. case LineRelativeAngle.State.ChoosingEntity:
  107. if (isArcShape(shape) ||
  108. isCircleShape(shape) ||
  109. isLineBasedShape(shape) ||
  110. isEllipseShape(shape)) {
  111. this.entity = entity;
  112. this.shape = shape;
  113. if (preview) {
  114. this.updatePreview();
  115. }
  116. else {
  117. this.setState(LineRelativeAngle.State.SettingPos);
  118. }
  119. }
  120. else {
  121. if (!preview) {
  122. EAction.warnNotLineArcCircleEllipsePolyline();
  123. }
  124. this.entity = undefined;
  125. this.shape = undefined;
  126. }
  127. break;
  128. }
  129. };
  130. LineRelativeAngle.prototype.pickCoordinate = function(event, preview) {
  131. var di = this.getDocumentInterface();
  132. switch (this.state) {
  133. case LineRelativeAngle.State.SettingPos:
  134. this.pos = event.getModelPosition();
  135. if (preview) {
  136. this.updatePreview();
  137. }
  138. else {
  139. var op = this.getOperation(false);
  140. if (!isNull(op)) {
  141. di.applyOperation(op);
  142. }
  143. }
  144. break;
  145. }
  146. };
  147. LineRelativeAngle.prototype.getHighlightedEntities = function() {
  148. var ret = [];
  149. if (isEntity(this.entity)) {
  150. ret.push(this.entity.getId());
  151. }
  152. return ret;
  153. };
  154. LineRelativeAngle.prototype.getOperation = function(preview) {
  155. if (isNull(this.pos) || isNull(this.entity) || isNull(this.referencePoint)) {
  156. return undefined;
  157. }
  158. var doc = this.getDocument();
  159. var line = this.getLine();
  160. if (isNull(line)) {
  161. return undefined;
  162. }
  163. var op = new RAddObjectsOperation();
  164. op.setText(this.getToolTitle());
  165. op.addObject(this.createLineEntity(doc, line.getStartPoint(), line.getEndPoint()));
  166. return op;
  167. };
  168. LineRelativeAngle.prototype.getLine = function() {
  169. var doc = this.getDocument();
  170. // check given entity / coord:
  171. if (isNull(this.shape) || isNull(this.pos) || isNull(this.referencePoint)) {
  172. return undefined;
  173. }
  174. var angle = this.getAbsoluteAngle();
  175. // for rays / xlines, always use start point as reference
  176. // with length = 1.0:
  177. var referencePoint = this.referencePoint;
  178. var length = this.len;
  179. if (this.isRayOrXLine()) {
  180. referencePoint = LineRelativeAngle.ReferencePoint.Start;
  181. length = 1.0;
  182. }
  183. var p1, p2;
  184. switch(referencePoint) {
  185. case LineRelativeAngle.ReferencePoint.Start:
  186. p1 = this.pos;
  187. p2 = this.pos.operator_add(
  188. RVector.createPolar(+length, angle)
  189. );
  190. break;
  191. case LineRelativeAngle.ReferencePoint.Middle:
  192. p1 = this.pos.operator_add(
  193. RVector.createPolar(-length/2, angle)
  194. );
  195. p2 = this.pos.operator_add(
  196. RVector.createPolar(+length/2, angle)
  197. );
  198. break;
  199. case LineRelativeAngle.ReferencePoint.End:
  200. p1 = this.pos.operator_add(
  201. RVector.createPolar(-length, angle)
  202. );
  203. p2 = this.pos;
  204. break;
  205. default:
  206. return undefined;
  207. }
  208. return new RLine(p1, p2);
  209. };
  210. LineRelativeAngle.prototype.getAbsoluteAngle = function() {
  211. var ret;
  212. if (isLineBasedShape(this.shape)) {
  213. ret = this.shape.getAngle();
  214. }
  215. else if (isArcShape(this.shape) || isCircleShape(this.shape)) {
  216. ret = this.shape.getCenter().getAngleTo(this.pos) + Math.PI/2.0;
  217. }
  218. else if (isEllipseShape(this.shape)) {
  219. var p = this.shape.getClosestPointOnShape(this.pos, false);
  220. ret = this.shape.getAngleAtPoint(p);
  221. }
  222. ret += this.angle;
  223. return ret;
  224. };
  225. LineRelativeAngle.prototype.slotAngleChanged = function(value) {
  226. this.angle = value;
  227. this.updatePreview(true);
  228. };
  229. LineRelativeAngle.prototype.slotLengthChanged = function(value) {
  230. this.len = value;
  231. this.updatePreview(true);
  232. };
  233. LineRelativeAngle.prototype.slotReferencePointChanged = function(value) {
  234. this.referencePoint = value;
  235. this.updatePreview(true);
  236. };
  237. LineRelativeAngle.prototype.typeChanged = function() {
  238. var optionsToolBar = EAction.getOptionsToolBar();
  239. var ws = ["LengthLabel", "Length", "ReferencePointLabel", "ReferencePoint"];
  240. for (var i=0; i<ws.length; i++) {
  241. var w = optionsToolBar.findChild(ws[i]);
  242. if (!isNull(w)) {
  243. w.enabled = !this.isRayOrXLine();
  244. }
  245. }
  246. };