routing for canvase level object is finished.
This commit is contained in:
Binary file not shown.
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 439 KiB |
@@ -0,0 +1,243 @@
|
|||||||
|
# =============================================
|
||||||
|
# mxPIC Cell/Project Definition File
|
||||||
|
# =============================================
|
||||||
|
schema_version: "2.0.0"
|
||||||
|
kind: cell
|
||||||
|
coordinate_system: gds_y_up
|
||||||
|
canvas_size:
|
||||||
|
width: 1000
|
||||||
|
height: 1000
|
||||||
|
project: mxpic_project_1
|
||||||
|
name: canvas_1
|
||||||
|
type: composite
|
||||||
|
version: "1.0.0"
|
||||||
|
|
||||||
|
# 1. External Ports (How this cell connects to the outside world)
|
||||||
|
ports:
|
||||||
|
- name: port
|
||||||
|
layer: WG_CORE
|
||||||
|
x: 200.0
|
||||||
|
y: -370.0
|
||||||
|
angle: 180.0
|
||||||
|
width: 0.5
|
||||||
|
- name: port_2
|
||||||
|
layer: WG_CORE
|
||||||
|
x: 200.0
|
||||||
|
y: -370.0
|
||||||
|
angle: 180.0
|
||||||
|
width: 0.5
|
||||||
|
- name: port_1
|
||||||
|
layer: WG_CORE
|
||||||
|
x: 200.0
|
||||||
|
y: -420.0
|
||||||
|
angle: 180.0
|
||||||
|
width: 0.5
|
||||||
|
- name: port_3
|
||||||
|
layer: WG_CORE
|
||||||
|
x: 691.9
|
||||||
|
y: -267.5
|
||||||
|
angle: 0.0
|
||||||
|
width: 0.5
|
||||||
|
|
||||||
|
# 2. Instances (The sub-components dropped onto this canvas)
|
||||||
|
instances:
|
||||||
|
MMI_7:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 310.0
|
||||||
|
y: -370.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
MMI_8:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 560.0
|
||||||
|
y: -130.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
MMI_9:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 560.0
|
||||||
|
y: -180.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
MMI_10:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 560.0
|
||||||
|
y: -230.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
MMI_11:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 560.0
|
||||||
|
y: -280.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
MMI_12:
|
||||||
|
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
||||||
|
x: 310.0
|
||||||
|
y: -420.0
|
||||||
|
rotation: 0.0
|
||||||
|
flip: 0
|
||||||
|
flop: 0
|
||||||
|
mirror: false
|
||||||
|
settings:
|
||||||
|
length:
|
||||||
|
|
||||||
|
elements:
|
||||||
|
port:
|
||||||
|
type: port
|
||||||
|
x: 200.0
|
||||||
|
y: -370.0
|
||||||
|
angle: 0.0
|
||||||
|
port_number: 1
|
||||||
|
pitch: 10
|
||||||
|
layer: WG_CORE
|
||||||
|
width: 0.5
|
||||||
|
description: ""
|
||||||
|
Anchor_1:
|
||||||
|
type: anchor
|
||||||
|
x: 460.0
|
||||||
|
y: -300.0
|
||||||
|
angle: 90.0
|
||||||
|
port_number: 4
|
||||||
|
pitch: 10
|
||||||
|
layer: WG_CORE
|
||||||
|
width: 0.5
|
||||||
|
description: ""
|
||||||
|
port_2:
|
||||||
|
type: port
|
||||||
|
x: 200.0
|
||||||
|
y: -370.0
|
||||||
|
angle: 0.0
|
||||||
|
port_number: 1
|
||||||
|
pitch: 10
|
||||||
|
layer: WG_CORE
|
||||||
|
width: 0.5
|
||||||
|
description: ""
|
||||||
|
port_1:
|
||||||
|
type: port
|
||||||
|
x: 200.0
|
||||||
|
y: -420.0
|
||||||
|
angle: 0.0
|
||||||
|
port_number: 1
|
||||||
|
pitch: 10
|
||||||
|
layer: WG_CORE
|
||||||
|
width: 0.5
|
||||||
|
description: ""
|
||||||
|
port_3:
|
||||||
|
type: port
|
||||||
|
x: 691.9
|
||||||
|
y: -267.5
|
||||||
|
angle: 180.0
|
||||||
|
port_number: 1
|
||||||
|
pitch: 10
|
||||||
|
layer: WG_CORE
|
||||||
|
width: 0.5
|
||||||
|
description: ""
|
||||||
|
|
||||||
|
# 3. Bundles (Grouped links for multi-bus/parallel routing)
|
||||||
|
bundles:
|
||||||
|
output_bus:
|
||||||
|
routing_type: euler_bend
|
||||||
|
links:
|
||||||
|
- from: MMI_7:a1
|
||||||
|
to: port_2:port
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_12:a1
|
||||||
|
to: port_1:port
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_7:b1
|
||||||
|
to: Anchor_1:a1
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_7:b2
|
||||||
|
to: Anchor_1:a2
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_12:b1
|
||||||
|
to: Anchor_1:a3
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_12:b2
|
||||||
|
to: Anchor_1:a4
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: Anchor_1:b4
|
||||||
|
to: MMI_11:a1
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: Anchor_1:b3
|
||||||
|
to: MMI_10:a1
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: Anchor_1:b2
|
||||||
|
to: MMI_9:a1
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: Anchor_1:b1
|
||||||
|
to: MMI_8:a1
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
|
- from: MMI_11:b1
|
||||||
|
to: port_3:port
|
||||||
|
xsection: strip
|
||||||
|
family: optical
|
||||||
|
width: 0.45
|
||||||
|
radius: 10
|
||||||
|
routing_type: euler_bend
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 538 KiB After Width: | Height: | Size: 579 KiB |
@@ -23,21 +23,10 @@ ports:
|
|||||||
|
|
||||||
# 2. Instances (The sub-components dropped onto this canvas)
|
# 2. Instances (The sub-components dropped onto this canvas)
|
||||||
instances:
|
instances:
|
||||||
EC_1:
|
MZM_1:
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/edge_couplers/EC_SiN400_1310_1p0dB_L635_A0_QY_202604
|
component: Silterra/EMO1_2ML_CU_Al_RDL/composites/Mach_Zender_modulators/MZI_SiN400_Si220_PIN_mod_1310_L1300_QY_202603
|
||||||
x: 0.0
|
x: 1740.0
|
||||||
y: -2660.0
|
y: -2350.0
|
||||||
rotation: 180.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_1:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 936.8
|
|
||||||
y: -2358.5
|
|
||||||
rotation: 0.0
|
rotation: 0.0
|
||||||
flip: 0
|
flip: 0
|
||||||
flop: 0
|
flop: 0
|
||||||
@@ -45,87 +34,10 @@ instances:
|
|||||||
settings:
|
settings:
|
||||||
length:
|
length:
|
||||||
|
|
||||||
MMI_2:
|
canvas_1:
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
component: canvas_1
|
||||||
x: 1089.2
|
x: 903.5
|
||||||
y: -2247.3
|
y: -2681.6
|
||||||
rotation: 0.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_3:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 1096.8
|
|
||||||
y: -2598.0
|
|
||||||
rotation: 0.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_4:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 735.0
|
|
||||||
y: -2541.1
|
|
||||||
rotation: 90.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_5:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 1086.5
|
|
||||||
y: -2097.1
|
|
||||||
rotation: 0.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
EC_2:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/edge_couplers/EC_SiN400_1310_1p0dB_L635_A0_QY_202604
|
|
||||||
x: 0.0
|
|
||||||
y: -2825.7
|
|
||||||
rotation: 180.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_6:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 913.7
|
|
||||||
y: -2537.3
|
|
||||||
rotation: 90.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_7:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 1027.2
|
|
||||||
y: -2736.7
|
|
||||||
rotation: 0.0
|
|
||||||
flip: 0
|
|
||||||
flop: 0
|
|
||||||
mirror: false
|
|
||||||
settings:
|
|
||||||
length:
|
|
||||||
|
|
||||||
MMI_8:
|
|
||||||
component: Silterra/EMO1_2ML_CU_Al_RDL/primitives/multimode_interferometers/1x2MMI_1310nm_TE_Silterra_202603_ZKY_v2
|
|
||||||
x: 842.6
|
|
||||||
y: -2941.6
|
|
||||||
rotation: 0.0
|
rotation: 0.0
|
||||||
flip: 0
|
flip: 0
|
||||||
flop: 0
|
flop: 0
|
||||||
@@ -138,86 +50,27 @@ elements:
|
|||||||
type: port
|
type: port
|
||||||
x: 50.0
|
x: 50.0
|
||||||
y: -150.0
|
y: -150.0
|
||||||
angle: 0.0
|
angle: 180.0
|
||||||
port_number: 1
|
port_number: 1
|
||||||
pitch: 10
|
pitch: 10
|
||||||
layer: WG_CORE
|
layer: WG_CORE
|
||||||
width: 0.5
|
width: 0.5
|
||||||
description: ""
|
description: ""
|
||||||
anchor_1:
|
|
||||||
type: anchor
|
|
||||||
x: 732.7
|
|
||||||
y: -2824.7
|
|
||||||
angle: 0.0
|
|
||||||
port_number: 5
|
|
||||||
pitch: 10
|
|
||||||
layer: WG_CORE
|
|
||||||
width: 0.5
|
|
||||||
description: ""
|
|
||||||
|
|
||||||
# 3. Bundles (Grouped links for multi-bus/parallel routing)
|
# 3. Bundles (Grouped links for multi-bus/parallel routing)
|
||||||
bundles:
|
bundles:
|
||||||
output_bus:
|
output_bus:
|
||||||
routing_type: euler_bend
|
routing_type: euler_bend
|
||||||
links:
|
links:
|
||||||
- from: MMI_1:b1
|
- from: canvas_1:port_1
|
||||||
to: MMI_2:a1
|
to: MZM_1:a1
|
||||||
xsection: strip
|
xsection: strip
|
||||||
family: optical
|
family: optical
|
||||||
width: 0.45
|
width: 0.45
|
||||||
radius: 10
|
radius: 10
|
||||||
routing_type: euler_bend
|
routing_type: euler_bend
|
||||||
- from: MMI_1:b2
|
- from: canvas_1:port_3
|
||||||
to: MMI_3:a1
|
to: MZM_1:a2
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: EC_1:a1
|
|
||||||
to: anchor_1:a1
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: anchor_1:b1
|
|
||||||
to: MMI_4:a1
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: MMI_4:b2
|
|
||||||
to: MMI_1:a1
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: MMI_5:a1
|
|
||||||
to: MMI_4:b1
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: EC_2:a1
|
|
||||||
to: anchor_1:a2
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: anchor_1:b2
|
|
||||||
to: MMI_6:a1
|
|
||||||
xsection: strip
|
|
||||||
family: optical
|
|
||||||
width: 0.45
|
|
||||||
radius: 10
|
|
||||||
routing_type: euler_bend
|
|
||||||
- from: MMI_8:b1
|
|
||||||
to: MMI_7:a1
|
|
||||||
xsection: strip
|
xsection: strip
|
||||||
family: optical
|
family: optical
|
||||||
width: 0.45
|
width: 0.45
|
||||||
|
|||||||
Binary file not shown.
+35
-10
@@ -446,7 +446,8 @@
|
|||||||
const vertical = side === 'left' || side === 'right';
|
const vertical = side === 'left' || side === 'right';
|
||||||
|
|
||||||
return ports.map((port, index) => {
|
return ports.map((port, index) => {
|
||||||
const percent = fallbackPercent(index, ports.length);
|
const explicitPercent = Number(port.info && port.info.handlePercent);
|
||||||
|
const percent = Number.isFinite(explicitPercent) ? explicitPercent : fallbackPercent(index, ports.length);
|
||||||
const percentValue = `${percent}%`;
|
const percentValue = `${percent}%`;
|
||||||
const style = vertical
|
const style = vertical
|
||||||
? { top: percentValue, transform: side === 'left' ? 'translate(-50%, -50%)' : 'translate(50%, -50%)' }
|
? { top: percentValue, transform: side === 'left' ? 'translate(-50%, -50%)' : 'translate(50%, -50%)' }
|
||||||
@@ -587,6 +588,24 @@
|
|||||||
// Calculate the centered offset for one repeated port index.
|
// Calculate the centered offset for one repeated port index.
|
||||||
const elementPortOffset = (index, count, pitch) => ((count - 1) / 2 - index) * pitch;
|
const elementPortOffset = (index, count, pitch) => ((count - 1) / 2 - index) * pitch;
|
||||||
|
|
||||||
|
// Keep Basic line-like components at twice the 10 px canvas port-circle size.
|
||||||
|
const BASIC_LINE_COMPONENT_HEIGHT = 20;
|
||||||
|
|
||||||
|
// Keep Basic line-like components visually slim with a stable canvas hit area.
|
||||||
|
const basicLineComponentHeight = () => BASIC_LINE_COMPONENT_HEIGHT;
|
||||||
|
|
||||||
|
// Keep bend components readable by using the radius-25 footprint as the
|
||||||
|
// minimum canvas size, while still allowing larger radii to grow.
|
||||||
|
const BASIC_BEND_MIN_CANVAS_RADIUS = 25;
|
||||||
|
|
||||||
|
// Normalize bend radius into a positive canvas footprint dimension.
|
||||||
|
const basicBendRadiusSize = (radius) => {
|
||||||
|
const numericRadius = Number(radius || 0);
|
||||||
|
return Number.isFinite(numericRadius) && numericRadius > 0
|
||||||
|
? Math.max(BASIC_BEND_MIN_CANVAS_RADIUS, numericRadius)
|
||||||
|
: BASIC_BEND_MIN_CANVAS_RADIUS;
|
||||||
|
};
|
||||||
|
|
||||||
// Grow port and anchor visual bodies so repeated port circles do not overlap.
|
// Grow port and anchor visual bodies so repeated port circles do not overlap.
|
||||||
const buildElementBoxSize = (data) => {
|
const buildElementBoxSize = (data) => {
|
||||||
const portNumber = normalizePortNumber(data && data.portNumber);
|
const portNumber = normalizePortNumber(data && data.portNumber);
|
||||||
@@ -643,6 +662,7 @@
|
|||||||
const values = createBasicSettings(componentName, settings);
|
const values = createBasicSettings(componentName, settings);
|
||||||
const length = Number(values.length || 0);
|
const length = Number(values.length || 0);
|
||||||
const radius = Number(values.radius || 10);
|
const radius = Number(values.radius || 10);
|
||||||
|
const bendSize = basicBendRadiusSize(radius);
|
||||||
const width = Number(values.width ?? values.width1 ?? 0.5);
|
const width = Number(values.width ?? values.width1 ?? 0.5);
|
||||||
const xsection = values.xsection || values.xs || 'strip';
|
const xsection = values.xsection || values.xs || 'strip';
|
||||||
if (componentName === 'waveguide') {
|
if (componentName === 'waveguide') {
|
||||||
@@ -653,14 +673,14 @@
|
|||||||
}
|
}
|
||||||
if (componentName === '90 bend') {
|
if (componentName === '90 bend') {
|
||||||
return {
|
return {
|
||||||
a1: { x: 0, y: 0, a: 180, width, xsection, description: 'Optical power input' },
|
a1: { x: 0, y: bendSize / 2, a: 180, width, xsection, description: 'Optical power input' },
|
||||||
b1: { x: radius, y: radius, a: 90, width, xsection, description: 'Optical power output' }
|
b1: { x: bendSize / 2, y: 0, a: 90, width, xsection, description: 'Optical power output' }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (componentName === '180 bend') {
|
if (componentName === '180 bend') {
|
||||||
return {
|
return {
|
||||||
a1: { x: 0, y: 0, a: 180, width, xsection, description: 'Optical power input' },
|
a1: { x: 0, y: 0, a: 180, width, xsection, description: 'Optical power input' },
|
||||||
b1: { x: 0, y: 2 * radius, a: 180, width, xsection, description: 'Optical power output' }
|
b1: { x: 0, y: 2 * bendSize, a: 180, width, xsection, description: 'Optical power output' }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (componentName === 'cricle' || componentName === 'circle') {
|
if (componentName === 'cricle' || componentName === 'circle') {
|
||||||
@@ -686,13 +706,14 @@
|
|||||||
const radius = Number(values.radius || 10);
|
const radius = Number(values.radius || 10);
|
||||||
const width = Number(values.width ?? values.width1 ?? 0.5);
|
const width = Number(values.width ?? values.width1 ?? 0.5);
|
||||||
const width2 = Number(values.width2 ?? width);
|
const width2 = Number(values.width2 ?? width);
|
||||||
|
const bendSize = basicBendRadiusSize(radius);
|
||||||
const boxSize = componentName === 'waveguide'
|
const boxSize = componentName === 'waveguide'
|
||||||
? [Math.max(length, 10), Math.max(width * 4, 4)]
|
? [Math.max(length, 10), basicLineComponentHeight(width)]
|
||||||
: componentName === 'taper'
|
: componentName === 'taper'
|
||||||
? [Math.max(length, 10), Math.max(width, width2) * 10 + 18]
|
? [Math.max(length, 10), basicLineComponentHeight(width, width2)]
|
||||||
: componentName === '180 bend'
|
: componentName === '180 bend'
|
||||||
? [radius, radius * 2]
|
? [bendSize, bendSize * 2]
|
||||||
: [radius, radius];
|
: [bendSize, bendSize];
|
||||||
return {
|
return {
|
||||||
name: componentName,
|
name: componentName,
|
||||||
foundry: 'mxpic',
|
foundry: 'mxpic',
|
||||||
@@ -703,6 +724,10 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flip an internal standalone Port angle into the outward-facing cell port
|
||||||
|
// angle used when this canvas is placed as a component elsewhere.
|
||||||
|
const externalPortAngle = (angle) => normalizeAngle(Number(angle ?? 0) + 180);
|
||||||
|
|
||||||
// Convert standalone port nodes into page-level layout ports.
|
// Convert standalone port nodes into page-level layout ports.
|
||||||
const buildPageComponentPorts = (port, nodes) => {
|
const buildPageComponentPorts = (port, nodes) => {
|
||||||
const portNodes = (nodes || []).filter(isPortElementNode);
|
const portNodes = (nodes || []).filter(isPortElementNode);
|
||||||
@@ -723,7 +748,7 @@
|
|||||||
ports[exportName] = {
|
ports[exportName] = {
|
||||||
x: Number(point.x || 0),
|
x: Number(point.x || 0),
|
||||||
y: Number(point.y || 0),
|
y: Number(point.y || 0),
|
||||||
a: Number(portInfo.a ?? data.angle ?? data.a ?? 0),
|
a: externalPortAngle(portInfo.a ?? data.angle ?? data.a ?? 0),
|
||||||
width: Number(portInfo.width || data.width || 0.5)
|
width: Number(portInfo.width || data.width || 0.5)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -735,7 +760,7 @@
|
|||||||
port: {
|
port: {
|
||||||
x: Number(port.x || 0),
|
x: Number(port.x || 0),
|
||||||
y: Number(port.y || 0),
|
y: Number(port.y || 0),
|
||||||
a: Number(port.a || 0),
|
a: externalPortAngle(port.a || 0),
|
||||||
width: Number(port.width || 0.5)
|
width: Number(port.width || 0.5)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+54
-18
@@ -1186,7 +1186,7 @@ Organization : OptiHK Limited
|
|||||||
border: 1px solid var(--floating-label-border);
|
border: 1px solid var(--floating-label-border);
|
||||||
color: var(--port-label-text);
|
color: var(--port-label-text);
|
||||||
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.18);
|
box-shadow: 0 5px 12px rgba(0, 0, 0, 0.18);
|
||||||
font-size: 0.42rem;
|
font-size: 0.3rem;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
font-family: 'IBM Plex Mono', Consolas, Monaco, monospace;
|
font-family: 'IBM Plex Mono', Consolas, Monaco, monospace;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -1278,6 +1278,10 @@ Organization : OptiHK Limited
|
|||||||
box-shadow: var(--floating-label-shadow);
|
box-shadow: var(--floating-label-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.canvas-text-hidden .component-floating-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
body.light-mode .port-name-label {
|
body.light-mode .port-name-label {
|
||||||
background: var(--port-label-bg);
|
background: var(--port-label-bg);
|
||||||
border-color: var(--floating-label-border);
|
border-color: var(--floating-label-border);
|
||||||
@@ -1312,14 +1316,14 @@ Organization : OptiHK Limited
|
|||||||
}
|
}
|
||||||
|
|
||||||
.component-floating-label strong {
|
.component-floating-label strong {
|
||||||
font-size: 0.52rem;
|
font-size: 0.4rem;
|
||||||
font-weight: 650;
|
font-weight: 650;
|
||||||
}
|
}
|
||||||
|
|
||||||
.component-floating-label span {
|
.component-floating-label span {
|
||||||
margin-top: 1px;
|
margin-top: 1px;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 0.44rem;
|
font-size: 0.32rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas-size-panel {
|
.canvas-size-panel {
|
||||||
@@ -1379,7 +1383,7 @@ Organization : OptiHK Limited
|
|||||||
background: rgba(9, 18, 28, 0.94);
|
background: rgba(9, 18, 28, 0.94);
|
||||||
color: #e2f7f3;
|
color: #e2f7f3;
|
||||||
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.3);
|
||||||
font: 600 0.62rem/1.35 'IBM Plex Mono', Consolas, Monaco, monospace;
|
font: 600 0.5rem/1.35 'IBM Plex Mono', Consolas, Monaco, monospace;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@@ -1594,7 +1598,7 @@ Organization : OptiHK Limited
|
|||||||
}, [id, data.ports, data.componentName, data.boxSize]);
|
}, [id, data.ports, data.componentName, data.boxSize]);
|
||||||
|
|
||||||
const baseHandleStyle = {
|
const baseHandleStyle = {
|
||||||
width: 10, height: 10,
|
width: 8, height: 8,
|
||||||
background: 'var(--bg-main)',
|
background: 'var(--bg-main)',
|
||||||
border: '2px solid var(--accent)',
|
border: '2px solid var(--accent)',
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
@@ -1611,6 +1615,7 @@ Organization : OptiHK Limited
|
|||||||
);
|
);
|
||||||
const componentSize = normalizeBoxSize({ box_size: data.boxSize }, DEFAULT_COMPONENT_BOX_SIZE);
|
const componentSize = normalizeBoxSize({ box_size: data.boxSize }, DEFAULT_COMPONENT_BOX_SIZE);
|
||||||
const isAnchorElement = data.elementType === 'anchor';
|
const isAnchorElement = data.elementType === 'anchor';
|
||||||
|
const isBasicCompactComponent = isBasicComponent(data.componentName) && ['waveguide', 'taper', '90 bend'].includes(data.componentName);
|
||||||
const visualSize = isAnchorElement ? { width: PORT_NODE_SIZE, height: PORT_NODE_SIZE } : componentSize;
|
const visualSize = isAnchorElement ? { width: PORT_NODE_SIZE, height: PORT_NODE_SIZE } : componentSize;
|
||||||
const iconSize = createComponentSymbolMetrics(componentSize);
|
const iconSize = createComponentSymbolMetrics(componentSize);
|
||||||
const portLabelStyle = (portHandle) => {
|
const portLabelStyle = (portHandle) => {
|
||||||
@@ -1643,9 +1648,16 @@ Organization : OptiHK Limited
|
|||||||
style={{
|
style={{
|
||||||
width: componentSize.width,
|
width: componentSize.width,
|
||||||
height: visualSize.height,
|
height: visualSize.height,
|
||||||
|
minHeight: visualSize.height,
|
||||||
border: selected ? '2px solid var(--accent)' : '1px solid var(--border)',
|
border: selected ? '2px solid var(--accent)' : '1px solid var(--border)',
|
||||||
transform: `rotate(${data.rotation || 0}deg) scaleX(${data.flop ? -1 : 1}) scaleY(${data.flip ? -1 : 1})`,
|
transform: `rotate(${data.rotation || 0}deg) scaleX(${data.flop ? -1 : 1}) scaleY(${data.flip ? -1 : 1})`,
|
||||||
boxShadow: selected ? '0 0 15px rgba(56, 189, 248, 0.2)' : '0 4px 6px rgba(0,0,0,0.3)',
|
boxShadow: selected ? '0 0 15px rgba(56, 189, 248, 0.2)' : '0 4px 6px rgba(0,0,0,0.3)',
|
||||||
|
...(isBasicCompactComponent ? {
|
||||||
|
padding: 0,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
} : {}),
|
||||||
...(isAnchorElement ? {
|
...(isAnchorElement ? {
|
||||||
width: PORT_NODE_SIZE,
|
width: PORT_NODE_SIZE,
|
||||||
minHeight: PORT_NODE_SIZE,
|
minHeight: PORT_NODE_SIZE,
|
||||||
@@ -1658,7 +1670,7 @@ Organization : OptiHK Limited
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isAnchorElement ? (
|
{isAnchorElement ? (
|
||||||
<span style={{ fontSize: 10, fontWeight: 800, color: selected ? 'var(--accent)' : 'var(--text-main)' }}>A</span>
|
<span style={{ fontSize: 8, fontWeight: 800, color: selected ? 'var(--accent)' : 'var(--text-main)' }}>A</span>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '8px', minHeight: '100%' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: '8px', minHeight: '100%' }}>
|
||||||
{!data.hideIcon && data.category && (
|
{!data.hideIcon && data.category && (
|
||||||
@@ -1733,8 +1745,8 @@ Organization : OptiHK Limited
|
|||||||
};
|
};
|
||||||
const baseHandleStyle = {
|
const baseHandleStyle = {
|
||||||
background: 'var(--accent)',
|
background: 'var(--accent)',
|
||||||
width: 8,
|
width: 6,
|
||||||
height: 8
|
height: 6
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
@@ -1743,7 +1755,7 @@ Organization : OptiHK Limited
|
|||||||
border: selected ? '2px solid white' : '2px solid var(--accent)',
|
border: selected ? '2px solid white' : '2px solid var(--accent)',
|
||||||
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
|
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
|
||||||
color: selected ? 'white' : 'var(--accent)',
|
color: selected ? 'white' : 'var(--accent)',
|
||||||
fontSize: 10, fontWeight: 'bold',
|
fontSize: 8, fontWeight: 'bold',
|
||||||
boxShadow: selected ? '0 0 10px rgba(56,189,248,0.4)' : 'none',
|
boxShadow: selected ? '0 0 10px rgba(56,189,248,0.4)' : 'none',
|
||||||
transform: `rotate(${angle}deg)`,
|
transform: `rotate(${angle}deg)`,
|
||||||
}}>
|
}}>
|
||||||
@@ -1783,8 +1795,8 @@ Organization : OptiHK Limited
|
|||||||
bottom: Position.Bottom
|
bottom: Position.Bottom
|
||||||
};
|
};
|
||||||
const baseHandleStyle = {
|
const baseHandleStyle = {
|
||||||
width: 8,
|
width: 6,
|
||||||
height: 8,
|
height: 6,
|
||||||
background: 'var(--accent)',
|
background: 'var(--accent)',
|
||||||
border: '1px solid var(--bg-main)',
|
border: '1px solid var(--bg-main)',
|
||||||
borderRadius: '50%'
|
borderRadius: '50%'
|
||||||
@@ -2729,6 +2741,7 @@ Organization : OptiHK Limited
|
|||||||
const selectedNodeBoxSize = selectedNode?.data?.componentName && !selectedNode?.data?.elementType
|
const selectedNodeBoxSize = selectedNode?.data?.componentName && !selectedNode?.data?.elementType
|
||||||
? normalizeBoxSize({ box_size: selectedNode.data?.boxSize }, DEFAULT_COMPONENT_BOX_SIZE)
|
? normalizeBoxSize({ box_size: selectedNode.data?.boxSize }, DEFAULT_COMPONENT_BOX_SIZE)
|
||||||
: null;
|
: null;
|
||||||
|
const xsections = Object.keys((technologyManifest || FALLBACK_TECHNOLOGY_MANIFEST).xsections || {});
|
||||||
|
|
||||||
const selectedRouteEdges = selectedEdges.length > 0 ? selectedEdges : (selectedEdge ? [selectedEdge] : []);
|
const selectedRouteEdges = selectedEdges.length > 0 ? selectedEdges : (selectedEdge ? [selectedEdge] : []);
|
||||||
if (selectedRouteEdges.length > 0) {
|
if (selectedRouteEdges.length > 0) {
|
||||||
@@ -2744,7 +2757,6 @@ Organization : OptiHK Limited
|
|||||||
radius: mixedValue('radius'),
|
radius: mixedValue('radius'),
|
||||||
routing_type: mixedValue('routing_type')
|
routing_type: mixedValue('routing_type')
|
||||||
};
|
};
|
||||||
const xsections = Object.keys((technologyManifest || FALLBACK_TECHNOLOGY_MANIFEST).xsections || {});
|
|
||||||
const routingTypes = (technologyManifest || FALLBACK_TECHNOLOGY_MANIFEST).routing_types || ['euler_bend', 'standard_bend'];
|
const routingTypes = (technologyManifest || FALLBACK_TECHNOLOGY_MANIFEST).routing_types || ['euler_bend', 'standard_bend'];
|
||||||
return (
|
return (
|
||||||
<aside style={{
|
<aside style={{
|
||||||
@@ -3164,12 +3176,26 @@ Organization : OptiHK Limited
|
|||||||
{Object.entries(basicArguments).map(([key, value]) => (
|
{Object.entries(basicArguments).map(([key, value]) => (
|
||||||
<label key={key} style={{ display: 'grid', gap: 4 }}>
|
<label key={key} style={{ display: 'grid', gap: 4 }}>
|
||||||
<span style={{ color: 'var(--text-muted)' }}>{key}</span>
|
<span style={{ color: 'var(--text-muted)' }}>{key}</span>
|
||||||
<input
|
{key === 'xsection' ? (
|
||||||
type={typeof value === 'number' ? 'number' : 'text'}
|
<select
|
||||||
step="any"
|
value={value ?? ''}
|
||||||
value={value ?? ''}
|
onChange={(event) => updateBasicArgument(key, event.target.value)}
|
||||||
onChange={(event) => updateBasicArgument(key, event.target.value)}
|
>
|
||||||
/>
|
{value && !xsections.includes(value) && (
|
||||||
|
<option value={value}>{value}</option>
|
||||||
|
)}
|
||||||
|
{xsections.map(xsection => (
|
||||||
|
<option key={xsection} value={xsection}>{xsection}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
) : (
|
||||||
|
<input
|
||||||
|
type={typeof value === 'number' ? 'number' : 'text'}
|
||||||
|
step="any"
|
||||||
|
value={value ?? ''}
|
||||||
|
onChange={(event) => updateBasicArgument(key, event.target.value)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</label>
|
</label>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -3461,6 +3487,7 @@ Organization : OptiHK Limited
|
|||||||
const [dragging, setDragging] = useState(null);
|
const [dragging, setDragging] = useState(null);
|
||||||
|
|
||||||
const [gridSnap, setGridSnap] = useState(false);
|
const [gridSnap, setGridSnap] = useState(false);
|
||||||
|
const [canvasTextVisible, setCanvasTextVisible] = useState(true);
|
||||||
const [themeMode, setThemeMode] = useState(() => localStorage.getItem('mxpic-theme') || 'dark');
|
const [themeMode, setThemeMode] = useState(() => localStorage.getItem('mxpic-theme') || 'dark');
|
||||||
const [logs, setLogs] = useState([{ time: new Date().toLocaleTimeString(), message: 'Editor ready.' }]);
|
const [logs, setLogs] = useState([{ time: new Date().toLocaleTimeString(), message: 'Editor ready.' }]);
|
||||||
const [buildLayoutBusy, setBuildLayoutBusy] = useState(false);
|
const [buildLayoutBusy, setBuildLayoutBusy] = useState(false);
|
||||||
@@ -5463,6 +5490,11 @@ Organization : OptiHK Limited
|
|||||||
setGridSnap(prev => !prev);
|
setGridSnap(prev => !prev);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Toggle the instance name/PDK labels shown above canvas components.
|
||||||
|
const toggleCanvasText = useCallback(() => {
|
||||||
|
setCanvasTextVisible(prev => !prev);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Toggle the measurement ruler and clear partial measurements.
|
// Toggle the measurement ruler and clear partial measurements.
|
||||||
const toggleRulerMode = useCallback(() => {
|
const toggleRulerMode = useCallback(() => {
|
||||||
setRulerMode(prev => {
|
setRulerMode(prev => {
|
||||||
@@ -5999,6 +6031,9 @@ ${bundlesBlock}`;
|
|||||||
transition: 'transform 0.2s',
|
transition: 'transform 0.2s',
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
<button className="mini-btn" onClick={toggleCanvasText} aria-pressed={canvasTextVisible ? 'true' : 'false'}>
|
||||||
|
{canvasTextVisible ? 'Text On' : 'Text Off'}
|
||||||
|
</button>
|
||||||
<details className="link-mode-tabs" title="Route type used for new links">
|
<details className="link-mode-tabs" title="Route type used for new links">
|
||||||
<summary className="link-mode-summary">
|
<summary className="link-mode-summary">
|
||||||
<span className="link-mode-label">Link</span>
|
<span className="link-mode-label">Link</span>
|
||||||
@@ -6069,6 +6104,7 @@ ${bundlesBlock}`;
|
|||||||
<LayoutSvgPreview page={activePage} />
|
<LayoutSvgPreview page={activePage} />
|
||||||
) : (
|
) : (
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
|
className={canvasTextVisible ? '' : 'canvas-text-hidden'}
|
||||||
nodes={renderNodes}
|
nodes={renderNodes}
|
||||||
edges={renderEdges}
|
edges={renderEdges}
|
||||||
onNodesChange={onNodesChange}
|
onNodesChange={onNodesChange}
|
||||||
|
|||||||
@@ -172,18 +172,46 @@ assert.deepStrictEqual(
|
|||||||
);
|
);
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
helpers.getBasicComponentMetadata('waveguide', { length: 120, width: 0.5 }).box_size,
|
helpers.getBasicComponentMetadata('waveguide', { length: 120, width: 0.5 }).box_size,
|
||||||
[120, 4],
|
[120, 20],
|
||||||
'basic waveguide symbol should use a narrow default height'
|
'basic waveguide symbol should use a height that is two port-circle diameters'
|
||||||
);
|
);
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
helpers.getBasicComponentMetadata('90 bend', { radius: 15 }).box_size,
|
helpers.getBasicComponentMetadata('90 bend', { radius: 15 }).box_size,
|
||||||
[15, 15],
|
[25, 25],
|
||||||
'90 bend symbol should be square with side length equal to radius'
|
'90 bend symbol should not shrink below the radius-25 canvas size'
|
||||||
);
|
);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
helpers.getBasicComponentMetadata('90 bend', { radius: 30 }).box_size,
|
||||||
|
[30, 30],
|
||||||
|
'90 bend symbol should still scale above radius 25'
|
||||||
|
);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
helpers.buildBasicComponentPorts('90 bend', { radius: 15, width: 0.6 }),
|
||||||
|
{
|
||||||
|
a1: { x: 0, y: 12.5, a: 180, width: 0.6, xsection: 'strip', description: 'Optical power input' },
|
||||||
|
b1: { x: 12.5, y: 0, a: 90, width: 0.6, xsection: 'strip', description: 'Optical power output' }
|
||||||
|
},
|
||||||
|
'90 bend ports should sit at the middle of the left and top sides of the square'
|
||||||
|
);
|
||||||
|
const ninetyBendHandles = helpers.buildPortHandles(helpers.buildBasicComponentPorts('90 bend', { radius: 15 }));
|
||||||
|
assert.strictEqual(ninetyBendHandles.find(handle => handle.name === 'a1').position, 'left');
|
||||||
|
assert.strictEqual(ninetyBendHandles.find(handle => handle.name === 'a1').style.top, '50%');
|
||||||
|
assert.strictEqual(ninetyBendHandles.find(handle => handle.name === 'b1').position, 'top');
|
||||||
|
assert.strictEqual(ninetyBendHandles.find(handle => handle.name === 'b1').style.left, '50%');
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
helpers.getBasicComponentMetadata('180 bend', { radius: 15 }).box_size,
|
helpers.getBasicComponentMetadata('180 bend', { radius: 15 }).box_size,
|
||||||
[15, 30],
|
[25, 50],
|
||||||
'180 bend symbol should be one radius wide and two radii tall'
|
'180 bend symbol should not shrink below the radius-25 canvas size'
|
||||||
|
);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
helpers.getBasicComponentMetadata('180 bend', { radius: 30 }).box_size,
|
||||||
|
[30, 60],
|
||||||
|
'180 bend symbol should still scale above radius 25'
|
||||||
|
);
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
helpers.getBasicComponentMetadata('taper', { length: 80, width1: 0.4, width2: 1.2 }).box_size,
|
||||||
|
[80, 20],
|
||||||
|
'basic taper symbol should use a height that is two port-circle diameters'
|
||||||
);
|
);
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
helpers.getBasicComponentMetadata('taper', { length: 80, width1: 0.4, width2: 1.2 }).ports.a1.description,
|
helpers.getBasicComponentMetadata('taper', { length: 80, width1: 0.4, width2: 1.2 }).ports.a1.description,
|
||||||
@@ -259,11 +287,11 @@ const pagePortsYaml = helpers.buildPortsYaml({ x: 50, y: 150, a: 90 });
|
|||||||
assert(pagePortsYaml.includes('- name: port'));
|
assert(pagePortsYaml.includes('- name: port'));
|
||||||
assert(pagePortsYaml.includes('x: 50.0'));
|
assert(pagePortsYaml.includes('x: 50.0'));
|
||||||
assert(pagePortsYaml.includes('y: -150.0'));
|
assert(pagePortsYaml.includes('y: -150.0'));
|
||||||
assert(pagePortsYaml.includes('angle: 90.0'));
|
assert(pagePortsYaml.includes('angle: -90.0'));
|
||||||
|
|
||||||
const componentPorts = helpers.buildPageComponentPorts({ x: 12, y: -6, a: 180 });
|
const componentPorts = helpers.buildPageComponentPorts({ x: 12, y: -6, a: 180 });
|
||||||
assert.deepStrictEqual(componentPorts, {
|
assert.deepStrictEqual(componentPorts, {
|
||||||
port: { x: 12, y: -6, a: 180, width: 0.5 }
|
port: { x: 12, y: -6, a: 0, width: 0.5 }
|
||||||
});
|
});
|
||||||
|
|
||||||
const elementNodes = [
|
const elementNodes = [
|
||||||
@@ -341,9 +369,9 @@ assert.deepStrictEqual(
|
|||||||
data: { componentDisplayName: 'array', elementType: 'port', portNumber: 3, pitch: 10, width: 0.6 }
|
data: { componentDisplayName: 'array', elementType: 'port', portNumber: 3, pitch: 10, width: 0.6 }
|
||||||
}]),
|
}]),
|
||||||
{
|
{
|
||||||
array_1: { x: 100, y: 190, a: 0, width: 0.6 },
|
array_1: { x: 100, y: 190, a: 180, width: 0.6 },
|
||||||
array_2: { x: 100, y: 200, a: 0, width: 0.6 },
|
array_2: { x: 100, y: 200, a: 180, width: 0.6 },
|
||||||
array_3: { x: 100, y: 210, a: 0, width: 0.6 }
|
array_3: { x: 100, y: 210, a: 180, width: 0.6 }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -352,6 +380,7 @@ assert(canvasPortsYaml.includes('name: in0'));
|
|||||||
assert(canvasPortsYaml.includes('description: "input port"'));
|
assert(canvasPortsYaml.includes('description: "input port"'));
|
||||||
assert(canvasPortsYaml.includes('width: 0.7'));
|
assert(canvasPortsYaml.includes('width: 0.7'));
|
||||||
assert(canvasPortsYaml.includes('y: -20.0'));
|
assert(canvasPortsYaml.includes('y: -20.0'));
|
||||||
|
assert(canvasPortsYaml.includes('angle: 0.0'));
|
||||||
|
|
||||||
const elementsYaml = helpers.buildElementsYaml(elementNodes);
|
const elementsYaml = helpers.buildElementsYaml(elementNodes);
|
||||||
assert(elementsYaml.includes('in0:'));
|
assert(elementsYaml.includes('in0:'));
|
||||||
@@ -372,7 +401,7 @@ assert(instancesWithoutElements.includes('component_1:'));
|
|||||||
assert(instancesWithoutElements.includes('y: -60.0'));
|
assert(instancesWithoutElements.includes('y: -60.0'));
|
||||||
|
|
||||||
const multiPortComponentPorts = helpers.buildPageComponentPorts(null, elementNodes);
|
const multiPortComponentPorts = helpers.buildPageComponentPorts(null, elementNodes);
|
||||||
assert.deepStrictEqual(multiPortComponentPorts.in0, { x: 10, y: 20, a: 180, width: 0.7 });
|
assert.deepStrictEqual(multiPortComponentPorts.in0, { x: 10, y: 20, a: 0, width: 0.7 });
|
||||||
|
|
||||||
const technologyManifest = {
|
const technologyManifest = {
|
||||||
defaults: { xsection: 'strip', width: 0.45, radius: 10, routing_type: 'euler_bend' },
|
defaults: { xsection: 'strip', width: 0.45, radius: 10, routing_type: 'euler_bend' },
|
||||||
|
|||||||
@@ -282,6 +282,15 @@ assert(
|
|||||||
canvasHtml.includes('component-floating-label') && canvasHtml.includes('component-visual-body'),
|
canvasHtml.includes('component-floating-label') && canvasHtml.includes('component-visual-body'),
|
||||||
'component labels should float outside the rotated body'
|
'component labels should float outside the rotated body'
|
||||||
);
|
);
|
||||||
|
assert(
|
||||||
|
canvasHtml.includes('canvasTextVisible') &&
|
||||||
|
canvasHtml.includes('toggleCanvasText') &&
|
||||||
|
canvasHtml.includes('Text On') &&
|
||||||
|
canvasHtml.includes('Text Off') &&
|
||||||
|
canvasHtml.includes('canvas-text-hidden') &&
|
||||||
|
canvasHtml.includes('.canvas-text-hidden .component-floating-label'),
|
||||||
|
'canvas toolbar should toggle instance name and PDK text above components'
|
||||||
|
);
|
||||||
assert(
|
assert(
|
||||||
canvasHtml.includes('--floating-label-bg') && canvasHtml.includes('--port-label-bg') && canvasHtml.includes('--mini-button-bg'),
|
canvasHtml.includes('--floating-label-bg') && canvasHtml.includes('--port-label-bg') && canvasHtml.includes('--mini-button-bg'),
|
||||||
'theme variables should keep labels, port chips, and header buttons readable in light and dark modes'
|
'theme variables should keep labels, port chips, and header buttons readable in light and dark modes'
|
||||||
@@ -400,6 +409,34 @@ assert(
|
|||||||
canvasHtml.includes("isUserCell ? 'compact-tree-card' : ''"),
|
canvasHtml.includes("isUserCell ? 'compact-tree-card' : ''"),
|
||||||
'Basic, Port, and Anchor entries should render as consistent 2D cards instead of compact list rows'
|
'Basic, Port, and Anchor entries should render as consistent 2D cards instead of compact list rows'
|
||||||
);
|
);
|
||||||
|
assert(
|
||||||
|
canvasHtml.includes("key === 'xsection'") &&
|
||||||
|
canvasHtml.includes('<select') &&
|
||||||
|
canvasHtml.includes('xsections.map(xsection =>') &&
|
||||||
|
canvasHtml.includes('updateBasicArgument(key, event.target.value)'),
|
||||||
|
'Basic component xsection should be selected from technology manifest xsections instead of free text'
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
canvasHtml.indexOf('const xsections = Object.keys') <
|
||||||
|
canvasHtml.indexOf('if (selectedRouteEdges.length > 0)'),
|
||||||
|
'Basic and route property panels should share the same xsection list from RightPanel scope'
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
canvasHtml.includes("['waveguide', 'taper', '90 bend'].includes(data.componentName)") &&
|
||||||
|
canvasHtml.includes('minHeight: visualSize.height') &&
|
||||||
|
canvasHtml.includes('isBasicCompactComponent ?'),
|
||||||
|
'waveguide, taper, and 90 bend nodes should override the default component min-height and padding on the canvas'
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
canvasHtml.includes('font-size: 0.3rem;') &&
|
||||||
|
canvasHtml.includes('font-size: 0.4rem;') &&
|
||||||
|
canvasHtml.includes('font-size: 0.32rem;') &&
|
||||||
|
canvasHtml.includes("font: 600 0.5rem/1.35") &&
|
||||||
|
canvasHtml.includes('width: 8, height: 8') &&
|
||||||
|
canvasHtml.includes('width: 6,') &&
|
||||||
|
canvasHtml.includes('fontSize: 8'),
|
||||||
|
'canvas labels and port circles should render smaller than the previous sizing'
|
||||||
|
);
|
||||||
assert(
|
assert(
|
||||||
canvasHtml.includes('ParallelRouteEdge') &&
|
canvasHtml.includes('ParallelRouteEdge') &&
|
||||||
canvasHtml.includes('parallelOffset') &&
|
canvasHtml.includes('parallelOffset') &&
|
||||||
|
|||||||
Reference in New Issue
Block a user