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, Debug)]
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, Debug)]
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, Debug)]
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 type Output = Self;
396
397 fn mul(mut self, rhs: i64) -> Self::Output {
398 self.border.as_mut().unwrap().width *= rhs as f32;
399 self.line.as_mut().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 type Output = Self;
408
409 fn mul(mut self, rhs: i32) -> Self::Output {
410 self.border.as_mut().unwrap().width *= rhs as f32;
411 self.line.as_mut().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 type Output = Self;
420
421 fn mul(mut self, rhs: f32) -> Self::Output {
422 self.border.as_mut().unwrap().width *= rhs;
423 self.line.as_mut().unwrap().width *= rhs;
424 self.font.as_mut().unwrap().size *= rhs;
425 self
426 }
427}
428
429impl Mul<f64> for MapStyle {
430 type Output = Self;
432
433 fn mul(mut self, rhs: f64) -> Self::Output {
434 self.border.as_mut().unwrap().width *= rhs as f32;
435 self.line.as_mut().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 type Output = Self;
444
445 fn div(mut self, rhs: i64) -> Self::Output {
446 self.border.as_mut().unwrap().width /= rhs as f32;
447 self.line.as_mut().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 type Output = Self;
456
457 fn div(mut self, rhs: i32) -> Self::Output {
458 self.border.as_mut().unwrap().width /= rhs as f32;
459 self.line.as_mut().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 type Output = Self;
468
469 fn div(mut self, rhs: f32) -> Self::Output {
470 self.border.as_mut().unwrap().width /= rhs;
471 self.line.as_mut().unwrap().width /= rhs;
472 self.font.as_mut().unwrap().size /= rhs;
473 self
474 }
475}
476
477impl Div<f64> for MapStyle {
478 type Output = Self;
480
481 fn div(mut self, rhs: f64) -> Self::Output {
482 self.border.as_mut().unwrap().width /= rhs as f32;
483 self.line.as_mut().unwrap().width /= rhs as f32;
484 self.font.as_mut().unwrap().size /= rhs as f32;
485 self
486 }
487}
488
489#[derive(Clone, Debug)]
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, Debug)]
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#[derive(Clone, Debug)]
528pub struct MapPoint {
529 pub raw_point: RawPoint,
531 pub connections: Vec<String>,
533 id: usize,
535 name: String,
537}
538
539impl MapPoint {
540 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, Debug)]
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 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 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, Debug, 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}
699
700#[cfg(test)]
701mod tests {
702 use super::*;
703 use std::collections::HashMap;
704
705 #[test]
708 fn raw_point_new() {
709 let p = RawPoint::new(3.5, -2.0);
710 assert_eq!(p.components, [3.5, -2.0]);
711 }
712
713 #[test]
714 fn raw_point_default() {
715 let p = RawPoint::default();
716 assert_eq!(p.components, [0.0, 0.0]);
717 }
718
719 #[test]
720 fn raw_point_mul_i64() {
721 let p = RawPoint::new(2.0, -3.0) * 3i64;
722 assert_eq!(p.components, [6.0, -9.0]);
723 }
724
725 #[test]
726 fn raw_point_mul_i32() {
727 let p = RawPoint::new(2.0, -3.0) * 3i32;
728 assert_eq!(p.components, [6.0, -9.0]);
729 }
730
731 #[test]
732 fn raw_point_mul_u64() {
733 let p = RawPoint::new(2.0, -3.0) * 3u64;
734 assert_eq!(p.components, [6.0, -9.0]);
735 }
736
737 #[test]
738 fn raw_point_mul_u32() {
739 let p = RawPoint::new(2.0, -3.0) * 3u32;
740 assert_eq!(p.components, [6.0, -9.0]);
741 }
742
743 #[test]
744 fn raw_point_mul_f32() {
745 let p = RawPoint::new(2.0, -3.0) * 0.5f32;
746 assert_eq!(p.components, [1.0, -1.5]);
747 }
748
749 #[test]
750 fn raw_point_mul_assign_i64() {
751 let mut p = RawPoint::new(2.0, -3.0);
752 p *= 3i64;
753 assert_eq!(p.components, [6.0, -9.0]);
754 }
755
756 #[test]
757 fn raw_point_mul_assign_i32() {
758 let mut p = RawPoint::new(2.0, -3.0);
759 p *= 3i32;
760 assert_eq!(p.components, [6.0, -9.0]);
761 }
762
763 #[test]
764 fn raw_point_mul_assign_u64() {
765 let mut p = RawPoint::new(2.0, -3.0);
766 p *= 3u64;
767 assert_eq!(p.components, [6.0, -9.0]);
768 }
769
770 #[test]
771 fn raw_point_mul_assign_u32() {
772 let mut p = RawPoint::new(2.0, -3.0);
773 p *= 3u32;
774 assert_eq!(p.components, [6.0, -9.0]);
775 }
776
777 #[test]
778 fn raw_point_mul_assign_f32() {
779 let mut p = RawPoint::new(2.0, -3.0);
780 p *= 0.5f32;
781 assert_eq!(p.components, [1.0, -1.5]);
782 }
783
784 #[test]
785 fn raw_point_div_i64() {
786 let p = RawPoint::new(6.0, -9.0) / 3i64;
787 assert_eq!(p.components, [2.0, -3.0]);
788 }
789
790 #[test]
791 fn raw_point_div_i32() {
792 let p = RawPoint::new(6.0, -9.0) / 3i32;
793 assert_eq!(p.components, [2.0, -3.0]);
794 }
795
796 #[test]
797 fn raw_point_div_u64() {
798 let p = RawPoint::new(6.0, -9.0) / 3u64;
799 assert_eq!(p.components, [2.0, -3.0]);
800 }
801
802 #[test]
803 fn raw_point_div_u32() {
804 let p = RawPoint::new(6.0, -9.0) / 3u32;
805 assert_eq!(p.components, [2.0, -3.0]);
806 }
807
808 #[test]
809 fn raw_point_div_f32() {
810 let p = RawPoint::new(1.0, -1.5) / 0.5f32;
811 assert_eq!(p.components, [2.0, -3.0]);
812 }
813
814 #[test]
815 fn raw_point_div_assign_i64() {
816 let mut p = RawPoint::new(6.0, -9.0);
817 p /= 3i64;
818 assert_eq!(p.components, [2.0, -3.0]);
819 }
820
821 #[test]
822 fn raw_point_div_assign_i32() {
823 let mut p = RawPoint::new(6.0, -9.0);
824 p /= 3i32;
825 assert_eq!(p.components, [2.0, -3.0]);
826 }
827
828 #[test]
829 fn raw_point_div_assign_u64() {
830 let mut p = RawPoint::new(6.0, -9.0);
831 p /= 3u64;
832 assert_eq!(p.components, [2.0, -3.0]);
833 }
834
835 #[test]
836 fn raw_point_div_assign_u32() {
837 let mut p = RawPoint::new(6.0, -9.0);
838 p /= 3u32;
839 assert_eq!(p.components, [2.0, -3.0]);
840 }
841
842 #[test]
843 fn raw_point_div_assign_f32() {
844 let mut p = RawPoint::new(1.0, -1.5);
845 p /= 0.5f32;
846 assert_eq!(p.components, [2.0, -3.0]);
847 }
848
849 #[test]
850 fn raw_point_add() {
851 let a = RawPoint::new(1.0, 2.0);
852 let b = RawPoint::new(3.0, -4.0);
853 let c = a + b;
854 assert_eq!(c.components, [4.0, -2.0]);
855 }
856
857 #[test]
858 fn raw_point_sub() {
859 let a = RawPoint::new(1.0, 2.0);
860 let b = RawPoint::new(3.0, -4.0);
861 let c = a - b;
862 assert_eq!(c.components, [-2.0, 6.0]);
863 }
864
865 #[test]
866 fn raw_point_add_ref() {
867 let a = RawPoint::new(1.0, 2.0);
868 let b = RawPoint::new(3.0, -4.0);
869 let c = a + &b;
870 assert_eq!(c.components, [4.0, -2.0]);
871 assert_eq!(b.components, [3.0, -4.0]);
873 }
874
875 #[test]
876 fn raw_point_sub_ref() {
877 let a = RawPoint::new(1.0, 2.0);
878 let b = RawPoint::new(3.0, -4.0);
879 let c = a - &b;
880 assert_eq!(c.components, [-2.0, 6.0]);
881 assert_eq!(b.components, [3.0, -4.0]);
882 }
883
884 #[test]
885 fn raw_point_from_f32_array() {
886 let p = RawPoint::from([1.5f32, -2.5f32]);
887 assert_eq!(p.components, [1.5, -2.5]);
888 }
889
890 #[test]
891 fn raw_point_from_i64_array() {
892 let p = RawPoint::from([3i64, -4i64]);
893 assert_eq!(p.components, [3.0, -4.0]);
894 }
895
896 #[test]
897 fn raw_point_from_i32_array() {
898 let p = RawPoint::from([3i32, -4i32]);
899 assert_eq!(p.components, [3.0, -4.0]);
900 }
901
902 #[test]
903 fn raw_point_from_i16_array() {
904 let p = RawPoint::from([3i16, -4i16]);
905 assert_eq!(p.components, [3.0, -4.0]);
906 }
907
908 #[test]
909 fn raw_point_from_i8_array() {
910 let p = RawPoint::from([3i8, -4i8]);
911 assert_eq!(p.components, [3.0, -4.0]);
912 }
913
914 #[test]
915 fn raw_point_from_pos2() {
916 let p = RawPoint::from(Pos2::new(7.0, 8.0));
917 assert_eq!(p.components, [7.0, 8.0]);
918 }
919
920 #[test]
921 fn raw_point_into_f32_array() {
922 let arr: [f32; 2] = RawPoint::new(7.0, 8.0).into();
923 assert_eq!(arr, [7.0, 8.0]);
924 }
925
926 #[test]
927 fn raw_point_into_pos2() {
928 let pos: Pos2 = RawPoint::new(7.0, 8.0).into();
929 assert_eq!(pos, Pos2::new(7.0, 8.0));
930 }
931
932 #[test]
935 fn raw_line_new() {
936 let a = RawPoint::new(1.0, 2.0);
937 let b = RawPoint::new(3.0, 4.0);
938 let line = RawLine::new(a, b);
939 assert_eq!(line.points[0].components, [1.0, 2.0]);
940 assert_eq!(line.points[1].components, [3.0, 4.0]);
941 }
942
943 #[test]
944 fn raw_line_distance() {
945 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(3.0, 4.0));
947 assert_eq!(line.distance(), 5.0);
948 }
949
950 #[test]
951 fn raw_line_distance_zero() {
952 let line = RawLine::new(RawPoint::new(2.0, 2.0), RawPoint::new(2.0, 2.0));
953 assert_eq!(line.distance(), 0.0);
954 }
955
956 #[test]
957 fn raw_line_midpoint() {
958 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(4.0, 6.0));
959 let mid = line.midpoint();
960 assert_eq!(mid.components, [2.0, 3.0]);
961 }
962
963 #[test]
964 fn raw_line_into_pos2_array() {
965 let line = RawLine::new(RawPoint::new(1.0, 2.0), RawPoint::new(3.0, 4.0));
966 let arr: [Pos2; 2] = line.into();
967 assert_eq!(arr, [Pos2::new(1.0, 2.0), Pos2::new(3.0, 4.0)]);
968 }
969
970 #[test]
971 fn raw_line_from_i64_arrays() {
972 let line = RawLine::from([[1i64, 2i64], [3i64, 4i64]]);
973 assert_eq!(line.points[0].components, [1.0, 2.0]);
974 assert_eq!(line.points[1].components, [3.0, 4.0]);
975 }
976
977 fn full_style() -> MapStyle {
980 MapStyle {
981 border: Some(Stroke::new(2.0, Color32::RED)),
982 line: Some(Stroke::new(4.0, Color32::BLUE)),
983 fill_color: Color32::GREEN,
984 text_color: Color32::WHITE,
985 font: Some(FontId::new(10.0, FontFamily::Proportional)),
986 background_color: Color32::BLACK,
987 alert_color: Color32::YELLOW,
988 }
989 }
990
991 #[test]
992 fn map_style_new() {
993 let s = MapStyle::new();
994 assert!(s.border.is_none());
995 assert!(s.line.is_none());
996 assert!(s.font.is_none());
997 assert_eq!(s.fill_color, Color32::TRANSPARENT);
998 assert_eq!(s.text_color, Color32::TRANSPARENT);
999 assert_eq!(s.background_color, Color32::TRANSPARENT);
1000 assert_eq!(s.alert_color, Color32::TRANSPARENT);
1001 }
1002
1003 #[test]
1004 fn map_style_default_equals_new() {
1005 let s = MapStyle::default();
1006 assert!(s.border.is_none());
1007 assert!(s.line.is_none());
1008 assert!(s.font.is_none());
1009 }
1010
1011 #[test]
1012 fn map_style_mul_i64() {
1013 let s = full_style() * 2i64;
1014 assert_eq!(s.border.unwrap().width, 4.0);
1015 assert_eq!(s.line.unwrap().width, 8.0);
1016 assert_eq!(s.font.unwrap().size, 20.0);
1017 }
1018
1019 #[test]
1020 fn map_style_mul_i32() {
1021 let s = full_style() * 2i32;
1022 assert_eq!(s.border.unwrap().width, 4.0);
1023 assert_eq!(s.line.unwrap().width, 8.0);
1024 assert_eq!(s.font.unwrap().size, 20.0);
1025 }
1026
1027 #[test]
1028 fn map_style_mul_f32() {
1029 let s = full_style() * 0.5f32;
1030 assert_eq!(s.border.unwrap().width, 1.0);
1031 assert_eq!(s.line.unwrap().width, 2.0);
1032 assert_eq!(s.font.unwrap().size, 5.0);
1033 }
1034
1035 #[test]
1036 fn map_style_mul_f64() {
1037 let s = full_style() * 0.5f64;
1038 assert_eq!(s.border.unwrap().width, 1.0);
1039 assert_eq!(s.line.unwrap().width, 2.0);
1040 assert_eq!(s.font.unwrap().size, 5.0);
1041 }
1042
1043 #[test]
1044 fn map_style_div_i64() {
1045 let s = full_style() / 2i64;
1046 assert_eq!(s.border.unwrap().width, 1.0);
1047 assert_eq!(s.line.unwrap().width, 2.0);
1048 assert_eq!(s.font.unwrap().size, 5.0);
1049 }
1050
1051 #[test]
1052 fn map_style_div_i32() {
1053 let s = full_style() / 2i32;
1054 assert_eq!(s.border.unwrap().width, 1.0);
1055 assert_eq!(s.line.unwrap().width, 2.0);
1056 assert_eq!(s.font.unwrap().size, 5.0);
1057 }
1058
1059 #[test]
1060 fn map_style_div_f32() {
1061 let s = full_style() / 0.5f32;
1062 assert_eq!(s.border.unwrap().width, 4.0);
1063 assert_eq!(s.line.unwrap().width, 8.0);
1064 assert_eq!(s.font.unwrap().size, 20.0);
1065 }
1066
1067 #[test]
1068 fn map_style_div_f64() {
1069 let s = full_style() / 0.5f64;
1070 assert_eq!(s.border.unwrap().width, 4.0);
1071 assert_eq!(s.line.unwrap().width, 8.0);
1072 assert_eq!(s.font.unwrap().size, 20.0);
1073 }
1074
1075 #[test]
1078 fn map_label_new() {
1079 let l = MapLabel::new();
1080 assert_eq!(l.text, String::new());
1081 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1082 }
1083
1084 #[test]
1085 fn map_label_default_equals_new() {
1086 let l = MapLabel::default();
1087 assert_eq!(l.text, String::new());
1088 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1089 }
1090
1091 #[test]
1094 fn map_line_new() {
1095 let a = RawPoint::new(1.0, 2.0);
1096 let b = RawPoint::new(3.0, 4.0);
1097 let line = MapLine::new(a, b);
1098 assert!(line.id.is_none());
1099 assert_eq!(line.raw_line.points[0].components, [1.0, 2.0]);
1100 assert_eq!(line.raw_line.points[1].components, [3.0, 4.0]);
1101 }
1102
1103 #[test]
1106 fn map_point_new() {
1107 let p = MapPoint::new(42, RawPoint::new(1.0, 2.0));
1108 assert_eq!(p.get_id(), 42);
1109 assert_eq!(p.raw_point.components, [1.0, 2.0]);
1110 assert!(p.connections.is_empty());
1111 assert_eq!(p.get_name(), String::new());
1112 }
1113
1114 #[test]
1115 fn map_point_set_and_get_name() {
1116 let mut p = MapPoint::new(1, RawPoint::default());
1117 p.set_name("Jita".to_string());
1118 assert_eq!(p.get_name(), "Jita");
1119 }
1120
1121 #[test]
1122 fn map_point_from_occupied_entry() {
1123 let mut map: HashMap<usize, MapPoint> = HashMap::new();
1124 let mut original = MapPoint::new(7, RawPoint::new(5.0, 6.0));
1125 original.set_name("Amarr".to_string());
1126 map.insert(7, original);
1127
1128 use std::collections::hash_map::Entry;
1129 if let Entry::Occupied(entry) = map.entry(7) {
1130 let cloned = MapPoint::from(entry);
1131 assert_eq!(cloned.get_id(), 7);
1132 assert_eq!(cloned.get_name(), "Amarr");
1133 assert_eq!(cloned.raw_point.components, [5.0, 6.0]);
1134 } else {
1135 panic!("se esperaba una entrada ocupada");
1136 }
1137 }
1138
1139 #[test]
1142 fn map_bounds_new() {
1143 let b = MapBounds::new();
1144 assert_eq!(b.min.components, [0.0, 0.0]);
1145 assert_eq!(b.max.components, [0.0, 0.0]);
1146 assert_eq!(b.pos.components, [0.0, 0.0]);
1147 assert_eq!(b.dist, 0.0);
1148 }
1149
1150 #[test]
1151 fn map_bounds_default_equals_new() {
1152 let b = MapBounds::default();
1153 assert_eq!(b.dist, 0.0);
1154 assert_eq!(b.pos.components, [0.0, 0.0]);
1155 }
1156
1157 #[test]
1160 fn map_settings_new() {
1161 let s = MapSettings::new();
1162 assert_eq!(s.max_zoom, 0.0);
1163 assert_eq!(s.min_zoom, 0.0);
1164 assert_eq!(s.line_visible_zoom, 0.0);
1165 assert_eq!(s.label_visible_zoom, 0.0);
1166 assert_eq!(s.node_text_visibility, VisibilitySetting::Allways);
1167 assert_eq!(s.styles.len(), 1);
1168 }
1169
1170 #[test]
1171 fn map_settings_default() {
1172 let s = MapSettings::default();
1173 assert_eq!(s.max_zoom, 2.0);
1174 assert_eq!(s.min_zoom, 0.1);
1175 assert_eq!(s.line_visible_zoom, 0.2);
1176 assert_eq!(s.label_visible_zoom, 0.58);
1177 assert_eq!(s.node_text_visibility, VisibilitySetting::Allways);
1178 assert_eq!(s.styles.len(), 2);
1180 assert_eq!(s.styles[0].background_color, Color32::WHITE);
1182 assert!(s.styles[0].border.is_some());
1183 assert!(s.styles[0].line.is_some());
1184 assert!(s.styles[0].font.is_some());
1185 assert_eq!(s.styles[1].background_color, Color32::DARK_GRAY);
1187 assert!(s.styles[1].border.is_some());
1188 assert!(s.styles[1].line.is_some());
1189 assert!(s.styles[1].font.is_some());
1190 }
1191
1192 #[test]
1195 fn visibility_setting_equality() {
1196 assert_eq!(VisibilitySetting::Hidden, VisibilitySetting::Hidden);
1197 assert_eq!(VisibilitySetting::Hover, VisibilitySetting::Hover);
1198 assert_eq!(VisibilitySetting::Allways, VisibilitySetting::Allways);
1199 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Hover);
1200 assert_ne!(VisibilitySetting::Hover, VisibilitySetting::Allways);
1201 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Allways);
1202 }
1203}