diff --git a/web/app/3d/ctrl.js b/web/app/3d/ctrl.js
index 025d8506..06bf2fc3 100644
--- a/web/app/3d/ctrl.js
+++ b/web/app/3d/ctrl.js
@@ -163,7 +163,7 @@ function UI(app) {
IO.exportTextData(stl.data[0], app.id + ".stl");
});
app.bus.subscribe("solid-pick", function(solid) {
- new TransformWizard(app.viewer, solid).createUI(mainBox);
+ ui.registerWizard(new TransformWizard(app.viewer, solid));
});
}
diff --git a/web/app/3d/wizards/transform.js b/web/app/3d/wizards/transform.js
index ab4d6e07..c2dfd85b 100644
--- a/web/app/3d/wizards/transform.js
+++ b/web/app/3d/wizards/transform.js
@@ -1,35 +1,130 @@
-import * as tk from '../../ui/toolkit'
+import {AXIS, IDENTITY_BASIS} from '../../math/l3space'
+import * as tk from '../../ui/toolkit.js'
+import {FACE_COLOR} from '../cad-utils'
+import {addOkCancelLogic} from './wizard-commons'
-export function TransformWizard(viewer, solid) {
+export function TransformWizard(viewer, solid, initParams) {
+ this.previewGroup = new THREE.Object3D();
this.viewer = viewer;
this.solid = solid;
+ addOkCancelLogic(this);
+ if (!initParams) {
+ initParams = TransformWizard.DEFAULT_PARAMS;
+ }
+ this._cancelClick = this.cancelClick;
+ this.cancelClick = function() {
+ this.discardChanges();
+ this._cancelClick();
+ };
+ this.ui = {};
+ this.initialPosition = this.solid.cadGroup.position.clone();
+ this.viewer.transformControls.attach(this.solid.cadGroup);
+ this.transfomControlListener = tk.methodRef(this, "synchToUI");
+ this.viewer.transformControls.addEventListener( 'objectChange', this.transfomControlListener );
+ this.createUI.apply(this, initParams);
+ this.synch();
}
-TransformWizard.prototype.createUI = function(alignComponent) {
- this.viewer.transformControls.attach(this.solid.cadGroup);
+TransformWizard.DEFAULT_PARAMS = [0, 0, 0, 0, 0, 0, 1];
+
+TransformWizard.prototype.discardChanges = function() {
+ this.solid.cadGroup.position.copy(this.initialPosition);
+};
+
+TransformWizard.prototype.update = function(x, y, z, rotationX, rotationY, rotationZ, rotationW) {
+ this.solid.cadGroup.position.setX(x);
+ this.solid.cadGroup.position.setX(y);
+ this.solid.cadGroup.position.setX(z);
+
+ this.solid.cadGroup.quaternion.x = rotationX;
+ this.solid.cadGroup.quaternion.y = rotationY;
+ this.solid.cadGroup.quaternion.z = rotationZ;
+ this.solid.cadGroup.quaternion.w = rotationW;
+
+ this.viewer.transformControls.update();
this.viewer.render();
- var box = new tk.Box();
- box.root.css({left : (alignComponent.root.width() + 10) + 'px', top : 0});
- var folder = new tk.Folder("Transformation");
- tk.add(box, folder);
- var wizard = this;
- function close() {
- box.close();
- wizard.dispose();
+};
+
+TransformWizard.prototype.createUI = function(x, y, z, rotationX, rotationY, rotationZ, rotationW) {
+ var ui = this.ui;
+ ui.box = new tk.Box();
+ var folder = new tk.Folder("Solid Transform");
+ var position = new tk.Folder("Position");
+ var rotation = new tk.Folder("Rotation");
+ tk.add(folder, position);
+ tk.add(folder, rotation);
+ tk.add(ui.box, folder);
+ ui.x = new tk.Number("Position X", x, 1, 6);
+ ui.y = new tk.Number("Position Y", y, 1, 6);
+ ui.z = new tk.Number("Position Z", z, 1, 6);
+ ui.rotationX = tk.config(new tk.Number("Rotation X", rotationX, 0.1, 6), {min: -1, max: 1});
+ ui.rotationY = tk.config(new tk.Number("Rotation Y", rotationY, 0.1, 6), {min: -1, max: 1});
+ ui.rotationZ = tk.config(new tk.Number("Rotation Z", rotationZ, 0.1, 6), {min: -1, max: 1});
+ ui.rotationW = tk.config(new tk.Number("Rotation W", rotationW, 0.1, 6), {min: -1, max: 1});
+ ui.mode = new tk.InlineRadio(['translate(T)', 'rotate(R)'], ['translate', 'rotate'], 0);
+ tk.add(position, ui.x);
+ tk.add(position, ui.y);
+ tk.add(position, ui.z);
+ tk.add(rotation, ui.rotationX);
+ tk.add(rotation, ui.rotationY);
+ tk.add(rotation, ui.rotationZ);
+ tk.add(rotation, ui.rotationW);
+ tk.add(rotation, ui.mode);
+ this.ui.mode.root.find('input:radio').change(tk.methodRef(this, "modeChanged"));
+ var onChange = tk.methodRef(this, "synch");
+ ui.x.input.on('t-change', onChange);
+ ui.y.input.on('t-change', onChange);
+ ui.z.input.on('t-change', onChange);
+ ui.rotationX.input.on('t-change', onChange);
+ ui.rotationY.input.on('t-change', onChange);
+ ui.rotationZ.input.on('t-change', onChange);
+ tk.add(folder, new tk.ButtonRow(["Cancel", "OK"], [tk.methodRef(this, "cancelClick"), tk.methodRef(this, "okClick")]));
+};
+
+TransformWizard.prototype.modeChanged = function() {
+ var mode = this.ui.mode.getValue();
+ this.viewer.transformControls.setMode(mode);
+};
+
+TransformWizard.prototype.synchToUI = function() {
+ function round(val){return val.toFixed(6);}
+ var ui = this.ui;
+ ui.x.input.val( round(this.solid.cadGroup.position.x) );
+ ui.y.input.val( round(this.solid.cadGroup.position.y) );
+ ui.z.input.val( round(this.solid.cadGroup.position.z) );
+ ui.rotationX.input.val( round(this.solid.cadGroup.quaternion.x) );
+ ui.rotationY.input.val( round(this.solid.cadGroup.quaternion.y) );
+ ui.rotationZ.input.val( round(this.solid.cadGroup.quaternion.z) );
+ ui.rotationW.input.val( round(this.solid.cadGroup.quaternion.w) );
+ this.viewer.render();
+};
+
+TransformWizard.prototype.synch = function() {
+ this.update.apply(this, this.getParams());
+ this.viewer.render();
+};
+
+TransformWizard.prototype.getParams = function() {
+ return [this.ui.x.val(), this.ui.y.val(), this.ui.z.val(),
+ this.ui.rotationX.val(), this.ui.rotationY.val(), this.ui.rotationZ.val(), this.ui.rotationW.val()];
+};
+
+TransformWizard.prototype.createRequest = function() {
+ var params = this.getParams();
+ return {
+ type: 'TRANSFORM',
+ solids : [],
+ params : {
+ position: {x : params[0], y : params[1], z : params[2]},
+ rotate: {x : params[3], y : params[4], z : params[5]}
+ } ,
+ protoParams : params
}
- function apply() {
- //app.craft.modify({
- // type: 'PLANE',
- // solids : [],
- // params : wizard.operationParams,
- // protoParams : protoParams()
- //}, overiding);
- close();
- }
- tk.add(folder, new tk.ButtonRow(["Cancel", "Apply"], [close, apply]));
};
TransformWizard.prototype.dispose = function() {
+ this.viewer.transformControls.removeEventListener( 'objectChange', this.transfomControlListener );
this.viewer.transformControls.detach(this.solid.cadGroup);
+ this.ui.box.close();
this.viewer.render();
};
diff --git a/web/app/ui/toolkit.js b/web/app/ui/toolkit.js
index a650b441..ef167833 100644
--- a/web/app/ui/toolkit.js
+++ b/web/app/ui/toolkit.js
@@ -47,7 +47,7 @@ export function InlineRadio(choiceLabels, choiceValues, checkedIndex) {
this.inputs = [];
for (var i = 0; i < choiceLabels.length; i++) {
var checked = checkedIndex === i ? "checked" : '';
- var label = $('');
+ var label = $('');
this.inputs.push(label.find("input"));
this.root.append(label);
}
@@ -110,7 +110,7 @@ function NumberWidget(name, initValue, baseStep, round) {
if (scope.min != null && val < scope.min) {
val = scope.min;
}
- if (scope.max != null && val > scope.min) {
+ if (scope.max != null && val > scope.max) {
val = scope.max;
}
if (round !== 0) {
diff --git a/web/css/toolkit.css b/web/css/toolkit.css
index 51a2f803..2100f56e 100644
--- a/web/css/toolkit.css
+++ b/web/css/toolkit.css
@@ -82,6 +82,14 @@
color: #eee;
}
+.tc-ctrl input[type=checkbox] {
+ vertical-align: sub;
+}
+
+.tc-ctrl input[type=radio] {
+ vertical-align: sub;
+}
+
.tc-scroll {
overflow-y: auto;
overflow-x: hidden;
@@ -140,6 +148,10 @@
padding-right: 5px;
}
+input[type=checkbox] {
+ vertical-align: sub;
+}
+
.tc-pseudo-btn {
cursor : pointer;
}