diff options
author | Minijackson <minijackson@riseup.net> | 2022-12-22 12:19:59 +0100 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2022-12-22 12:19:59 +0100 |
commit | 92a02c34628343153b33602eae00cef46e28d191 (patch) | |
tree | 8622ec528d24e456be22d984d93aa9bcafc97399 /examples/lib-dfscq-log/src/labeled_delimiter.rs | |
download | diaphragm-92a02c34628343153b33602eae00cef46e28d191.tar.gz diaphragm-92a02c34628343153b33602eae00cef46e28d191.zip |
WIP
Diffstat (limited to 'examples/lib-dfscq-log/src/labeled_delimiter.rs')
-rw-r--r-- | examples/lib-dfscq-log/src/labeled_delimiter.rs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/examples/lib-dfscq-log/src/labeled_delimiter.rs b/examples/lib-dfscq-log/src/labeled_delimiter.rs new file mode 100644 index 0000000..5a1c610 --- /dev/null +++ b/examples/lib-dfscq-log/src/labeled_delimiter.rs | |||
@@ -0,0 +1,121 @@ | |||
1 | use diaphragm_core::{ | ||
2 | core_shapes::{StraightPath, Text}, | ||
3 | types::{Bounds, Float, Point2D, ShapeContext}, | ||
4 | ComplexShape, DrawResult, Drawable, SolverContext, | ||
5 | }; | ||
6 | |||
7 | #[derive(Debug, Clone)] | ||
8 | pub struct Delimiter { | ||
9 | pub width: Float, | ||
10 | pub label: Drawable<Text>, | ||
11 | } | ||
12 | |||
13 | #[derive(Debug, Clone)] | ||
14 | pub struct LabeledDelimiter { | ||
15 | pub delimiters: Vec<Delimiter>, | ||
16 | pub tick_height: Float, | ||
17 | } | ||
18 | |||
19 | impl ComplexShape for LabeledDelimiter { | ||
20 | fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult { | ||
21 | let mut result = DrawResult::new(); | ||
22 | |||
23 | let bounds_left = context.bounds().left(solver); | ||
24 | let bounds_right = context.bounds().right(solver); | ||
25 | let bounds_bottom = context.bounds().bottom(solver); | ||
26 | let bounds_width = context.bounds().width(solver); | ||
27 | |||
28 | let tick_top = context.bounds().top(solver); | ||
29 | let tick_bottom = solver.float_add(&[tick_top, self.tick_height]); | ||
30 | |||
31 | let first_tick = Drawable::builder(StraightPath::new(vec![ | ||
32 | context.bounds().top_left(solver), | ||
33 | Point2D::new(bounds_left, tick_bottom), | ||
34 | ])) | ||
35 | .bounds( | ||
36 | Bounds::builder() | ||
37 | .top(tick_top) | ||
38 | .left(bounds_left) | ||
39 | .height(self.tick_height) | ||
40 | .width(Float::Fixed(0.)) | ||
41 | .build(solver), | ||
42 | ) | ||
43 | .stroke(context.stroke().clone()) | ||
44 | .build(solver); | ||
45 | |||
46 | let baseline_y = first_tick.bounds().vert_center(solver); | ||
47 | |||
48 | result.push(first_tick); | ||
49 | |||
50 | // TODO: split everything into functions | ||
51 | |||
52 | let baseline = Drawable::builder(StraightPath::new(vec![ | ||
53 | Point2D::new(bounds_left, baseline_y), | ||
54 | Point2D::new(bounds_right, baseline_y), | ||
55 | ])) | ||
56 | .bounds( | ||
57 | Bounds::builder() | ||
58 | .top(baseline_y) | ||
59 | .left(bounds_left) | ||
60 | .width(bounds_width) | ||
61 | .height(Float::Fixed(0.)) | ||
62 | .build(solver), | ||
63 | ) | ||
64 | .stroke(context.stroke().clone()) | ||
65 | .build(solver); | ||
66 | |||
67 | result.push(baseline); | ||
68 | |||
69 | let mut section_end = bounds_left; | ||
70 | let mut all_label_bottoms = vec![]; | ||
71 | |||
72 | for &Delimiter { | ||
73 | width: section_width, | ||
74 | ref label, | ||
75 | } in &self.delimiters | ||
76 | { | ||
77 | let section_begin = section_end; | ||
78 | section_end = solver.float_add(&[section_end, section_width]); | ||
79 | |||
80 | let section_half_width = solver.float_div(section_width, Float::Fixed(2.)); | ||
81 | let section_middle = solver.float_add(&[section_begin, section_half_width]); | ||
82 | |||
83 | let tick = Drawable::builder(StraightPath::new(vec![ | ||
84 | Point2D::new(section_end, tick_top), | ||
85 | Point2D::new(section_end, tick_bottom), | ||
86 | ])) | ||
87 | .bounds( | ||
88 | Bounds::builder() | ||
89 | .top(tick_top) | ||
90 | .left(section_end) | ||
91 | .height(self.tick_height) | ||
92 | .width(Float::Fixed(0.)) | ||
93 | .build(solver), | ||
94 | ) | ||
95 | .stroke(context.stroke().clone()) | ||
96 | .build(solver); | ||
97 | |||
98 | result.push(tick); | ||
99 | |||
100 | let label_top = label.bounds().top(solver); | ||
101 | let label_bottom = label.bounds().bottom(solver); | ||
102 | let label_horiz_center = label.bounds().horiz_center(solver); | ||
103 | |||
104 | let label_top_constraint = solver.float_eq(label_top, tick_bottom); | ||
105 | solver.constrain(label_top_constraint); | ||
106 | |||
107 | let label_middle_constraint = solver.float_eq(label_horiz_center, section_middle); | ||
108 | solver.constrain(label_middle_constraint); | ||
109 | |||
110 | result.push(label.clone()); | ||
111 | |||
112 | all_label_bottoms.push(label_bottom); | ||
113 | } | ||
114 | |||
115 | let wanted_bounds_bottom = solver.float_max(&all_label_bottoms); | ||
116 | let bounds_bottom_constraint = solver.float_eq(bounds_bottom, wanted_bounds_bottom); | ||
117 | solver.constrain(bounds_bottom_constraint); | ||
118 | |||
119 | result | ||
120 | } | ||
121 | } | ||