Round number fields to the precision they display
`decimals` only reached `formatNumber`, so it changed the label and nothing else: typing 640.5 into a field with `decimals: 0` stored 640.5 and displayed 641. The two existing users got away with it because rounding happened outside the widget (`normalizeFrameRect`, the slice dialog), which their comments had to point out. `NumberField.clampValue` now rounds before it clamps, and every path that sets a value goes through it (typing, scrubbing, arrow keys, the constructor), so the stored number matches the shown one and `min`/`max` stay exact. The rounding is `roundTo` in math.ts, which `snapToStep` already did inline. With that safe, camera `View width`/`View height` and text `Font size` become integers – they were showing 640.000 and 32.000. Everything else that looked integral is not: positions, sprite and collider sizes and zoom are all scrubbed, and `z` is a summed coordinate (walk.ts), not a layer. Verified remotely against the RTX 4070 host: 270 checks, all passed (step 10 gained a check that the field text has no decimal point and survives a reopen). `npm run check` green, 407 tests.
This commit is contained in:
1 parent
6cf47fd2ae
commit
1b16a55ffc
8 files changed
+80
-19
No files matched your search
@@ -5,8 +5,9 @@ import type { PropertyBag, PropertyValue } from '../model/Properties';
|
||||
/** The inspector is generated from these entries, so a new property is one line in a schema below. */
|
||||
export type PropertyDef =
|
||||
/**
|
||||
* `decimals` belongs only on properties that are integral by meaning (counts, indices), not on
|
||||
* geometry: dragging produces fractions, and a field that hid them would commit the rounded value.
|
||||
* `decimals` belongs only on properties that are integral by meaning (counts, sizes in whole
|
||||
* pixels), not on geometry: dragging produces fractions, and the field rounds the value away
|
||||
* rather than hiding it.
|
||||
*/
|
||||
| {
|
||||
key: string;
|
||||
@@ -58,8 +59,9 @@ export function isCommonProp(key: string): boolean {
|
||||
const ASSET_SCHEMAS: Record<AssetType, PropertySchema> = {
|
||||
scene: [{ key: 'backgroundColor', label: 'Background', kind: 'color', default: 0x2a2d34 }],
|
||||
camera: [
|
||||
{ key: 'width', label: 'View width', kind: 'number', default: 640, min: 16, step: 1 },
|
||||
{ key: 'height', label: 'View height', kind: 'number', default: 360, min: 16, step: 1 },
|
||||
// A view is a pixel raster, so half a pixel of it means nothing.
|
||||
{ key: 'width', label: 'View width', kind: 'number', default: 640, min: 16, step: 1, decimals: 0 },
|
||||
{ key: 'height', label: 'View height', kind: 'number', default: 360, min: 16, step: 1, decimals: 0 },
|
||||
{ key: 'zoom', label: 'Zoom', kind: 'number', default: 1, min: 0.1, max: 10, step: 0.1 },
|
||||
],
|
||||
sprite: [
|
||||
@@ -104,7 +106,7 @@ const ASSET_SCHEMAS: Record<AssetType, PropertySchema> = {
|
||||
container: [],
|
||||
text: [
|
||||
{ key: 'text', label: 'Text', kind: 'text', default: 'Text' },
|
||||
{ key: 'fontSize', label: 'Font size', kind: 'number', default: 32, min: 1, step: 1 },
|
||||
{ key: 'fontSize', label: 'Font size', kind: 'number', default: 32, min: 1, step: 1, decimals: 0 },
|
||||
{ key: 'color', label: 'Color', kind: 'color', default: 0xffffff },
|
||||
{
|
||||
key: 'align',
|
||||
|
||||
Reference in new issue
Block a user