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)]
402pub struct MapStyle {
403 pub border: Option<Stroke>,
405 pub line: Option<Stroke>,
407 pub fill_color: Color32,
409 pub text_color: Color32,
411 pub font: Option<FontId>,
413 pub background_color: Color32,
415 pub alert_color: Color32,
417}
418
419impl MapStyle {
420 pub fn new() -> Self {
422 MapStyle {
423 border: None,
424 line: None,
425 fill_color: Color32::TRANSPARENT,
426 text_color: Color32::TRANSPARENT,
427 font: None,
428 background_color: Color32::TRANSPARENT,
429 alert_color: Color32::TRANSPARENT,
430 }
431 }
432}
433
434impl Default for MapStyle {
435 fn default() -> Self {
436 MapStyle::new()
437 }
438}
439
440impl Mul<i64> for MapStyle {
441 type Output = Self;
443
444 fn mul(mut self, rhs: i64) -> Self::Output {
445 self.border.as_mut().unwrap().width *= rhs as f32;
446 self.line.as_mut().unwrap().width *= rhs as f32;
447 self.font.as_mut().unwrap().size *= rhs as f32;
448 self
449 }
450}
451
452impl Mul<i32> for MapStyle {
453 type Output = Self;
455
456 fn mul(mut self, rhs: i32) -> Self::Output {
457 self.border.as_mut().unwrap().width *= rhs as f32;
458 self.line.as_mut().unwrap().width *= rhs as f32;
459 self.font.as_mut().unwrap().size *= rhs as f32;
460 self
461 }
462}
463
464impl Mul<f32> for MapStyle {
465 type Output = Self;
467
468 fn mul(mut self, rhs: f32) -> Self::Output {
469 self.border.as_mut().unwrap().width *= rhs;
470 self.line.as_mut().unwrap().width *= rhs;
471 self.font.as_mut().unwrap().size *= rhs;
472 self
473 }
474}
475
476impl Mul<f64> for MapStyle {
477 type Output = Self;
479
480 fn mul(mut self, rhs: f64) -> Self::Output {
481 self.border.as_mut().unwrap().width *= rhs as f32;
482 self.line.as_mut().unwrap().width *= rhs as f32;
483 self.font.as_mut().unwrap().size *= rhs as f32;
484 self
485 }
486}
487
488impl Div<i64> for MapStyle {
489 type Output = Self;
491
492 fn div(mut self, rhs: i64) -> Self::Output {
493 self.border.as_mut().unwrap().width /= rhs as f32;
494 self.line.as_mut().unwrap().width /= rhs as f32;
495 self.font.as_mut().unwrap().size /= rhs as f32;
496 self
497 }
498}
499
500impl Div<i32> for MapStyle {
501 type Output = Self;
503
504 fn div(mut self, rhs: i32) -> Self::Output {
505 self.border.as_mut().unwrap().width /= rhs as f32;
506 self.line.as_mut().unwrap().width /= rhs as f32;
507 self.font.as_mut().unwrap().size /= rhs as f32;
508 self
509 }
510}
511
512impl Div<f32> for MapStyle {
513 type Output = Self;
515
516 fn div(mut self, rhs: f32) -> Self::Output {
517 self.border.as_mut().unwrap().width /= rhs;
518 self.line.as_mut().unwrap().width /= rhs;
519 self.font.as_mut().unwrap().size /= rhs;
520 self
521 }
522}
523
524impl Div<f64> for MapStyle {
525 type Output = Self;
527
528 fn div(mut self, rhs: f64) -> Self::Output {
529 self.border.as_mut().unwrap().width /= rhs as f32;
530 self.line.as_mut().unwrap().width /= rhs as f32;
531 self.font.as_mut().unwrap().size /= rhs as f32;
532 self
533 }
534}
535
536#[derive(Clone, Debug)]
540pub struct MapLabel {
541 pub text: String,
543 pub center: Pos2,
545}
546
547impl Default for MapLabel {
548 fn default() -> Self {
549 MapLabel::new()
550 }
551}
552
553impl MapLabel {
554 pub fn new() -> Self {
556 MapLabel {
557 text: String::new(),
558 center: Pos2::new(0.00, 0.00),
559 }
560 }
561}
562
563#[derive(Clone, Debug)]
568pub struct MapLine {
569 pub id: Option<String>,
571 pub raw_line: RawLine,
573}
574
575impl MapLine {
576 pub fn new(point1: RawPoint, point2: RawPoint) -> Self {
578 MapLine {
579 id: None,
580 raw_line: RawLine::new(point1, point2),
581 }
582 }
583}
584
585#[derive(Clone, Debug)]
591pub struct MapPoint {
592 pub raw_point: RawPoint,
594 pub connections: Vec<String>,
601 id: usize,
603 name: String,
605}
606
607impl MapPoint {
608 pub fn new(id: usize, coords: RawPoint) -> MapPoint {
610 MapPoint {
611 raw_point: coords,
612 id,
613 connections: Vec::new(),
614 name: String::new(),
615 }
616 }
617
618 pub fn get_id(&self) -> usize {
620 self.id
621 }
622
623 pub fn get_name(&self) -> String {
625 self.name.clone()
626 }
627
628 pub fn set_name(&mut self, value: String) {
630 self.name = value;
631 }
632}
633
634impl From<std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>> for MapPoint {
635 fn from(value: std::collections::hash_map::OccupiedEntry<'_, usize, MapPoint>) -> Self {
636 let k = value.get();
637 k.clone()
638 }
639}
640
641#[derive(Clone)]
642pub(crate) struct MapBounds {
643 pub min: RawPoint,
644 pub max: RawPoint,
645 pub pos: RawPoint,
646 pub dist: f32,
647}
648
649impl MapBounds {
650 pub fn new() -> Self {
651 MapBounds {
652 min: RawPoint::default(),
653 max: RawPoint::default(),
654 pos: RawPoint::default(),
655 dist: 0.0,
656 }
657 }
658}
659
660impl Default for MapBounds {
661 fn default() -> Self {
662 MapBounds::new()
663 }
664}
665
666pub(crate) struct TextSettings {
667 pub position: RawPoint,
668 pub anchor: Align2,
669 pub text: String,
670 pub size: f32,
671 pub family: FontFamily,
672 pub text_color: Color32,
673}
674
675#[derive(Clone, Debug)]
682pub struct MapSettings {
683 pub max_zoom: f32,
685 pub min_zoom: f32,
687 pub line_visible_zoom: f32,
689 pub label_visible_zoom: f32,
693 pub node_text_visibility: VisibilitySetting,
695 pub styles: Vec<MapStyle>,
698}
699
700impl MapSettings {
701 pub fn new() -> Self {
707 MapSettings {
708 max_zoom: 0.0,
709 min_zoom: 0.0,
710 line_visible_zoom: 0.0,
711 label_visible_zoom: 0.0,
712 node_text_visibility: VisibilitySetting::Allways,
713 styles: vec![MapStyle::new()],
714 }
715 }
716}
717
718impl Default for MapSettings {
719 fn default() -> Self {
723 let mut obj = MapSettings {
724 max_zoom: 2.0,
725 min_zoom: 0.1,
726 line_visible_zoom: 0.2,
727 label_visible_zoom: 0.58,
728 node_text_visibility: VisibilitySetting::Allways,
729 styles: Vec::new(),
730 };
731
732 obj.styles.push(MapStyle {
734 border: Some(egui::Stroke {
735 width: 2.0,
736 color: Color32::from_rgb(216, 142, 58),
737 }),
738 line: Some(egui::Stroke {
739 width: 2.0,
740 color: Color32::DARK_RED,
741 }),
742 fill_color: Color32::from_rgb(216, 142, 58),
743 text_color: Color32::DARK_GREEN,
744 font: Some(FontId::new(12.00, FontFamily::Proportional)),
745 background_color: Color32::WHITE,
746 alert_color: Color32::from_rgb(246, 30, 131),
747 });
748
749 obj.styles.push(MapStyle {
751 border: Some(egui::Stroke {
752 width: 2.0,
753 color: Color32::GOLD,
754 }),
755 line: Some(egui::Stroke {
756 width: 2.0,
757 color: Color32::LIGHT_RED,
758 }),
759 fill_color: Color32::GOLD,
760 text_color: Color32::LIGHT_GREEN,
761 font: Some(FontId::new(12.00, FontFamily::Proportional)),
762 background_color: Color32::DARK_GRAY,
763 alert_color: Color32::from_rgb(128, 12, 67),
764 });
765 obj
766 }
767}
768
769#[derive(Clone, Debug, PartialEq)]
771pub enum VisibilitySetting {
772 Hidden,
774 Hover,
776 Allways,
778}
779
780pub trait ContextMenuManager {
799 fn ui(&self, ui: &mut Ui);
801}
802
803pub trait NodeTemplate {
899 fn node_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32, _system: &MapPoint);
905
906 fn selection_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32);
911
912 fn notification_ui(
920 &self,
921 ui: &mut Ui,
922 _viewport_point: Pos2,
923 _zoom: f32,
924 initial_time: Instant,
925 color: Color32,
926 ) -> bool;
927
928 fn marker_ui(&self, ui: &mut Ui, _viewport_point: Pos2, _zoom: f32);
935}
936
937#[cfg(test)]
938mod tests {
939 use super::*;
940 use std::collections::HashMap;
941
942 #[test]
945 fn raw_point_new() {
946 let p = RawPoint::new(3.5, -2.0);
947 assert_eq!(p.components, [3.5, -2.0]);
948 }
949
950 #[test]
951 fn raw_point_default() {
952 let p = RawPoint::default();
953 assert_eq!(p.components, [0.0, 0.0]);
954 }
955
956 #[test]
957 fn raw_point_mul_i64() {
958 let p = RawPoint::new(2.0, -3.0) * 3i64;
959 assert_eq!(p.components, [6.0, -9.0]);
960 }
961
962 #[test]
963 fn raw_point_mul_i32() {
964 let p = RawPoint::new(2.0, -3.0) * 3i32;
965 assert_eq!(p.components, [6.0, -9.0]);
966 }
967
968 #[test]
969 fn raw_point_mul_u64() {
970 let p = RawPoint::new(2.0, -3.0) * 3u64;
971 assert_eq!(p.components, [6.0, -9.0]);
972 }
973
974 #[test]
975 fn raw_point_mul_u32() {
976 let p = RawPoint::new(2.0, -3.0) * 3u32;
977 assert_eq!(p.components, [6.0, -9.0]);
978 }
979
980 #[test]
981 fn raw_point_mul_f32() {
982 let p = RawPoint::new(2.0, -3.0) * 0.5f32;
983 assert_eq!(p.components, [1.0, -1.5]);
984 }
985
986 #[test]
987 fn raw_point_mul_assign_i64() {
988 let mut p = RawPoint::new(2.0, -3.0);
989 p *= 3i64;
990 assert_eq!(p.components, [6.0, -9.0]);
991 }
992
993 #[test]
994 fn raw_point_mul_assign_i32() {
995 let mut p = RawPoint::new(2.0, -3.0);
996 p *= 3i32;
997 assert_eq!(p.components, [6.0, -9.0]);
998 }
999
1000 #[test]
1001 fn raw_point_mul_assign_u64() {
1002 let mut p = RawPoint::new(2.0, -3.0);
1003 p *= 3u64;
1004 assert_eq!(p.components, [6.0, -9.0]);
1005 }
1006
1007 #[test]
1008 fn raw_point_mul_assign_u32() {
1009 let mut p = RawPoint::new(2.0, -3.0);
1010 p *= 3u32;
1011 assert_eq!(p.components, [6.0, -9.0]);
1012 }
1013
1014 #[test]
1015 fn raw_point_mul_assign_f32() {
1016 let mut p = RawPoint::new(2.0, -3.0);
1017 p *= 0.5f32;
1018 assert_eq!(p.components, [1.0, -1.5]);
1019 }
1020
1021 #[test]
1022 fn raw_point_div_i64() {
1023 let p = RawPoint::new(6.0, -9.0) / 3i64;
1024 assert_eq!(p.components, [2.0, -3.0]);
1025 }
1026
1027 #[test]
1028 fn raw_point_div_i32() {
1029 let p = RawPoint::new(6.0, -9.0) / 3i32;
1030 assert_eq!(p.components, [2.0, -3.0]);
1031 }
1032
1033 #[test]
1034 fn raw_point_div_u64() {
1035 let p = RawPoint::new(6.0, -9.0) / 3u64;
1036 assert_eq!(p.components, [2.0, -3.0]);
1037 }
1038
1039 #[test]
1040 fn raw_point_div_u32() {
1041 let p = RawPoint::new(6.0, -9.0) / 3u32;
1042 assert_eq!(p.components, [2.0, -3.0]);
1043 }
1044
1045 #[test]
1046 fn raw_point_div_f32() {
1047 let p = RawPoint::new(1.0, -1.5) / 0.5f32;
1048 assert_eq!(p.components, [2.0, -3.0]);
1049 }
1050
1051 #[test]
1052 fn raw_point_div_assign_i64() {
1053 let mut p = RawPoint::new(6.0, -9.0);
1054 p /= 3i64;
1055 assert_eq!(p.components, [2.0, -3.0]);
1056 }
1057
1058 #[test]
1059 fn raw_point_div_assign_i32() {
1060 let mut p = RawPoint::new(6.0, -9.0);
1061 p /= 3i32;
1062 assert_eq!(p.components, [2.0, -3.0]);
1063 }
1064
1065 #[test]
1066 fn raw_point_div_assign_u64() {
1067 let mut p = RawPoint::new(6.0, -9.0);
1068 p /= 3u64;
1069 assert_eq!(p.components, [2.0, -3.0]);
1070 }
1071
1072 #[test]
1073 fn raw_point_div_assign_u32() {
1074 let mut p = RawPoint::new(6.0, -9.0);
1075 p /= 3u32;
1076 assert_eq!(p.components, [2.0, -3.0]);
1077 }
1078
1079 #[test]
1080 fn raw_point_div_assign_f32() {
1081 let mut p = RawPoint::new(1.0, -1.5);
1082 p /= 0.5f32;
1083 assert_eq!(p.components, [2.0, -3.0]);
1084 }
1085
1086 #[test]
1087 fn raw_point_add() {
1088 let a = RawPoint::new(1.0, 2.0);
1089 let b = RawPoint::new(3.0, -4.0);
1090 let c = a + b;
1091 assert_eq!(c.components, [4.0, -2.0]);
1092 }
1093
1094 #[test]
1095 fn raw_point_sub() {
1096 let a = RawPoint::new(1.0, 2.0);
1097 let b = RawPoint::new(3.0, -4.0);
1098 let c = a - b;
1099 assert_eq!(c.components, [-2.0, 6.0]);
1100 }
1101
1102 #[test]
1103 fn raw_point_add_ref() {
1104 let a = RawPoint::new(1.0, 2.0);
1105 let b = RawPoint::new(3.0, -4.0);
1106 let c = a + &b;
1107 assert_eq!(c.components, [4.0, -2.0]);
1108 assert_eq!(b.components, [3.0, -4.0]);
1110 }
1111
1112 #[test]
1113 fn raw_point_sub_ref() {
1114 let a = RawPoint::new(1.0, 2.0);
1115 let b = RawPoint::new(3.0, -4.0);
1116 let c = a - &b;
1117 assert_eq!(c.components, [-2.0, 6.0]);
1118 assert_eq!(b.components, [3.0, -4.0]);
1119 }
1120
1121 #[test]
1122 fn raw_point_from_f32_array() {
1123 let p = RawPoint::from([1.5f32, -2.5f32]);
1124 assert_eq!(p.components, [1.5, -2.5]);
1125 }
1126
1127 #[test]
1128 fn raw_point_from_i64_array() {
1129 let p = RawPoint::from([3i64, -4i64]);
1130 assert_eq!(p.components, [3.0, -4.0]);
1131 }
1132
1133 #[test]
1134 fn raw_point_from_i32_array() {
1135 let p = RawPoint::from([3i32, -4i32]);
1136 assert_eq!(p.components, [3.0, -4.0]);
1137 }
1138
1139 #[test]
1140 fn raw_point_from_i16_array() {
1141 let p = RawPoint::from([3i16, -4i16]);
1142 assert_eq!(p.components, [3.0, -4.0]);
1143 }
1144
1145 #[test]
1146 fn raw_point_from_i8_array() {
1147 let p = RawPoint::from([3i8, -4i8]);
1148 assert_eq!(p.components, [3.0, -4.0]);
1149 }
1150
1151 #[test]
1152 fn raw_point_from_pos2() {
1153 let p = RawPoint::from(Pos2::new(7.0, 8.0));
1154 assert_eq!(p.components, [7.0, 8.0]);
1155 }
1156
1157 #[test]
1158 fn raw_point_into_f32_array() {
1159 let arr: [f32; 2] = RawPoint::new(7.0, 8.0).into();
1160 assert_eq!(arr, [7.0, 8.0]);
1161 }
1162
1163 #[test]
1164 fn raw_point_into_pos2() {
1165 let pos: Pos2 = RawPoint::new(7.0, 8.0).into();
1166 assert_eq!(pos, Pos2::new(7.0, 8.0));
1167 }
1168
1169 #[test]
1172 fn raw_line_new() {
1173 let a = RawPoint::new(1.0, 2.0);
1174 let b = RawPoint::new(3.0, 4.0);
1175 let line = RawLine::new(a, b);
1176 assert_eq!(line.points[0].components, [1.0, 2.0]);
1177 assert_eq!(line.points[1].components, [3.0, 4.0]);
1178 }
1179
1180 #[test]
1181 fn raw_line_distance() {
1182 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(3.0, 4.0));
1184 assert_eq!(line.distance(), 5.0);
1185 }
1186
1187 #[test]
1188 fn raw_line_distance_zero() {
1189 let line = RawLine::new(RawPoint::new(2.0, 2.0), RawPoint::new(2.0, 2.0));
1190 assert_eq!(line.distance(), 0.0);
1191 }
1192
1193 #[test]
1194 fn raw_line_midpoint() {
1195 let line = RawLine::new(RawPoint::new(0.0, 0.0), RawPoint::new(4.0, 6.0));
1196 let mid = line.midpoint();
1197 assert_eq!(mid.components, [2.0, 3.0]);
1198 }
1199
1200 #[test]
1201 fn raw_line_into_pos2_array() {
1202 let line = RawLine::new(RawPoint::new(1.0, 2.0), RawPoint::new(3.0, 4.0));
1203 let arr: [Pos2; 2] = line.into();
1204 assert_eq!(arr, [Pos2::new(1.0, 2.0), Pos2::new(3.0, 4.0)]);
1205 }
1206
1207 #[test]
1208 fn raw_line_from_i64_arrays() {
1209 let line = RawLine::from([[1i64, 2i64], [3i64, 4i64]]);
1210 assert_eq!(line.points[0].components, [1.0, 2.0]);
1211 assert_eq!(line.points[1].components, [3.0, 4.0]);
1212 }
1213
1214 fn full_style() -> MapStyle {
1217 MapStyle {
1218 border: Some(Stroke::new(2.0, Color32::RED)),
1219 line: Some(Stroke::new(4.0, Color32::BLUE)),
1220 fill_color: Color32::GREEN,
1221 text_color: Color32::WHITE,
1222 font: Some(FontId::new(10.0, FontFamily::Proportional)),
1223 background_color: Color32::BLACK,
1224 alert_color: Color32::YELLOW,
1225 }
1226 }
1227
1228 #[test]
1229 fn map_style_new() {
1230 let s = MapStyle::new();
1231 assert!(s.border.is_none());
1232 assert!(s.line.is_none());
1233 assert!(s.font.is_none());
1234 assert_eq!(s.fill_color, Color32::TRANSPARENT);
1235 assert_eq!(s.text_color, Color32::TRANSPARENT);
1236 assert_eq!(s.background_color, Color32::TRANSPARENT);
1237 assert_eq!(s.alert_color, Color32::TRANSPARENT);
1238 }
1239
1240 #[test]
1241 fn map_style_default_equals_new() {
1242 let s = MapStyle::default();
1243 assert!(s.border.is_none());
1244 assert!(s.line.is_none());
1245 assert!(s.font.is_none());
1246 }
1247
1248 #[test]
1249 fn map_style_mul_i64() {
1250 let s = full_style() * 2i64;
1251 assert_eq!(s.border.unwrap().width, 4.0);
1252 assert_eq!(s.line.unwrap().width, 8.0);
1253 assert_eq!(s.font.unwrap().size, 20.0);
1254 }
1255
1256 #[test]
1257 fn map_style_mul_i32() {
1258 let s = full_style() * 2i32;
1259 assert_eq!(s.border.unwrap().width, 4.0);
1260 assert_eq!(s.line.unwrap().width, 8.0);
1261 assert_eq!(s.font.unwrap().size, 20.0);
1262 }
1263
1264 #[test]
1265 fn map_style_mul_f32() {
1266 let s = full_style() * 0.5f32;
1267 assert_eq!(s.border.unwrap().width, 1.0);
1268 assert_eq!(s.line.unwrap().width, 2.0);
1269 assert_eq!(s.font.unwrap().size, 5.0);
1270 }
1271
1272 #[test]
1273 fn map_style_mul_f64() {
1274 let s = full_style() * 0.5f64;
1275 assert_eq!(s.border.unwrap().width, 1.0);
1276 assert_eq!(s.line.unwrap().width, 2.0);
1277 assert_eq!(s.font.unwrap().size, 5.0);
1278 }
1279
1280 #[test]
1281 fn map_style_div_i64() {
1282 let s = full_style() / 2i64;
1283 assert_eq!(s.border.unwrap().width, 1.0);
1284 assert_eq!(s.line.unwrap().width, 2.0);
1285 assert_eq!(s.font.unwrap().size, 5.0);
1286 }
1287
1288 #[test]
1289 fn map_style_div_i32() {
1290 let s = full_style() / 2i32;
1291 assert_eq!(s.border.unwrap().width, 1.0);
1292 assert_eq!(s.line.unwrap().width, 2.0);
1293 assert_eq!(s.font.unwrap().size, 5.0);
1294 }
1295
1296 #[test]
1297 fn map_style_div_f32() {
1298 let s = full_style() / 0.5f32;
1299 assert_eq!(s.border.unwrap().width, 4.0);
1300 assert_eq!(s.line.unwrap().width, 8.0);
1301 assert_eq!(s.font.unwrap().size, 20.0);
1302 }
1303
1304 #[test]
1305 fn map_style_div_f64() {
1306 let s = full_style() / 0.5f64;
1307 assert_eq!(s.border.unwrap().width, 4.0);
1308 assert_eq!(s.line.unwrap().width, 8.0);
1309 assert_eq!(s.font.unwrap().size, 20.0);
1310 }
1311
1312 #[test]
1315 fn map_label_new() {
1316 let l = MapLabel::new();
1317 assert_eq!(l.text, String::new());
1318 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1319 }
1320
1321 #[test]
1322 fn map_label_default_equals_new() {
1323 let l = MapLabel::default();
1324 assert_eq!(l.text, String::new());
1325 assert_eq!(l.center, Pos2::new(0.0, 0.0));
1326 }
1327
1328 #[test]
1331 fn map_line_new() {
1332 let a = RawPoint::new(1.0, 2.0);
1333 let b = RawPoint::new(3.0, 4.0);
1334 let line = MapLine::new(a, b);
1335 assert!(line.id.is_none());
1336 assert_eq!(line.raw_line.points[0].components, [1.0, 2.0]);
1337 assert_eq!(line.raw_line.points[1].components, [3.0, 4.0]);
1338 }
1339
1340 #[test]
1343 fn map_point_new() {
1344 let p = MapPoint::new(42, RawPoint::new(1.0, 2.0));
1345 assert_eq!(p.get_id(), 42);
1346 assert_eq!(p.raw_point.components, [1.0, 2.0]);
1347 assert!(p.connections.is_empty());
1348 assert_eq!(p.get_name(), String::new());
1349 }
1350
1351 #[test]
1352 fn map_point_set_and_get_name() {
1353 let mut p = MapPoint::new(1, RawPoint::default());
1354 p.set_name("Jita".to_string());
1355 assert_eq!(p.get_name(), "Jita");
1356 }
1357
1358 #[test]
1359 fn map_point_from_occupied_entry() {
1360 let mut map: HashMap<usize, MapPoint> = HashMap::new();
1361 let mut original = MapPoint::new(7, RawPoint::new(5.0, 6.0));
1362 original.set_name("Amarr".to_string());
1363 map.insert(7, original);
1364
1365 use std::collections::hash_map::Entry;
1366 if let Entry::Occupied(entry) = map.entry(7) {
1367 let cloned = MapPoint::from(entry);
1368 assert_eq!(cloned.get_id(), 7);
1369 assert_eq!(cloned.get_name(), "Amarr");
1370 assert_eq!(cloned.raw_point.components, [5.0, 6.0]);
1371 } else {
1372 panic!("se esperaba una entrada ocupada");
1373 }
1374 }
1375
1376 #[test]
1379 fn map_bounds_new() {
1380 let b = MapBounds::new();
1381 assert_eq!(b.min.components, [0.0, 0.0]);
1382 assert_eq!(b.max.components, [0.0, 0.0]);
1383 assert_eq!(b.pos.components, [0.0, 0.0]);
1384 assert_eq!(b.dist, 0.0);
1385 }
1386
1387 #[test]
1388 fn map_bounds_default_equals_new() {
1389 let b = MapBounds::default();
1390 assert_eq!(b.dist, 0.0);
1391 assert_eq!(b.pos.components, [0.0, 0.0]);
1392 }
1393
1394 #[test]
1397 fn map_settings_new() {
1398 let s = MapSettings::new();
1399 assert_eq!(s.max_zoom, 0.0);
1400 assert_eq!(s.min_zoom, 0.0);
1401 assert_eq!(s.line_visible_zoom, 0.0);
1402 assert_eq!(s.label_visible_zoom, 0.0);
1403 assert_eq!(s.node_text_visibility, VisibilitySetting::Allways);
1404 assert_eq!(s.styles.len(), 1);
1405 }
1406
1407 #[test]
1408 fn map_settings_default() {
1409 let s = MapSettings::default();
1410 assert_eq!(s.max_zoom, 2.0);
1411 assert_eq!(s.min_zoom, 0.1);
1412 assert_eq!(s.line_visible_zoom, 0.2);
1413 assert_eq!(s.label_visible_zoom, 0.58);
1414 assert_eq!(s.node_text_visibility, VisibilitySetting::Allways);
1415 assert_eq!(s.styles.len(), 2);
1417 assert_eq!(s.styles[0].background_color, Color32::WHITE);
1419 assert!(s.styles[0].border.is_some());
1420 assert!(s.styles[0].line.is_some());
1421 assert!(s.styles[0].font.is_some());
1422 assert_eq!(s.styles[1].background_color, Color32::DARK_GRAY);
1424 assert!(s.styles[1].border.is_some());
1425 assert!(s.styles[1].line.is_some());
1426 assert!(s.styles[1].font.is_some());
1427 }
1428
1429 #[test]
1432 fn visibility_setting_equality() {
1433 assert_eq!(VisibilitySetting::Hidden, VisibilitySetting::Hidden);
1434 assert_eq!(VisibilitySetting::Hover, VisibilitySetting::Hover);
1435 assert_eq!(VisibilitySetting::Allways, VisibilitySetting::Allways);
1436 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Hover);
1437 assert_ne!(VisibilitySetting::Hover, VisibilitySetting::Allways);
1438 assert_ne!(VisibilitySetting::Hidden, VisibilitySetting::Allways);
1439 }
1440}