-
Notifications
You must be signed in to change notification settings - Fork 104
Expand file tree
/
Copy pathlinear.rs
More file actions
124 lines (105 loc) · 3.44 KB
/
Copy pathlinear.rs
File metadata and controls
124 lines (105 loc) · 3.44 KB
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
use crate::GridInput;
use crate::axis::transform::AxisSpace;
use emath::{Rangef, remap};
use std::ops::RangeInclusive;
#[derive(Debug, Copy, Clone)]
pub struct LinearAxisSpace {
min: f64,
max: f64,
invert: bool,
frame_start: f32,
frame_end: f32,
}
impl LinearAxisSpace {
pub fn new(value_range: RangeInclusive<f64>, frame_range: Rangef, invert: bool) -> Self {
Self {
min: *value_range.start(),
max: *value_range.end(),
frame_start: frame_range.min,
frame_end: frame_range.max,
invert,
}
}
fn clamp_to_finite(&mut self) {
self.min = self.min.clamp(f64::MIN, f64::MAX);
if self.min.is_nan() {
self.min = 0.0;
}
self.max = self.max.clamp(f64::MIN, f64::MAX);
if self.max.is_nan() {
self.max = 0.0;
}
}
/// Specifies the output range of the space, inverting it
/// if inversion is selected.
fn frame_range(&self) -> RangeInclusive<f32> {
if self.invert {
(self.frame_end)..=(self.frame_start)
} else {
(self.frame_start)..=(self.frame_end)
}
}
/// Get the frame range as f64 format. This is not the natural
/// format for screen units but is needed for remapping to and
/// from values.
fn frame_range_f64(&self) -> RangeInclusive<f64> {
let as_f32 = self.frame_range();
*as_f32.start() as f64..=*as_f32.end() as f64
}
fn dvalue_per_dpos(&self) -> f64 {
let frame_range = self.frame_range_f64();
self.value_length() / (frame_range.end() - frame_range.start())
}
}
impl AxisSpace for LinearAxisSpace {
fn value_min(&self) -> f64 {
self.min
}
fn value_max(&self) -> f64 {
self.max
}
fn frame_min(&self) -> f32 {
self.frame_start
}
fn frame_max(&self) -> f32 {
self.frame_end
}
fn set_inverted(&mut self, invert: bool) {
self.invert = invert;
}
fn set_value_range(&mut self, range: RangeInclusive<f64>) {
self.min = *range.start();
self.max = *range.end();
self.clamp_to_finite();
}
fn position_from_value(&self, value: f64) -> f32 {
remap(value, self.min..=self.max, self.frame_range_f64()) as f32
}
fn value_from_position(&self, position: f32) -> f64 {
remap(position as f64, self.frame_range_f64(), self.min..=self.max)
}
fn position_delta_from_screen_delta(&self, _start_position: f64, drag_delta: f32) -> f64 {
drag_delta as f64 * self.dvalue_per_dpos()
}
fn grid_input(&self, spacing: f32) -> GridInput {
GridInput {
bounds: (self.min, self.max),
base_step_size: self.dvalue_per_dpos().abs() * (spacing as f64),
}
}
fn screen_distance_between_values(&self, value1: f64, value2: f64) -> f32 {
let delta = value2 - value1;
(delta / self.dvalue_per_dpos()) as f32
}
fn translate(&mut self, frame_distance: f32) {
let dvalue_per_dpos = self.dvalue_per_dpos();
let value_translation = frame_distance as f64 * dvalue_per_dpos;
self.min += value_translation;
self.max += value_translation;
self.clamp_to_finite();
}
fn zoom(&mut self, zoom_factor: f32, center: f64) {
self.min = center + (self.min - center) / (zoom_factor as f64);
self.max = center + (self.max - center) / (zoom_factor as f64);
}
}