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