dioxus_three/
selection.rs1use crate::input::EntityId;
4use std::collections::HashSet;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
7pub enum SelectionMode {
8 #[default]
9 Single,
10 Multiple,
11 Toggle,
12}
13
14#[derive(Debug, Clone, PartialEq)]
15pub struct SelectionStyle {
16 pub outline: bool,
17 pub outline_color: String,
18 pub outline_width: f32,
19 pub highlight: bool,
20 pub highlight_color: String,
21 pub highlight_opacity: f32,
22 pub show_gizmo: bool,
23}
24
25impl Default for SelectionStyle {
26 fn default() -> Self {
27 Self {
28 outline: true,
29 outline_color: "#DEC647".to_string(),
30 outline_width: 2.0,
31 highlight: true,
32 highlight_color: "#DEC647".to_string(),
33 highlight_opacity: 0.3,
34 show_gizmo: true,
35 }
36 }
37}
38
39#[derive(Debug, Clone, PartialEq)]
40pub struct Selection {
41 selected: HashSet<EntityId>,
42 mode: SelectionMode,
43 last_selected: Option<EntityId>,
44}
45
46impl Selection {
47 pub fn new() -> Self {
48 Self::empty()
49 }
50
51 pub fn empty() -> Self {
52 Self {
53 selected: HashSet::new(),
54 mode: SelectionMode::Single,
55 last_selected: None,
56 }
57 }
58
59 pub fn with_mode(mode: SelectionMode) -> Self {
60 Self {
61 selected: HashSet::new(),
62 mode,
63 last_selected: None,
64 }
65 }
66
67 pub fn is_selected(&self, entity: EntityId) -> bool {
68 self.selected.contains(&entity)
69 }
70
71 pub fn select(&mut self, entity: EntityId) {
72 match self.mode {
73 SelectionMode::Single => {
74 self.selected.clear();
75 self.selected.insert(entity);
76 }
77 _ => {
78 self.selected.insert(entity);
79 }
80 }
81 self.last_selected = Some(entity);
82 }
83
84 pub fn toggle(&mut self, entity: EntityId) {
85 if self.selected.contains(&entity) {
86 self.selected.remove(&entity);
87 } else {
88 if self.mode == SelectionMode::Single {
89 self.selected.clear();
90 }
91 self.selected.insert(entity);
92 }
93 self.last_selected = Some(entity);
94 }
95
96 pub fn deselect(&mut self, entity: EntityId) {
97 self.selected.remove(&entity);
98 if self.last_selected == Some(entity) {
99 self.last_selected = self.selected.iter().copied().last();
100 }
101 }
102
103 pub fn clear(&mut self) {
104 self.selected.clear();
105 self.last_selected = None;
106 }
107
108 pub fn count(&self) -> usize {
109 self.selected.len()
110 }
111
112 pub fn has_selection(&self) -> bool {
113 !self.selected.is_empty()
114 }
115
116 pub fn primary(&self) -> Option<EntityId> {
117 self.last_selected
118 }
119
120 pub fn iter(&self) -> impl Iterator<Item = EntityId> + '_ {
121 self.selected.iter().copied()
122 }
123}
124
125impl Default for Selection {
126 fn default() -> Self {
127 Self::new()
128 }
129}