summaryrefslogtreecommitdiffstats
path: root/examples/lib-dfscq-log/src/layer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/lib-dfscq-log/src/layer.rs')
-rw-r--r--examples/lib-dfscq-log/src/layer.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/examples/lib-dfscq-log/src/layer.rs b/examples/lib-dfscq-log/src/layer.rs
new file mode 100644
index 0000000..45edb56
--- /dev/null
+++ b/examples/lib-dfscq-log/src/layer.rs
@@ -0,0 +1,169 @@
1use diaphragm_core::{
2 core_shapes::Rectangle,
3 core_shapes::Text,
4 text::FontDescription,
5 types::{Bounds, Float, ShapeContext},
6 ComplexShape, DrawResult, Drawable, DynDrawable, SolverContext,
7};
8
9#[derive(Clone)]
10pub struct Entry {
11 // TODO: transform this to just Text
12 pub label: Option<String>,
13 pub label_vert_center_offset: Option<Float>,
14 pub content: DynDrawable,
15}
16
17#[derive(Clone)]
18pub struct Layer {
19 // TODO: transform this to just Text
20 pub name: String,
21 pub name_font: FontDescription,
22 pub label_font: FontDescription,
23 pub padding: Float,
24 pub entries: Vec<Entry>,
25 pub entries_width: Float,
26}
27
28impl ComplexShape for Layer {
29 fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult {
30 let mut result = DrawResult::new();
31
32 let bounds_top = context.bounds().top(solver);
33 let bounds_left = context.bounds().left(solver);
34 let bounds_right = context.bounds().right(solver);
35 let bounds_height = context.bounds().height(solver);
36
37 let inner_top = solver.float_add(&[bounds_top, self.padding]);
38 let inner_right = solver.float_sub(&[bounds_right, self.padding]);
39
40 // Outer box
41
42 result.push(Drawable::new(Rectangle {}, context.clone()));
43
44 // Layer name
45
46 let layer_name = Drawable::builder(Text {
47 content: self.name.clone(),
48 font: self.name_font.clone(),
49 })
50 .bounds(
51 Bounds::builder()
52 .top(inner_top)
53 .left(solver.float_add(&[bounds_left, self.padding]))
54 .build(solver),
55 )
56 .stroke(context.stroke().clone())
57 .fill(context.fill().clone())
58 .build(solver);
59
60 let layer_name_bottom = layer_name.bounds().bottom(solver);
61
62 /*
63 let mut rect_context = layer_name_context.clone();
64 rect_context.stroke = StrokeStyle::solid(Color::from_rgb(1., 0., 0.));
65 result.push_shape(Rectangle {}, rect_context);
66 */
67
68 result.push(layer_name);
69
70 // Entries
71
72 let mut entry_y_acc = inner_top;
73
74 for entry in &self.entries {
75 // Entry content
76
77 /*
78 let content_context = ShapeContext {
79 bounds: Bounds {
80 top: solver.new_free_float(),
81 left: content_left,
82 width: entry.width,
83 height: entry.height,
84 },
85 fill: Default::default(),
86 stroke: Default::default(),
87 };
88 */
89
90 let content_vert_center = entry.content.bounds().vert_center(solver);
91 let content_top = entry.content.bounds().top(solver);
92 let content_left = entry.content.bounds().left(solver);
93 let content_bottom = entry.content.bounds().bottom(solver);
94
95 // TODO: to replace with label offset
96 let content_half_height = solver.float_sub(&[content_vert_center, content_top]);
97
98 result.push_dyn(entry.content.clone());
99
100 // Entry label
101
102 if let Some(label_content) = entry.label.clone() {
103 let label_top = solver.new_free_float();
104 let label_width = solver.new_free_float();
105 let label_left = solver.float_sub(&[inner_right, self.entries_width, label_width]);
106
107 let label = Drawable::builder(Text {
108 content: label_content,
109 font: self.label_font.clone(),
110 })
111 .bounds(
112 Bounds::builder()
113 .top(label_top)
114 .left(label_left)
115 .width(label_width)
116 .build(solver),
117 )
118 .build(solver);
119
120 /*
121 let mut rect_context = label_context.clone();
122 rect_context.stroke = StrokeStyle::solid(Color::from_rgb(1., 0., 0.));
123 result.push_shape(Rectangle {}, rect_context);
124 */
125
126 // TODO
127 let label_vert_center = label.bounds().vert_center(solver);
128 let label_top = label.bounds().top(solver);
129 let label_right = label.bounds().right(solver);
130
131 let label_vert_center_constraint =
132 solver.float_eq(label_vert_center, content_vert_center);
133 solver.constrain(label_vert_center_constraint);
134
135 let label_half_height = solver.float_sub(&[label_vert_center, label_top]);
136
137 let dumb_label_mid_placement =
138 solver.float_add(&[entry_y_acc, content_half_height]);
139 let safe_label_mid_placement =
140 solver.float_add(&[layer_name_bottom, label_half_height]);
141 let label_mid_placement =
142 solver.float_max(&[safe_label_mid_placement, dumb_label_mid_placement]);
143 let label_mid_placement_constraint =
144 solver.float_eq(label_vert_center, label_mid_placement);
145 solver.constrain(label_mid_placement_constraint);
146
147 let label_right_constraint = solver.float_eq(label_right, content_left);
148 solver.constrain(label_right_constraint);
149
150 result.push(label);
151 } else {
152 let content_top_constraint = solver.float_eq(content_top, entry_y_acc);
153 solver.constrain(content_top_constraint);
154
155 let wanted_content_left = solver.float_sub(&[inner_right, self.entries_width]);
156 let content_left_constraint = solver.float_eq(content_left, wanted_content_left);
157 solver.constrain(content_left_constraint);
158 }
159
160 entry_y_acc = solver.float_add(&[content_bottom, self.padding]);
161 }
162
163 let wanted_bounds_height = solver.float_sub(&[entry_y_acc, bounds_top]);
164 let height_constraint = solver.float_eq(bounds_height, wanted_bounds_height);
165 solver.constrain(height_constraint);
166
167 result
168 }
169}