feat(editor): F4.3 the editor's frame and surface; a switch's cloud read and written
packages/editor (React 18, Vite) draws a document as Java FILIUS does: Java's default hardware icons, the device button of JSidebarButton, cables as JCablePanel's quadratic curve between the buttons' middles, wireless cables dashed, documentation items below. The surface moves with mouse and finger (the pointer captured only once it moved) and zooms with Ctrl and the wheel, a trackpad pinch, two fingers and the zoom bar; the first view shows all. German and English catalogs with Java's device names, the dashboard's colour tokens, the bridge with its origin check. packages/doc gets the drawing's light view of a document. Java's Switch.cloud (the Internet in the examples) was lost on reading; it is now read, kept in the model and written, with FlsOracle and the corpus, written and exported checks renewed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
// Java's drawing of a device and a cable (JSidebarButton, JCablePanel).
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { bounds, cablePath, deviceBox, iconOf, ICONS, JAVA_LABEL_FONT_HEIGHT } from '../src/canvas/layout.js';
|
||||
|
||||
describe("Java's drawing", () => {
|
||||
it('picks the icon of each kind, the cloud for a switch drawn as one', () => {
|
||||
expect((['pc', 'notebook', 'networkSwitch', 'router', 'gateway', 'remoteLink', 'unsupported'] as const).map((kind) => iconOf(kind, false))).toEqual([
|
||||
'server',
|
||||
'laptop',
|
||||
'switch',
|
||||
'router',
|
||||
'gateway',
|
||||
'modem',
|
||||
'cloud',
|
||||
]);
|
||||
expect(iconOf('networkSwitch', true)).toBe('cloud');
|
||||
expect(iconOf('router', true)).toBe('router');
|
||||
});
|
||||
|
||||
it('makes a button as wide as its icon or its label, plus 5 and twice the border, and as high as both plus 5', () => {
|
||||
const short = deviceBox({ kind: 'pc', cloud: false, x: 100, y: 200 }, 30);
|
||||
expect(short).toMatchObject({ x: 100, y: 200, width: 64 + 21, height: JAVA_LABEL_FONT_HEIGHT + 94 + 5, icon: 'server' });
|
||||
// The icon at the top, in the middle; the label's baseline under it, in the middle.
|
||||
expect(short.iconRect).toEqual({ x: 100 + (85 - 64) / 2, y: 200, width: 64, height: 94 });
|
||||
expect(short.label).toEqual({ x: 100 + 85 / 2, y: 200 + 94 + 14 });
|
||||
const long = deviceBox({ kind: 'router', cloud: false, x: 0, y: 0 }, 124.6);
|
||||
expect(long.width).toBe(125 + 21);
|
||||
expect(long.iconRect.x).toBe((146 - 77) / 2);
|
||||
});
|
||||
|
||||
it('meets cables in the middle of the button, in whole pixels as Java does', () => {
|
||||
const box = deviceBox({ kind: 'notebook', cloud: false, x: 11, y: 7 }, 10);
|
||||
// 84 + 21 = 105 wide, 17 + 80 + 5 = 102 high.
|
||||
expect(box.center).toEqual({ x: Math.trunc(11 + 52.5), y: Math.trunc(7 + 51) });
|
||||
});
|
||||
|
||||
it("draws a cable as JCablePanel's curve", () => {
|
||||
// Rising to the right (y falls): the control point a quarter across the panel.
|
||||
// Panel from (98, 48); control (98 + trunc((2 + 302) / 4), 48 + trunc((52 + 2) / 4)) = (174, 61).
|
||||
expect(cablePath({ x: 100, y: 100 }, { x: 400, y: 50 })).toBe('M 100 100 Q 174 61 400 50');
|
||||
// Falling to the right: three quarters across.
|
||||
expect(cablePath({ x: 100, y: 50 }, { x: 400, y: 100 })).toBe(`M 100 50 Q ${98 + 3 * Math.trunc(304 / 4)} 61 400 100`);
|
||||
// The same either way round.
|
||||
expect(cablePath({ x: 400, y: 100 }, { x: 100, y: 50 })).toBe(`M 400 100 Q ${98 + 3 * Math.trunc(304 / 4)} 61 100 50`);
|
||||
// Straight down: not falling (x does not change); the panel from (8, 8), control (8 + trunc(4 / 4), 8 + trunc(84 / 4)).
|
||||
expect(cablePath({ x: 10, y: 10 }, { x: 10, y: 90 })).toBe('M 10 10 Q 9 29 10 90');
|
||||
});
|
||||
|
||||
it('knows every icon it draws', () => {
|
||||
expect(Object.keys(ICONS).sort()).toEqual(['cloud', 'gateway', 'laptop', 'modem', 'router', 'server', 'switch']);
|
||||
});
|
||||
|
||||
it('spans the rectangles around everything', () => {
|
||||
expect(bounds([])).toEqual({ x: 0, y: 0, width: 0, height: 0 });
|
||||
expect(bounds([{ x: 10, y: 20, width: 5, height: 5 }, { x: -5, y: 30, width: 10, height: 10 }])).toEqual({ x: -5, y: 20, width: 20, height: 20 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user