blockworx/shape/
comment.rs1use crate::theme::Style;
2use egui::{Pos2, Rect};
3
4use blockworx_doc::block_model::Comment;
5
6use crate::render::block_title_position;
7use crate::{
8 canvas::Renderer,
9 edit::{
10 lower::{accent_from_role, px_rect, shape_label},
11 naming::InterfaceLock,
12 },
13 grid::grid_rect,
14 shape::{BaseShape, ShapeLabel, block::resize_rect},
15 state::RenderMode,
16 theme::Role,
17};
18
19fn accent(comment: &Comment) -> Role {
23 crate::theme::accent_role(accent_from_role(*comment.role.as_ref()))
24 .unwrap_or(Role::CommentStroke)
25}
26
27fn draw<R: Renderer>(
29 comment: &Comment,
30 bbox: Rect,
31 title: &ShapeLabel<'_>,
32 painter: &mut Style<'_, R>,
33) {
34 crate::render::draw_box_outline(bbox, Role::Transparent, (1.0, accent(comment)), painter);
35 crate::render::draw_block_title(bbox, title, InterfaceLock::Unlocked, painter);
36}
37
38impl BaseShape for Comment {
39 fn title(&self) -> Option<ShapeLabel<'_>> {
40 Some(shape_label(&self.title))
41 }
42 fn gui_rect(&self) -> Rect {
43 px_rect(*self.rect.as_ref())
44 }
45 fn title_anchor(&self) -> Option<Pos2> {
46 let (pos, _) = block_title_position(self.gui_rect(), &shape_label(&self.title));
47 Some(pos)
48 }
49 fn resizable(&self) -> bool {
50 true
51 }
52 fn render_ng<R: Renderer>(&self, mode: RenderMode, painter: &mut Style<'_, R>) {
53 let bbox = self.gui_rect();
54 let title = shape_label(&self.title);
55 match mode {
56 RenderMode::Moving { delta } => {
57 let shifted = bbox.translate(delta);
58 draw(self, shifted, &title, painter);
59 }
60 RenderMode::Selected { .. } => {
61 draw(self, bbox, &title, painter);
62 crate::render::draw_selection_frame(bbox, None, painter);
63 }
64 RenderMode::Resizing { mode, delta } => {
65 let resized = grid_rect(resize_rect(&bbox, mode, delta));
66 draw(self, resized, &title, painter);
67 crate::render::draw_selection_frame(resized, Some(mode), painter);
68 }
69 RenderMode::TitleDragged { delta } => {
70 let (anchor_pos, _) = block_title_position(bbox, &title);
74 let text_w = painter.text_size(title.name, &painter.theme().title_font).x;
75 let shifted = ShapeLabel {
76 side: crate::render::label_side_for_y(bbox, anchor_pos.y + delta.y),
77 offset: crate::render::clamp_label_offset(
78 bbox,
79 text_w,
80 title.offset + delta.x,
81 egui::Align::Center,
82 ),
83 ..title
84 };
85 draw(self, bbox, &shifted, painter);
86 painter.line_segment(
87 [bbox.left_center(), bbox.right_center()],
88 (2.0, Role::PinDragIndicator),
89 );
90 }
91 _ => draw(self, bbox, &title, painter),
94 }
95 }
96}