drag animation 60 fps testing
This commit is contained in:
parent
6d670afdbf
commit
0a90e486c3
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -209,6 +209,7 @@ dependencies = [
|
||||
"geo-types",
|
||||
"glib",
|
||||
"glib-build-tools",
|
||||
"glib-macros",
|
||||
"gtk4",
|
||||
"ndarray",
|
||||
"npyz",
|
||||
@ -657,15 +658,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glib-build-tools"
|
||||
version = "0.17.10"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a65d79efe318ef2cbbbb37032b125866fd82c34ea44c816132621bbc552e716"
|
||||
checksum = "8f8480c9ba9cc06aa8d5baf446037f8dc237bee127e9b62080c4db7e293d8ea0"
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
version = "0.17.9"
|
||||
version = "0.17.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a7206c5c03851ef126ea1444990e81fdd6765fb799d5bc694e4897ca01bb97f"
|
||||
checksum = "eca5c79337338391f1ab8058d6698125034ce8ef31b72a442437fa6c8580de26"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
|
||||
@ -22,6 +22,7 @@ npyz = { version = "0.8.0", features = ["npz"] }
|
||||
ndarray = "0.15.6"
|
||||
quadtree_rs = "0.1.2"
|
||||
proj-sys = "0.23.1"
|
||||
glib-macros = "0.17.10"
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
67
src/main.rs
67
src/main.rs
@ -1,3 +1,9 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use glib::{timeout_add, timeout_add_local};
|
||||
use glib_macros::clone;
|
||||
use gtk::gdk::Display;
|
||||
use gtk::{
|
||||
gio, glib, style_context_add_provider_for_display, Application, ApplicationWindow, CssProvider,
|
||||
@ -11,9 +17,10 @@ mod painter;
|
||||
mod render;
|
||||
mod tree;
|
||||
mod window;
|
||||
use data::{CoordType, Npz, Radar2d};
|
||||
use painter::wgs84::{LatLonCoord, Mercator, Range};
|
||||
use painter::Painter;
|
||||
use data::{Npz, Radar2d, RadarData2d};
|
||||
use num_traits::{FromPrimitive, Num};
|
||||
use painter::wgs84::{LatLonCoord, Mercator, ProjectionS, Range};
|
||||
use painter::{Coord, Painter};
|
||||
|
||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||
|
||||
@ -33,33 +40,55 @@ fn main() -> glib::ExitCode {
|
||||
|
||||
fn build_ui(app: &Application) {
|
||||
// Create a window and set the title
|
||||
|
||||
// let window = Window::new(app);
|
||||
|
||||
let window = ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title("My GTK App")
|
||||
.build();
|
||||
|
||||
let drawing_area = DrawingArea::new();
|
||||
let path = "/Users/ruomu/test2.npz";
|
||||
let path = "/home/ruomu/Desktop/test.npz";
|
||||
let data = Radar2d::<i8>::load(path, Npz).unwrap();
|
||||
|
||||
let data = Rc::new(RefCell::new(data));
|
||||
let data3_clone = data.clone();
|
||||
|
||||
let projection = Mercator::new();
|
||||
let aa = Range::from((
|
||||
*data.borrow().0.dim1.first().unwrap(),
|
||||
*data.borrow().0.dim1.last().unwrap(),
|
||||
));
|
||||
let ab = Range::from((
|
||||
*data.borrow().0.dim2.first().unwrap(),
|
||||
*data.borrow().0.dim2.last().unwrap(),
|
||||
));
|
||||
let coord = LatLonCoord::new(Some(aa), Some(ab), ((0, 1000), (0, 1000)), projection);
|
||||
let painter = Rc::new(RefCell::new(Painter::new(coord, 1000, 1000)));
|
||||
let painter_b = painter.clone();
|
||||
|
||||
let gesture = GestureDrag::new();
|
||||
|
||||
// gesture.connect_drag_end(|s, x, y| {
|
||||
// (&drawing_area).queue_draw();
|
||||
// });
|
||||
// drawing_area.add_controller(gesture);
|
||||
drawing_area.set_draw_func(move |a, b, c, d| {
|
||||
let projection = Mercator::new();
|
||||
let aa = Range::from((*data.0.dim1.first().unwrap(), *data.0.dim1.last().unwrap()));
|
||||
let ab = Range::from((*data.0.dim2.first().unwrap(), *data.0.dim2.last().unwrap()));
|
||||
gesture.connect_drag_update(clone!(
|
||||
@strong drawing_area => move |_, x,y| {
|
||||
let painter = painter.clone();
|
||||
painter.borrow_mut().set_shift(x,y);
|
||||
println!("{:.2},{:.2}",x,y);
|
||||
}
|
||||
));
|
||||
|
||||
let coord = LatLonCoord::new(Some(aa), Some(ab), ((0, c), (0, d)), projection);
|
||||
let painter: Painter<'_, f64, LatLonCoord<Mercator>> =
|
||||
Painter::new(b, coord, c as u32, c as u32);
|
||||
painter.draw_radar_2d(&data.0);
|
||||
drawing_area.add_controller(gesture);
|
||||
|
||||
drawing_area.set_draw_func(move |a, b, c, d| {
|
||||
painter_b.borrow().draw_radar_2d(b, &data3_clone.borrow().0);
|
||||
});
|
||||
|
||||
timeout_add_local(
|
||||
Duration::from_micros(1000u64 / 20u64),
|
||||
clone!(@strong drawing_area => move || {
|
||||
drawing_area.queue_draw();
|
||||
Continue(true)
|
||||
}),
|
||||
);
|
||||
|
||||
window.set_child(Some(&drawing_area));
|
||||
window.set_default_width(1000);
|
||||
window.set_default_height(800);
|
||||
|
||||
@ -8,4 +8,5 @@ pub trait Coord<T: Num> {
|
||||
|
||||
fn dim1_range(&self) -> (T, T);
|
||||
fn dim2_range(&self) -> (T, T);
|
||||
|
||||
}
|
||||
|
||||
@ -69,6 +69,10 @@ impl<T: ProjectionS> LatLonCoord<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_actual(&mut self,actual: ((i32, i32), (i32, i32))) {
|
||||
self.actual = (Range::from(actual.0), Range::from(actual.1));
|
||||
}
|
||||
|
||||
pub fn lon_range(&self) -> Range {
|
||||
self.pcs.lon_range
|
||||
}
|
||||
@ -102,6 +106,7 @@ impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
|
||||
let v = self.lat_range();
|
||||
(v.0, v.1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
||||
@ -3,3 +3,4 @@ mod painter;
|
||||
|
||||
pub use painter::Painter;
|
||||
pub use coords::wgs84;
|
||||
pub use coords::Coord;
|
||||
@ -1,4 +1,8 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
marker::PhantomData,
|
||||
rc::{self, Rc},
|
||||
};
|
||||
|
||||
use crate::{data::RadarData2d, tree::get};
|
||||
|
||||
@ -8,27 +12,27 @@ use gtk::{
|
||||
gdk::{builders::RGBABuilder, RGBA},
|
||||
};
|
||||
use num_traits::{FromPrimitive, Num};
|
||||
pub struct Painter<'a, T: Num, C: Coord<T>> {
|
||||
pub struct Painter<T: Num, C: Coord<T>> {
|
||||
width: u32,
|
||||
height: u32,
|
||||
context: &'a Context,
|
||||
shift: (f64, f64),
|
||||
coord: C,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T: Num + Clone, C: Coord<T>> Painter<'a, T, C> {
|
||||
pub fn new(context: &'a Context, coord: C, width: u32, height: u32) -> Self {
|
||||
impl<T: Num + Clone, C: Coord<T>> Painter<T, C> {
|
||||
pub fn new(coord: C, width: u32, height: u32) -> Self {
|
||||
Self {
|
||||
context,
|
||||
coord,
|
||||
width,
|
||||
height,
|
||||
shift: (0f64, 0f64),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_color(&self, color: &RGBA) {
|
||||
self.context.set_source_rgba(
|
||||
fn set_color(&self, context: &Context, color: &RGBA) {
|
||||
context.set_source_rgba(
|
||||
color.red() as f64,
|
||||
color.green() as f64,
|
||||
color.blue() as f64,
|
||||
@ -36,19 +40,30 @@ impl<'a, T: Num + Clone, C: Coord<T>> Painter<'a, T, C> {
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_pixel(&self, point: ScreenCoord, color: &RGBA) {
|
||||
self.context
|
||||
.rectangle(f64::from(point.0), f64::from(point.1), 1.0, 1.0);
|
||||
self.set_color(color);
|
||||
fn draw_pixel(&self, context: &Context, point: ScreenCoord, color: &RGBA) {
|
||||
context.rectangle(f64::from(point.0), f64::from(point.1), 1.0, 1.0);
|
||||
self.set_color(context, color);
|
||||
|
||||
self.context.fill();
|
||||
context.fill();
|
||||
}
|
||||
|
||||
fn draw_rect(&self, point: ScreenCoord, width: f64, height: f64, color: &RGBA, fill: bool) {
|
||||
self.set_color(color);
|
||||
self.set_stroke_width(1);
|
||||
self.context.rectangle(point.0, point.1, width, height);
|
||||
self.context.fill();
|
||||
pub fn set_shift(&mut self, dx: f64, dy: f64) {
|
||||
self.shift = (self.shift.0 + dx, self.shift.1 + dy);
|
||||
}
|
||||
|
||||
fn draw_rect(
|
||||
&self,
|
||||
context: &Context,
|
||||
point: ScreenCoord,
|
||||
width: f64,
|
||||
height: f64,
|
||||
color: &RGBA,
|
||||
fill: bool,
|
||||
) {
|
||||
self.set_color(context, color);
|
||||
self.set_stroke_width(context, 1);
|
||||
context.rectangle(point.0, point.1, width, height);
|
||||
context.fill();
|
||||
// if fill {
|
||||
// self.context.fill();
|
||||
// } else {
|
||||
@ -56,35 +71,40 @@ impl<'a, T: Num + Clone, C: Coord<T>> Painter<'a, T, C> {
|
||||
// }
|
||||
}
|
||||
|
||||
fn set_stroke_width(&self, width: u32) {
|
||||
self.context.set_line_width(f64::from(width));
|
||||
fn translate(&self,context:&Context) {
|
||||
context.translate(self.shift.0, self.shift.1);
|
||||
}
|
||||
|
||||
fn draw_line(&self, start: ScreenCoord, end: ScreenCoord) {
|
||||
self.set_color(&RGBA::BLACK);
|
||||
self.set_stroke_width(1);
|
||||
self.context.move_to(start.0, start.1);
|
||||
self.context.line_to(end.0, end.1);
|
||||
|
||||
self.context.stroke();
|
||||
fn set_stroke_width(&self, context: &Context, width: u32) {
|
||||
context.set_line_width(f64::from(width));
|
||||
}
|
||||
|
||||
fn draw_path<I: IntoIterator<Item = ScreenCoord>>(&self, path: I) {
|
||||
fn draw_line(&self, context: &Context, start: ScreenCoord, end: ScreenCoord) {
|
||||
self.set_color(context, &RGBA::BLACK);
|
||||
self.set_stroke_width(context, 1);
|
||||
context.move_to(start.0, start.1);
|
||||
context.line_to(end.0, end.1);
|
||||
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
fn draw_path<I: IntoIterator<Item = ScreenCoord>>(&self, context: &Context, path: I) {
|
||||
let mut path = path.into_iter();
|
||||
if let Some((x, y)) = path.next() {
|
||||
self.context.move_to(x, y);
|
||||
context.move_to(x, y);
|
||||
}
|
||||
|
||||
for (x, y) in path {
|
||||
self.context.line_to(x, y);
|
||||
context.line_to(x, y);
|
||||
}
|
||||
self.context.stroke();
|
||||
context.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
||||
impl<C: Coord<f64>> Painter<f64, C> {
|
||||
pub fn draw_radar_2d<T: Num + Clone + PartialEq + PartialOrd + FromPrimitive + Copy, D>(
|
||||
&self,
|
||||
context: &Context,
|
||||
data: &RadarData2d<T, D>,
|
||||
) where
|
||||
D: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
@ -183,11 +203,11 @@ impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
||||
.build(),
|
||||
];
|
||||
|
||||
let mut polygons: Vec<(shapefile::Polygon, _)> =
|
||||
shapefile::read_as::<_, shapefile::Polygon, shapefile::dbase::Record>(
|
||||
"/Users/ruomu/china/省界_region.shp",
|
||||
)
|
||||
.unwrap();
|
||||
// let mut polygons: Vec<(shapefile::Polygon, _)> =
|
||||
// shapefile::read_as::<_, shapefile::Polygon, shapefile::dbase::Record>(
|
||||
// "/Users/ruomu/china/省界_region.shp",
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
// for (polygon, _) in polygons.into_iter() {
|
||||
// let x_range = polygon.bbox().x_range();
|
||||
@ -196,13 +216,15 @@ impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
||||
// let lon_range = self.coord.dim1_range();
|
||||
// let lat_range = self.coord.dim2_range();
|
||||
// }
|
||||
|
||||
self.translate(context);
|
||||
data.data.outer_iter().enumerate().for_each(|(r_num, row)| {
|
||||
row.iter().enumerate().for_each(|(c_num, v)| {
|
||||
let point = self.coord.map(data.dim1[c_num], data.dim2[r_num]);
|
||||
if *v > T::from_i8(-125).unwrap() {
|
||||
let color = get(&levels, &colors, *v);
|
||||
// self.draw_pixel(point, &color);
|
||||
self.draw_rect(point, 1.5, 1.5, &color, true);
|
||||
self.draw_rect(context, point, 1.5, 1.5, &color, true);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user