fix(editor): site-panel property-line coords + area/perimeter follow the unit toggle
The property-line vertex X/Z inputs and the Area/Perimeter readout were hardcoded to meters. Convert them to feet / ft² when the viewer preference is imperial, matching every other length input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
69813a6e62
commit
5ffde5f66a
@@ -38,6 +38,11 @@ import {
|
|||||||
} from './../../../../../lib/level-duplication'
|
} from './../../../../../lib/level-duplication'
|
||||||
import { getDefaultLevelName } from '@pascal-app/core'
|
import { getDefaultLevelName } from '@pascal-app/core'
|
||||||
import { deleteLevelWithFallbackSelection } from './../../../../../lib/level-selection'
|
import { deleteLevelWithFallbackSelection } from './../../../../../lib/level-selection'
|
||||||
|
import {
|
||||||
|
getLinearUnitLabel,
|
||||||
|
linearUnitToMeters,
|
||||||
|
metersToLinearUnit,
|
||||||
|
} from './../../../../../lib/measurements'
|
||||||
import { createLocalGuideImage } from './../../../../../lib/local-guide-image'
|
import { createLocalGuideImage } from './../../../../../lib/local-guide-image'
|
||||||
import { cn } from './../../../../../lib/utils'
|
import { cn } from './../../../../../lib/utils'
|
||||||
import useEditor from './../../../../../store/use-editor'
|
import useEditor from './../../../../../store/use-editor'
|
||||||
@@ -93,6 +98,7 @@ const PropertyLineSection = memo(function PropertyLineSection() {
|
|||||||
const updateNode = useScene((state) => state.updateNode)
|
const updateNode = useScene((state) => state.updateNode)
|
||||||
const mode = useEditor((state) => state.mode)
|
const mode = useEditor((state) => state.mode)
|
||||||
const setMode = useEditor((state) => state.setMode)
|
const setMode = useEditor((state) => state.setMode)
|
||||||
|
const viewerUnit = useViewer((state) => state.unit)
|
||||||
|
|
||||||
if (!siteNode) return null
|
if (!siteNode) return null
|
||||||
|
|
||||||
@@ -101,6 +107,14 @@ const PropertyLineSection = memo(function PropertyLineSection() {
|
|||||||
const perimeter = calculatePerimeter(points)
|
const perimeter = calculatePerimeter(points)
|
||||||
const isEditing = mode === 'edit'
|
const isEditing = mode === 'edit'
|
||||||
|
|
||||||
|
// Property-line coordinates and readouts follow the metric/imperial toggle.
|
||||||
|
const isImperial = viewerUnit === 'imperial'
|
||||||
|
const linearLabel = getLinearUnitLabel(viewerUnit)
|
||||||
|
const toDisplayLinear = (meters: number) => metersToLinearUnit(meters, viewerUnit)
|
||||||
|
const toStoredLinear = (display: number) => linearUnitToMeters(display, viewerUnit)
|
||||||
|
const displayArea = isImperial ? area * 10.763_910_417 : area
|
||||||
|
const displayPerimeter = toDisplayLinear(perimeter)
|
||||||
|
|
||||||
const handleToggleEdit = () => {
|
const handleToggleEdit = () => {
|
||||||
setMode(isEditing ? 'select' : 'edit')
|
setMode(isEditing ? 'select' : 'edit')
|
||||||
}
|
}
|
||||||
@@ -166,10 +180,16 @@ const PropertyLineSection = memo(function PropertyLineSection() {
|
|||||||
{/* Measurements */}
|
{/* Measurements */}
|
||||||
<div className="relative flex gap-3 pr-3 pb-2 pl-10">
|
<div className="relative flex gap-3 pr-3 pb-2 pl-10">
|
||||||
<div className="text-muted-foreground text-xs">
|
<div className="text-muted-foreground text-xs">
|
||||||
Area: <span className="text-foreground">{area.toFixed(1)} m²</span>
|
Area:{' '}
|
||||||
|
<span className="text-foreground">
|
||||||
|
{displayArea.toFixed(1)} {isImperial ? 'ft²' : 'm²'}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-muted-foreground text-xs">
|
<div className="text-muted-foreground text-xs">
|
||||||
Perimeter: <span className="text-foreground">{perimeter.toFixed(1)} m</span>
|
Perimeter:{' '}
|
||||||
|
<span className="text-foreground">
|
||||||
|
{displayPerimeter.toFixed(1)} {linearLabel}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -184,21 +204,21 @@ const PropertyLineSection = memo(function PropertyLineSection() {
|
|||||||
<input
|
<input
|
||||||
className="w-16 rounded border border-border/50 bg-accent/50 px-1.5 py-0.5 text-foreground text-xs focus:border-primary focus:outline-none"
|
className="w-16 rounded border border-border/50 bg-accent/50 px-1.5 py-0.5 text-foreground text-xs focus:border-primary focus:outline-none"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handlePointChange(index, 0, Number.parseFloat(e.target.value) || 0)
|
handlePointChange(index, 0, toStoredLinear(Number.parseFloat(e.target.value) || 0))
|
||||||
}
|
}
|
||||||
step={0.5}
|
step={0.5}
|
||||||
type="number"
|
type="number"
|
||||||
value={point[0]}
|
value={Number(toDisplayLinear(point[0]).toFixed(2))}
|
||||||
/>
|
/>
|
||||||
<label className="shrink-0 text-muted-foreground">Z</label>
|
<label className="shrink-0 text-muted-foreground">Z</label>
|
||||||
<input
|
<input
|
||||||
className="w-16 rounded border border-border/50 bg-accent/50 px-1.5 py-0.5 text-foreground text-xs focus:border-primary focus:outline-none"
|
className="w-16 rounded border border-border/50 bg-accent/50 px-1.5 py-0.5 text-foreground text-xs focus:border-primary focus:outline-none"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handlePointChange(index, 1, Number.parseFloat(e.target.value) || 0)
|
handlePointChange(index, 1, toStoredLinear(Number.parseFloat(e.target.value) || 0))
|
||||||
}
|
}
|
||||||
step={0.5}
|
step={0.5}
|
||||||
type="number"
|
type="number"
|
||||||
value={point[1]}
|
value={Number(toDisplayLinear(point[1]).toFixed(2))}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
Reference in New Issue
Block a user