Skip to content

Commit 5733b89

Browse files
arjxn-pypre-commit-ci[bot]martinRenou
authored
Enable toggling transform controls (#578)
* Enable toggling transform controls * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Attach and detach `transformControls` correctly * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Prevent edge selection while transforming * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Make switch mode text discoverable * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Now works without attach detach calls * No need to re-render * Remove rerendering * Update packages/base/src/3dview/mainview.tsx Co-authored-by: martinRenou <[email protected]> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: martinRenou <[email protected]>
1 parent b3b346a commit 5733b89

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

packages/base/src/3dview/mainview.tsx

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ interface IStates {
7171
annotations: IDict<IAnnotation>;
7272
firstLoad: boolean;
7373
wireframe: boolean;
74+
transform: boolean;
75+
clipEnabled: boolean;
7476
}
7577

7678
interface ILineIntersection extends THREE.Intersection {
@@ -113,7 +115,9 @@ export class MainView extends React.Component<IProps, IStates> {
113115
loading: true,
114116
annotations: {},
115117
firstLoad: true,
116-
wireframe: false
118+
wireframe: false,
119+
transform: false,
120+
clipEnabled: true
117121
};
118122
}
119123

@@ -641,7 +645,9 @@ export class MainView extends React.Component<IProps, IStates> {
641645
if (
642646
!intersect.object.visible ||
643647
!intersect.object.parent?.visible ||
644-
intersect.object.name === SELECTION_BOUNDING_BOX
648+
intersect.object.name === SELECTION_BOUNDING_BOX ||
649+
(this._transformControls.enabled &&
650+
intersect.object.name.startsWith('edge'))
645651
) {
646652
continue;
647653
}
@@ -1192,8 +1198,8 @@ export class MainView extends React.Component<IProps, IStates> {
11921198
this._transformControls.position.copy(positionVector);
11931199
}
11941200

1195-
this._transformControls.visible = true;
1196-
this._transformControls.enabled = true;
1201+
this._transformControls.visible = this.state.transform;
1202+
this._transformControls.enabled = this.state.transform;
11971203

11981204
return;
11991205
}
@@ -1429,9 +1435,13 @@ export class MainView extends React.Component<IProps, IStates> {
14291435
const clipSettings = change.newValue as ClipSettings | undefined;
14301436

14311437
if (change.type !== 'remove' && clipSettings) {
1432-
this._clipSettings = clipSettings;
1433-
1434-
this._updateClipping();
1438+
this.setState(
1439+
oldState => ({ ...oldState, clipEnabled: clipSettings.enabled }),
1440+
() => {
1441+
this._clipSettings = clipSettings;
1442+
this._updateClipping();
1443+
}
1444+
);
14351445
}
14361446
}
14371447

@@ -1449,12 +1459,25 @@ export class MainView extends React.Component<IProps, IStates> {
14491459
child.material.needsUpdate = true;
14501460
}
14511461
});
1452-
this._renderer.render(this._scene, this._camera);
14531462
}
14541463
}
14551464
);
14561465
}
14571466
}
1467+
1468+
if (change.key === 'transform') {
1469+
const transformEnabled = change.newValue as boolean | undefined;
1470+
1471+
if (transformEnabled !== undefined) {
1472+
this.setState(
1473+
old => ({ ...old, transform: transformEnabled }),
1474+
() => {
1475+
this._transformControls.visible = transformEnabled;
1476+
this._transformControls.enabled = transformEnabled;
1477+
}
1478+
);
1479+
}
1480+
}
14581481
}
14591482

14601483
private _setupExplodedView() {
@@ -1621,6 +1644,8 @@ export class MainView extends React.Component<IProps, IStates> {
16211644
return screenPosition;
16221645
}
16231646
render(): JSX.Element {
1647+
const isTransformOrClipEnabled =
1648+
this.state.transform || this._clipSettings.enabled;
16241649
return (
16251650
<div
16261651
className="jcad-Mainview data-jcad-keybinding"
@@ -1665,6 +1690,22 @@ export class MainView extends React.Component<IProps, IStates> {
16651690
height: 'calc(100%)'
16661691
}}
16671692
/>
1693+
{isTransformOrClipEnabled && (
1694+
<div
1695+
style={{
1696+
position: 'absolute',
1697+
bottom: '10px',
1698+
left: '10px',
1699+
padding: '8px',
1700+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
1701+
color: 'white',
1702+
borderRadius: '4px',
1703+
fontSize: '12px'
1704+
}}
1705+
>
1706+
Press R to switch mode
1707+
</div>
1708+
)}
16681709
</div>
16691710
);
16701711
}

packages/base/src/commands.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,32 @@ export function addCommands(
954954
commands.notifyCommandChanged(CommandIDs.wireframe);
955955
});
956956

957+
commands.addCommand(CommandIDs.transform, {
958+
label: trans.__('Toggle Transform Controls'),
959+
isEnabled: () => {
960+
return tracker.currentWidget !== null;
961+
},
962+
isToggled: () => {
963+
const current = tracker.currentWidget?.content;
964+
return current?.transform || false;
965+
},
966+
execute: async () => {
967+
const current = tracker.currentWidget?.content;
968+
969+
if (!current) {
970+
return;
971+
}
972+
973+
current.transform = !current.transform;
974+
commands.notifyCommandChanged(CommandIDs.transform);
975+
},
976+
icon: axesIcon
977+
});
978+
979+
tracker.currentChanged.connect(() => {
980+
commands.notifyCommandChanged(CommandIDs.transform);
981+
});
982+
957983
commands.addCommand(CommandIDs.chamfer, {
958984
label: trans.__('Make chamfer'),
959985
isEnabled: () => {
@@ -1134,6 +1160,7 @@ export namespace CommandIDs {
11341160
export const union = 'jupytercad:union';
11351161
export const intersection = 'jupytercad:intersection';
11361162
export const wireframe = 'jupytercad:wireframe';
1163+
export const transform = 'jupytercad:transform';
11371164

11381165
export const chamfer = 'jupytercad:chamfer';
11391166
export const fillet = 'jupytercad:fillet';

packages/base/src/toolbar/widget.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ export class ToolbarWidget extends ReactiveToolbar {
192192
commands: options.commands
193193
})
194194
);
195+
this.addItem(
196+
'Toggle Transform Controls',
197+
new CommandToolbarButton({
198+
id: CommandIDs.transform,
199+
label: '',
200+
commands: options.commands
201+
})
202+
);
195203
this.addItem('separator6', new Separator());
196204

197205
this.addItem(

packages/base/src/widget.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ export class JupyterCadPanel extends SplitPanel {
145145
this._view.set('wireframe', value);
146146
}
147147

148+
get transform(): boolean {
149+
return this._view.get('transform') as boolean;
150+
}
151+
152+
set transform(value: boolean) {
153+
this._view.set('transform', value);
154+
}
155+
148156
executeConsole() {
149157
if (this._consoleView) {
150158
this._consoleView.execute();

0 commit comments

Comments
 (0)