self drawing and drag gesture testing
This commit is contained in:
parent
1c1f2925cf
commit
6d670afdbf
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -657,9 +657,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glib-build-tools"
|
||||
version = "0.17.0"
|
||||
version = "0.17.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f8480c9ba9cc06aa8d5baf446037f8dc237bee127e9b62080c4db7e293d8ea0"
|
||||
checksum = "7a65d79efe318ef2cbbbb37032b125866fd82c34ea44c816132621bbc552e716"
|
||||
|
||||
[[package]]
|
||||
name = "glib-macros"
|
||||
|
||||
@ -23,9 +23,9 @@ ndarray = "0.15.6"
|
||||
quadtree_rs = "0.1.2"
|
||||
proj-sys = "0.23.1"
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
glib-build-tools = "0.17.0"
|
||||
# plotters = "0.3.4"
|
||||
|
||||
[dependencies.geo-macros]
|
||||
path = "geo-macros"
|
||||
|
||||
12
p.py
12
p.py
@ -1,12 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
a = np.load("/home/ruomu/Desktop/test.npz")
|
||||
|
||||
b = a['value']
|
||||
lon = a['lon']
|
||||
lat = a['lat']
|
||||
|
||||
a = np.load("/home/ruomu/Desktop/test2.npz")['value']
|
||||
|
||||
|
||||
np.savez("/home/ruomu/Desktop/test2.npz", value=np.max(b,axis=0), lon=lon, lat=lat)
|
||||
19
src/data.rs
19
src/data.rs
@ -25,7 +25,7 @@ pub enum CoordType {
|
||||
#[derive(Clone)]
|
||||
pub struct RadarData2d<T, Raw, X = f64, Y = f64>
|
||||
where
|
||||
T: Num + Clone,
|
||||
T: Num + Clone + PartialEq + PartialOrd,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
X: Num,
|
||||
Y: Num,
|
||||
@ -53,7 +53,7 @@ trait MultiDimensionData {}
|
||||
|
||||
impl<T, Raw> RadarData2d<T, Raw>
|
||||
where
|
||||
T: Num + AsPrimitive<f64> + FromPrimitive + Clone + Debug,
|
||||
T: Num + AsPrimitive<f64> + FromPrimitive + Clone + Debug + PartialOrd + PartialEq,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
{
|
||||
fn value_to_owned(self) -> RadarData2d<T, OwnedRepr<T>> {
|
||||
@ -198,11 +198,13 @@ fn windowed_sinc(x: f64, y: f64) -> f64 {
|
||||
sinc * window
|
||||
}
|
||||
|
||||
pub struct LevelData<T: Num + Clone>(pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>);
|
||||
pub struct LevelData<T: Num + Clone + PartialEq + PartialOrd>(
|
||||
pub Quadtree<i64, RadarData2d<T, OwnedRepr<T>>>,
|
||||
);
|
||||
|
||||
impl<T> LevelData<T>
|
||||
where
|
||||
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
||||
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug + PartialEq + PartialOrd,
|
||||
{
|
||||
fn value(
|
||||
level_data: Vec<RadarData2d<T, OwnedRepr<T>>>,
|
||||
@ -252,6 +254,7 @@ where
|
||||
pub fn levels<T>(data: Radar2d<T>, levels: usize) -> Vec<LevelData<T>>
|
||||
where
|
||||
T: Num + Clone + AsPrimitive<f64> + FromPrimitive + Debug,
|
||||
T: PartialEq + PartialOrd,
|
||||
{
|
||||
let numerator = 1.0 / levels as f64;
|
||||
(0..levels)
|
||||
@ -263,6 +266,7 @@ where
|
||||
impl<T, Raw> MultiDimensionData for RadarData2d<T, Raw>
|
||||
where
|
||||
T: Num + Clone,
|
||||
T: PartialEq + PartialOrd,
|
||||
Raw: ndarray::Data<Elem = T> + Clone + RawDataClone,
|
||||
{
|
||||
}
|
||||
@ -308,6 +312,7 @@ impl Npz {
|
||||
impl<T> DataLoader<RadarData2d<T, OwnedRepr<T>>> for Npz
|
||||
where
|
||||
T: Num + Clone + Deserialize,
|
||||
T: PartialEq + PartialOrd,
|
||||
{
|
||||
fn load<P: AsRef<Path>>(&self, path: P) -> Result<RadarData2d<T, OwnedRepr<T>>, DataError> {
|
||||
let mut data: NpzArchive<BufReader<std::fs::File>> = npyz::npz::NpzArchive::open(path)?;
|
||||
@ -324,15 +329,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Num + Clone> RadarData2d<T, OwnedRepr<T>> {
|
||||
impl<T: Num + Clone + PartialEq + PartialOrd> RadarData2d<T, OwnedRepr<T>> {
|
||||
pub fn load<P: AsRef<Path>, M: DataLoader<Self>>(p: P, meth: M) -> Self {
|
||||
meth.load(p).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Radar2d<T: Num + Clone>(pub RadarData2d<T, OwnedRepr<T>>);
|
||||
pub struct Radar2d<T: Num + Clone + PartialEq + PartialOrd>(pub RadarData2d<T, OwnedRepr<T>>);
|
||||
|
||||
impl<T: Num + Clone> Radar2d<T> {
|
||||
impl<T: Num + Clone + PartialEq + PartialOrd> Radar2d<T> {
|
||||
pub fn load(
|
||||
path: impl AsRef<Path>,
|
||||
meth: impl DataLoader<RadarData2d<T, OwnedRepr<T>>>,
|
||||
|
||||
42
src/main.rs
42
src/main.rs
@ -1,26 +1,24 @@
|
||||
use geo_types::{MultiPolygon, Polygon};
|
||||
use gtk::builders::DrawingAreaBuilder;
|
||||
use gtk::gdk::Display;
|
||||
use gtk::{
|
||||
gio, glib, style_context_add_provider_for_display, Application, ApplicationWindow, CssProvider,
|
||||
GestureDrag,
|
||||
};
|
||||
use gtk::{prelude::*, DrawingArea};
|
||||
use painter::wgs84::*;
|
||||
use painter::Painter;
|
||||
// use plotters::prelude::DrawingArea;
|
||||
use window::Window;
|
||||
// mod backend;
|
||||
mod data;
|
||||
mod painter;
|
||||
// mod trees;
|
||||
mod render;
|
||||
mod tree;
|
||||
mod window;
|
||||
|
||||
use data::{CoordType, Npz, Radar2d};
|
||||
use painter::wgs84::{LatLonCoord, Mercator, Range};
|
||||
use painter::Painter;
|
||||
|
||||
const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||
|
||||
fn main() -> glib::ExitCode {
|
||||
gio::resources_register_include!("window.gresource").expect("Failed to register resources");
|
||||
// gio::resources_register_include!("window.gresource").expect("Failed to register resources");
|
||||
// Create a new application
|
||||
let app = Application::builder().application_id(APP_ID).build();
|
||||
|
||||
@ -36,23 +34,33 @@ fn main() -> glib::ExitCode {
|
||||
fn build_ui(app: &Application) {
|
||||
// Create a window and set the title
|
||||
|
||||
let window = Window::new(app);
|
||||
// let window = Window::new(app);
|
||||
|
||||
let window = ApplicationWindow::builder()
|
||||
.application(app)
|
||||
.title("My GTK App")
|
||||
.build();
|
||||
|
||||
let drawing_area = DrawingArea::new();
|
||||
|
||||
let path = "/home/ruomu/Desktop/test.npz";
|
||||
|
||||
let path = "/Users/ruomu/test2.npz";
|
||||
let data = Radar2d::<i8>::load(path, Npz).unwrap();
|
||||
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 coord = LatLonCoord::new(None, None, ((0, c), (0, d)), projection);
|
||||
let painter: Painter<'_, f64, LatLonCoord<Mercator>> = Painter::new(b, coord, c as u32, c as u32);
|
||||
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()));
|
||||
|
||||
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);
|
||||
|
||||
});
|
||||
|
||||
// window.set_child(Some(&drawing_area));
|
||||
window.set_child(Some(&drawing_area));
|
||||
window.set_default_width(1000);
|
||||
window.set_default_height(800);
|
||||
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
use num_traits::Num;
|
||||
pub mod wgs84;
|
||||
|
||||
pub type ScreenCoord = (i32, i32);
|
||||
pub type ScreenCoord = (f64, f64);
|
||||
|
||||
pub trait Coord<T: Num> {
|
||||
fn map(&self, axis_1: T, axis_2: T) -> ScreenCoord;
|
||||
|
||||
fn dim1_range(&self) -> (T, T);
|
||||
fn dim2_range(&self) -> (T, T);
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
use super::Coord;
|
||||
use geo_macros::Prj;
|
||||
use num_traits::{AsPrimitive, FromPrimitive, Num};
|
||||
use proj::{Proj, ProjError};
|
||||
use thiserror::Error;
|
||||
|
||||
type Lat = f64;
|
||||
type Lon = f64;
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Range(pub f64, pub f64);
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
@ -16,15 +18,17 @@ pub enum CoordError {
|
||||
},
|
||||
}
|
||||
|
||||
impl From<(f64, f64)> for Range {
|
||||
fn from(value: (f64, f64)) -> Self {
|
||||
impl<T: AsPrimitive<f64> + Num> From<(T, T)> for Range {
|
||||
fn from(value: (T, T)) -> Self {
|
||||
let value = (value.0.as_(), value.1.as_());
|
||||
let (_min, _max) = (value.0.min(value.1), value.0.max(value.1));
|
||||
Self(_min, _max)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LatLonCoord<T: ProjectionS> {
|
||||
actual: ((i32, i32), (i32, i32)),
|
||||
// actual: ((f64, f64), (f64, f64)),
|
||||
actual: (Range, Range),
|
||||
logical: (Range, Range),
|
||||
pcs: PCS<T>,
|
||||
}
|
||||
@ -53,21 +57,50 @@ impl<T: ProjectionS> LatLonCoord<T> {
|
||||
lon: Option<Range>,
|
||||
lat: Option<Range>,
|
||||
actual: ((i32, i32), (i32, i32)),
|
||||
// actual: (Range, Range),
|
||||
project: T,
|
||||
) -> Self {
|
||||
let pcs = PCS::new(project, lon, lat);
|
||||
let _box = pcs.bbox().unwrap();
|
||||
Self {
|
||||
actual,
|
||||
actual: (Range::from(actual.0), Range::from(actual.1)),
|
||||
pcs: pcs,
|
||||
logical: _box,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lon_range(&self) -> Range {
|
||||
self.pcs.lon_range
|
||||
}
|
||||
|
||||
pub fn lat_range(&self) -> Range {
|
||||
self.pcs.lat_range
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ProjectionS> Coord<f64> for LatLonCoord<T> {
|
||||
fn map(&self, axis_1: f64, axis_2: f64) -> super::ScreenCoord {
|
||||
(0, 0)
|
||||
let point = self.pcs.map((axis_1, axis_2));
|
||||
let logical_dim1_span = self.logical.0 .1 - self.logical.0 .0;
|
||||
|
||||
let dim1_rate = (point.0 - self.logical.0 .0) / logical_dim1_span;
|
||||
let logical_dim2_span = self.logical.1 .1 - self.logical.1 .0;
|
||||
let dim2_rate = (point.1 - self.logical.1 .0) / logical_dim2_span;
|
||||
|
||||
(
|
||||
(dim1_rate * (self.actual.0 .1 - self.actual.0 .0) as f64) + self.actual.0 .0,
|
||||
(dim2_rate * (self.actual.1 .1 - self.actual.1 .0) as f64) + self.actual.1 .0,
|
||||
)
|
||||
}
|
||||
|
||||
fn dim1_range(&self) -> (f64, f64) {
|
||||
let v = self.lon_range();
|
||||
(v.0, v.1)
|
||||
}
|
||||
|
||||
fn dim2_range(&self) -> (f64, f64) {
|
||||
let v = self.lat_range();
|
||||
(v.0, v.1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,8 +190,8 @@ impl Mercator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
central_lon: 0.0,
|
||||
min_latitude: 0.0,
|
||||
max_latitude: 70.0,
|
||||
min_latitude: -82.0,
|
||||
max_latitude: 82.0,
|
||||
false_easting: 0.0,
|
||||
false_northing: 0.0,
|
||||
latitude_true_scale: 0.0,
|
||||
@ -198,7 +231,7 @@ impl ProjectionS for Mercator {
|
||||
|
||||
let lat_range = Range {
|
||||
0: lat_range.0.max(self.min_latitude),
|
||||
1: lat_range.0.min(self.max_latitude),
|
||||
1: lat_range.1.min(self.max_latitude),
|
||||
};
|
||||
(lon_range, lat_range)
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use crate::data::RadarData2d;
|
||||
use crate::{data::RadarData2d, tree::get};
|
||||
|
||||
use super::coords::{Coord, ScreenCoord};
|
||||
use gtk::{cairo::*, gdk::RGBA};
|
||||
use num_traits::Num;
|
||||
use gtk::{
|
||||
cairo::*,
|
||||
gdk::{builders::RGBABuilder, RGBA},
|
||||
};
|
||||
use num_traits::{FromPrimitive, Num};
|
||||
pub struct Painter<'a, T: Num, C: Coord<T>> {
|
||||
width: u32,
|
||||
height: u32,
|
||||
@ -33,18 +36,175 @@ impl<'a, T: Num + Clone, C: Coord<T>> Painter<'a, T, C> {
|
||||
);
|
||||
}
|
||||
|
||||
fn draw_pixel(&self, point: ScreenCoord) {}
|
||||
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_rect(&self, point: ScreenCoord, width: f64, height: f64) {}
|
||||
self.context.fill();
|
||||
}
|
||||
|
||||
fn draw_line(&self, start: ScreenCoord, end: ScreenCoord) {}
|
||||
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();
|
||||
// if fill {
|
||||
// self.context.fill();
|
||||
// } else {
|
||||
// self.context.stroke();
|
||||
// }
|
||||
}
|
||||
|
||||
fn set_stroke_width(&self, width: u32) {
|
||||
self.context.set_line_width(f64::from(width));
|
||||
}
|
||||
|
||||
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 draw_path<I: IntoIterator<Item = ScreenCoord>>(&self, path: I) {
|
||||
let mut path = path.into_iter();
|
||||
if let Some((x, y)) = path.next() {
|
||||
self.context.move_to(x, y);
|
||||
}
|
||||
|
||||
for (x, y) in path {
|
||||
self.context.line_to(x, y);
|
||||
}
|
||||
self.context.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C: Coord<f64>> Painter<'a, f64, C> {
|
||||
pub fn draw_radar_2d<T: Num + Clone, D>(&self, data: &RadarData2d<T, D>)
|
||||
where
|
||||
pub fn draw_radar_2d<T: Num + Clone + PartialEq + PartialOrd + FromPrimitive + Copy, D>(
|
||||
&self,
|
||||
data: &RadarData2d<T, D>,
|
||||
) where
|
||||
D: ndarray::Data<Elem = T> + Clone + ndarray::RawDataClone,
|
||||
{
|
||||
let levels: Vec<T> = vec![
|
||||
T::from_i8(0).unwrap(),
|
||||
T::from_i8(5).unwrap(),
|
||||
T::from_i8(10).unwrap(),
|
||||
T::from_i8(15).unwrap(),
|
||||
T::from_i8(20).unwrap(),
|
||||
T::from_i8(25).unwrap(),
|
||||
T::from_i8(30).unwrap(),
|
||||
T::from_i8(35).unwrap(),
|
||||
T::from_i8(40).unwrap(),
|
||||
T::from_i8(45).unwrap(),
|
||||
T::from_i8(50).unwrap(),
|
||||
T::from_i8(55).unwrap(),
|
||||
T::from_i8(60).unwrap(),
|
||||
T::from_i8(65).unwrap(),
|
||||
];
|
||||
let colors = vec![
|
||||
RGBABuilder::default()
|
||||
.red(0 as f32 / 255.0)
|
||||
.green(172 as f32 / 255.0)
|
||||
.blue(164 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(192 as f32 / 255.0)
|
||||
.green(192 as f32 / 255.0)
|
||||
.blue(254 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(122 as f32 / 255.0)
|
||||
.green(114 as f32 / 255.0)
|
||||
.blue(238 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(30 as f32 / 255.0)
|
||||
.green(38 as f32 / 255.0)
|
||||
.blue(208 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(166 as f32 / 255.0)
|
||||
.green(252 as f32 / 255.0)
|
||||
.blue(168 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(0 as f32 / 255.0)
|
||||
.green(234 as f32 / 255.0)
|
||||
.blue(0 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(16 as f32 / 255.0)
|
||||
.green(146 as f32 / 255.0)
|
||||
.blue(26 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(252 as f32 / 255.0)
|
||||
.green(244 as f32 / 255.0)
|
||||
.blue(100 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(200 as f32 / 255.0)
|
||||
.green(200 as f32 / 255.0)
|
||||
.blue(2 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(140 as f32 / 255.0)
|
||||
.green(140 as f32 / 255.0)
|
||||
.blue(0 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(254 as f32 / 255.0)
|
||||
.green(172 as f32 / 255.0)
|
||||
.blue(172 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(254 as f32 / 255.0)
|
||||
.green(100 as f32 / 255.0)
|
||||
.blue(92 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(238 as f32 / 255.0)
|
||||
.green(2 as f32 / 255.0)
|
||||
.blue(48 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(212 as f32 / 255.0)
|
||||
.green(142 as f32 / 255.0)
|
||||
.blue(254 as f32 / 255.0)
|
||||
.build(),
|
||||
RGBABuilder::default()
|
||||
.red(170 as f32 / 255.0)
|
||||
.green(36 as f32 / 255.0)
|
||||
.blue(250 as f32 / 255.0)
|
||||
.build(),
|
||||
];
|
||||
|
||||
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();
|
||||
// let y_range = polygon.bbox().y_range();
|
||||
|
||||
// let lon_range = self.coord.dim1_range();
|
||||
// let lat_range = self.coord.dim2_range();
|
||||
// }
|
||||
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);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
43
src/render/imp.rs
Normal file
43
src/render/imp.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use glib::{ObjectExt, ParamSpec, Properties, Value};
|
||||
use gtk::glib;
|
||||
use gtk::subclass::prelude::*;
|
||||
use std::cell::Cell;
|
||||
|
||||
#[derive(Properties, Default)]
|
||||
#[properties(wrapper_type = super::Render)]
|
||||
pub struct Render {
|
||||
#[property(get, set)]
|
||||
height: Cell<u32>,
|
||||
#[property(get, set)]
|
||||
width: Cell<u32>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for Render {
|
||||
const NAME: &'static str = "MyRender";
|
||||
type Type = super::Render;
|
||||
type ParentType = gtk::DrawingArea;
|
||||
}
|
||||
|
||||
// Trait shared by all GObjects
|
||||
impl ObjectImpl for Render {
|
||||
fn properties() -> &'static [ParamSpec] {
|
||||
Self::derived_properties()
|
||||
}
|
||||
|
||||
fn set_property(&self, id: usize, value: &Value, pspec: &ParamSpec) {
|
||||
self.derived_set_property(id, value, pspec)
|
||||
}
|
||||
|
||||
fn property(&self, id: usize, pspec: &ParamSpec) -> Value {
|
||||
self.derived_property(id, pspec)
|
||||
}
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
}
|
||||
}
|
||||
|
||||
// Trait shared by all widgets
|
||||
impl WidgetImpl for Render {}
|
||||
|
||||
impl DrawingAreaImpl for Render {}
|
||||
18
src/render/mod.rs
Normal file
18
src/render/mod.rs
Normal file
@ -0,0 +1,18 @@
|
||||
mod imp;
|
||||
use glib::Object;
|
||||
use gtk::glib;
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct Render(ObjectSubclass<imp::Render>)
|
||||
@extends gtk::DrawingArea,gtk::Widget,
|
||||
@implements gtk::Accessible, gtk::Actionable, gtk::Buildable, gtk::ConstraintTarget;
|
||||
}
|
||||
|
||||
impl Render {
|
||||
pub fn new(height: u32, width: u32) -> Self {
|
||||
Object::builder()
|
||||
.property("height", height)
|
||||
.property("width", width)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
use gtk::gdk::RGBA;
|
||||
use num_traits::Num;
|
||||
use plotters::style::RGBAColor;
|
||||
pub fn get<T>(levels: &Vec<T>, colors: &Vec<RGBAColor>, v: T) -> RGBAColor
|
||||
|
||||
pub fn get<T>(levels: &Vec<T>, colors: &Vec<RGBA>, v: T) -> RGBA
|
||||
where
|
||||
T: Num + PartialOrd,
|
||||
T: Num + PartialOrd + Copy,
|
||||
{
|
||||
let len = levels.len();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user