LineBoxJoint.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /**
  2. * Copyright (c) 2013 by Matthias Melcher. All rights reserved.
  3. *
  4. * This file is an extension of the QCAD project.
  5. *
  6. * LineBoxJoint 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. * LineBoxJoint 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("script/EAction.js");
  20. /**
  21. * \class LineBoxJoint
  22. * \brief Box joint line between two points.
  23. * \ingroup ecma_misc_draw
  24. */
  25. function LineBoxJoint(guiAction) {
  26. EAction.call(this, guiAction);
  27. this.corner1 = undefined;
  28. this.corner2 = undefined;
  29. this.fingerHeight = undefined;
  30. this.fingerLength = undefined;
  31. this.slotRatio = undefined;
  32. this.fingerStyle = undefined;
  33. this.setUiOptions("LineBoxJoint.ui");
  34. }
  35. LineBoxJoint.prototype = new EAction();
  36. LineBoxJoint.State = {
  37. SettingCorner1 : 0,
  38. SettingCorner2 : 1
  39. };
  40. LineBoxJoint.prototype.beginEvent = function() {
  41. EAction.prototype.beginEvent.call(this);
  42. this.setState(LineBoxJoint.State.SettingCorner1);
  43. };
  44. LineBoxJoint.prototype.setState = function(state) {
  45. EAction.prototype.setState.call(this, state);
  46. this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
  47. this.setCrosshairCursor();
  48. var appWin = RMainWindowQt.getMainWindow();
  49. switch (this.state) {
  50. case LineBoxJoint.State.SettingCorner1:
  51. var trCorner1 = qsTr("First point");
  52. this.setCommandPrompt(trCorner1);
  53. this.setLeftMouseTip(trCorner1);
  54. this.setRightMouseTip(EAction.trCancel);
  55. break;
  56. case LineBoxJoint.State.SettingCorner2:
  57. var trCorner2 = qsTr("Second point");
  58. this.setCommandPrompt(trCorner2);
  59. this.setLeftMouseTip(trCorner2);
  60. this.setRightMouseTip(EAction.trDone);
  61. break;
  62. }
  63. EAction.showSnapTools();
  64. };
  65. LineBoxJoint.prototype.escapeEvent = function() {
  66. switch (this.state) {
  67. case LineBoxJoint.State.SettingCorner1:
  68. EAction.prototype.escapeEvent.call(this);
  69. break;
  70. case LineBoxJoint.State.SettingCorner2:
  71. this.setState(LineBoxJoint.State.SettingCorner1);
  72. break;
  73. }
  74. };
  75. LineBoxJoint.prototype.pickCoordinate = function(event, preview) {
  76. var di = this.getDocumentInterface();
  77. switch (this.state) {
  78. case LineBoxJoint.State.SettingCorner1:
  79. this.corner1 = event.getModelPosition();
  80. if (!preview) {
  81. di.setRelativeZero(this.corner1);
  82. //di.repaintViews();
  83. this.setState(LineBoxJoint.State.SettingCorner2);
  84. }
  85. break;
  86. case LineBoxJoint.State.SettingCorner2:
  87. this.corner2 = event.getModelPosition();
  88. if (preview) {
  89. this.updatePreview();
  90. }
  91. else {
  92. var op = this.getOperation(false);
  93. if (!isNull(op)) {
  94. di.applyOperation(op);
  95. di.setRelativeZero(this.corner2);
  96. this.setState(LineBoxJoint.State.SettingCorner1);
  97. }
  98. }
  99. break;
  100. }
  101. };
  102. LineBoxJoint.prototype.getOperation = function(preview) {
  103. if (isNull(this.corner1) || isNull(this.corner2)) {
  104. return undefined;
  105. }
  106. if (!isNumberGreaterZero(this.fingerHeight) || !isNumberGreaterZero(this.slotRatio) || !isNumberGreaterZero(this.fingerLength)) {
  107. return undefined;
  108. }
  109. var c1 = this.corner1;
  110. var c2 = this.corner2;
  111. var c3 = c2;
  112. var len = this.corner1.getDistanceTo(this.corner2);
  113. var ang = this.corner1.getAngleTo(this.corner2);
  114. var slotLength = this.fingerLength * this.slotRatio;
  115. var nFingers = Math.ceil((len-slotLength)/(this.fingerLength+slotLength));
  116. if (!isNumber(nFingers)) {
  117. return undefined;
  118. }
  119. slotLength = (len-(nFingers*this.fingerLength))/(nFingers+1);
  120. var op = new RAddObjectsOperation();
  121. var fingerIn = new RVector();
  122. fingerIn.setPolar(this.fingerHeight, ang-Math.PI/2.0);
  123. var fingerOut = new RVector();
  124. fingerOut.setPolar(this.fingerHeight, ang+Math.PI/2.0);
  125. var fingerEdge = new RVector();
  126. fingerEdge.setPolar(this.fingerLength, ang);
  127. var slotEdge = new RVector();
  128. slotEdge.setPolar(slotLength, ang);
  129. switch (this.fingerStyle) {
  130. case 0:
  131. c2 = c1;
  132. for (var n=nFingers; n>0; n--) {
  133. c1 = c2; c2 = c2.operator_add(slotEdge);
  134. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  135. c1 = c2; c2 = c2.operator_add(fingerIn);
  136. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  137. c1 = c2; c2 = c2.operator_add(fingerEdge);
  138. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  139. c1 = c2; c2 = c2.operator_add(fingerOut);
  140. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  141. }
  142. c1 = c2; c2 = c2.operator_add(slotEdge);
  143. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  144. break;
  145. case 1:
  146. c2 = c1;
  147. c1 = c2; c2 = c2.operator_add(fingerIn);
  148. for (var n=nFingers; n>0; n--) {
  149. c1 = c2; c2 = c2.operator_add(slotEdge);
  150. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  151. c1 = c2; c2 = c2.operator_add(fingerOut);
  152. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  153. c1 = c2; c2 = c2.operator_add(fingerEdge);
  154. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  155. c1 = c2; c2 = c2.operator_add(fingerIn);
  156. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  157. }
  158. c1 = c2; c2 = c2.operator_add(slotEdge);
  159. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  160. break;
  161. case 2:
  162. c2 = c1;
  163. for (var n=nFingers; n>0; n--) {
  164. c1 = c2; c2 = c2.operator_add(slotEdge);
  165. c1 = c2; c2 = c2.operator_add(fingerEdge);
  166. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c2)));
  167. c3 = c1; c3 = c3.operator_add(fingerIn);
  168. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c3)));
  169. c1 = c3; c3 = c3.operator_add(fingerEdge);
  170. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c1, c3)));
  171. op.addObject(new RLineEntity(this.getDocument(), new RLineData(c3, c2)));
  172. }
  173. break;
  174. }
  175. return op;
  176. };
  177. LineBoxJoint.prototype.slotFingerHeightChanged = function(value) {
  178. this.fingerHeight = value;
  179. this.updatePreview(true);
  180. };
  181. LineBoxJoint.prototype.slotFingerLengthChanged = function(value) {
  182. this.fingerLength = value;
  183. this.updatePreview(true);
  184. };
  185. LineBoxJoint.prototype.slotSlotRatioChanged = function(value) {
  186. this.slotRatio = value;
  187. this.updatePreview(true);
  188. };
  189. LineBoxJoint.prototype.slotFingerStyleChanged = function(value) {
  190. this.fingerStyle = value;
  191. this.updatePreview(true);
  192. };