| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- /**
- * Copyright (c) 2011-2021 by Andrew Mustun. All rights reserved.
- *
- * This file is part of the QCAD project.
- *
- * QCAD is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * QCAD is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with QCAD.
- */
- include("../Transform.js");
- include("scripts/ShapeAlgorithms.js");
- /**
- * \class Scale
- * \brief Scales selected entities. Supports multiple copies.
- * \ingroup ecma_modify
- */
- function Scale(guiAction) {
- Transform.call(this, guiAction);
- this.focusPoint = undefined;
- this.referencePoint = undefined;
- this.targetPoint = undefined;
- this.factorX = undefined;
- this.factorY = undefined;
- this.factorByMouse = false;
- this.useDialog = RSettings.getBoolValue("Scale/UseDialog", true);
- if (!this.useDialog) {
- this.setUiOptions("Scale.ui");
- }
- }
- Scale.prototype = new Transform();
- Scale.includeBasePath = includeBasePath;
- Scale.getPreferencesCategory = function() {
- return [qsTr("Modify"), qsTr("Scale")];
- };
- Scale.State = {
- SettingFocusPoint : 0,
- SettingReferencePoint : 1,
- SettingTargetPoint : 2
- };
- Scale.prototype.beginEvent = function() {
- Transform.prototype.beginEvent.call(this);
- if (!this.verifySelection()) {
- return;
- }
- this.setState(Scale.State.SettingFocusPoint);
- };
- Scale.prototype.setState = function(state) {
- Transform.prototype.setState.call(this, state);
- this.getDocumentInterface().setClickMode(RAction.PickCoordinate);
- this.setCrosshairCursor();
- var appWin = RMainWindowQt.getMainWindow();
- switch (this.state) {
- case Scale.State.SettingFocusPoint:
- this.referencePoint = undefined;
- this.targetPoint = undefined;
- //this.factorX = undefined;
- //this.factorY = undefined;
- var trCenterPoint = qsTr("Focus point");
- this.setCommandPrompt(trCenterPoint);
- this.setLeftMouseTip(trCenterPoint);
- this.setRightMouseTip(EAction.trCancel);
- break;
- case Scale.State.SettingReferencePoint:
- this.referencePoint = undefined;
- this.targetPoint = undefined;
- this.factorX = undefined;
- this.factorY = undefined;
- var trReferencePoint = qsTr("Reference point");
- this.setCommandPrompt(trReferencePoint);
- this.setLeftMouseTip(trReferencePoint);
- this.setRightMouseTip(EAction.trBack);
- break;
- case Scale.State.SettingTargetPoint:
- this.targetPoint = undefined;
- this.factorX = undefined;
- this.factorY = undefined;
- var trTargetPoint = qsTr("Target point");
- this.setCommandPrompt(trTargetPoint);
- this.setLeftMouseTip(trTargetPoint);
- this.setRightMouseTip(EAction.trBack);
- break;
- }
- EAction.showSnapTools();
- };
- Scale.prototype.initUiOptions = function(resume, optionsToolBar) {
- EAction.prototype.initUiOptions.call(this, resume, optionsToolBar);
- this.initWidgets(optionsToolBar, "Sq");
- };
- Scale.prototype.escapeEvent = function() {
- switch (this.state) {
- case Scale.State.SettingFocusPoint:
- Transform.prototype.escapeEvent.call(this);
- break;
- case Scale.State.SettingReferencePoint:
- this.setState(Scale.State.SettingFocusPoint);
- break;
- case Scale.State.SettingTargetPoint:
- this.setState(Scale.State.SettingReferencePoint);
- break;
- }
- };
- Scale.prototype.pickCoordinate = function(event, preview) {
- var di = this.getDocumentInterface();
- var op;
- switch (this.state) {
- case Scale.State.SettingFocusPoint:
- this.focusPoint = event.getModelPosition();
- if (preview) {
- this.updatePreview();
- }
- else {
- if (this.useDialog) {
- this.setState(-1);
- if (!this.showDialog()) {
- // dialog canceled:
- this.terminate();
- return;
- }
- }
- // define factor with mouse:
- if (this.factorByMouse===true) {
- this.setState(Scale.State.SettingReferencePoint);
- }
- // factor defined in dialog:
- else {
- op = this.getOperation(false);
- if (!isNull(op)) {
- di.applyOperation(op);
- this.terminate();
- }
- }
- di.setRelativeZero(this.focusPoint);
- }
- break;
- case Scale.State.SettingReferencePoint:
- this.referencePoint = event.getModelPosition();
- if (preview) {
- this.updatePreview();
- }
- else {
- di.setRelativeZero(this.referencePoint);
- this.setState(Scale.State.SettingTargetPoint);
- }
- break;
- case Scale.State.SettingTargetPoint:
- this.targetPoint = event.getModelPosition();
- if (preview) {
- this.updatePreview();
- }
- else {
- op = this.getOperation(false);
- if (!isNull(op)) {
- di.applyOperation(op);
- di.setRelativeZero(this.targetPoint);
- this.setState(-1);
- this.terminate();
- }
- }
- break;
- }
- };
- /**
- * Shows the scaling dialog.
- *
- * \return True if the dialog was accepted, false if it was canceled.
- */
- Scale.prototype.showDialog = function() {
- var dialog = WidgetFactory.createDialog(Scale.includeBasePath, "ScaleDialog.ui");
- var widgets = getWidgets(dialog);
- this.initWidgets(dialog);
- WidgetFactory.restoreState(dialog);
- if (!dialog.exec()) {
- destr(dialog);
- EAction.activateMainWindow();
- return false;
- }
- if (widgets["DeleteOriginal"].checked===true) {
- this.copies = 0;
- }
- else if (widgets["KeepOriginal"].checked===true) {
- this.copies = 1;
- }
- else {
- this.copies = widgets["NumberOfCopies"].getValue();
- }
- if (widgets["FactorByMouse"].checked===true) {
- this.factorByMouse = true;
- this.factorX = undefined;
- this.factorY = undefined;
- }
- else {
- this.factorByMouse = false;
- this.factorX = widgets["FactorX"].getValue();
- if (widgets["KeepProportions"].checked===false) {
- this.factorY = widgets["FactorY"].getValue();
- }
- else {
- this.factorY = undefined;
- }
- }
- this.useCurrentAttributes = (widgets["UseCurrentAttributes"].checked===true);
- WidgetFactory.saveState(dialog);
- destr(dialog);
- EAction.activateMainWindow();
- return true;
- };
- Scale.prototype.initWidgets = function(widget, postfix) {
- if (isNull(postfix)) {
- postfix = "";
- }
- var widgets = getWidgets(widget);
- widgets["FactorX"].textChanged.connect(
- function(text) {
- if (widgets["KeepProportions"].checked===true) {
- widgets["FactorY"].text = text;
- }
- });
- widgets["KeepProportions"].toggled.connect(
- function(checked) {
- if (checked) {
- widgets["FactorY"].text = widgets["FactorX"].text;
- }
- if (checked) {
- widgets["KeepProportions"].icon = new QIcon(Scale.includeBasePath + "/KeepProportionsOn" + postfix + ".svg");
- }
- else {
- widgets["KeepProportions"].icon = new QIcon(Scale.includeBasePath + "/KeepProportionsOff" + postfix + ".svg");
- }
- });
- };
- Scale.prototype.getOperation = function(preview) {
- if (!isValidVector(this.focusPoint)) {
- return undefined;
- }
- if (this.factorByMouse===true) {
- if (!isValidVector(this.referencePoint) || !isValidVector(this.targetPoint)) {
- return undefined;
- }
- var s1, s2;
- s1 = this.focusPoint.getDistanceTo(this.referencePoint);
- if (s1<RS.PointTolerance) {
- return undefined;
- }
- s2 = this.focusPoint.getDistanceTo(this.targetPoint);
- if (s2<RS.PointTolerance) {
- return undefined;
- }
- this.factorX = s2/s1;
- this.factorY = undefined;
- }
- if (!isNumber(this.factorX)) {
- return undefined;
- }
- return Transform.prototype.getOperation.call(this, preview);
- };
- Scale.prototype.transformArc = function(shape, sv) {
- var s = shape;
- if (isFunction(shape.data)) {
- s = getPtr(shape);
- }
- if (isCircleShape(s)) {
- s = ShapeAlgorithms.circleToArc(s, 0.0);
- }
- return RShape.scaleArc(s, sv, this.focusPoint);
- };
- /**
- * Callback function for Transform.getOperation.
- */
- Scale.prototype.transform = function(entity, k, op, preview, flags) {
- // uniform scaling (supported by all entities):
- if (isNull(this.factorY) || RMath.fuzzyCompare(this.factorX, this.factorY)) {
- entity.scale(Math.pow(this.factorX, k), this.focusPoint);
- op.addObject(entity, flags);
- return;
- }
- this.preTransform(entity);
- var e;
- // non-uniform scaling of arc, circle or ellipse:
- var sv = new RVector(Math.pow(this.factorX, k), Math.pow(this.factorY, k));
- if (isArcEntity(entity) || isCircleEntity(entity) || isEllipseEntity(entity)) {
- var arc = entity.castToShape();
- var shape = this.transformArc(arc, sv);
- e = shapeToEntity(this.getDocument(), shape);
- if (!isNull(e)) {
- e.copyAttributesFrom(entity);
- e.setDrawOrder(entity.getDrawOrder());
- e.setSelected(true);
- }
- if (this.getCopies()===0) {
- op.deleteObject(entity);
- }
- if (!isNull(e)) {
- this.postTransform(e);
- op.addObject(e, flags);
- }
- return;
- }
- // non-uniform scaling of hatches:
- if (isHatchEntity(entity)) {
- //debugger;
- var data = entity.getData();
- var newHatchData = new RHatchData();
- newHatchData.setDocument(data.getDocument());
- newHatchData.copyAttributesFrom(data);
- //newHatchData.clearBoundary();
- for (var i=0; i<entity.getLoopCount(); i++) {
- newHatchData.newLoop();
- var shapes = entity.getLoopBoundary(i);
- for (var n=0; n<shapes.length; n++) {
- shape = shapes[n];
- if (isArcShape(shape) || isCircleShape(shape) || isEllipseShape(shape)) {
- var newShape = this.transformArc(shape, sv);
- if (RSettings.getQtVersion() >= 0x060000) {
- newHatchData.addBoundary(newShape.clone());
- }
- else {
- newHatchData.addBoundary(newShape);
- }
- }
- else {
- // line, spline:
- shape.scale(sv, this.focusPoint);
- if (RSettings.getQtVersion() >= 0x060000) {
- newHatchData.addBoundary(shape.clone());
- }
- else {
- newHatchData.addBoundary(shape);
- }
- }
- }
- }
- newHatchData.setSolid(entity.isSolid());
- newHatchData.setPatternName(entity.getPatternName());
- newHatchData.setScale(entity.getScale());
- newHatchData.setAngle(entity.getAngle());
- newHatchData.setOriginPoint(entity.getOriginPoint());
- entity.setData(newHatchData);
- this.postTransform(entity);
- op.addObject(entity, flags);
- return;
- }
- // non-uniform scaling of other entities:
- entity.scale(sv, this.focusPoint);
- this.postTransform(entity);
- op.addObject(entity, flags);
- };
- Scale.prototype.preTransform = function(entity) {
- return;
- };
- Scale.prototype.postTransform = function(entity) {
- return;
- };
- Scale.prototype.getAuxPreview = function() {
- if (!isValidVector(this.focusPoint)) {
- return undefined;
- }
- var ret = [];
- if (this.state==Scale.State.SettingReferencePoint || this.state==Scale.State.SettingTargetPoint) {
- if (isValidVector(this.referencePoint)) {
- ret.push(new RLine(this.focusPoint, this.referencePoint));
- }
- }
- if (this.state==Scale.State.SettingTargetPoint) {
- if (isValidVector(this.targetPoint)) {
- ret.push(new RLine(this.focusPoint, this.targetPoint));
- }
- }
- return ret;
- };
- Scale.prototype.slotFactorXChanged = function(v) {
- this.factorX = v;
- };
- Scale.prototype.slotFactorYChanged = function(v) {
- this.factorY = v;
- };
- Scale.prototype.slotFactorByMouseChanged = function(v) {
- this.factorByMouse = v;
- };
|