forked from HEL/circuiteria
Compare commits
2
Commits
u-shape
...
group-ports
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
563bb7b1d2 | ||
|
|
0d1478c765 |
No files matched your search
@@ -188,6 +188,48 @@ wire.wire("w2", ("b2-port-out", "b3-port-in2"),
|
|||||||
style: "zigzag")
|
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,
|
||||||
|
port-name-padding: 4pt,
|
||||||
|
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)
|
||||||
|
// with extra padding via port-name-padding
|
||||||
|
element.group(
|
||||||
|
id: "g2", name: "inside",
|
||||||
|
stroke: (dash: "dashed"),
|
||||||
|
fill: util.colors.orange.lighten(60%),
|
||||||
|
padding: 2em,
|
||||||
|
outside-port-names: false,
|
||||||
|
port-name-padding: 0.4em,
|
||||||
|
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(```
|
#let intersection = example(```
|
||||||
wire.wire("w1", ((0, 0), (1, 1)), style: "zigzag")
|
wire.wire("w1", ((0, 0), (1, 1)), style: "zigzag")
|
||||||
wire.wire("w2", ((0, 0), (1, -.5)),
|
wire.wire("w2", ((0, 0), (1, -.5)),
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,86 @@
|
|||||||
|
// 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 INSIDE (outside-port-names: false) ---
|
||||||
|
element.group(
|
||||||
|
id: "cpu",
|
||||||
|
name: "CPU (labels outside)",
|
||||||
|
name-anchor: "north",
|
||||||
|
stroke: (dash: "dashed"),
|
||||||
|
fill: util.colors.yellow.lighten(60%),
|
||||||
|
padding: 1em,
|
||||||
|
port-name-padding: .5em,
|
||||||
|
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,
|
||||||
|
port-name-padding: 0.5em,
|
||||||
|
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")
|
||||||
|
})
|
||||||
+7343
-6761
File diff suppressed because it is too large.
Load diff
@@ -27,6 +27,7 @@
|
|||||||
name-anchor: "center",
|
name-anchor: "center",
|
||||||
ports: (),
|
ports: (),
|
||||||
ports-margins: (),
|
ports-margins: (),
|
||||||
|
port-name-padding: 2pt,
|
||||||
fill: none,
|
fill: none,
|
||||||
radius: 0.5em,
|
radius: 0.5em,
|
||||||
stroke: black + 1pt,
|
stroke: black + 1pt,
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
name-anchor: name-anchor,
|
name-anchor: name-anchor,
|
||||||
ports: ports,
|
ports: ports,
|
||||||
ports-margins: ports-margins,
|
ports-margins: ports-margins,
|
||||||
|
port-name-padding: port-name-padding,
|
||||||
fill: fill,
|
fill: fill,
|
||||||
stroke: stroke,
|
stroke: stroke,
|
||||||
id: id,
|
id: id,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
/// - `clock` (`bool`): Whether it is a clock port (triangle symbol)
|
/// - `clock` (`bool`): Whether it is a clock port (triangle symbol)
|
||||||
/// - `vertical` (`bool`): Whether the name should be drawn vertically
|
/// - `vertical` (`bool`): Whether the name should be drawn vertically
|
||||||
/// - ports-margins (dictionary): Dictionary of ports margins (used with automatic port placement). They keys are cardinal directions ("north", "east", "south", "west"). The values are tuples of (`<start>`, `<end>`) margins (numbers)
|
/// - ports-margins (dictionary): Dictionary of ports margins (used with automatic port placement). They keys are cardinal directions ("north", "east", "south", "west"). The values are tuples of (`<start>`, `<end>`) margins (numbers)
|
||||||
|
/// - port-name-padding (number, length): Padding between the port name label and the port anchor point (default `2pt`)
|
||||||
/// - fill (none, color): Fill color
|
/// - fill (none, color): Fill color
|
||||||
/// - stroke (stroke): Border stroke
|
/// - stroke (stroke): Border stroke
|
||||||
/// - id (str): The block id (for future reference)
|
/// - id (str): The block id (for future reference)
|
||||||
@@ -56,6 +57,7 @@
|
|||||||
name-anchor: "center",
|
name-anchor: "center",
|
||||||
ports: (:),
|
ports: (:),
|
||||||
ports-margins: (:),
|
ports-margins: (:),
|
||||||
|
port-name-padding: 2pt,
|
||||||
fill: none,
|
fill: none,
|
||||||
stroke: black + 1pt,
|
stroke: black + 1pt,
|
||||||
id: "",
|
id: "",
|
||||||
@@ -140,7 +142,8 @@
|
|||||||
tl, tr, br, bl,
|
tl, tr, br, bl,
|
||||||
ports,
|
ports,
|
||||||
ports-margins,
|
ports-margins,
|
||||||
debug: debug.ports
|
debug: debug.ports,
|
||||||
|
name-padding: port-name-padding,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
+33
-1
@@ -1,9 +1,15 @@
|
|||||||
#import "/src/cetz.typ": draw, coordinate
|
#import "/src/cetz.typ": draw, coordinate
|
||||||
#import "../util.typ"
|
#import "../util.typ"
|
||||||
|
#import "ports.typ": add-ports
|
||||||
|
|
||||||
/// Draws a group of elements
|
/// Draws a group of elements
|
||||||
///
|
///
|
||||||
/// #examples.group
|
/// #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
|
/// - body (elements, function): Elements to group
|
||||||
/// - id (str): see #doc-ref("element.elmt")
|
/// - id (str): see #doc-ref("element.elmt")
|
||||||
/// - name (str): The group's name
|
/// - name (str): The group's name
|
||||||
@@ -16,6 +22,11 @@
|
|||||||
/// - array: either (`<all>`,), (`<vertical>`, `<horizontal>`) or (`<top>`, `<right>`, `<bottom>`, `<left>`)
|
/// - array: either (`<all>`,), (`<vertical>`, `<horizontal>`) or (`<top>`, `<right>`, `<bottom>`, `<left>`)
|
||||||
/// - dictionary: valid keys are "top", "right", "bottom" and "left"
|
/// - dictionary: valid keys are "top", "right", "bottom" and "left"
|
||||||
/// - radius (number): The corner radius
|
/// - 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
|
||||||
|
/// - port-name-padding (number, length): Padding between the port name label and the group border (default `2pt`). Accepts anything CeTZ accepts as `padding` (number or length)
|
||||||
|
/// - debug (dictionary): see #doc-ref("element.elmt")
|
||||||
#let group(
|
#let group(
|
||||||
body,
|
body,
|
||||||
id: "",
|
id: "",
|
||||||
@@ -24,7 +35,14 @@
|
|||||||
fill: none,
|
fill: none,
|
||||||
stroke: black + 1pt,
|
stroke: black + 1pt,
|
||||||
padding: 0.5em,
|
padding: 0.5em,
|
||||||
radius: 0.5em
|
radius: 0.5em,
|
||||||
|
ports: (:),
|
||||||
|
ports-margins: (:),
|
||||||
|
outside-port-names: true,
|
||||||
|
port-name-padding: 2pt,
|
||||||
|
debug: (
|
||||||
|
ports: false
|
||||||
|
)
|
||||||
) = {
|
) = {
|
||||||
let min-x = none
|
let min-x = none
|
||||||
let max-x = none
|
let max-x = none
|
||||||
@@ -68,6 +86,20 @@
|
|||||||
stroke: stroke,
|
stroke: stroke,
|
||||||
fill: fill
|
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,
|
||||||
|
name-padding: port-name-padding,
|
||||||
|
)
|
||||||
|
|
||||||
if name != none {
|
if name != none {
|
||||||
draw.content(
|
draw.content(
|
||||||
id + "." + name-anchor,
|
id + "." + name-anchor,
|
||||||
|
|||||||
+24
-6
@@ -1,11 +1,13 @@
|
|||||||
#import "/src/cetz.typ": draw
|
#import "/src/cetz.typ": draw
|
||||||
#import "../util.typ": rotate-anchor
|
#import "../util.typ": rotate-anchor, opposite-anchor
|
||||||
|
|
||||||
#let add-port(
|
#let add-port(
|
||||||
elmt-id, side, port, pos,
|
elmt-id, side, port, pos,
|
||||||
prev: none,
|
prev: none,
|
||||||
next: none,
|
next: none,
|
||||||
debug: false
|
debug: false,
|
||||||
|
outside-name: false,
|
||||||
|
name-padding: 2pt,
|
||||||
) = {
|
) = {
|
||||||
let name = port.at("name", default: "")
|
let name = port.at("name", default: "")
|
||||||
let name-rotate = port.at("vertical", default: false)
|
let name-rotate = port.at("vertical", default: false)
|
||||||
@@ -27,10 +29,22 @@
|
|||||||
// TODO: use context or vectors to have the height relative to the width
|
// TODO: use context or vectors to have the height relative to the width
|
||||||
draw.line(prev, pos1, next)
|
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(
|
draw.content(
|
||||||
pos,
|
pos,
|
||||||
anchor: if name-rotate {rotate-anchor(side)} else {side},
|
anchor: name-anchor,
|
||||||
padding: 2pt,
|
padding: name-padding,
|
||||||
angle: if name-rotate {90deg} else {0deg},
|
angle: if name-rotate {90deg} else {0deg},
|
||||||
name
|
name
|
||||||
)
|
)
|
||||||
@@ -60,7 +74,9 @@
|
|||||||
tl, tr, br, bl,
|
tl, tr, br, bl,
|
||||||
ports,
|
ports,
|
||||||
ports-margins,
|
ports-margins,
|
||||||
debug: false
|
debug: false,
|
||||||
|
outside-name: false,
|
||||||
|
name-padding: 2pt,
|
||||||
) = {
|
) = {
|
||||||
let sides = (
|
let sides = (
|
||||||
"north": (tl, tr),
|
"north": (tl, tr),
|
||||||
@@ -109,7 +125,9 @@
|
|||||||
pos,
|
pos,
|
||||||
prev: pos-prev,
|
prev: pos-prev,
|
||||||
next: pos-next,
|
next: pos-next,
|
||||||
debug: debug
|
debug: debug,
|
||||||
|
outside-name: outside-name,
|
||||||
|
name-padding: name-padding,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user