egui_cable/
default_plug.rs1use egui::{Rect, Response, Sense, Ui, Widget};
2use epaint::Stroke;
3
4use crate::{
5 plug_params::PlugParams,
6 utils::{widget_visuals, SIZE},
7};
8
9#[derive(Debug)]
10pub struct DefaultPlug;
11
12impl Widget for DefaultPlug {
13 fn ui(self, ui: &mut Ui) -> Response {
14 let params = PlugParams::get(ui);
15 let vector = params.vector;
16 let active = params.active;
17 let plugged = params.plugged;
18 let locked = params.locked;
19
20 let (rect, response) = ui.allocate_exact_size(
21 SIZE,
22 if (active || !plugged) && !locked {
23 Sense::drag()
24 } else {
25 Sense::hover()
27 },
28 );
29
30 let pos = rect.left_top() + response.drag_delta();
32 let size = rect.size();
33 let center_pos = pos + size / 2.0;
35
36 if ui.is_rect_visible(Rect::from_center_size(center_pos, size)) {
37 let visuals = if locked {
38 ui.visuals().widgets.noninteractive
39 } else {
40 widget_visuals(ui, &response)
41 };
42 if response.dragged() {
43 if let Some(vector) = vector {
44 ui.painter().arrow(
45 center_pos,
46 vector * size.x / 2.0 * 1.5,
47 Stroke::new(2.0, visuals.fg_stroke.color),
48 );
49 }
50 }
51 ui.painter().add(epaint::CircleShape {
52 center: center_pos,
53 radius: size.x / 2.0 * if active { 0.7 } else { 0.2 },
54 fill: visuals.fg_stroke.color,
55 stroke: visuals.fg_stroke,
56 });
57 }
58
59 response
60 }
61}