|
|
@@ -44,6 +44,7 @@ pub mod vertex_attrib;
|
|
44
|
44
|
|
|
45
|
45
|
use coord::{LatLonDeg, ScreenCoord};
|
|
46
|
46
|
use glutin::{ControlFlow, ElementState, Event, GlContext, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent};
|
|
|
47
|
+use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
|
|
47
|
48
|
use map_view_gl::MapViewGl;
|
|
48
|
49
|
use std::error::Error;
|
|
49
|
50
|
use std::sync::mpsc;
|
|
|
@@ -51,11 +52,11 @@ use std::time::{Duration, Instant};
|
|
51
|
52
|
use tile_source::TileSource;
|
|
52
|
53
|
|
|
53
|
54
|
|
|
54
|
|
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
55
|
+#[derive(Copy, Clone, Debug, PartialEq)]
|
|
55
|
56
|
enum Action {
|
|
56
|
57
|
Nothing,
|
|
57
|
58
|
Redraw,
|
|
58
|
|
- Resize(u32, u32),
|
|
|
59
|
+ Resize(LogicalSize),
|
|
59
|
60
|
Close,
|
|
60
|
61
|
}
|
|
61
|
62
|
|
|
|
@@ -63,8 +64,8 @@ impl Action {
|
|
63
|
64
|
fn combine_with(&mut self, newer_action: Self) {
|
|
64
|
65
|
*self = match (*self, newer_action) {
|
|
65
|
66
|
(Action::Close, _) | (_, Action::Close) => Action::Close,
|
|
66
|
|
- (Action::Resize(..), Action::Resize(w, h)) => Action::Resize(w, h),
|
|
67
|
|
- (Action::Resize(w, h), _) | (_, Action::Resize(w, h)) => Action::Resize(w, h),
|
|
|
67
|
+ (Action::Resize(..), Action::Resize(size)) => Action::Resize(size),
|
|
|
68
|
+ (Action::Resize(size), _) | (_, Action::Resize(size)) => Action::Resize(size),
|
|
68
|
69
|
(Action::Redraw, _) | (_, Action::Redraw) => Action::Redraw,
|
|
69
|
70
|
(Action::Nothing, Action::Nothing) => Action::Nothing,
|
|
70
|
71
|
};
|
|
|
@@ -73,8 +74,10 @@ impl Action {
|
|
73
|
74
|
|
|
74
|
75
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
|
75
|
76
|
struct InputState {
|
|
76
|
|
- mouse_position: (f64, f64),
|
|
|
77
|
+ mouse_position: LogicalPosition,
|
|
77
|
78
|
mouse_pressed: bool,
|
|
|
79
|
+ viewport_size: LogicalSize,
|
|
|
80
|
+ dpi_factor: f64,
|
|
78
|
81
|
}
|
|
79
|
82
|
|
|
80
|
83
|
fn handle_event(
|
|
|
@@ -101,46 +104,51 @@ fn handle_event(
|
|
101
|
104
|
input_state.mouse_pressed = false;
|
|
102
|
105
|
Action::Nothing
|
|
103
|
106
|
},
|
|
104
|
|
- WindowEvent::CursorMoved { position: (x, y), .. } => {
|
|
|
107
|
+ WindowEvent::CursorMoved { position: pos, .. } => {
|
|
105
|
108
|
if input_state.mouse_pressed {
|
|
106
|
109
|
map.move_pixel(
|
|
107
|
|
- input_state.mouse_position.0 - x,
|
|
108
|
|
- input_state.mouse_position.1 - y,
|
|
|
110
|
+ (input_state.mouse_position.x - pos.x) * input_state.dpi_factor,
|
|
|
111
|
+ (input_state.mouse_position.y - pos.y) * input_state.dpi_factor,
|
|
109
|
112
|
);
|
|
110
|
|
- input_state.mouse_position = (x, y);
|
|
|
113
|
+ input_state.mouse_position = pos;
|
|
111
|
114
|
Action::Redraw
|
|
112
|
115
|
} else {
|
|
113
|
|
- input_state.mouse_position = (x, y);
|
|
|
116
|
+ input_state.mouse_position = pos;
|
|
114
|
117
|
Action::Nothing
|
|
115
|
118
|
}
|
|
116
|
119
|
},
|
|
117
|
120
|
WindowEvent::MouseWheel { delta, modifiers, .. } => {
|
|
118
|
|
- let (dx, dy) = match delta {
|
|
|
121
|
+ let delta: PhysicalPosition = match delta {
|
|
119
|
122
|
MouseScrollDelta::LineDelta(dx, dy) => {
|
|
120
|
123
|
// filter strange wheel events with huge values.
|
|
121
|
124
|
// (maybe this is just a personal touchpad driver issue)
|
|
122
|
125
|
if dx.abs() < 16.0 && dy.abs() < 16.0 {
|
|
123
|
126
|
//TODO find a sensible line height value (servo (the glutin port) uses 38)
|
|
124
|
|
- (dx, dy * 38.0)
|
|
|
127
|
+ PhysicalPosition::new(
|
|
|
128
|
+ f64::from(dx) * input_state.dpi_factor,
|
|
|
129
|
+ f64::from(dy) * 38.0 * input_state.dpi_factor,
|
|
|
130
|
+ )
|
|
125
|
131
|
} else {
|
|
126
|
|
- (0.0, 0.0)
|
|
|
132
|
+ PhysicalPosition::new(0.0, 0.0)
|
|
127
|
133
|
}
|
|
128
|
134
|
},
|
|
129
|
|
- MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy),
|
|
|
135
|
+ MouseScrollDelta::PixelDelta(size) => {
|
|
|
136
|
+ size.to_physical(input_state.dpi_factor)
|
|
|
137
|
+ }
|
|
130
|
138
|
};
|
|
131
|
139
|
|
|
132
|
140
|
//TODO add option for default mouse wheel behavior (scroll or zoom?)
|
|
133
|
141
|
//TODO add option to reverse scroll/zoom direction
|
|
134
|
142
|
|
|
135
|
143
|
if modifiers.ctrl {
|
|
136
|
|
- map.move_pixel(f64::from(-dx), f64::from(-dy));
|
|
|
144
|
+ map.move_pixel(-delta.x, -delta.y);
|
|
137
|
145
|
} else {
|
|
138
|
146
|
map.zoom_at(
|
|
139
|
147
|
ScreenCoord::new(
|
|
140
|
|
- input_state.mouse_position.0,
|
|
141
|
|
- input_state.mouse_position.1,
|
|
|
148
|
+ input_state.mouse_position.x * input_state.dpi_factor,
|
|
|
149
|
+ input_state.mouse_position.y * input_state.dpi_factor,
|
|
142
|
150
|
),
|
|
143
|
|
- f64::from(dy) * (1.0 / 320.0),
|
|
|
151
|
+ f64::from(delta.y) * (1.0 / 320.0),
|
|
144
|
152
|
);
|
|
145
|
153
|
}
|
|
146
|
154
|
Action::Redraw
|
|
|
@@ -210,9 +218,15 @@ fn handle_event(
|
|
210
|
218
|
WindowEvent::Refresh => {
|
|
211
|
219
|
Action::Redraw
|
|
212
|
220
|
},
|
|
213
|
|
- WindowEvent::Resized(w, h) => {
|
|
214
|
|
- Action::Resize(w, h)
|
|
|
221
|
+ WindowEvent::Resized(size) => {
|
|
|
222
|
+ input_state.viewport_size = size;
|
|
|
223
|
+ Action::Resize(size)
|
|
215
|
224
|
},
|
|
|
225
|
+ WindowEvent::HiDpiFactorChanged(dpi_factor) => {
|
|
|
226
|
+ input_state.dpi_factor = dpi_factor;
|
|
|
227
|
+ map.set_dpi_factor(dpi_factor);
|
|
|
228
|
+ Action::Resize(input_state.viewport_size)
|
|
|
229
|
+ }
|
|
216
|
230
|
_ => Action::Nothing,
|
|
217
|
231
|
},
|
|
218
|
232
|
_ => Action::Nothing,
|
|
|
@@ -258,12 +272,20 @@ fn run() -> Result<(), Box<Error>> {
|
|
258
|
272
|
let _ = unsafe { gl_window.make_current() };
|
|
259
|
273
|
let mut cx = context::Context::from_gl_window(&gl_window);
|
|
260
|
274
|
|
|
|
275
|
+ let mut input_state = InputState {
|
|
|
276
|
+ mouse_position: LogicalPosition::new(0.0, 0.0),
|
|
|
277
|
+ mouse_pressed: false,
|
|
|
278
|
+ viewport_size: window.get_inner_size().unwrap(),
|
|
|
279
|
+ dpi_factor: window.get_hidpi_factor(),
|
|
|
280
|
+ };
|
|
|
281
|
+
|
|
261
|
282
|
let mut map = {
|
|
262
|
283
|
let proxy = events_loop.create_proxy();
|
|
263
|
284
|
|
|
264
|
285
|
map_view_gl::MapViewGl::new(
|
|
265
|
286
|
&mut cx,
|
|
266
|
|
- window.get_inner_size().unwrap(),
|
|
|
287
|
+ input_state.viewport_size.to_physical(input_state.dpi_factor).into(),
|
|
|
288
|
+ input_state.dpi_factor,
|
|
267
|
289
|
move || { proxy.wakeup().unwrap(); },
|
|
268
|
290
|
config.use_network(),
|
|
269
|
291
|
config.async(),
|
|
|
@@ -274,11 +296,6 @@ fn run() -> Result<(), Box<Error>> {
|
|
274
|
296
|
map.restore_session(session);
|
|
275
|
297
|
}
|
|
276
|
298
|
|
|
277
|
|
- let mut input_state = InputState {
|
|
278
|
|
- mouse_position: (0.0, 0.0),
|
|
279
|
|
- mouse_pressed: false,
|
|
280
|
|
- };
|
|
281
|
|
-
|
|
282
|
299
|
let (marker_tx, marker_rx) = mpsc::channel();
|
|
283
|
300
|
if let (Some(path), Some(pattern)) = (config.pbf_path(), config.search_pattern()) {
|
|
284
|
301
|
let proxy = events_loop.create_proxy();
|
|
|
@@ -361,9 +378,12 @@ fn run() -> Result<(), Box<Error>> {
|
|
361
|
378
|
}
|
|
362
|
379
|
}
|
|
363
|
380
|
|
|
364
|
|
- if let Action::Resize(w, h) = action {
|
|
365
|
|
- gl_window.resize(w, h);
|
|
366
|
|
- map.set_viewport_size(&mut cx, w, h);
|
|
|
381
|
+ if let Action::Resize(size) = action {
|
|
|
382
|
+ let phys_size = size.to_physical(input_state.dpi_factor);
|
|
|
383
|
+ gl_window.resize(phys_size);
|
|
|
384
|
+
|
|
|
385
|
+ let phys_size: (u32, u32) = phys_size.into();
|
|
|
386
|
+ map.set_viewport_size(&mut cx, phys_size.0, phys_size.1);
|
|
367
|
387
|
}
|
|
368
|
388
|
|
|
369
|
389
|
let redraw = match action {
|