@things-factory/figure-ui 10.1.92 → 10.1.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/modeller/fasten-geometry.ts +152 -0
- package/client/modeller/figure-cavity-drawing.ts +259 -0
- package/client/modeller/figure-fasten-drawing.ts +406 -0
- package/client/modeller/figure-links.ts +71 -35
- package/client/modeller/figure-section-panel.ts +2 -0
- package/client/modeller/section-controls.ts +19 -0
- package/dist-client/modeller/fasten-geometry.d.ts +60 -0
- package/dist-client/modeller/fasten-geometry.js +138 -0
- package/dist-client/modeller/fasten-geometry.js.map +1 -0
- package/dist-client/modeller/figure-cavity-drawing.d.ts +48 -0
- package/dist-client/modeller/figure-cavity-drawing.js +253 -0
- package/dist-client/modeller/figure-cavity-drawing.js.map +1 -0
- package/dist-client/modeller/figure-fasten-drawing.d.ts +74 -0
- package/dist-client/modeller/figure-fasten-drawing.js +452 -0
- package/dist-client/modeller/figure-fasten-drawing.js.map +1 -0
- package/dist-client/modeller/figure-links.d.ts +7 -0
- package/dist-client/modeller/figure-links.js +70 -33
- package/dist-client/modeller/figure-links.js.map +1 -1
- package/dist-client/modeller/figure-section-panel.d.ts +1 -0
- package/dist-client/modeller/figure-section-panel.js +2 -0
- package/dist-client/modeller/figure-section-panel.js.map +1 -1
- package/dist-client/modeller/section-controls.d.ts +10 -0
- package/dist-client/modeller/section-controls.js +17 -0
- package/dist-client/modeller/section-controls.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test/browser/acceptance-page.js +10 -0
- package/test/cavity-drawing.test.ts +69 -0
- package/test/fasten-drawing.test.ts +45 -0
- package/test/fasten-geometry.test.ts +79 -0
- package/test/links.test.ts +3 -1
- package/translations/en.json +11 -1
- package/translations/ja.json +11 -1
- package/translations/ko.json +11 -1
- package/translations/ms.json +11 -1
- package/translations/zh.json +11 -1
|
@@ -6,8 +6,12 @@ import { i18next, localize } from '@operato/i18n';
|
|
|
6
6
|
import { FIGURE_FACES } from '@hatiolab/figure-model';
|
|
7
7
|
import { acceptsOf, alignAxesOf, mountingPlaneOf, alignOf, AXES, canFasten, facesOf, canFollow, dimensionNow, followableAxes, positionIsShare, choiceOf, heldBy, followOf, hangsFrom, shownWhenOf, visibilityControlsOf, placeKeptOf, fasteningOf, hasInstanceSize, holdsThings, leadersFor, motionOf, motionFormOf, motionJoint, placeFacesOf, placeIdFor, placesOn, rowAxesOf, rowBlockOf, fixedJointOf, rowOf, positionsWorkedOut, fieldWordsOf, measureNow } from './links.js';
|
|
8
8
|
import { SidePanelStyles } from './side-panel-styles.js';
|
|
9
|
+
import './figure-fasten-drawing.js';
|
|
10
|
+
import { faceViewOf, modeOf, myFaceFor, turnsInPlace } from './fasten-geometry.js';
|
|
9
11
|
import { HelpToggles } from './help.js';
|
|
10
12
|
const FACES = Object.keys(FIGURE_FACES);
|
|
13
|
+
/** The target list's entry for the plane the figure stands by. */
|
|
14
|
+
const PLANE = '__plane';
|
|
11
15
|
const freshFasten = () => ({
|
|
12
16
|
face: 'bottom',
|
|
13
17
|
toPlane: false,
|
|
@@ -438,15 +442,19 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
438
442
|
/* The faces are the ones each shape declares: a part is fastened by one of its outer faces, to any face of the target. */
|
|
439
443
|
/* On the mounting plane only the faces it takes: a bottom or a top on the floor, a back on a wall. */
|
|
440
444
|
const plane = mountingPlaneOf(asset);
|
|
445
|
+
const planeWord = i18next.t('figure.label.resize-place-' + (asset.placement ?? 'floor'));
|
|
441
446
|
/* Its outer faces, and its centre -- a roller spins about its middle (ADR-0093); the mounting plane takes a face. */
|
|
442
447
|
const mineFaces = [
|
|
443
448
|
...facesOf(asset, this.partId).filter(face => FACES.includes(face) && (!f.toPlane || plane.faces.includes(face))),
|
|
444
449
|
...(f.toPlane ? [] : ['centre'])
|
|
445
450
|
];
|
|
446
|
-
const myFace = mineFaces.includes(f.face) ? f.face : mineFaces[0];
|
|
447
451
|
const theirFaces = f.target ? facesOf(asset, f.target) : FACES;
|
|
448
452
|
const targetFace = theirFaces.includes(f.targetFace) ? f.targetFace : theirFaces[0];
|
|
449
453
|
const aim = f.toPlane ? 'plane' : { part: f.target, face: targetFace };
|
|
454
|
+
/* The part's own face is not chosen: the target's face and how give it (user 2026-10-01; the kernel takes no other). */
|
|
455
|
+
const mode = f.toPlane ? 'meet' : modeOf(f.face, f.facing);
|
|
456
|
+
const derived = f.toPlane || f.target ? myFaceFor(asset, this.partId, aim, mode) : undefined;
|
|
457
|
+
const myFace = derived ?? (mineFaces.includes(f.face) ? f.face : mineFaces[0]);
|
|
450
458
|
const align = f.target || f.toPlane ? alignOf(asset, this.partId, aim, f.align, f.alignMm, !!f.twist, f.alignInput) : undefined;
|
|
451
459
|
const action = f.toPlane || f.target
|
|
452
460
|
? {
|
|
@@ -514,40 +522,41 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
514
522
|
</div>
|
|
515
523
|
${this.renderDetachWords()}`
|
|
516
524
|
: nothing}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
</
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
525
|
+
<div form>
|
|
526
|
+
<span>${i18next.t('figure.label.target-part')}</span>
|
|
527
|
+
<select @change=${(e) => {
|
|
528
|
+
const value = e.target.value;
|
|
529
|
+
this.aimAt(asset, value === PLANE ? { ...f, toPlane: true, target: '' } : { ...f, toPlane: false, target: value });
|
|
530
|
+
}}>
|
|
531
|
+
<option value="" ?selected=${!f.target && !f.toPlane}>${i18next.t('figure.label.target-part-placeholder')}</option>
|
|
532
|
+
<option value=${PLANE} ?selected=${f.toPlane}>${planeWord}</option>
|
|
533
|
+
${targets.map(one => loops(one)
|
|
534
|
+
? html `<option value=${one} disabled>${i18next.t('figure.text.target-would-loop', { part: one, mine: this.partId })}</option>`
|
|
535
|
+
: html `<option value=${one} ?selected=${one === f.target && !f.toPlane}>${one}</option>`)}
|
|
536
|
+
</select>
|
|
537
|
+
</div>
|
|
538
|
+
${f.toPlane || f.target
|
|
539
|
+
? html `<p fasten-sentence>${this.sentenceOf(myFace, f.toPlane ? planeWord : `${f.target}의 ${i18next.t('figure.label.face-' + targetFace)}`, mode)}</p>
|
|
540
|
+
<figure-fasten-drawing
|
|
541
|
+
.target=${f.toPlane ? '' : f.target}
|
|
542
|
+
.planeWord=${planeWord}
|
|
543
|
+
.faces=${theirFaces}
|
|
544
|
+
.face=${targetFace}
|
|
545
|
+
.modes=${f.toPlane ? ['meet'] : ([...['meet', 'flush'], ...(turnsInPlace(asset, this.partId) ? ['centre'] : [])])}
|
|
546
|
+
.mode=${mode}
|
|
547
|
+
.view=${faceViewOf(asset, this.partId, aim)}
|
|
548
|
+
.align=${f.align}
|
|
549
|
+
.alignMm=${f.alignMm}
|
|
550
|
+
.gap=${f.gap}
|
|
551
|
+
.partName=${this.partId}
|
|
552
|
+
?locked=${this.locked}
|
|
553
|
+
?said=${!!held}
|
|
554
|
+
@fasten-change=${(e) => this.onFastenChange(asset, e.detail)}
|
|
555
|
+
@fasten-release=${() => this.onFastenRelease(!!held)}
|
|
556
|
+
></figure-fasten-drawing>`
|
|
557
|
+
: html `<p hint>${i18next.t('figure.text.fasten-target-first')}</p>`}
|
|
540
558
|
${(f.toPlane || f.target) ? html `<details fasten-detail>
|
|
541
559
|
<summary>${i18next.t('figure.label.fasten-detail')} · <span fasten-summary>${detail.length ? detail.join(' · ') : i18next.t('figure.text.fasten-summary-default')}</span></summary>
|
|
542
|
-
${f.toPlane
|
|
543
|
-
? nothing
|
|
544
|
-
: html `<div form>
|
|
545
|
-
<span>${i18next.t('figure.label.facing')}</span>
|
|
546
|
-
<select @change=${(e) => (this.fasten = { ...f, facing: e.target.value })}>
|
|
547
|
-
<option value="meet" ?selected=${f.facing === 'meet'}>${i18next.t('figure.label.facing-meet')}</option>
|
|
548
|
-
<option value="flush" ?selected=${f.facing === 'flush'}>${i18next.t('figure.label.facing-flush')}</option>
|
|
549
|
-
</select>
|
|
550
|
-
</div>`}
|
|
551
560
|
${this.renderAlignment(f.toPlane || f.target ? alignAxesOf(asset, this.partId, aim, !!f.twist) : [])}
|
|
552
561
|
<div form>
|
|
553
562
|
<span>${i18next.t('figure.label.gap')}</span>
|
|
@@ -562,6 +571,34 @@ let FigureLinks = class FigureLinks extends localize(i18next)(LitElement) {
|
|
|
562
571
|
</button>` : nothing}
|
|
563
572
|
`;
|
|
564
573
|
}
|
|
574
|
+
/** 「lid 의 아랫면을 bin 의 윗면에 맞닿게」: what the fastening is, in one line, the part's own face said as a result. */
|
|
575
|
+
sentenceOf(myFace, to, mode) {
|
|
576
|
+
return i18next.t(`figure.text.fasten-sentence-${mode}`, { part: this.partId, face: i18next.t('figure.label.face-' + myFace), to });
|
|
577
|
+
}
|
|
578
|
+
/** A change the drawing asks: to the form only; the preview behind follows the form. */
|
|
579
|
+
onFastenChange(asset, c) {
|
|
580
|
+
const f = this.fasten;
|
|
581
|
+
if ('targetFace' in c)
|
|
582
|
+
this.aimAt(asset, { ...f, targetFace: c.targetFace });
|
|
583
|
+
else if ('mode' in c)
|
|
584
|
+
this.fasten = { ...f, face: c.mode === 'centre' ? 'centre' : f.face === 'centre' ? 'bottom' : f.face, facing: c.mode === 'flush' ? 'flush' : 'meet' };
|
|
585
|
+
else if ('gap' in c)
|
|
586
|
+
this.fasten = { ...f, gap: c.gap };
|
|
587
|
+
else
|
|
588
|
+
this.fasten = {
|
|
589
|
+
...f,
|
|
590
|
+
align: { ...f.align, [c.axis]: c.how },
|
|
591
|
+
alignMm: c.how === 'mm' ? { ...f.alignMm, [c.axis]: c.mm ?? 0 } : f.alignMm
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
/** Let go: a fastening the part already has is applied as it now is (one step); a new one waits for 붙이기. */
|
|
595
|
+
async onFastenRelease(held) {
|
|
596
|
+
if (!held)
|
|
597
|
+
return;
|
|
598
|
+
await this.updateComplete;
|
|
599
|
+
if (this.fastenCandidate)
|
|
600
|
+
this.command(this.fastenCandidate.action);
|
|
601
|
+
}
|
|
565
602
|
renderDetachWords() {
|
|
566
603
|
return this.detachWords.length ? html `<ul detach-words>${this.detachWords.map(line => html `<li>${line}</li>`)}</ul>` : nothing;
|
|
567
604
|
}
|