1use egui::{Align2, Color32, FontFamily, FontId, Pos2, Stroke, Ui};
9use std::convert::{From, Into};
10use std::ops::{Add, Div, DivAssign, Mul, MulAssign, Sub};
11use std::time::Instant;
12
13#[derive(Copy, Clone, Debug)]
32pub struct RawPoint {
33 pub components: [f32; 2],
35}
36
37impl RawPoint {
38 pub fn new(x: f32, y: f32) -> Self {
40 Self { components: [x, y] }
41 }
42}
43
44impl Default for RawPoint {
45 fn default() -> Self {
46 Self::new(0.00, 0.00)
47 }
48}
49
50impl Mul<i64> for RawPoint {
51 type Output = Self;
52
53 fn mul(self, rhs: i64) -> Self::Output {
54 Self {
55 components: [
56 self.components[0] * rhs as f32,
57 self.components[1] * rhs as f32,
58 ],
59 }
60 }
61}
62
63impl Mul<i32> for RawPoint {
64 type Output = Self;
65
66 fn mul(self, rhs: i32) -> Self::Output {
67 Self {
68 components: [
69 self.components[0] * rhs as f32,
70 self.components[1] * rhs as f32,
71 ],
72 }
73 }
74}
75
76impl Mul<u64> for RawPoint {
77 type Output = Self;
78
79 fn mul(self, rhs: u64) -> Self::Output {
80 Self {
81 components: [
82 self.components[0] * rhs as f32,
83 self.components[1] * rhs as f32,
84 ],
85 }
86 }
87}
88
89impl Mul<u32> for RawPoint {
90 type Output = Self;
91
92 fn mul(self, rhs: u32) -> Self::Output {
93 Self {
94 components: [
95 self.components[0] * rhs as f32,
96 self.components[1] * rhs as f32,
97 ],
98 }
99 }
100}
101
102impl Mul<f32> for RawPoint {
103 type Output = Self;
104
105 fn mul(self, rhs: f32) -> Self::Output {
106 Self {
107 components: [self.components[0] * rhs, self.components[1] * rhs],
108 }
109 }
110}
111
112impl MulAssign<i64> for RawPoint {
113 fn mul_assign(&mut self, rhs: i64) {
114 self.components[0] = self.components[0] * rhs as f32;
115 self.components[1] = self.components[1] * rhs as f32;
116 }
117}
118
119impl MulAssign<i32> for RawPoint {
120 fn mul_assign(&mut self, rhs: i32) {
121 self.components[0] = self.components[0] * rhs as f32;
122 self.components[1] = self.components[1] * rhs as f32;
123 }
124}
125
126impl MulAssign<u64> for RawPoint {
127 fn mul_assign(&mut self, rhs: u64) {
128 self.components[0] = self.components[0] * rhs as f32;
129 self.components[1] = self.components[1] * rhs as f32;
130 }
131}
132
133impl MulAssign<u32> for RawPoint {
134 fn mul_assign(&mut self, rhs: u32) {
135 self.components[0] = self.components[0] * rhs as f32;
136 self.components[1] = self.components[1] * rhs as f32;
137 }
138}
139
140impl MulAssign<f32> for RawPoint {
141 fn mul_assign(&mut self, rhs: f32) {
142 self.components[0] = self.components[0] * rhs;
143 self.components[1] = self.components[1] * rhs;
144 }
145}
146
147impl Div<i64> for RawPoint {
148 type Output = Self;
149
150 fn div(self, rhs: i64) -> Self::Output {
151 Self {
152 components: [
153 self.components[0] / rhs as f32,
154 self.components[1] / rhs as f32,
155 ],
156 }
157 }
158}
159
160impl Div<i32> for RawPoint {
161 type Output = Self;
162
163 fn div(self, rhs: i32) -> Self::Output {
164 Self {
165 components: [
166 self.components[0] / rhs as f32,
167 self.components[1] / rhs as f32,
168 ],
169 }
170 }
171}
172
173impl Div<u64> for RawPoint {
174 type Output = Self;
175
176 fn div(self, rhs: u64) -> Self::Output {
177 Self {
178 components: [
179 self.components[0] / rhs as f32,
180 self.components[1] / rhs as f32,
181 ],
182 }
183 }
184}
185
186impl Div<u32> for RawPoint {
187 type Output = Self;
188
189 fn div(self, rhs: u32) -> Self::Output {
190 Self {
191 components: [
192 self.components[0] / rhs as f32,
193 self.components[1] / rhs as f32,
194 ],
195 }
196 }
197}
198
199impl Div<f32> for RawPoint {
200 type Output = Self;
201
202 fn div(self, rhs: f32) -> Self::Output {
203 Self {
204 components: [self.components[0] / rhs, self.components[1] / rhs],
205 }
206 }
207}
208
209impl DivAssign<i64> for RawPoint {
210 fn div_assign(&mut self, rhs: i64) {
211 self.components[0] = self.components[0] / rhs as f32;
212 self.components[1] = self.components[1] / rhs as f32;
213 }
214}
215
216impl DivAssign<i32> for RawPoint {
217 fn div_assign(&mut self, rhs: i32) {
218 self.components[0] = self.components[0] / rhs as f32;
219 self.components[1] = self.components[1] / rhs as f32;
220 }
221}
222
223impl DivAssign<u64> for RawPoint {
224 fn div_assign(&mut self, rhs: u64) {
225 self.components[0] = self.components[0] / rhs as f32;
226 self.components[1] = self.components[1] / rhs as f32;
227 }
228}
229
230impl DivAssign<u32> for RawPoint {
231 fn div_assign(&mut self, rhs: u32) {
232 self.components[0] = self.components[0] / rhs as f32;
233 self.components[1] = self.components[1] / rhs as f32;
234 }
235}
236
237impl DivAssign<f32> for RawPoint {
238 fn div_assign(&mut self, rhs: f32) {
239 self.components[0] = self.components[0] / rhs;
240 self.components[1] = self.components[1] / rhs;
241 }
242}
243
244impl Add<RawPoint> for RawPoint {
245 type Output = RawPoint;
246 fn add(self, rhs: RawPoint) -> Self::Output {
247 Self {
248 components: [
249 self.components[0] + rhs.components[0],
250 self.components[1] + rhs.components[1],
251 ],
252 }
253 }
254}
255
256impl Sub<RawPoint> for RawPoint {
257 type Output = RawPoint;
258 fn sub(self, rhs: RawPoint) -> Self::Output {
259 Self {
260 components: [
261 self.components[0] - rhs.components[0],
262 self.components[1] - rhs.components[1],
263 ],
264 }
265 }
266}
267
268impl Add<&RawPoint> for RawPoint {
269 type Output = RawPoint;
270 fn add(self, rhs: &RawPoint) -> Self::Output {
271 Self {
272 components: [
273 self.components[0] + rhs.components[0],
274 self.components[1] + rhs.components[1],
275 ],
276 }
277 }
278}
279
280impl Sub<&RawPoint> for RawPoint {
281 type Output = RawPoint;
282 fn sub(self, rhs: &RawPoint) -> Self::Output {
283 Self {
284 components: [
285 self.components[0] - rhs.components[0],
286 self.components[1] - rhs.components[1],
287 ],
288 }
289 }
290}
291
292impl From<[f32; 2]> for RawPoint {
293 fn from(value: [f32; 2]) -> Self {
294 Self { components: value }
295 }
296}
297
298impl From<Pos2> for RawPoint {
299 fn from(value: Pos2) -> Self {
300 Self {
301 components: [value.x, value.y],
302 }
303 }
304}
305
306impl From<[i64; 2]> for RawPoint {
307 fn from(value: [i64; 2]) -> Self {
308 Self {
309 components: [value[0] as f32, value[1] as f32],
310 }
311 }
312}
313
314impl From<[i32; 2]> for RawPoint {
315 fn from(value: [i32; 2]) -> Self {
316 Self {
317 components: [value[0] as f32, value[1] as f32],
318 }
319 }
320}
321
322impl From<[i16; 2]> for RawPoint {
323 fn from(value: [i16; 2]) -> Self {
324 Self {
325 components: [value[0] as f32, value[1] as f32],
326 }
327 }
328}
329
330impl From<[i8; 2]> for RawPoint {
331 fn from(value: [i8; 2]) -> Self {
332 Self {
333 components: [value[0] as f32, value[1] as f32],
334 }
335 }
336}
337
338impl From<RawPoint> for [f32; 2] {
339 fn from(val: RawPoint) -> Self {
340 [val.components[0], val.components[1]]
341 }
342}
343
344impl From<RawPoint> for Pos2 {
345 fn from(val: RawPoint) -> Self {
346 Pos2::from(val.components)
347 }
348}
349
350#[derive(Copy, Clone, Debug)]
352pub struct RawLine {
353 pub points: [RawPoint; 2],
355}
356
357impl RawLine {
358 pub fn new(a: RawPoint, b: RawPoint) -> Self {
360 Self { points: [a, b] }
361 }
362
363 pub fn distance(self) -> f32 {
365 let x = self.points[0].components[0] - self.points[1].components[0];
366 let y = self.points[0].components[1] - self.points[1].components[1];
367 (x.powi(2) + y.powi(2)).sqrt()
368 }
369
370 pub fn midpoint(self) -> RawPoint {
372 let x = (self.points[0].components[0] + self.points[1].components[0]) / 2.0;
373 let y = (self.points[0].components[1] + self.points[1].components[1]) / 2.0;
374 RawPoint::new(x, y)
375 }
376}
377
378impl From<RawLine> for [Pos2; 2] {
379 fn from(val: RawLine) -> Self {
380 let position1 = val.points[0].into();
381 let position2 = val.points[1].into();
382 [position1, position2]
383 }
384}
385
386impl From<[[i64; 2]; 2]> for RawLine {
387 fn from(value: [[i64; 2]; 2]) -> Self {
388 Self {
389 points: [RawPoint::from(value[0]), RawPoint::from(value[1])],
390 }
391 }
392}
393
394#[derive(Clone, Debug)]
401pub struct MapStyle {
402 pub border: Option<Stroke>,
404 pub line: Option<Stroke>,
406 pub fill_color: Color32,
408 pub text_color: Color32,
410 pub font: Option<FontId>,
412 pub background_color: Color32,
414 pub alert_color: Color32,
416}
417
418impl MapStyle {
419 pub fn new() -> Self {
421 MapStyle {
422 border: None,
423 line: None,
424 fill_color: Color32::TRANSPARENT,
425 text_color: Color32::TRANSPARENT,
426 font: None,
427 background_color: Color32::TRANSPARENT,
428 alert_color: Color32::TRANSPARENT,
429 }
430 }
431}
432
433impl Default for MapStyle {
434 fn default() -> Self {
435 MapStyle::new()
436 }
437}
438
439impl MapStyle {
440 fn scaled(mut self, factor: f32) -> Self {
443 if let Some(border) = self.border.as_mut() {
444 border.width *= factor;
445 }
446 if let Some(line) = self.line.as_mut() {
447 line.width *= factor;
448 }
449 if let Some(font) = self.font.as_mut() {
450 font.size *= factor;
451 }
452 self
453 }
454}
455
456impl Mul<i64> for MapStyle {
457 type Output = Self;
458
459 fn mul(self, rhs: i64) -> Self::Output {
460 self.scaled(rhs as f32)
461 }
462}
463
464impl Mul<i32> for MapStyle {
465 type Output = Self;
466
467 fn mul(self, rhs: i32) -> Self::Output {
468 self.scaled(rhs as f32)
469 }
470}
471
472impl Mul<f32> for MapStyle {
473 type Output = Self;
474
475 fn mul(self, rhs: f32) -> Self::Output {
476 self.scaled(rhs)
477 }
478}
479
480impl Mul<f64> for MapStyle {
481 type Output = Self;
482
483 fn mul(self, rhs: f64) -> Self::Output {
484 self.scaled(rhs as f32)
485 }
486}
487
488impl Div<i64> for MapStyle {
489 type Output = Self;
490
491 fn div(self, rhs: i64) -> Self::Output {
492 self.scaled(1.0 / rhs as f32)
493 }
494}
495
496impl Div<i32> for MapStyle {
497 type Output = Self;
498
499 fn div(self, rhs: i32) -> Self::Output {
500 self.scaled(1.0 / rhs as f32)
501 }
502}
503
504impl Div<f32> for MapStyle {
505 type Output = Self;
506
507 fn div(self, rhs: f32) -> Self::Output {
508 self.scaled(1.0 / rhs)
509 }
510}
511
512impl Div<f64> for MapStyle {
513 type Output = Self;
514
515 fn div(self, rhs: f64) -> Self::Output {
516 self.scaled(1.0 / rhs as f32)
517 }
518}
519
520#[derive(Clone, Debug)]
524pub struct MapLabel {
525 pub text: String,
527 pub center: Pos2,
529}
530
531impl Default for MapLabel {
532 fn default() -> Self {
533 MapLabel::new()
534 }
535}
536
537impl MapLabel {
538 pub fn new() -> Self {
540 MapLabel {
541 text: String::new(),
542 center: Pos2::new(0.00, 0.00),
543 }
544 }
545}
546
547#[derive(Clone, Debug)]
552pub struct MapLine {
553 pub id: Option<String>,
555 pub raw_line: RawLine,
557}
558
559impl MapLine {
560 pub fn new(point1: RawPoint, point2: RawPoint) -> Self {
562 MapLine {
563 id: None,
564 raw_line: RawLine::new(point1, point2),
565 }
566 }
567}
568
569#[derive(Clone, Debug)]
575pub struct MapPoint {
576 pub raw_point: RawPoint,
578 pub connections: Vec<String>,
585 id: usize,
587 name: String,
589}
590
591impl MapPoint {
592 pub fn new(id: usize, coords: RawPoint) -> MapPoint {
594 MapPoint {
595 raw_point: coords,
596 id,
597 connections: Vec::new(),
598 name: String::new(),
599 }
600 }
601
602 pub fn get_id(&self) -> usize {
604 self.id
605 }
606
607 pub fn get_name(&self) -> String {
609 self.name.clone()
610 }
611
612 pub fn set_name(&mut self, value: String) {
614 self.name = value;
615 }
616}
617
618impl From<std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>> for MapPoint {
619 fn from(value: std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>) -> Self {
620 let k = value.get();
621 k.clone()
622 }
623}
624
625#[derive(Clone)]
626pub(crate) struct MapBounds {
627 pub min: RawPoint,
628 pub max: RawPoint,
629 pub pos: RawPoint,
630 pub dist: f32,
631}
632
633impl MapBounds {
634 pub fn new() -> Self {
635 MapBounds {
636 min: RawPoint::default(),
637 max: RawPoint::default(),
638 pos: RawPoint::default(),
639 dist: 0.0,
640 }
641 }
642}
643
644impl Default for MapBounds {
645 fn default() -> Self {
646 MapBounds::new()
647 }
648}
649
650pub(crate) struct TextSettings {
651 pub position: RawPoint,
652 pub anchor: Align2,
653 pub text: String,
654 pub size: f32,
655 pub family: FontFamily,
656 pub text_color: Color32,
657}
658
659#[derive(Clone, Debug)]
666pub struct MapSettings {
667 pub max_zoom: f32,
669 pub min_zoom: f32,
671 pub line_visible_zoom: f32,
673 pub label_visible_zoom: f32,
677 pub node_text_visibility: VisibilitySetting,
679 pub styles: Vec<MapStyle>,
682}
683
684impl MapSettings {
685 pub fn new() -> Self {
691 MapSettings {
692 max_zoom: 0.0,
693 min_zoom: 0.0,
694 line_visible_zoom: 0.0,
695 label_visible_zoom: 0.0,
696 node_text_visibility: VisibilitySetting::Always,
697 styles: vec![MapStyle::new()],
698 }
699 }
700}
701
702impl Default for MapSettings {
703 fn default() -> Self {
707 let mut obj = MapSettings {
708 max_zoom: 2.0,
709 min_zoom: 0.1,
710 line_visible_zoom: 0.2,
711 label_visible_zoom: 0.58,
712 node_text_visibility: VisibilitySetting::Always,
713 styles: Vec::new(),
714 };
715
716 obj.styles.push(MapStyle {
718 border: Some(egui::Stroke {
719 width: 2.0,
720 color: Color32::from_rgb(216, 142, 58),
721 }),
722 line: Some(egui::Stroke {
723 width: 2.0,
724 color: Color32::DARK_RED,
725 }),
726 fill_color: Color32::from_rgb(216, 142, 58),
727 text_color: Color32::DARK_GREEN,
728 font: Some(FontId::new(12.00, FontFamily::Proportional)),
729 background_color: Color32::WHITE,
730 alert_color: Color32::from_rgb(246, 30, 131),
731 });
732
733 obj.styles.push(MapStyle {
735 border: Some(egui::Stroke {
736 width: 2.0,
737 color: Color32::GOLD,
738 }),
739 line: Some(egui::Stroke {
740 width: 2.0,
741 color: Color32::LIGHT_RED,
742 }),
743 fill_color: Color32::GOLD,
744 text_color: Color32::LIGHT_GREEN,
745 font: Some(FontId::new(12.00, FontFamily::Proportional)),
746 background_color: Color32::DARK_GRAY,
747 alert_color: Color32::from_rgb(128, 12, 67),
748 });
749 obj
750 }
751}
752
753#[derive(Clone, Debug, PartialEq)]
755pub enum VisibilitySetting {
756 Hidden,
758 Hover,
760 Always,
762}
763
764pub trait ContextMenuManager {
783 fn ui(&self, ui: &mut Ui);
785}
786
787pub trait NodeTemplate {
883 fn node_ui(&self, ui: &mut Ui, _viewport_position: Pos2, _zoom: f32, _point: &MapPoint);
889
890 fn selection_ui(&self, ui: &mut Ui, _viewport_position: Pos2, _zoom: f32);
895
896 fn notification_ui(
904 &self,
905 ui: &mut Ui,
906 _viewport_position: Pos2,
907 _zoom: f32,
908 initial_time: Instant,
909 color: Color32,
910 ) -> bool;
911
912 fn marker_ui(&self, ui: &mut Ui, _viewport_position: Pos2, _zoom: f32);
919}
920
921#[cfg(test)]
922mod tests {
923 use super::*;
924 use std::collections::HashMap;
925
926 #[test]
929 fn raw_point_new() {
930 let p = RawPoint::new(3.5, -2.0);
931 assert_eq!(p.components, [3.5, -2.0]);
932 }
933
934 #[test]
935 fn raw_point_default() {
936 let p = RawPoint::default();
937 assert_eq!(p.components, [0.0, 0.0]);
938 }
939
940 #[test]
941 fn raw_point_mul_i64() {
942 let p = RawPoint::new(2.0, -3.0) * 3i64;
943 assert_eq!(p.components, [6.0, -9.0]);
944 }
945
946 #[test]
947 fn raw_point_mul_i32() {
948 let p = RawPoint::new(2.0, -3.0) * 3i32;
949 assert_eq!(p.components, [6.0, -9.0]);
950 }
951
952 #[test]
953 fn raw_point_mul_u64() {
954 let p = RawPoint::new(2.0, -3.0) * 3u64;
955 assert_eq!(p.components, [6.0, -9.0]);
956 }
957
958 #[test]
959 fn raw_point_mul_u32() {
960 let p = RawPoint::new(2.0, -3.0) * 3u32;
961 assert_eq!(p.components, [6.0, -9.0]);
962 }
963
964 #[test]
965 fn raw_point_mul_f32() {
966 let p = RawPoint::new(2.0, -3.0) * 0.5f32;
967 assert_eq!(p.components, [1.0, -1.5]);
968 }
969
970 #[test]
971 fn raw_point_mul_assign_i64() {
972 let mut p = RawPoint::new(2.0, -3.0);
973 p *= 3i64;
974 assert_eq!(p.components, [6.0, -9.0]);
975 }
976
977 #[test]
978 fn raw_point_mul_assign_i32() {
979 let mut p = RawPoint::new(2.0, -3.0);
980 p *= 3i32;
981 assert_eq!(p.components, [6.0, -9.0]);
982 }
983
984 #[test]
985 fn raw_point_mul_assign_u64() {
986 let mut p = RawPoint::new(2.0, -3.0);
987 p *= 3u64;
988 assert_eq!(p.components, [6.0, -9.0]);
989 }
990
991 #[test]
992 fn raw_point_mul_assign_u32() {
993 let mut p = RawPoint::new(2.0, -3.0);
994 p *= 3u32;
995 assert_eq!(p.components, [6.0, -9.0]);
996 }
997
998 #[test]
999 fn raw_point_mul_assign_f32() {
1000 let mut p = RawPoint::new(2.0, -3.0);
1001 p *= 0.5f32;
1002 assert_eq!(p.components, [1.0, -1.5]);
1003 }
1004
1005 #[test]
1006 fn raw_point_div_i64() {
1007 let p = RawPoint::new(6.0, -9.0) / 3i64;
1008 assert_eq!(p.components, [2.0, -3.0]);
1009 }
1010
1011 #[test]
1012 fn raw_point_div_i32() {
1013 let p = RawPoint::new(6.0, -9.0) / 3i32;
1014 assert_eq!(p.components, [2.0, -3.0]);
1015 }
1016
1017 #[test]
1018 fn raw_point_div_u64() {
1019 let p = RawPoint::new(6.0, -9.0) / 3u64;
1020 assert_eq!(p.components, [2.0, -3.0]);
1021 }
1022
1023 #[test]
1024 fn raw_point_div_u32() {
1025 let p = RawPoint::new(6.0, -9.0) / 3u32;
1026 assert_eq!(p.components, [2.0, -3.0]);
1027 }
1028
1029 #[test]
1030 fn raw_point_div_f32() {
1031 let p = RawPoint::new(1.0, -1.5) / 0.5f32;
1032 assert_eq!(p.components, [2.0, -3.0]);
1033 }
1034
1035 #[test]
1036 fn raw_point_div_assign_i64() {
1037 let mut p = RawPoint::new(6.0, -9.0);
1038 p /= 3i64;
1039 assert_eq!(p.components, [2.0, -3.0]);
1040 }
1041
1042 #[test]
1043 fn raw_point_div_assign_i32() {
1044 let mut p = RawPoint::new(6.0, -9.0);
1045 p /= 3i32;
1046 assert_eq!(p.components, [2.0, -3.0]);
1047 }
1048
1049 #[test]
1050 fn raw_point_div_assign_u64() {
1051 let mut p = RawPoint::new(6.0, -9.0);
1052 p /= 3u64;
1053 assert_eq!(p.components, [2.0, -3.0]);
1054 }
1055
1056 #[test]
1057 fn raw_point_div_assign_u32() {
1058 let mut p = RawPoint::new(6.0, -9.0);
1059 p /= 3u32;
1060 assert_eq!(p.components, [2.0, -3.0]);
1061 }
1062
1063 #[test]
1064 fn raw_point_div_assign_f32() {
1065 let mut p = RawPoint::new(1.0, -1.5);
1066 p /= 0.5f32;
1067 assert_eq!(p.components, [2.0, -3.0]);
1068 }
1069
1070 #[test]
1071 fn raw_point_add() {
1072 let a = RawPoint::new(1.0, 2.0);
1073 let b = RawPoint::new(3.0, -4.0);
1074 let c = a + b;
1075 assert_eq!(c.components, [4.0, -2.0]);
1076 }
1077
1078 #[test]
1079 fn raw_point_sub() {
1080 let a = RawPoint::new(1.0, 2.0);
1081 let b = RawPoint::new(3.0, -4.0);
1082 let c = a - b;
1083 assert_eq!(c.components, [-2.0, 6.0]);
1084 }
1085
1086 #[test]
1087 #[allow(clippy::op_ref)] fn raw_point_add_ref() {
1089 let a = RawPoint::new(1.0, 2.0);
1090 let b = RawPoint::new(3.0, -4.0);
1091 let c = a + &b;
1092 assert_eq!(c.components, [4.0, -2.0]);
1093 assert_eq!(b.components, [3.0, -4.0]);
1095 }
1096
1097 #[test]
1098 #[allow(clippy::op_ref)] fn raw_point_sub_ref() {
1100 let a = RawPoint::new(1.0, 2.0);
1101 let b = RawPoint::new(3.0, -4.0);
1102 let c = a - &b;
1103 assert_eq!(c.components, [-2.0, 6.0]);
1104 assert_eq!(b.components, [3.0, -4.0]);
1105 }
1106
1107 #[test]
1108 fn raw_point_from_f32_array() {
1109 let p = RawPoint::from([1.5f32, -2.5f32]);
1110 assert_eq!(p.components, [1.5, -2.5]);
1111 }
1112
1113 #[test]
1114 fn raw_point_from_i64_array() {
1115 let p = RawPoint::from([3i64, -4i64]);
1116 assert_eq!(p.components, [3.0, -4.0]);
1117 }
1118
1119 #[test]
1120 fn raw_point_from_i32_array() {
1121 let p = RawPoint::from([3i32, -4i32]);
1122 assert_eq!(p.components, [3.0, -4.0]);
1123 }
1124
1125 #[test]
1126 fn raw_point_from_i16_array() {
1127 let p = RawPoint::from([3i16, -4i16]);
1128 assert_eq!(p.components, [3.0, -4.0]);
1129 }
1130
1131 #[test]
1132 fn raw_point_from_i8_array() {
1133 let p = RawPoint::from([3i8, -4i8]);
1134 assert_eq!(p.components, [3.0, -4.0]);
1135 }
1136
1137 #[test]
1138 fn raw_point_from_pos2() {
1139 let p = RawPoint::from(Pos2::new(7.0, 8.0));
1140 assert_eq!(p.components, [7.0, 8.0]);
1141 }
1142
1143 #[test]
1144 fn raw_point_into_f32_array() {
1145 let arr: [f32; 2] = RawPoint::new(7.0, 8.0).into();
1146 assert_eq!(arr, [7.0, 8.0]);
1147 }
1148
1149 #[test]
1150 fn raw_point_into_pos2() {
1151 let pos: Pos2 = RawPoint::new(7.0, 8.0).into();
1152 assert_eq!(pos, Pos2::new(7.0, 8.0));
1153 }
1154
1155 #[test]
1158 fn raw_line_new() {
1159 let a = RawPoint::new(1.0, 2.0);
1160 let b = RawPoint::new(3.0, 4.0);
1161 let line = RawLine::new(a, b);
1162 assert_eq!(line.points[0].components, [1.0, 2.0]);
1163 assert_eq!(line.points[1].components, [3.0, 4.0]);
1164 }
1165
1166 #[test]
1167 fn raw_line_distance() {
1168 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(3.0, 4.0));
1170 assert_eq!(line.distance(), 5.0);
1171 }
1172
1173 #[test]
1174 fn raw_line_distance_zero() {
1175 let line = RawLine::new(RawPoint::new(2.0, 2.0), RawPoint::new(2.0, 2.0));
1176 assert_eq!(line.distance(), 0.0);
1177 }
1178
1179 #[test]
1180 fn raw_line_midpoint() {
1181 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(4.0, 6.0));
1182 let mid = line.midpoint();
1183 assert_eq!(mid.components, [2.0, 3.0]);
1184 }
1185
1186 #[test]
1187 fn raw_line_into_pos2_array() {
1188 let line = RawLine::new(RawPoint::new(1.0, 2.0), RawPoint::new(3.0, 4.0));
1189 let arr: [Pos2; 2] = line.into();
1190 assert_eq!(arr, [Pos2::new(1.0, 2.0), Pos2::new(3.0, 4.0)]);
1191 }
1192
1193 #[test]
1194 fn raw_line_from_i64_arrays() {
1195 let line = RawLine::from([[1i64, 2i64], [3i64, 4i64]]);
1196 assert_eq!(line.points[0].components, [1.0, 2.0]);
1197 assert_eq!(line.points[1].components, [3.0, 4.0]);
1198 }
1199
1200 fn full_style() -> MapStyle {
1203 MapStyle {
1204 border: Some(Stroke::new(2.0, Color32::RED)),
1205 line: Some(Stroke::new(4.0, Color32::BLUE)),
1206 fill_color: Color32::GREEN,
1207 text_color: Color32::WHITE,
1208 font: Some(FontId::new(10.0, FontFamily::Proportional)),
1209 background_color: Color32::BLACK,
1210 alert_color: Color32::YELLOW,
1211 }
1212 }
1213
1214 #[test]
1215 fn map_style_new() {
1216 let s = MapStyle::new();
1217 assert!(s.border.is_none());
1218 assert!(s.line.is_none());
1219 assert!(s.font.is_none());
1220 assert_eq!(s.fill_color, Color32::TRANSPARENT);
1221 assert_eq!(s.text_color, Color32::TRANSPARENT);
1222 assert_eq!(s.background_color, Color32::TRANSPARENT);
1223 assert_eq!(s.alert_color, Color32::TRANSPARENT);
1224 }
1225
1226 #[test]
1227 fn map_style_default_equals_new() {
1228 let s = MapStyle::default();
1229 assert!(s.border.is_none());
1230 assert!(s.line.is_none());
1231 assert!(s.font.is_none());
1232 }
1233
1234 #[test]
1235 fn map_style_mul_i64() {
1236 let s = full_style() * 2i64;
1237 assert_eq!(s.border.unwrap().width, 4.0);
1238 assert_eq!(s.line.unwrap().width, 8.0);
1239 assert_eq!(s.font.unwrap().size, 20.0);
1240 }
1241
1242 #[test]
1243 fn map_style_mul_i32() {
1244 let s = full_style() * 2i32;
1245 assert_eq!(s.border.unwrap().width, 4.0);
1246 assert_eq!(s.line.unwrap().width, 8.0);
1247 assert_eq!(s.font.unwrap().size, 20.0);
1248 }
1249
1250 #[test]
1251 fn map_style_mul_f32() {
1252 let s = full_style() * 0.5f32;
1253 assert_eq!(s.border.unwrap().width, 1.0);
1254 assert_eq!(s.line.unwrap().width, 2.0);
1255 assert_eq!(s.font.unwrap().size, 5.0);
1256 }
1257
1258 #[test]
1259 fn map_style_mul_f64() {
1260 let s = full_style() * 0.5f64;
1261 assert_eq!(s.border.unwrap().width, 1.0);
1262 assert_eq!(s.line.unwrap().width, 2.0);
1263 assert_eq!(s.font.unwrap().size, 5.0);
1264 }
1265
1266 #[test]
1267 fn map_style_div_i64() {
1268 let s = full_style() / 2i64;
1269 assert_eq!(s.border.unwrap().width, 1.0);
1270 assert_eq!(s.line.unwrap().width, 2.0);
1271 assert_eq!(s.font.unwrap().size, 5.0);
1272 }
1273
1274 #[test]
1275 fn map_style_div_i32() {
1276 let s = full_style() / 2i32;
1277 assert_eq!(s.border.unwrap().width, 1.0);
1278 assert_eq!(s.line.unwrap().width, 2.0);
1279 assert_eq!(s.font.unwrap().size, 5.0);
1280 }
1281
1282 #[test]
1283 fn map_style_div_f32() {
1284 let s = full_style() / 0.5f32;
1285 assert_eq!(s.border.unwrap().width, 4.0);
1286 assert_eq!(s.line.unwrap().width, 8.0);
1287 assert_eq!(s.font.unwrap().size, 20.0);
1288 }
1289
1290 #[test]
1291 fn map_style_div_f64() {
1292 let s = full_style() / 0.5f64;
1293 assert_eq!(s.border.unwrap().width, 4.0);
1294 assert_eq!(s.line.unwrap().width, 8.0);
1295 assert_eq!(s.font.unwrap().size, 20.0);
1296 }
1297
1298 #[test]
1301 fn map_label_new() {
1302 let l = MapLabel::new();
1303 assert_eq!(l.text, String::new());
1304 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1305 }
1306
1307 #[test]
1308 fn map_label_default_equals_new() {
1309 let l = MapLabel::default();
1310 assert_eq!(l.text, String::new());
1311 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1312 }
1313
1314 #[test]
1317 fn map_line_new() {
1318 let a = RawPoint::new(1.0, 2.0);
1319 let b = RawPoint::new(3.0, 4.0);
1320 let line = MapLine::new(a, b);
1321 assert!(line.id.is_none());
1322 assert_eq!(line.raw_line.points[0].components, [1.0, 2.0]);
1323 assert_eq!(line.raw_line.points[1].components, [3.0, 4.0]);
1324 }
1325
1326 #[test]
1329 fn map_point_new() {
1330 let p = MapPoint::new(42, RawPoint::new(1.0, 2.0));
1331 assert_eq!(p.get_id(), 42);
1332 assert_eq!(p.raw_point.components, [1.0, 2.0]);
1333 assert!(p.connections.is_empty());
1334 assert_eq!(p.get_name(), String::new());
1335 }
1336
1337 #[test]
1338 fn map_point_set_and_get_name() {
1339 let mut p = MapPoint::new(1, RawPoint::default());
1340 p.set_name("Jita".to_string());
1341 assert_eq!(p.get_name(), "Jita");
1342 }
1343
1344 #[test]
1345 fn map_point_from_occupied_entry() {
1346 let mut map: HashMap<usize, MapPoint> = HashMap::new();
1347 let mut original = MapPoint::new(7, RawPoint::new(5.0, 6.0));
1348 original.set_name("Amarr".to_string());
1349 map.insert(7, original);
1350
1351 use std::collections::hash_map::Entry;
1352 if let Entry::Occupied(entry) = map.entry(7) {
1353 let cloned = MapPoint::from(entry);
1354 assert_eq!(cloned.get_id(), 7);
1355 assert_eq!(cloned.get_name(), "Amarr");
1356 assert_eq!(cloned.raw_point.components, [5.0, 6.0]);
1357 } else {
1358 panic!("se esperaba una entrada ocupada");
1359 }
1360 }
1361
1362 #[test]
1365 fn map_bounds_new() {
1366 let b = MapBounds::new();
1367 assert_eq!(b.min.components, [0.0, 0.0]);
1368 assert_eq!(b.max.components, [0.0, 0.0]);
1369 assert_eq!(b.pos.components, [0.0, 0.0]);
1370 assert_eq!(b.dist, 0.0);
1371 }
1372
1373 #[test]
1374 fn map_bounds_default_equals_new() {
1375 let b = MapBounds::default();
1376 assert_eq!(b.dist, 0.0);
1377 assert_eq!(b.pos.components, [0.0, 0.0]);
1378 }
1379
1380 #[test]
1383 fn map_settings_new() {
1384 let s = MapSettings::new();
1385 assert_eq!(s.max_zoom, 0.0);
1386 assert_eq!(s.min_zoom, 0.0);
1387 assert_eq!(s.line_visible_zoom, 0.0);
1388 assert_eq!(s.label_visible_zoom, 0.0);
1389 assert_eq!(s.node_text_visibility, VisibilitySetting::Always);
1390 assert_eq!(s.styles.len(), 1);
1391 }
1392
1393 #[test]
1394 fn map_settings_default() {
1395 let s = MapSettings::default();
1396 assert_eq!(s.max_zoom, 2.0);
1397 assert_eq!(s.min_zoom, 0.1);
1398 assert_eq!(s.line_visible_zoom, 0.2);
1399 assert_eq!(s.label_visible_zoom, 0.58);
1400 assert_eq!(s.node_text_visibility, VisibilitySetting::Always);
1401 assert_eq!(s.styles.len(), 2);
1403 assert_eq!(s.styles[0].background_color, Color32::WHITE);
1405 assert!(s.styles[0].border.is_some());
1406 assert!(s.styles[0].line.is_some());
1407 assert!(s.styles[0].font.is_some());
1408 assert_eq!(s.styles[1].background_color, Color32::DARK_GRAY);
1410 assert!(s.styles[1].border.is_some());
1411 assert!(s.styles[1].line.is_some());
1412 assert!(s.styles[1].font.is_some());
1413 }
1414
1415 #[test]
1418 fn visibility_setting_equality() {
1419 assert_eq!(VisibilitySetting::Hidden, VisibilitySetting::Hidden);
1420 assert_eq!(VisibilitySetting::Hover, VisibilitySetting::Hover);
1421 assert_eq!(VisibilitySetting::Always, VisibilitySetting::Always);
1422 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Hover);
1423 assert_ne!(VisibilitySetting::Hover, VisibilitySetting::Always);
1424 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Always);
1425 }
1426}