1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use super::CoordTranslate;
use crate::drawing::backend::{BackendCoord, DrawingBackend, DrawingErrorKind};
use crate::style::ShapeStyle;
use std::ops::Range;
pub trait Ranged {
type ValueType;
fn map(&self, value: &Self::ValueType, limit: (i32, i32)) -> i32;
fn key_points(&self, max_points: usize) -> Vec<Self::ValueType>;
fn range(&self) -> Range<Self::ValueType>;
}
pub struct RangedCoord<X: Ranged, Y: Ranged> {
logic_x: X,
logic_y: Y,
back_x: (i32, i32),
back_y: (i32, i32),
}
impl<X: Ranged, Y: Ranged> RangedCoord<X, Y> {
pub fn new<IntoX: Into<X>, IntoY: Into<Y>>(
logic_x: IntoX,
logic_y: IntoY,
actual: (Range<i32>, Range<i32>),
) -> Self {
return Self {
logic_x: logic_x.into(),
logic_y: logic_y.into(),
back_x: (actual.0.start, actual.0.end),
back_y: (actual.1.start, actual.1.end),
};
}
pub fn draw_mesh<E, DrawMesh: FnMut(MeshLine<X, Y>) -> Result<(), E>>(
&self,
h_limit: usize,
v_limit: usize,
mut draw_mesh: DrawMesh,
) -> Result<(), E> {
let (xkp, ykp) = (
self.logic_x.key_points(v_limit),
self.logic_y.key_points(h_limit),
);
for logic_x in xkp {
let x = self.logic_x.map(&logic_x, self.back_x);
draw_mesh(MeshLine::XMesh(
(x, self.back_y.0),
(x, self.back_y.1),
&logic_x,
))?;
}
for logic_y in ykp {
let y = self.logic_y.map(&logic_y, self.back_y);
draw_mesh(MeshLine::YMesh(
(self.back_x.0, y),
(self.back_x.1, y),
&logic_y,
))?;
}
return Ok(());
}
pub fn get_x_range(&self) -> Range<X::ValueType> {
return self.logic_x.range();
}
pub fn get_y_range(&self) -> Range<Y::ValueType> {
return self.logic_y.range();
}
}
impl<X: Ranged, Y: Ranged> CoordTranslate for RangedCoord<X, Y> {
type From = (X::ValueType, Y::ValueType);
fn translate(&self, from: &Self::From) -> BackendCoord {
return (
self.logic_x.map(&from.0, self.back_x),
self.logic_y.map(&from.1, self.back_y),
);
}
}
pub enum MeshLine<'a, X: Ranged, Y: Ranged> {
XMesh(BackendCoord, BackendCoord, &'a X::ValueType),
YMesh(BackendCoord, BackendCoord, &'a Y::ValueType),
}
impl<'a, X: Ranged, Y: Ranged> MeshLine<'a, X, Y> {
pub fn draw<DB: DrawingBackend>(
&self,
backend: &mut DB,
style: &ShapeStyle,
) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
let (&left, &right) = match self {
MeshLine::XMesh(a, b, _) => (a, b),
MeshLine::YMesh(a, b, _) => (a, b),
};
return backend.draw_line(left, right, &Box::new(style.color));
}
}
pub trait DescreteRanged
where
Self: Ranged,
Self::ValueType: Eq,
{
fn next_value(this: &Self::ValueType) -> Self::ValueType;
}