egui_map/map/
objects.rs

1use egui::{Align2, Color32, FontFamily, FontId, Pos2, Stroke, Ui};
2use std::convert::{From, Into};
3use std::ops::{Add, Div, DivAssign, Mul, MulAssign, Sub};
4use std::time::Instant;
5
6#[derive(Copy, Clone)]
7pub struct RawPoint {
8    pub components: [f32; 2],
9}
10
11impl RawPoint {
12    pub fn new(x: f32, y: f32) -> Self {
13        Self { components: [x, y] }
14    }
15}
16
17impl Default for RawPoint {
18    fn default() -> Self {
19        Self::new(0.00, 0.00)
20    }
21}
22
23impl Mul<i64> for RawPoint {
24    type Output = Self;
25
26    fn mul(self, rhs: i64) -> Self::Output {
27        Self {
28            components: [
29                self.components[0] * rhs as f32,
30                self.components[1] * rhs as f32,
31            ],
32        }
33    }
34}
35
36impl Mul<i32> for RawPoint {
37    type Output = Self;
38
39    fn mul(self, rhs: i32) -> Self::Output {
40        Self {
41            components: [
42                self.components[0] * rhs as f32,
43                self.components[1] * rhs as f32,
44            ],
45        }
46    }
47}
48
49impl Mul<u64> for RawPoint {
50    type Output = Self;
51
52    fn mul(self, rhs: u64) -> Self::Output {
53        Self {
54            components: [
55                self.components[0] * rhs as f32,
56                self.components[1] * rhs as f32,
57            ],
58        }
59    }
60}
61
62impl Mul<u32> for RawPoint {
63    type Output = Self;
64
65    fn mul(self, rhs: u32) -> Self::Output {
66        Self {
67            components: [
68                self.components[0] * rhs as f32,
69                self.components[1] * rhs as f32,
70            ],
71        }
72    }
73}
74
75impl Mul<f32> for RawPoint {
76    type Output = Self;
77
78    fn mul(self, rhs: f32) -> Self::Output {
79        Self {
80            components: [self.components[0] * rhs, self.components[1] * rhs],
81        }
82    }
83}
84
85impl MulAssign<i64> for RawPoint {
86    fn mul_assign(&mut self, rhs: i64) {
87        self.components[0] = self.components[0] * rhs as f32;
88        self.components[1] = self.components[1] * rhs as f32;
89    }
90}
91
92impl MulAssign<i32> for RawPoint {
93    fn mul_assign(&mut self, rhs: i32) {
94        self.components[0] = self.components[0] * rhs as f32;
95        self.components[1] = self.components[1] * rhs as f32;
96    }
97}
98
99impl MulAssign<u64> for RawPoint {
100    fn mul_assign(&mut self, rhs: u64) {
101        self.components[0] = self.components[0] * rhs as f32;
102        self.components[1] = self.components[1] * rhs as f32;
103    }
104}
105
106impl MulAssign<u32> for RawPoint {
107    fn mul_assign(&mut self, rhs: u32) {
108        self.components[0] = self.components[0] * rhs as f32;
109        self.components[1] = self.components[1] * rhs as f32;
110    }
111}
112
113impl MulAssign<f32> for RawPoint {
114    fn mul_assign(&mut self, rhs: f32) {
115        self.components[0] = self.components[0] * rhs;
116        self.components[1] = self.components[1] * rhs;
117    }
118}
119
120impl Div<i64> for RawPoint {
121    type Output = Self;
122
123    fn div(self, rhs: i64) -> Self::Output {
124        Self {
125            components: [
126                self.components[0] / rhs as f32,
127                self.components[1] / rhs as f32,
128            ],
129        }
130    }
131}
132
133impl Div<i32> for RawPoint {
134    type Output = Self;
135
136    fn div(self, rhs: i32) -> Self::Output {
137        Self {
138            components: [
139                self.components[0] / rhs as f32,
140                self.components[1] / rhs as f32,
141            ],
142        }
143    }
144}
145
146impl Div<u64> for RawPoint {
147    type Output = Self;
148
149    fn div(self, rhs: u64) -> Self::Output {
150        Self {
151            components: [
152                self.components[0] / rhs as f32,
153                self.components[1] / rhs as f32,
154            ],
155        }
156    }
157}
158
159impl Div<u32> for RawPoint {
160    type Output = Self;
161
162    fn div(self, rhs: u32) -> Self::Output {
163        Self {
164            components: [
165                self.components[0] / rhs as f32,
166                self.components[1] / rhs as f32,
167            ],
168        }
169    }
170}
171
172impl Div<f32> for RawPoint {
173    type Output = Self;
174
175    fn div(self, rhs: f32) -> Self::Output {
176        Self {
177            components: [self.components[0] / rhs, self.components[1] / rhs],
178        }
179    }
180}
181
182impl DivAssign<i64> for RawPoint {
183    fn div_assign(&mut self, rhs: i64) {
184        self.components[0] = self.components[0] / rhs as f32;
185        self.components[1] = self.components[1] / rhs as f32;
186    }
187}
188
189impl DivAssign<i32> for RawPoint {
190    fn div_assign(&mut self, rhs: i32) {
191        self.components[0] = self.components[0] / rhs as f32;
192        self.components[1] = self.components[1] / rhs as f32;
193    }
194}
195
196impl DivAssign<u64> for RawPoint {
197    fn div_assign(&mut self, rhs: u64) {
198        self.components[0] = self.components[0] / rhs as f32;
199        self.components[1] = self.components[1] / rhs as f32;
200    }
201}
202
203impl DivAssign<u32> for RawPoint {
204    fn div_assign(&mut self, rhs: u32) {
205        self.components[0] = self.components[0] / rhs as f32;
206        self.components[1] = self.components[1] / rhs as f32;
207    }
208}
209
210impl DivAssign<f32> for RawPoint {
211    fn div_assign(&mut self, rhs: f32) {
212        self.components[0] = self.components[0] / rhs;
213        self.components[1] = self.components[1] / rhs;
214    }
215}
216
217impl Add<RawPoint> for RawPoint {
218    type Output = RawPoint;
219    fn add(self, rhs: RawPoint) -> Self::Output {
220        Self {
221            components: [
222                self.components[0] + rhs.components[0],
223                self.components[1] + rhs.components[1],
224            ],
225        }
226    }
227}
228
229impl Sub<RawPoint> for RawPoint {
230    type Output = RawPoint;
231    fn sub(self, rhs: RawPoint) -> Self::Output {
232        Self {
233            components: [
234                self.components[0] - rhs.components[0],
235                self.components[1] - rhs.components[1],
236            ],
237        }
238    }
239}
240
241impl Add<&RawPoint> for RawPoint {
242    type Output = RawPoint;
243    fn add(self, rhs: &RawPoint) -> Self::Output {
244        Self {
245            components: [
246                self.components[0] + rhs.components[0],
247                self.components[1] + rhs.components[1],
248            ],
249        }
250    }
251}
252
253impl Sub<&RawPoint> for RawPoint {
254    type Output = RawPoint;
255    fn sub(self, rhs: &RawPoint) -> Self::Output {
256        Self {
257            components: [
258                self.components[0] - rhs.components[0],
259                self.components[1] - rhs.components[1],
260            ],
261        }
262    }
263}
264
265impl From<[f32; 2]> for RawPoint {
266    fn from(value: [f32; 2]) -> Self {
267        Self { components: value }
268    }
269}
270
271impl From<Pos2> for RawPoint {
272    fn from(value: Pos2) -> Self {
273        Self {
274            components: [value.x, value.y],
275        }
276    }
277}
278
279impl From<[i64; 2]> for RawPoint {
280    fn from(value: [i64; 2]) -> Self {
281        Self {
282            components: [value[0] as f32, value[1] as f32],
283        }
284    }
285}
286
287impl From<[i32; 2]> for RawPoint {
288    fn from(value: [i32; 2]) -> Self {
289        Self {
290            components: [value[0] as f32, value[1] as f32],
291        }
292    }
293}
294
295impl From<[i16; 2]> for RawPoint {
296    fn from(value: [i16; 2]) -> Self {
297        Self {
298            components: [value[0] as f32, value[1] as f32],
299        }
300    }
301}
302
303impl From<[i8; 2]> for RawPoint {
304    fn from(value: [i8; 2]) -> Self {
305        Self {
306            components: [value[0] as f32, value[1] as f32],
307        }
308    }
309}
310
311impl From<RawPoint> for [f32; 2] {
312    fn from(val: RawPoint) -> Self {
313        [val.components[0], val.components[1]]
314    }
315}
316
317impl From<RawPoint> for Pos2 {
318    fn from(val: RawPoint) -> Self {
319        Pos2::from(val.components)
320    }
321}
322
323#[derive(Copy, Clone)]
324pub struct RawLine {
325    pub points: [RawPoint; 2],
326}
327
328impl RawLine {
329    pub fn new(a: RawPoint, b: RawPoint) -> Self {
330        Self { points: [a, b] }
331    }
332
333    pub fn distance(self) -> f32 {
334        let x = self.points[0].components[0] - self.points[1].components[0];
335        let y = self.points[0].components[1] - self.points[1].components[1];
336        (x.powi(2) + y.powi(2)).sqrt()
337    }
338
339    pub fn midpoint(self) -> RawPoint {
340        let x = (self.points[0].components[0] + self.points[1].components[0]) / 2.0;
341        let y = (self.points[0].components[1] + self.points[1].components[1]) / 2.0;
342        RawPoint::new(x, y)
343    }
344}
345
346impl From<RawLine> for [Pos2; 2] {
347    fn from(val: RawLine) -> Self {
348        let position1 = val.points[0].into();
349        let position2 = val.points[1].into();
350        [position1, position2]
351    }
352}
353
354impl From<[[i64; 2]; 2]> for RawLine {
355    fn from(value: [[i64; 2]; 2]) -> Self {
356        Self {
357            points: [RawPoint::from(value[0]), RawPoint::from(value[1])],
358        }
359    }
360}
361
362#[derive(Clone)]
363pub struct MapStyle {
364    pub border: Option<Stroke>,
365    pub line: Option<Stroke>,
366    pub fill_color: Color32,
367    pub text_color: Color32,
368    pub font: Option<FontId>,
369    pub background_color: Color32,
370    pub alert_color: Color32,
371}
372
373impl MapStyle {
374    pub fn new() -> Self {
375        MapStyle {
376            border: None,
377            line: None,
378            fill_color: Color32::TRANSPARENT,
379            text_color: Color32::TRANSPARENT,
380            font: None,
381            background_color: Color32::TRANSPARENT,
382            alert_color: Color32::TRANSPARENT,
383        }
384    }
385}
386
387impl Default for MapStyle {
388    fn default() -> Self {
389        MapStyle::new()
390    }
391}
392
393impl Mul<i64> for MapStyle {
394    // The multiplication of rational numbers is a closed operation.
395    type Output = Self;
396
397    fn mul(mut self, rhs: i64) -> Self::Output {
398        self.border.unwrap().width *= rhs as f32;
399        self.line.unwrap().width *= rhs as f32;
400        self.font.as_mut().unwrap().size *= rhs as f32;
401        self
402    }
403}
404
405impl Mul<i32> for MapStyle {
406    // The multiplication of rational numbers is a closed operation.
407    type Output = Self;
408
409    fn mul(mut self, rhs: i32) -> Self::Output {
410        self.border.unwrap().width *= rhs as f32;
411        self.line.unwrap().width *= rhs as f32;
412        self.font.as_mut().unwrap().size *= rhs as f32;
413        self
414    }
415}
416
417impl Mul<f32> for MapStyle {
418    // The multiplication of rational numbers is a closed operation.
419    type Output = Self;
420
421    fn mul(mut self, rhs: f32) -> Self::Output {
422        self.border.unwrap().width *= rhs;
423        self.line.unwrap().width *= rhs;
424        self.font.as_mut().unwrap().size *= rhs;
425        self
426    }
427}
428
429impl Mul<f64> for MapStyle {
430    // The multiplication of rational numbers is a closed operation.
431    type Output = Self;
432
433    fn mul(mut self, rhs: f64) -> Self::Output {
434        self.border.unwrap().width *= rhs as f32;
435        self.line.unwrap().width *= rhs as f32;
436        self.font.as_mut().unwrap().size *= rhs as f32;
437        self
438    }
439}
440
441impl Div<i64> for MapStyle {
442    // The multiplication of rational numbers is a closed operation.
443    type Output = Self;
444
445    fn div(mut self, rhs: i64) -> Self::Output {
446        self.border.unwrap().width /= rhs as f32;
447        self.line.unwrap().width /= rhs as f32;
448        self.font.as_mut().unwrap().size /= rhs as f32;
449        self
450    }
451}
452
453impl Div<i32> for MapStyle {
454    // The multiplication of rational numbers is a closed operation.
455    type Output = Self;
456
457    fn div(mut self, rhs: i32) -> Self::Output {
458        self.border.unwrap().width /= rhs as f32;
459        self.line.unwrap().width /= rhs as f32;
460        self.font.as_mut().unwrap().size /= rhs as f32;
461        self
462    }
463}
464
465impl Div<f32> for MapStyle {
466    // The multiplication of rational numbers is a closed operation.
467    type Output = Self;
468
469    fn div(mut self, rhs: f32) -> Self::Output {
470        self.border.unwrap().width /= rhs;
471        self.line.unwrap().width /= rhs;
472        self.font.as_mut().unwrap().size /= rhs;
473        self
474    }
475}
476
477impl Div<f64> for MapStyle {
478    // The multiplication of rational numbers is a closed operation.
479    type Output = Self;
480
481    fn div(mut self, rhs: f64) -> Self::Output {
482        self.border.unwrap().width /= rhs as f32;
483        self.line.unwrap().width /= rhs as f32;
484        self.font.as_mut().unwrap().size /= rhs as f32;
485        self
486    }
487}
488
489#[derive(Clone)]
490pub struct MapLabel {
491    pub text: String,
492    pub center: Pos2,
493}
494
495impl Default for MapLabel {
496    fn default() -> Self {
497        MapLabel::new()
498    }
499}
500
501impl MapLabel {
502    pub fn new() -> Self {
503        MapLabel {
504            text: String::new(),
505            center: Pos2::new(0.00, 0.00),
506        }
507    }
508}
509
510#[derive(Clone)]
511pub struct MapLine {
512    pub id: Option<String>,
513    pub raw_line: RawLine,
514}
515
516impl MapLine {
517    pub fn new(point1: RawPoint, point2: RawPoint) -> Self {
518        MapLine {
519            id: None,
520            raw_line: RawLine::new(point1, point2),
521        }
522    }
523}
524
525// This can by any object or point with its associated metadata
526/// Struct that contains coordinates to help calculate nearest point in space
527#[derive(Clone)]
528pub struct MapPoint {
529    /// coordinates of the Solar System
530    pub raw_point: RawPoint,
531    /// coordinates for lines connecting this point
532    pub connections: Vec<String>,
533    /// Object Identifier for search propurses
534    id: usize,
535    /// SolarSystem Name
536    name: String,
537}
538
539impl MapPoint {
540    /// Creates a new Spatial point with an Id (solarSystemId) and the system's 3D coordinates
541    pub fn new(id: usize, coords: RawPoint) -> MapPoint {
542        MapPoint {
543            raw_point: coords,
544            id,
545            connections: Vec::new(),
546            name: String::new(),
547        }
548    }
549
550    pub fn get_id(&self) -> usize {
551        self.id
552    }
553
554    pub fn get_name(&self) -> String {
555        self.name.clone()
556    }
557
558    pub fn set_name(&mut self, value: String) {
559        self.name = value;
560    }
561}
562
563impl From<std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>> for MapPoint {
564    fn from(value: std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>) -> Self {
565        let k = value.get();
566        k.clone()
567    }
568}
569
570#[derive(Clone)]
571pub(crate) struct MapBounds {
572    pub min: RawPoint,
573    pub max: RawPoint,
574    pub pos: RawPoint,
575    pub dist: f32,
576}
577
578impl MapBounds {
579    pub fn new() -> Self {
580        MapBounds {
581            min: RawPoint::default(),
582            max: RawPoint::default(),
583            pos: RawPoint::default(),
584            dist: 0.0,
585        }
586    }
587}
588
589impl Default for MapBounds {
590    fn default() -> Self {
591        MapBounds::new()
592    }
593}
594
595pub(crate) struct TextSettings {
596    pub position: RawPoint,
597    pub anchor: Align2,
598    pub text: String,
599    pub size: f32,
600    pub family: FontFamily,
601    pub text_color: Color32,
602}
603
604#[derive(Clone)]
605pub struct MapSettings {
606    pub max_zoom: f32,
607    pub min_zoom: f32,
608    pub line_visible_zoom: f32,
609    pub label_visible_zoom: f32,
610    pub node_text_visibility: VisibilitySetting,
611    pub styles: Vec<MapStyle>,
612}
613
614impl MapSettings {
615    pub fn new() -> Self {
616        MapSettings {
617            max_zoom: 0.0,
618            min_zoom: 0.0,
619            line_visible_zoom: 0.0,
620            label_visible_zoom: 0.0,
621            node_text_visibility: VisibilitySetting::Allways,
622            styles: vec![MapStyle::new()],
623        }
624    }
625}
626
627impl Default for MapSettings {
628    fn default() -> Self {
629        let mut obj = MapSettings {
630            max_zoom: 2.0,
631            min_zoom: 0.1,
632            line_visible_zoom: 0.2,
633            label_visible_zoom: 0.58,
634            node_text_visibility: VisibilitySetting::Allways,
635            styles: Vec::new(),
636        };
637
638        // light Theme
639        obj.styles.push(MapStyle {
640            border: Some(egui::Stroke {
641                width: 2.0,
642                color: Color32::from_rgb(216, 142, 58),
643            }),
644            line: Some(egui::Stroke {
645                width: 2.0,
646                color: Color32::DARK_RED,
647            }),
648            fill_color: Color32::from_rgb(216, 142, 58),
649            text_color: Color32::DARK_GREEN,
650            font: Some(FontId::new(12.00, FontFamily::Proportional)),
651            background_color: Color32::WHITE,
652            alert_color: Color32::from_rgb(246, 30, 131),
653        });
654
655        // Dark Theme
656        obj.styles.push(MapStyle {
657            border: Some(egui::Stroke {
658                width: 2.0,
659                color: Color32::GOLD,
660            }),
661            line: Some(egui::Stroke {
662                width: 2.0,
663                color: Color32::LIGHT_RED,
664            }),
665            fill_color: Color32::GOLD,
666            text_color: Color32::LIGHT_GREEN,
667            font: Some(FontId::new(12.00, FontFamily::Proportional)),
668            background_color: Color32::DARK_GRAY,
669            alert_color: Color32::from_rgb(128, 12, 67),
670        });
671        obj
672    }
673}
674
675#[derive(Clone, PartialEq)]
676pub enum VisibilitySetting {
677    Hidden,
678    Hover,
679    Allways,
680}
681
682pub trait ContextMenuManager {
683    fn ui(&self, ui: &mut Ui);
684}
685
686pub trait NodeTemplate {
687    fn node_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32, _system: &MapPoint);
688    fn selection_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32);
689    fn notification_ui(
690        &self,
691        ui: &mut Ui,
692        _viewport_point: Pos2,
693        _zoom: f32,
694        initial_time: Instant,
695        color: Color32,
696    ) -> bool;
697    fn marker_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32);
698}