InfoAngle.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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/Information/Information.js");
  20. /**
  21. * \class InfoAngle
  22. * \ingroup ecma_information
  23. * \brief Measure angle.
  24. */
  25. function InfoAngle(guiAction) {
  26. Information.call(this, guiAction);
  27. this.entity1 = undefined;
  28. this.shape1 = undefined;
  29. this.point1 = undefined;
  30. this.entity2 = undefined;
  31. this.shape2 = undefined;
  32. this.point2 = undefined;
  33. this.arc = undefined;
  34. this.position = undefined;
  35. this.setUiOptions(InfoAngle.includeBasePath + "/../Information.ui");
  36. }
  37. InfoAngle.prototype = new Information();
  38. InfoAngle.includeBasePath = includeBasePath;
  39. InfoAngle.State = {
  40. SettingFirstShape : 0,
  41. SettingSecondShape : 1
  42. };
  43. InfoAngle.prototype.beginEvent = function() {
  44. Information.prototype.beginEvent.call(this);
  45. this.setState(InfoAngle.State.SettingFirstShape);
  46. }
  47. InfoAngle.prototype.setState = function(state) {
  48. Information.prototype.setState.call(this, state);
  49. var di = this.getDocumentInterface();
  50. di.setClickMode(RAction.PickEntity);
  51. this.setCrosshairCursor();
  52. var appWin = RMainWindowQt.getMainWindow();
  53. switch (this.state) {
  54. case InfoAngle.State.SettingFirstShape:
  55. var trFirstLine = qsTr("Specify first line");
  56. this.setCommandPrompt(trFirstLine);
  57. this.setLeftMouseTip(trFirstLine);
  58. this.setRightMouseTip(EAction.trCancel);
  59. break;
  60. case InfoAngle.State.SettingSecondShape:
  61. this.entity2 = undefined;
  62. this.shape2 = undefined;
  63. this.point2 = undefined;
  64. var trSecondLine = qsTr("Specify second line");
  65. this.setCommandPrompt(trSecondLine);
  66. this.setLeftMouseTip(trSecondLine);
  67. this.setRightMouseTip(EAction.trDone);
  68. break;
  69. }
  70. EAction.showSnapTools();
  71. };
  72. InfoAngle.prototype.pickEntity = function(event, preview) {
  73. var di = this.getDocumentInterface();
  74. var doc = this.getDocument();
  75. var pos = event.getModelPosition();
  76. var entityId = this.getEntityId(event, preview);
  77. var entity = doc.queryEntity(entityId);
  78. var op;
  79. if (!this.isEntitySnappable(entity)) {
  80. // entity not on a snappable layer:
  81. return;
  82. }
  83. // keep showing preview after 2nd entity has been set:
  84. if (!this.addToDrawing) {
  85. op = this.getOperation(preview);
  86. if (!isNull(op)) {
  87. if (preview) {
  88. di.previewOperation(op);
  89. }
  90. else {
  91. destr(op);
  92. }
  93. }
  94. }
  95. if (isNull(entity)) {
  96. return;
  97. }
  98. var shape;
  99. switch (this.state) {
  100. case InfoAngle.State.SettingFirstShape:
  101. shape = entity.getClosestSimpleShape(pos);
  102. if (isLineBasedShape(shape)) {
  103. if (!preview) {
  104. this.entity1 = entity;
  105. this.shape1 = shape;
  106. this.point1 = this.shape1.getClosestPointOnShape(pos);
  107. }
  108. else {
  109. di.highlightEntity(entity.getId());
  110. }
  111. }
  112. else {
  113. if (!preview) {
  114. EAction.warnNotLine();
  115. }
  116. break;
  117. }
  118. if (!preview) {
  119. this.setState(InfoAngle.State.SettingSecondShape);
  120. }
  121. break;
  122. case InfoAngle.State.SettingSecondShape:
  123. di.highlightEntity(this.entity1.getId());
  124. shape = entity.getClosestSimpleShape(pos);
  125. if (isLineBasedShape(shape)) {
  126. this.entity2 = entity;
  127. this.shape2 = shape;
  128. this.point2 = this.shape2.getClosestPointOnShape(pos);
  129. this.position = pos;
  130. di.highlightEntity(this.entity2.getId());
  131. }
  132. op = this.getOperation(preview);
  133. if (preview) {
  134. di.previewOperation(op);
  135. }
  136. else {
  137. if (this.addToDrawing) {
  138. di.applyOperation(op);
  139. di.setRelativeZero(this.point2);
  140. }
  141. else {
  142. destr(op);
  143. }
  144. if (!isNull(this.arc)) {
  145. var value = this.arc.getAngleLength();
  146. var angleText = this.formatAngularResultCmd(value);
  147. EAction.getMainWindow().handleUserInfo(qsTr("Angle:") + " " + angleText);
  148. if (this.autoTerminate) {
  149. this.updateLineEdit(RMath.rad2deg(value));
  150. this.setNoState(false);
  151. this.terminate();
  152. return;
  153. }
  154. else {
  155. this.setState(InfoAngle.State.SettingFirstShape);
  156. }
  157. }
  158. else {
  159. this.setState(InfoAngle.State.SettingFirstShape);
  160. }
  161. }
  162. break;
  163. }
  164. };
  165. InfoAngle.prototype.addMeasuringArc = function(op, center, preview) {
  166. var di = this.getDocumentInterface();
  167. var a1 = center.getAngleTo(this.point1);
  168. var a2 = center.getAngleTo(this.point2);
  169. var r = center.getDistanceTo(this.position);
  170. var posAngle = center.getAngleTo(this.position);
  171. var reversed = RMath.isAngleBetween(posAngle, a1, a2, true);
  172. this.arc = new RArc(center, r, a1, a2, reversed);
  173. this.addShape(op, this.arc, preview);
  174. // add label:
  175. var view = di.getLastKnownViewWithFocus();
  176. view = getRGraphicsView(view);
  177. var label = this.formatAngularResult(this.arc.getAngleLength());
  178. view.clearTextLabels();
  179. this.addTextLabel(op, view, this.point2, label, preview);
  180. };
  181. InfoAngle.prototype.getOperation = function(preview) {
  182. if (isNull(this.shape1) || isNull(this.shape2) ||
  183. isNull(this.point1) || isNull(this.point2)) {
  184. return undefined;
  185. }
  186. var op = new RAddObjectsOperation();
  187. op.setText(this.getToolTitle());
  188. var sol = this.shape1.getIntersectionPoints(getPtr(this.shape2), false);
  189. if (!isNull(sol) && sol.length > 0) {
  190. var intersection = sol[0];
  191. if (intersection.isValid()) {
  192. var angle1 = intersection.getAngleTo(this.point1);
  193. var angle2 = intersection.getAngleTo(this.point2);
  194. var angle = RMath.getAngleDifference(angle1, angle2);
  195. this.addMeasuringArc(op, intersection, preview);
  196. }
  197. this.noAngle = false;
  198. } else {
  199. this.noAngle = true;
  200. }
  201. return op;
  202. };