forked from HEL/circuiteria
feat: Add ports on group elements
Groups now accept ports/ports-margins like blocks. Port name labels default to outside the group border (outside-port-names: true) so they don't overlap child elements; set to false for block-style inside labels.
This commit is contained in:
1 parent
002db0e6f5
commit
0d1478c765
6 files changed
+6970
-6424
No files matched your search
@@ -188,6 +188,45 @@ wire.wire("w2", ("b2-port-out", "b3-port-in2"),
|
||||
style: "zigzag")
|
||||
```)
|
||||
|
||||
#let group-ports = example(```
|
||||
// outside-port-names: true (default) — labels outside the border
|
||||
element.group(
|
||||
id: "g1", name: "outside (default)",
|
||||
stroke: (dash: "dashed"),
|
||||
fill: util.colors.blue.lighten(60%),
|
||||
padding: 2em,
|
||||
outside-port-names: true,
|
||||
ports: (
|
||||
west: ((id: "in", name: "D"),),
|
||||
east: ((id: "out", name: "Q"),),
|
||||
),
|
||||
{ element.block(id: "b1", w: 2, h: 1.5, x: 0, y: 0,
|
||||
fill: util.colors.green,
|
||||
ports: (west: ((id: "d", name: "d"),),
|
||||
east: ((id: "q", name: "q"),))) }
|
||||
)
|
||||
wire.wire("wG1in", ("g1-port-in", "b1-port-d"), directed: true)
|
||||
wire.wire("wG1out", ("b1-port-q", "g1-port-out"), directed: true)
|
||||
|
||||
// outside-port-names: false — labels inside the border (block style)
|
||||
element.group(
|
||||
id: "g2", name: "inside",
|
||||
stroke: (dash: "dashed"),
|
||||
fill: util.colors.orange.lighten(60%),
|
||||
padding: 2em,
|
||||
outside-port-names: false,
|
||||
ports: (
|
||||
west: ((id: "in", name: "D"),),
|
||||
east: ((id: "out", name: "Q"),),
|
||||
),
|
||||
{ element.block(id: "b2", w: 2, h: 1.5, x: 6, y: 0,
|
||||
fill: util.colors.green,
|
||||
ports: (west: ((id: "d"),), east: ((id: "q"),))) }
|
||||
)
|
||||
wire.stub("g2-port-in", "west")
|
||||
wire.stub("g2-port-out", "east")
|
||||
```, vertical: true)
|
||||
|
||||
#let intersection = example(```
|
||||
wire.wire("w1", ((0, 0), (1, 1)), style: "zigzag")
|
||||
wire.wire("w2", ((0, 0), (1, -.5)),
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,84 @@
|
||||
// Demonstrates ports on a group element.
|
||||
// outside-port-names: true (default) — labels outside the group border
|
||||
// outside-port-names: false — labels inside (block-style)
|
||||
#import "/src/lib.typ": circuit, element, util, wire
|
||||
|
||||
#set page(width: auto, height: auto, margin: .5cm)
|
||||
|
||||
#circuit({
|
||||
// --- Group with port labels OUTSIDE (default) ---
|
||||
element.group(
|
||||
id: "cpu",
|
||||
name: "CPU (labels outside)",
|
||||
name-anchor: "north",
|
||||
stroke: (dash: "dashed"),
|
||||
fill: util.colors.yellow.lighten(60%),
|
||||
padding: 1em,
|
||||
outside-port-names: true,
|
||||
ports: (
|
||||
west: (
|
||||
(id: "in1", name: "D1"),
|
||||
(id: "in2", name: "D2"),
|
||||
),
|
||||
east: ((id: "out", name: "Q"),),
|
||||
south: (
|
||||
(id: "rst", name: "RST", vertical: true),
|
||||
(id: "done", name: "DONE", vertical: true),
|
||||
),
|
||||
),
|
||||
{
|
||||
element.block(
|
||||
id: "reg2",
|
||||
w: 2.5,
|
||||
h: 3,
|
||||
x: 0,
|
||||
y: 0,
|
||||
fill: util.colors.green,
|
||||
ports: (
|
||||
west: ((id: "d1"), (id: "d2")),
|
||||
east: ((id: "q"),),
|
||||
north: ((id: "clk", clock: true),),
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
// --- Group with port labels INSIDE (outside-port-names: false) ---
|
||||
element.group(
|
||||
id: "cpu2",
|
||||
name: "CPU (labels inside)",
|
||||
name-anchor: "north",
|
||||
stroke: (dash: "dashed"),
|
||||
fill: util.colors.yellow.lighten(60%),
|
||||
padding: 4em,
|
||||
outside-port-names: false,
|
||||
ports: (
|
||||
west: (
|
||||
(id: "in1", name: "D1"),
|
||||
(id: "in2", name: "D2"),
|
||||
),
|
||||
east: ((id: "out", name: "Q"),),
|
||||
south: (
|
||||
(id: "rst", name: "RST", vertical: true),
|
||||
(id: "done", name: "DONE", vertical: true),
|
||||
),
|
||||
),
|
||||
{
|
||||
element.block(
|
||||
id: "reg2",
|
||||
w: 2.5,
|
||||
h: 3,
|
||||
x: 10,
|
||||
y: 0,
|
||||
fill: util.colors.green,
|
||||
ports: (
|
||||
west: ((id: "d1"), (id: "d2")),
|
||||
east: ((id: "q"),),
|
||||
north: ((id: "clk", clock: true),),
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
wire.stub("cpu2-port-in1", "west", name: "A")
|
||||
wire.stub("cpu2-port-in2", "west", name: "B")
|
||||
wire.stub("cpu2-port-out", "east", name: "Q")
|
||||
})
|
||||
+6797
-6418
File diff suppressed because it is too large.
Load diff
+30
-1
@@ -1,9 +1,15 @@
|
||||
#import "/src/cetz.typ": draw, coordinate
|
||||
#import "../util.typ"
|
||||
#import "ports.typ": add-ports
|
||||
|
||||
/// Draws a group of elements
|
||||
///
|
||||
/// #examples.group
|
||||
///
|
||||
/// Ports can also be defined on a group, just like on a block. By default
|
||||
/// port labels are drawn *outside* the group border so they do not overlap
|
||||
/// child elements. Set `outside-port-names: false` to draw them inside.
|
||||
/// #examples.group-ports
|
||||
/// - body (elements, function): Elements to group
|
||||
/// - id (str): see #doc-ref("element.elmt")
|
||||
/// - name (str): The group's name
|
||||
@@ -16,6 +22,10 @@
|
||||
/// - array: either (`<all>`,), (`<vertical>`, `<horizontal>`) or (`<top>`, `<right>`, `<bottom>`, `<left>`)
|
||||
/// - dictionary: valid keys are "top", "right", "bottom" and "left"
|
||||
/// - radius (number): The corner radius
|
||||
/// - ports (dictionary): see #doc-ref("element.elmt")
|
||||
/// - ports-margins (dictionary): see #doc-ref("element.elmt")
|
||||
/// - outside-port-names (bool): If `true` (default), port name labels are drawn outside the group border so they do not overlap child elements. Set to `false` to draw labels inside, matching the block behaviour
|
||||
/// - debug (dictionary): see #doc-ref("element.elmt")
|
||||
#let group(
|
||||
body,
|
||||
id: "",
|
||||
@@ -24,7 +34,13 @@
|
||||
fill: none,
|
||||
stroke: black + 1pt,
|
||||
padding: 0.5em,
|
||||
radius: 0.5em
|
||||
radius: 0.5em,
|
||||
ports: (:),
|
||||
ports-margins: (:),
|
||||
outside-port-names: true,
|
||||
debug: (
|
||||
ports: false
|
||||
)
|
||||
) = {
|
||||
let min-x = none
|
||||
let max-x = none
|
||||
@@ -68,6 +84,19 @@
|
||||
stroke: stroke,
|
||||
fill: fill
|
||||
)
|
||||
|
||||
add-ports(
|
||||
id,
|
||||
id + ".north-west",
|
||||
id + ".north-east",
|
||||
id + ".south-east",
|
||||
id + ".south-west",
|
||||
ports,
|
||||
ports-margins,
|
||||
debug: debug.ports,
|
||||
outside-name: outside-port-names,
|
||||
)
|
||||
|
||||
if name != none {
|
||||
draw.content(
|
||||
id + "." + name-anchor,
|
||||
|
||||
+20
-5
@@ -1,11 +1,12 @@
|
||||
#import "/src/cetz.typ": draw
|
||||
#import "../util.typ": rotate-anchor
|
||||
#import "../util.typ": rotate-anchor, opposite-anchor
|
||||
|
||||
#let add-port(
|
||||
elmt-id, side, port, pos,
|
||||
prev: none,
|
||||
next: none,
|
||||
debug: false
|
||||
debug: false,
|
||||
outside-name: false,
|
||||
) = {
|
||||
let name = port.at("name", default: "")
|
||||
let name-rotate = port.at("vertical", default: false)
|
||||
@@ -27,9 +28,21 @@
|
||||
// TODO: use context or vectors to have the height relative to the width
|
||||
draw.line(prev, pos1, next)
|
||||
}
|
||||
|
||||
// When outside-name is true (e.g. for groups) the label is placed on the
|
||||
// exterior of the element border so it does not overlap child elements.
|
||||
// Horizontal labels: anchor = opposite of the side (e.g. east port → west-anchored text, outside).
|
||||
// Vertical labels: same opposite side but rotated 90°, keeping text readable.
|
||||
let name-anchor = if outside-name {
|
||||
if name-rotate { rotate-anchor(opposite-anchor(side)) }
|
||||
else { opposite-anchor(side) }
|
||||
} else {
|
||||
if name-rotate { rotate-anchor(side) } else { side }
|
||||
}
|
||||
|
||||
draw.content(
|
||||
pos,
|
||||
anchor: if name-rotate {rotate-anchor(side)} else {side},
|
||||
anchor: name-anchor,
|
||||
padding: 2pt,
|
||||
angle: if name-rotate {90deg} else {0deg},
|
||||
name
|
||||
@@ -60,7 +73,8 @@
|
||||
tl, tr, br, bl,
|
||||
ports,
|
||||
ports-margins,
|
||||
debug: false
|
||||
debug: false,
|
||||
outside-name: false,
|
||||
) = {
|
||||
let sides = (
|
||||
"north": (tl, tr),
|
||||
@@ -109,7 +123,8 @@
|
||||
pos,
|
||||
prev: pos-prev,
|
||||
next: pos-next,
|
||||
debug: debug
|
||||
debug: debug,
|
||||
outside-name: outside-name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user