rebuild factor

This commit is contained in:
Tsuki 2024-08-27 23:50:18 +08:00
parent cd1d7023ed
commit ed9e8549aa
42 changed files with 991 additions and 674 deletions

121
Cargo.lock generated
View File

@ -201,55 +201,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.86" version = "1.0.86"
@ -830,7 +781,7 @@ dependencies = [
"proj-sys", "proj-sys",
"quadtree_rs", "quadtree_rs",
"quick_cache", "quick_cache",
"radarg_data", "radarg_core",
"radarg_plugin_interface", "radarg_plugin_interface",
"rayon", "rayon",
"regex", "regex",
@ -851,7 +802,6 @@ dependencies = [
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-condvar", "tokio-condvar",
"toml",
"topojson", "topojson",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@ -935,12 +885,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.7" version = "4.6.7"
@ -1331,29 +1275,6 @@ dependencies = [
"syn 2.0.75", "syn 2.0.75",
] ]
[[package]]
name = "env_filter"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"humantime",
"log",
]
[[package]] [[package]]
name = "epoxy" name = "epoxy"
version = "0.1.0" version = "0.1.0"
@ -1918,7 +1839,6 @@ dependencies = [
"chrono", "chrono",
"copypasta", "copypasta",
"dirs", "dirs",
"env_logger",
"femtovg", "femtovg",
"flate2", "flate2",
"freetype-rs", "freetype-rs",
@ -1939,9 +1859,10 @@ dependencies = [
"nom-derive", "nom-derive",
"once_cell", "once_cell",
"pathfinder_geometry", "pathfinder_geometry",
"radarg_data", "radarg_core",
"raw-window-handle", "raw-window-handle",
"regex", "regex",
"relm4",
"rust-embed", "rust-embed",
"serde", "serde",
"serde_json", "serde_json",
@ -2567,12 +2488,6 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.30" version = "0.14.30"
@ -2796,12 +2711,6 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.11.0" version = "0.11.0"
@ -4289,13 +4198,21 @@ dependencies = [
] ]
[[package]] [[package]]
name = "radarg_data" name = "radarg_core"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"dirs",
"ndarray 0.16.1", "ndarray 0.16.1",
"num-traits",
"proj",
"proj-sys",
"radarg_plugin_interface", "radarg_plugin_interface",
"relm4",
"rust-embed",
"serde",
"thiserror", "thiserror",
"toml",
] ]
[[package]] [[package]]
@ -4821,18 +4738,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.208" version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.208" version = "1.0.209"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
dependencies = [ dependencies = [
"proc-macro2 1.0.86", "proc-macro2 1.0.86",
"quote 1.0.37", "quote 1.0.37",
@ -5781,12 +5698,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "v_frame" name = "v_frame"
version = "0.3.8" version = "0.3.8"

View File

@ -6,5 +6,5 @@ members = [
"geo-macros", "geo-macros",
"radar-g", "radar-g",
"gi", "gi",
"radarg_data", "radarg_core",
] ]

217
config.toml Normal file
View File

@ -0,0 +1,217 @@
[[cmap]]
type = "DBZ"
levels = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]
colors = [
"#aaaaaa",
"#0022ff",
"#01a0f6",
"#00ecec",
"#00d800",
"#019000",
"#ffff00",
"#e7c000",
"#ff9000",
"#ff0000",
"#d60000",
"#c00000",
"#ff00f0",
"#9600b4",
"#ad90f0",
]
[[cmap]]
type = "VEL"
levels = [
-90,
-45,
-35,
-27,
-20,
-15,
-10,
-5,
-1,
0,
1,
5,
10,
15,
20,
27,
1000,
]
colors = [
"#9fffff",
"#00e0ff",
"#0080ff",
"#320096",
"#00fb90",
"#00bb90",
"#008f00",
"#cdc09f",
"#000000",
"#f88700",
"#ffcf00",
"#ffff00",
"#ae0000",
"#d07000",
"#dd0000",
"#ff0000",
]
[[cmap]]
type = "SW"
colors = [
"#E0E0E0",
"#7CE0E0",
"#00E0E0",
"#00B0B0",
"#00FEFE",
"#00C400",
"#008000",
"#FEFE00",
"#FED200",
"#FE7C00",
"#FEB0B0",
"#FE5858",
"#FE0000",
"#FEFEFE",
]
levels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[[cmap]]
type = "CC"
colors = [
"#003CFF",
"#00EFEF",
"#00BABF",
"#00837D",
"#008938",
"#00B729",
"#00DA0D",
"#00FF00",
"#FFFF3B",
"#FFF000",
"#FFC600",
"#FFA500",
"#FF7200",
"#FF1F00",
"#C10000",
"#D400AA",
]
levels = [
0,
0.1,
0.3,
0.5,
0.6,
0.7,
0.8,
0.85,
0.9,
0.92,
0.94,
0.95,
0.96,
0.97,
0.98,
0.99,
]
[[cmap]]
type = "KDP"
colors = [
"#00FFFF",
"#00EFEF",
"#00A8AC",
"#B4B4B4",
"#B4B4B4",
"#00C027",
"#00E80A",
"#24FF24",
"#FFFF1E",
"#FFE600",
"#FFBC00",
"#FF9800",
"#FF5E00",
"#F20F00",
"#BB003A",
"#DD009C",
"#FF00FF",
]
levels = [
-0.8,
-0.4,
-0.2,
-0.1,
0.1,
0.15,
0.22,
0.33,
0.5,
0.75,
1.1,
1.7,
2.4,
3.1,
7,
20,
]
[[cmap]]
type = "ZDR"
colors = [
"#464646",
"#505050",
"#5A5A5A",
"#646464",
"#6E6E6E",
"#787878",
"#828282",
"#8C8C8C",
"#969696",
"#AFAFAF",
"#C8C8C8",
"#DCF0DC",
"#00C027",
"#00E80A",
"#24FF24",
"#FFFF1E",
"#FFF20F",
"#FFE600",
"#FFBC00",
"#FF9800",
"#FF5E00",
"#FFFF00",
"#F20F00",
"#BB003A",
"#DD009C",
"#FF00FF",
]
levels = [
-5,
-4.5,
-4,
-3.5,
-3,
-2.5,
-2,
-1.5,
-1,
-0.5,
0,
0.5,
1,
1.5,
2,
2.5,
3,
3.5,
4,
4.5,
5,
5.5,
6,
6.5,
7,
]

View File

@ -12,7 +12,6 @@ cgmath = "0.18.0"
chrono = "0.4.38" chrono = "0.4.38"
copypasta = "0.10.1" copypasta = "0.10.1"
dirs = "5.0.1" dirs = "5.0.1"
env_logger = "0.11.3"
flate2 = "1.0.30" flate2 = "1.0.30"
freetype-rs = { version = "0.37.0", features = ["bundled"] } freetype-rs = { version = "0.37.0", features = ["bundled"] }
geo = "0.28.0" geo = "0.28.0"
@ -43,7 +42,7 @@ toml = "0.8.19"
femtovg = "0.9.2" femtovg = "0.9.2"
rust-embed = "8.5.0" rust-embed = "8.5.0"
tempfile = "3.12.0" tempfile = "3.12.0"
radarg_data = { path = "../radarg_data" } relm4 = { version = "0.9.0", features = ["libadwaita"] }
[features] [features]
default = ["sdf_font"] default = ["sdf_font"]
@ -57,3 +56,6 @@ femtovg = []
[lib] [lib]
name = "gi" name = "gi"
[dependencies.radarg_core]
path = "../radarg_core"

View File

@ -4,7 +4,7 @@ use nalgebra_glm::{look_at, Mat4x4, Vec3};
use std::num::NonZeroU32; use std::num::NonZeroU32;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Camera { pub struct Camera {
pos: Vec3, pos: Vec3,
upward: Vec3, upward: Vec3,
center: Vec3, center: Vec3,

View File

@ -28,14 +28,18 @@ impl LinearColormap {
} }
pub fn set_unvalid_value(&mut self, value: f32) { pub fn set_unvalid_value(&mut self, value: f32) {
if value != self.unvalid {
self.unvalid = value; self.unvalid = value;
self.color_changed = true; self.color_changed = true;
} }
}
pub fn set_colors(&mut self, colors: Vec<[u8; 4]>) { pub fn set_colors(&mut self, colors: Vec<[u8; 4]>) {
if colors != self.colors {
self.colors = colors; self.colors = colors;
self.color_changed = true; self.color_changed = true;
} }
}
pub fn set_range(&mut self, min: f32, max: f32) { pub fn set_range(&mut self, min: f32, max: f32) {
self.min = min; self.min = min;
@ -104,6 +108,9 @@ impl ColorMap for LinearColormap {
gl.active_texture(glow::TEXTURE0); gl.active_texture(glow::TEXTURE0);
gl.bind_texture(glow::TEXTURE_1D, self.texture); gl.bind_texture(glow::TEXTURE_1D, self.texture);
let location = program.get_uniform_location(gl, "colormap"); let location = program.get_uniform_location(gl, "colormap");
let error = gl.get_error();
gl.uniform_1_i32(location.as_ref(), 0); gl.uniform_1_i32(location.as_ref(), 0);
} }

View File

@ -7,7 +7,7 @@ use crate::components::{Program, Shader};
use crate::errors::*; use crate::errors::*;
use crate::graphics::colormap::linear::LinearColormap; use crate::graphics::colormap::linear::LinearColormap;
use glow::{HasContext, NativeBuffer, NativeVertexArray}; use glow::{HasContext, NativeBuffer, NativeVertexArray};
use radarg_data::{CoordType, ProbeDataType, RadarGridData}; use radarg_core::radarg_data::{CoordType, ProbeDataType, RadarGridData};
pub struct PPI { pub struct PPI {
program: Program, program: Program,
@ -201,10 +201,12 @@ impl AttaWithBuffer for PPI {
let mut vertices = Vec::with_capacity(azimuth_len * r_len); let mut vertices = Vec::with_capacity(azimuth_len * r_len);
let ele = *elevation.unwrap().get(layer).unwrap() as f32; let ele = *elevation.unwrap().get(layer).unwrap() as f32;
let last_range = *range.last().unwrap() as f32;
for azi_idx in 0..azimuth_len { for azi_idx in 0..azimuth_len {
for r_idx in 0..r_len { for r_idx in 0..r_len {
let azi = *azimuth.get(azi_idx).unwrap() as f32; let azi = *azimuth.get(azi_idx).unwrap() as f32;
let r = *range.get(r_idx).unwrap() as f32 / range[1] as f32; let r = *range.get(r_idx).unwrap() as f32 / last_range;
let data = &data.data; let data = &data.data;
let dt = data.get([layer, azi_idx, r_idx]).unwrap(); let dt = data.get([layer, azi_idx, r_idx]).unwrap();
vertices.extend([r, azi, ele, *dt]); vertices.extend([r, azi, ele, *dt]);

View File

@ -59,8 +59,8 @@ impl AttachWithIO for PlaneTrans {
// let shift_key = state.keyboard_state[imgui::Key::LeftShift as usize]; // let shift_key = state.keyboard_state[imgui::Key::LeftShift as usize];
// let ctrl_key = state.keyboard_state[imgui::Key::LeftCtrl as usize]; // let ctrl_key = state.keyboard_state[imgui::Key::LeftCtrl as usize];
let shift_key = true; let shift_key = false;
let ctrl_key = true; let ctrl_key = false;
match &state.mouse_state { match &state.mouse_state {
MouseState::Drag { from, delta } => { MouseState::Drag { from, delta } => {

View File

@ -6,7 +6,6 @@ mod errors;
mod font_manager; mod font_manager;
pub mod graphics; pub mod graphics;
pub mod pg; pub mod pg;
mod setting;
mod shaders; mod shaders;
pub mod ui; pub mod ui;
mod utils; mod utils;

View File

@ -1,5 +1,5 @@
use log::*; use log::*;
use radarg_data::Data; use radarg_core::radarg_data::Data;
use std::{cell::RefCell, path::PathBuf, rc::Rc}; use std::{cell::RefCell, path::PathBuf, rc::Rc};
use crate::{ use crate::{
@ -61,8 +61,12 @@ impl App {
&mut self.context.programs &mut self.context.programs
} }
pub fn load_data(&mut self, data: &Vec<Data>) -> Result<ModulePackage> { pub fn load_data(
self.program().load_data(data) &mut self,
data: &Vec<Data>,
setting: &radarg_core::config::Setting,
) -> Result<ModulePackage> {
self.program().load_data(data, setting)
} }
} }

View File

@ -3,7 +3,14 @@ use femtovg::renderer::OpenGl;
use femtovg::Canvas; use femtovg::Canvas;
use glow::HasContext; use glow::HasContext;
use layout_type::ViewPort; use layout_type::ViewPort;
use radarg_data::Data; use modules::PPIModuleConfigComponent;
use radarg_core::radarg_data::Data;
use relm4::{
gtk,
gtk::prelude::{Cast, IsA},
gtk::Widget,
Component, ComponentBuilder, Controller, Sender,
};
pub mod layout_type; pub mod layout_type;
mod modules; mod modules;
@ -20,10 +27,19 @@ use crate::utils::resources::GL;
use crate::{errors::*, graphics::Graphics}; use crate::{errors::*, graphics::Graphics};
pub use app::{App, Context}; pub use app::{App, Context};
pub use modules::{Module, ModuleCursor, PPIModule, PPIPackage}; pub use modules::{Module, ModuleCursor, PPIModule, PPIPackage};
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0); static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug)]
pub enum SideBarInputMsg {
Package(Rc<RefCell<ModulePackage>>),
Refresh,
None,
}
pub struct Programs { pub struct Programs {
gl: GL, gl: GL,
_ppi: PPI, _ppi: PPI,
@ -61,10 +77,16 @@ impl Programs {
PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line) PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line)
} }
pub fn load_data(&mut self, data: &Vec<Data>) -> Result<ModulePackage> { pub fn load_data(
&mut self,
data: &Vec<Data>,
setting: &radarg_core::config::Setting,
) -> Result<ModulePackage> {
let data = &data[0]; let data = &data[0];
match data { match data {
Data::RadarGridData(ref grid_data) => self.ppi().load_data(grid_data).map(|v| v.into()), Data::RadarGridData(ref grid_data) => {
self.ppi().load_data(grid_data, setting).map(|v| v.into())
}
_ => Err(Error::InvalidDataType), _ => Err(Error::InvalidDataType),
} }
} }
@ -86,7 +108,15 @@ impl Programs {
} }
macro_rules! impl_module_package { macro_rules! impl_module_package {
($({$t:ty => $b: tt}),+) => { ($({$t:ty => $b: tt | $c: ty}),+) => {
#[derive(Debug)]
pub enum _ModulePackage {
$(
$b($t),
)+
}
$( $(
impl From<$t> for _ModulePackage { impl From<$t> for _ModulePackage {
@ -95,29 +125,65 @@ macro_rules! impl_module_package {
} }
} }
)+ )+
};
}
#[derive(Debug)] pub enum ComponentBuilders {
pub struct ModulePackage { $(
$b(ComponentBuilder<$c>, Rc<RefCell<<$t as ModuleCursor>::Config>>, Box<dyn Fn(<$t as ModuleCursor>::ComponentOutput) -> SideBarInputMsg>),
)+
}
pub enum Components {
$(
$b(Controller<$c>),
)+
}
impl Components {
pub fn widget(&self) -> gtk::Widget{
use relm4::ComponentController;
match self {
$(
Components::$b(c) => c.widget().clone().upcast(),
)+
}
}
}
#[derive(Debug)]
pub struct ModulePackage {
id: usize, id: usize,
pub need_update: bool, pub need_update: bool,
modules: _ModulePackage, modules: _ModulePackage,
} }
#[derive(Debug)] impl ModulePackage {
pub enum _ModulePackage {
PPI(PPIPackage),
}
impl_module_package!({ pub fn component_builder(&self) -> ComponentBuilders {
PPIPackage => PPI match &self.modules {
}); $(
_ModulePackage::$b(t) => ComponentBuilders::$b(<$c as Component>::builder(), t.component_config(), t.component_sender()),
)+
}
}
impl<T> From<T> for ModulePackage }
where
impl ComponentBuilders {
pub fn build<ROOT: IsA<Widget>>(self, package: &ModulePackage, root: &ROOT, sender: &Sender<SideBarInputMsg>) -> Components {
match self {
$(
ComponentBuilders::$b(b, init, f) => Components::$b(b.launch(init).forward(sender, move |c| {f(c)})),
)+
}
}
}
impl<T> From<T> for ModulePackage
where
T: ModuleCursor + Into<_ModulePackage>, T: ModuleCursor + Into<_ModulePackage>,
{ {
fn from(t: T) -> Self { fn from(t: T) -> Self {
Self { Self {
id: MODULE_PACKAGE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst), id: MODULE_PACKAGE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
@ -125,14 +191,21 @@ where
need_update: true, need_update: true,
} }
} }
} }
impl PartialEq for ModulePackage { impl PartialEq for ModulePackage {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.id == other.id self.id == other.id
} }
}
};
} }
impl_module_package!(
{PPIPackage => PPI | PPIModuleConfigComponent}
);
impl ModulePackage { impl ModulePackage {
pub fn dirty(&mut self) { pub fn dirty(&mut self) {
self.need_update = true; self.need_update = true;

View File

@ -1,5 +1,3 @@
use std::rc::Rc;
use crate::{ use crate::{
graphics::AttachWithIO, graphics::AttachWithIO,
resources::{RcGlRcBuffer, RcGlRcVertexArray}, resources::{RcGlRcBuffer, RcGlRcVertexArray},
@ -12,11 +10,14 @@ use crate::{
}; };
use femtovg::{renderer::OpenGl, Canvas}; use femtovg::{renderer::OpenGl, Canvas};
use glow::{HasContext, NativeBuffer, NativeVertexArray}; use glow::{HasContext, NativeBuffer, NativeVertexArray};
use radarg_core::config::Setting;
use std::{cell::RefCell, path::Component, rc::Rc};
mod ppi; mod ppi;
use crate::errors::*; use crate::errors::*;
pub use ppi::{PPIModule, PPIPackage}; pub use ppi::{PPIModule, PPIModuleConfigComponent, PPIModuleConfigComponentWidgets, PPIPackage};
use relm4::Component as RComponent;
use super::layout_type::ViewPort; use super::{layout_type::ViewPort, SideBarInputMsg};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct Attach { struct Attach {
@ -101,15 +102,22 @@ pub trait Module: Sized {
viewport: &ViewPort, viewport: &ViewPort,
) -> Result<()>; ) -> Result<()>;
fn load_data<'dt>(&self, data: &Rc<Self::Data>) -> Result<Self::Cursor>; fn load_data<'dt>(&self, data: &Rc<Self::Data>, setting: &Setting) -> Result<Self::Cursor>;
} }
pub trait ModuleCursor { pub trait ModuleCursor {
type Module<'rf, 'gl: 'rf>: Module; type Module<'rf, 'gl: 'rf>: Module;
type Data; type Data;
type Config; type Config;
type Component: RComponent;
type ComponentOutput;
fn set_config<F>(&mut self, f: F) fn set_config<F>(&mut self, f: F)
where where
F: FnOnce(&mut Self::Config); F: FnOnce(&mut Self::Config);
fn component_config(&self) -> Rc<RefCell<Self::Config>>;
fn component_sender(&self) -> Box<dyn Fn(Self::ComponentOutput) -> SideBarInputMsg>;
} }

View File

@ -6,12 +6,22 @@ use crate::{
transforms::plane::PlaneTrans, transforms::plane::PlaneTrans,
AttaWithBuffer, Graphics, AttaWithBuffer, Graphics,
}, },
pg::SideBarInputMsg,
GL, GL,
}; };
use radarg_core::config::Setting;
use relm4::{
adw::{self, prelude::*},
gtk::{self, prelude::*},
ComponentParts, SimpleComponent,
};
use core::f32; use core::f32;
use glow::HasContext; use glow::HasContext;
use std::rc::Rc; use std::{
cell::{RefCell, RefMut},
rc::Rc,
};
use tracker::track; use tracker::track;
use crate::font_manager::{FontSize, FontStyle}; use crate::font_manager::{FontSize, FontStyle};
@ -20,7 +30,7 @@ use crate::pg::layout_type::ViewPort;
use crate::ui::operation::{self, Operation}; use crate::ui::operation::{self, Operation};
use crate::{errors::*, font_manager::FontManager, ui::typ, utils::resources::ManagedResource}; use crate::{errors::*, font_manager::FontManager, ui::typ, utils::resources::ManagedResource};
use radarg_data::RadarGridData; use radarg_core::radarg_data::RadarGridData;
use super::{Attach, Module, ModuleCursor}; use super::{Attach, Module, ModuleCursor};
pub struct PPIModule<'b, 'gl: 'b> { pub struct PPIModule<'b, 'gl: 'b> {
@ -154,14 +164,16 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
operation: &Operation<Self::Operation>, operation: &Operation<Self::Operation>,
viewport: &ViewPort, viewport: &ViewPort,
) -> Result<()> { ) -> Result<()> {
// PPI Program
let data = &cursor.data;
let mut config = &mut cursor.ppi_config.borrow_mut();
// Mount PPI Program // Mount PPI Program
self.ppi_program.mount(&self.gl)?; self.ppi_program.mount(&self.gl)?;
// Deal with the operation // Deal with the operation
operation.attach_with_program(&self.gl, self.ppi_program.program()); operation.attach_with_program(&self.gl, self.ppi_program.program());
// PPI Program
let ppi_attach = &mut cursor.ppi_attach; let ppi_attach = &mut cursor.ppi_attach;
let data = &cursor.data;
let config = &mut cursor.ppi_config;
// Update the config // Update the config
self.ppi_program self.ppi_program
@ -172,13 +184,6 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
self.bind_ppi_pg(ppi_attach, data, config); self.bind_ppi_pg(ppi_attach, data, config);
} }
if config.changed_range_line_num()
|| config.changed_ath_line_num()
|| config.changed_vertical_axis()
{
self.bind_line_pg(&mut cursor.line_attach, data, config)?;
}
// PPI Draw // PPI Draw
ppi_attach.bind_self(); ppi_attach.bind_self();
self.ppi_program.draw(&self.gl, ppi_attach.len())?; self.ppi_program.draw(&self.gl, ppi_attach.len())?;
@ -187,6 +192,13 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
// Unmount PPI Program // Unmount PPI Program
self.ppi_program.unmount(&self.gl)?; self.ppi_program.unmount(&self.gl)?;
if config.changed_range_line_num()
|| config.changed_ath_line_num()
|| config.changed_vertical_axis()
{
self.bind_line_pg(&mut cursor.line_attach, data, config)?;
}
// Mount Line Program // Mount Line Program
self.line_program.mount(&self.gl)?; self.line_program.mount(&self.gl)?;
@ -226,7 +238,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
Ok(()) Ok(())
} }
fn load_data<'dt>(&self, data: &Rc<Self::Data>) -> Result<Self::Cursor> { fn load_data<'dt>(&self, data: &Rc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
// Init the memory // Init the memory
let (vao, vbo, ebo) = self.ppi_program.init(&self.gl); let (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None); let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
@ -235,15 +247,13 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?; let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?;
// Find the color map // Find the color map
// let cmap = SETTING.find(&t); let cmap = setting.find(&t);
// let cmap = None;
// Check if the color map is valid // Check if the color map is valid
// if cmap.is_none() { if cmap.is_none() {
// return Err(Error::InvalidDataType); return Err(Error::InvalidDataType);
// } }
// let cmap = cmap.unwrap(); let cmap = cmap.unwrap();
// Init the memory for the line program // Init the memory for the line program
let (vao, vbo, ebo) = self.line_program.init(&self.gl); let (vao, vbo, ebo) = self.line_program.init(&self.gl);
@ -258,8 +268,8 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
config.adpi = a; config.adpi = a;
config.max_layer = max_layer; config.max_layer = max_layer;
config.unvalid_value = unvalid; config.unvalid_value = unvalid;
// config.colors = cmap.color()?; config.colors = cmap.color().unwrap();
// config.color_range = cmap.value_range(); config.color_range = cmap.value_range();
// Bind the data // Bind the data
self.bind_ppi_pg(&mut ppi_attach, &data, &config); self.bind_ppi_pg(&mut ppi_attach, &data, &config);
@ -280,7 +290,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct PPIPackage { pub struct PPIPackage {
draw_helper: bool, draw_helper: bool,
ppi_config: PPIModuleConfig, ppi_config: Rc<RefCell<PPIModuleConfig>>,
ppi_attach: Attach, ppi_attach: Attach,
line_attach: Attach, line_attach: Attach,
tick_attach: Attach, tick_attach: Attach,
@ -297,7 +307,7 @@ impl PPIPackage {
) -> Self { ) -> Self {
Self { Self {
draw_helper: true, draw_helper: true,
ppi_config, ppi_config: Rc::new(RefCell::new(ppi_config)),
ppi_attach, ppi_attach,
line_attach, line_attach,
tick_attach, tick_attach,
@ -307,7 +317,7 @@ impl PPIPackage {
} }
#[track] #[track]
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug, Clone)]
pub struct PPIModuleConfig { pub struct PPIModuleConfig {
pub ticks: bool, pub ticks: bool,
pub line_color: [f32; 4], pub line_color: [f32; 4],
@ -388,15 +398,92 @@ impl PPIModuleConfig {
} }
} }
pub struct PPIModuleConfigComponent {
config: Rc<RefCell<PPIModuleConfig>>,
}
#[derive(Debug)]
pub enum OutputMsg {
Refresh,
}
#[relm4::component(pub)]
impl SimpleComponent for PPIModuleConfigComponent {
type Widgets = PPIModuleConfigComponentWidgets;
type Init = Rc<RefCell<PPIModuleConfig>>;
type Input = ();
type Output = OutputMsg;
view! {
adw::PreferencesGroup {
set_title:"PPI Config",
set_hexpand:true,
set_vexpand:true,
adw::SwitchRow {
set_title:"Ticks",
set_active: init_config.ticks,
connect_active_notify[sender, config_ref] => move |this| {
let active = this.is_active();
config_ref.borrow_mut().set_ticks(active);
}
},
adw::SpinRow {
set_title: "Layer",
set_value: init_config.layer as f64,
set_range: (0.0, init_config.max_layer as f64),
set_digits: 0,
set_numeric: true,
set_climb_rate: 1.0,
connect_value_notify[sender, config_ref] => move |this| {
let layer = this.value() as usize;
config_ref.borrow_mut().set_layer(layer);
}
}
}
}
fn init(
init: Self::Init,
root: Self::Root,
sender: relm4::ComponentSender<Self>,
) -> relm4::ComponentParts<Self> {
let model = PPIModuleConfigComponent {
config: init.clone(),
};
let init_config = init.borrow().clone();
let config_ref = model.config.clone();
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender<Self>) {}
}
impl ModuleCursor for PPIPackage { impl ModuleCursor for PPIPackage {
type Module<'rf, 'gl: 'rf> = PPIModule<'rf, 'gl>; type Module<'rf, 'gl: 'rf> = PPIModule<'rf, 'gl>;
type Config = PPIModuleConfig; type Config = PPIModuleConfig;
type Data = RadarGridData; type Data = RadarGridData;
type Component = PPIModuleConfigComponent;
type ComponentOutput = OutputMsg;
fn set_config<F>(&mut self, f: F) fn set_config<F>(&mut self, f: F)
where where
F: FnOnce(&mut Self::Config), F: FnOnce(&mut Self::Config),
{ {
f(&mut self.ppi_config); let mut config = self.ppi_config.borrow_mut();
f(&mut config);
}
fn component_config(&self) -> Rc<RefCell<Self::Config>> {
self.ppi_config.clone()
}
fn component_sender(&self) -> Box<dyn Fn(Self::ComponentOutput) -> crate::pg::SideBarInputMsg> {
Box::new(|c| match c {
OutputMsg::Refresh => SideBarInputMsg::Refresh,
})
} }
} }

View File

@ -1,3 +1,4 @@
#[derive(Debug, Default)]
pub struct MouseIO { pub struct MouseIO {
pub position: [f32; 2], // 鼠标当前位置 pub position: [f32; 2], // 鼠标当前位置
pub drag_delta: Option<[f32; 2]>, // 拖动开始时的鼠标位置 pub drag_delta: Option<[f32; 2]>, // 拖动开始时的鼠标位置
@ -5,12 +6,21 @@ pub struct MouseIO {
pub left_button_pressed: bool, // 左键是否被按下 pub left_button_pressed: bool, // 左键是否被按下
pub right_button_pressed: bool, // 右键是否被按下 pub right_button_pressed: bool, // 右键是否被按下
pub wheel_delta: f32, // 鼠标滚轮变化值 pub wheel_delta: f32, // 鼠标滚轮变化值
pub drag_sum: [f32; 2], // 拖动累计值
} }
#[derive(Debug)]
pub struct KeyboardIO { pub struct KeyboardIO {
pub keys: [bool; 652], // 键盘按键状态 pub keys: [bool; 652], // 键盘按键状态
} }
impl Default for KeyboardIO {
fn default() -> Self {
Self { keys: [false; 652] }
}
}
#[derive(Debug, Default)]
pub struct IO { pub struct IO {
pub mouse: MouseIO, pub mouse: MouseIO,
pub keyboard: KeyboardIO, pub keyboard: KeyboardIO,

View File

@ -53,7 +53,6 @@ abi_stable = "0.11.3"
serde = "1.0.196" serde = "1.0.196"
serde_json = "1.0.112" serde_json = "1.0.112"
flate2 = "1.0.28" flate2 = "1.0.28"
toml = "0.8.8"
dirs = "5.0.1" dirs = "5.0.1"
regex = "1.10.3" regex = "1.10.3"
smallvec = "1.13.1" smallvec = "1.13.1"
@ -86,8 +85,8 @@ path = "../radarg_plugin_interface"
[dependencies.gi] [dependencies.gi]
path = "../gi" path = "../gi"
[dependencies.radarg_data] [dependencies.radarg_core]
path = "../radarg_data" path = "../radarg_core"
#[dependencies.etws_loader] #[dependencies.etws_loader]
#path = "etws_loader" #path = "etws_loader"

View File

@ -1,2 +0,0 @@
[plugins]
etws_loader = { version = "0.1.0" }

View File

@ -9,11 +9,8 @@ use super::{
use crate::components::sidebar::{SideBarInputMsg, SideBarModel}; use crate::components::sidebar::{SideBarInputMsg, SideBarModel};
use crate::datapool::{DataPool, Value}; use crate::datapool::{DataPool, Value};
use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete}; use crate::predefined::color_mapper::{BoundaryNorm, ColorMapper, ColorMapperComb, Discrete};
use crate::predefined::widgets::ColorBar;
use crate::widgets::{DynamicCol, ElementType}; use crate::widgets::{DynamicCol, ElementType};
use crate::{ use crate::{plugin_system::init_plugin, widgets::render::Layer, PLUGIN_MANAGER};
errors::RenderError, plugin_system::init_plugin, widgets::render::Layer, PLUGIN_MANAGER,
};
use abi_stable::std_types::RStr; use abi_stable::std_types::RStr;
use adw::prelude::*; use adw::prelude::*;
use chrono::{prelude::*, Duration}; use chrono::{prelude::*, Duration};
@ -24,7 +21,7 @@ use gtk::glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use ndarray::{ArrayView1, ArrayViewD}; use ndarray::{ArrayView1, ArrayViewD};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use radarg_data::Data; use radarg_core::Data;
use relm4::actions::{AccelsPlus, RelmAction, RelmActionGroup}; use relm4::actions::{AccelsPlus, RelmAction, RelmActionGroup};
use relm4::*; use relm4::*;
use relm4::{gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent}; use relm4::{gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
@ -70,6 +67,7 @@ pub enum FileIOType {
#[derive(Debug)] #[derive(Debug)]
pub enum AppMsg { pub enum AppMsg {
Refresh,
FileIO { typ: FileIOType }, FileIO { typ: FileIOType },
CloseRequest, CloseRequest,
Close, Close,
@ -82,8 +80,8 @@ pub struct AppModel {
// Components // Components
#[do_not_track] #[do_not_track]
open_dialog: Controller<OpenDialog>, open_dialog: Controller<OpenDialog>,
#[do_not_track] // #[do_not_track]
control: Controller<ControlPanelModel>, // control: Controller<ControlPanelModel>,
#[do_not_track] #[do_not_track]
render: Controller<MonitorModel>, render: Controller<MonitorModel>,
#[do_not_track] #[do_not_track]
@ -160,7 +158,7 @@ impl Component for AppModel {
set_hexpand: true, set_hexpand: true,
}, },
}, },
model.control.widget(), // model.control.widget(),
#[name="monitor_toast"] #[name="monitor_toast"]
adw::ToastOverlay{ adw::ToastOverlay{
set_hexpand: true, set_hexpand: true,
@ -214,20 +212,23 @@ impl Component for AppModel {
sender: ComponentSender<Self>, sender: ComponentSender<Self>,
) -> ComponentParts<Self> { ) -> ComponentParts<Self> {
let layers = Rc::new(RefCell::new(vec![])); let layers = Rc::new(RefCell::new(vec![]));
let control = ControlPanelModel::builder().launch(layers.clone()).forward( // let control = ControlPanelModel::builder().launch(layers.clone()).forward(
sender.input_sender(), // sender.input_sender(),
|msg| match msg { // |msg| match msg {
ControlPanelOutputMsg::OpenFile((key, time)) => AppMsg::Close, // ControlPanelOutputMsg::OpenFile((key, time)) => AppMsg::Close,
}, // },
); // );
let data_pool = DataPool::new(10); let data_pool = DataPool::new(10);
let data_pool = Rc::new(RefCell::new(data_pool)); let data_pool = Rc::new(RefCell::new(data_pool));
// SideBar Component // SideBar Component
let sidebar = SideBarModel::builder() let sidebar = SideBarModel::builder()
.launch(layers.clone()) .launch(None)
.forward(sender.input_sender(), |msg| AppMsg::Close); .forward(sender.input_sender(), |msg| match msg {
SideBarOutputMsg::QueueDraw => AppMsg::Refresh,
_ => AppMsg::Close,
});
let sidebar_sender = sidebar.sender(); let sidebar_sender = sidebar.sender();
@ -239,6 +240,7 @@ impl Component for AppModel {
sidebar_sender, sidebar_sender,
move |model_message| match model_message { move |model_message| match model_message {
MonitorOutputMsg::Attached(new_module) => { MonitorOutputMsg::Attached(new_module) => {
sidebar_sender.emit(SideBarInputMsg::Package(new_module));
AppMsg::Close AppMsg::Close
} }
_ => AppMsg::Close, _ => AppMsg::Close,
@ -290,7 +292,7 @@ impl Component for AppModel {
selected_layer: vec![], selected_layer: vec![],
sidebar, sidebar,
file_pool: data_pool, file_pool: data_pool,
control, // control,
layers, layers,
tracker: 0, tracker: 0,
}; };
@ -331,6 +333,8 @@ impl Component for AppModel {
AppMsg::FileIO { AppMsg::FileIO {
typ: FileIOType::Open(data), typ: FileIOType::Open(data),
} => self.render.emit(MonitorInputMsg::PushData(data)), } => self.render.emit(MonitorInputMsg::PushData(data)),
AppMsg::Refresh => self.render.emit(MonitorInputMsg::QueueDraw),
_ => {} _ => {}
} }
self.update_view(widgets, _sender); self.update_view(widgets, _sender);

View File

@ -1,16 +1,18 @@
use crate::datapool::Value; use crate::datapool::Value;
use gi::pg::ModulePackage; use gi::pg::ModulePackage;
use radarg_data::Data; use radarg_core::Data;
use std::{cell::RefCell, fmt::Debug, rc::Rc}; use std::{cell::RefCell, fmt::Debug, rc::Rc};
pub enum MonitorInputMsg { pub enum MonitorInputMsg {
PushData(Value<Data>), PushData(Value<Data>),
QueueDraw,
None, None,
} }
impl Debug for MonitorInputMsg { impl Debug for MonitorInputMsg {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
MonitorInputMsg::QueueDraw => write!(f, "MonitorInputMsg::QueueDraw"),
MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data), MonitorInputMsg::PushData(data) => write!(f, "MonitorInputMsg::PushData({:?})", data),
MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"), MonitorInputMsg::None => write!(f, "MonitorInputMsg::None"),
} }

View File

@ -1,6 +1,7 @@
use super::messages::{MonitorInputMsg, MonitorOutputMsg}; use super::messages::{MonitorInputMsg, MonitorOutputMsg};
use crate::predefined::color_mapper::BoundaryNorm; use crate::predefined::color_mapper::BoundaryNorm;
use crate::widgets::render::RenderConfig; use crate::widgets::render::RenderConfig;
use crate::SETTING;
use crate::{ use crate::{
widgets::dynamic_col::DynamicCol, widgets::dynamic_col::DynamicCol,
widgets::render::{Layer, Render}, widgets::render::{Layer, Render},
@ -94,7 +95,9 @@ impl Component for MonitorModel {
self.reset(); self.reset();
match message { match message {
MonitorInputMsg::PushData(data) => { MonitorInputMsg::PushData(data) => {
widgets.renderer.get_gi(|gi| match gi.load_data(&data) { widgets
.renderer
.get_gi(|gi| match gi.load_data(&data, &SETTING) {
Ok(package) => { Ok(package) => {
info!("data load success!"); info!("data load success!");
let rc_package = Rc::new(RefCell::new(package)); let rc_package = Rc::new(RefCell::new(package));
@ -106,6 +109,9 @@ impl Component for MonitorModel {
} }
}) })
} }
MonitorInputMsg::QueueDraw => {
widgets.renderer.queue_draw();
}
MonitorInputMsg::None => {} MonitorInputMsg::None => {}
_ => {} _ => {}
} }

View File

@ -1,11 +1,10 @@
use crate::actions::*; use crate::actions::*;
use gi::pg::SideBarInputMsg;
use gtk::prelude::*; use gtk::prelude::*;
use relm4::{ use relm4::{
actions::traits::ActionablePlus, factory::FactoryView, gtk, prelude::*, FactorySender, actions::traits::ActionablePlus, factory::FactoryView, gtk, prelude::*, FactorySender,
}; };
use super::SideBarInputMsg;
#[derive(Debug)] #[derive(Debug)]
pub enum TestMsg { pub enum TestMsg {
Delete, Delete,

View File

@ -2,3 +2,4 @@ pub mod sidebar;
pub use sidebar::*; pub use sidebar::*;
pub mod bottom_bar; pub mod bottom_bar;
pub mod meta_data_list; pub mod meta_data_list;
pub use gi::pg::SideBarInputMsg;

View File

@ -1,11 +1,14 @@
use crate::actions::*; use crate::actions::*;
use abi_stable::type_level::trait_marker::Hash; use abi_stable::type_level::trait_marker::Hash;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use gi::pg::SideBarInputMsg;
use gi::pg::{Components, ModulePackage};
use glib_macros::clone; use glib_macros::clone;
use gtk::glib; use gtk::glib;
use gtk::prelude::WidgetExt; use gtk::prelude::WidgetExt;
use gtk::prelude::*; use gtk::prelude::*;
use relm4::actions::{AccelsPlus, RelmAction}; use relm4::actions::{AccelsPlus, RelmAction};
use relm4::RelmRemoveAllExt;
use relm4::{ use relm4::{
binding::{Binding, U8Binding}, binding::{Binding, U8Binding},
factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque}, factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque},
@ -28,34 +31,20 @@ use super::{
}; };
pub struct SideBarModel { pub struct SideBarModel {
layers: Rc<RefCell<Vec<Layer>>>, components: Option<Components>,
selected_layer_idx: usize,
counter: u8,
list_view_wrapper: TypedListView<LayerItem, gtk::MultiSelection>,
bottom_bar_vec: FactoryVecDeque<BottomBarModel>,
meta_list_view: TypedColumnView<MyListItem, gtk::NoSelection>,
}
#[derive(Debug)]
pub enum SideBarInputMsg {
AddMetaItems(HashMap<String, String>),
ClearMetaItems,
RefreshList,
None,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum SideBarOutputMsg { pub enum SideBarOutputMsg {
SelectLayer(Vec<usize>), QueueDraw,
NewLayer(Layer),
SwitchToTimeSeries(usize),
} }
#[relm4::component(pub)] #[relm4::component(pub)]
impl SimpleComponent for SideBarModel { impl Component for SideBarModel {
type Init = Rc<RefCell<Vec<Layer>>>; type Init = Option<Components>;
type Output = SideBarOutputMsg; type Output = SideBarOutputMsg;
type Input = SideBarInputMsg; type Input = SideBarInputMsg;
type CommandOutput = ();
view! { view! {
#[root] #[root]
@ -64,64 +53,10 @@ impl SimpleComponent for SideBarModel {
set_spacing: 5, set_spacing: 5,
set_margin_all: 5, set_margin_all: 5,
gtk::Paned{ #[name="container"]
set_orientation: gtk::Orientation::Vertical, gtk::Box {}
set_position: 200,
#[wrap(Some)]
set_start_child = &gtk::Box{
set_orientation: gtk::Orientation::Vertical,
set_spacing: 5,
gtk::Frame{
add_css_class: "rb",
#[name="meta_panel"]
gtk::Notebook::builder().vexpand(true).hexpand(true).build() -> gtk::Notebook{}
},
}, },
#[wrap(Some)]
set_end_child=&gtk::Box{
set_orientation: gtk::Orientation::Vertical,
set_vexpand: true,
set_hexpand: true,
#[name="bottom_panel"]
gtk::Notebook::builder().vexpand(true).build() -> gtk::Notebook{
set_margin_top: 10,
set_margin_bottom: 5
},
#[local_ref]
counter_box -> gtk::Box{
set_spacing: 5,
}
}
}
},
layer_page = gtk::ScrolledWindow::builder()
.vexpand(true)
.hexpand(true)
.build() -> gtk::ScrolledWindow{
#[wrap(Some)]
#[local_ref]
set_child=my_view -> gtk::ListView{
},
set_margin_horizontal:5,
set_margin_vertical:3
},
#[local_ref]
meta_view -> gtk::ColumnView{
set_hexpand:true,
set_vexpand:true,
set_show_column_separators: true,
set_show_row_separators: true,
set_enable_rubberband:true,
set_reorderable:false,
},
bottom_panel.append_page(&layer_page, Some(&gtk::Label::new(Some("Layers")))),
meta_panel.append_page(meta_view, Some(&gtk::Label::new(Some("Meta")))),
// meta_panel.append_page(&Chart::new(), Some(&gtk::Label::new(Some("Chart")))),
#[local_ref]
info_c -> gtk::ColumnViewColumn{
set_expand: true
}
} }
fn init( fn init(
@ -129,274 +64,40 @@ impl SimpleComponent for SideBarModel {
root: Self::Root, root: Self::Root,
sender: ComponentSender<Self>, sender: ComponentSender<Self>,
) -> ComponentParts<Self> { ) -> ComponentParts<Self> {
// Initialize the ListView wrapper
let mut list_view_wrapper: TypedListView<LayerItem, gtk::MultiSelection> =
TypedListView::with_sorting();
list_view_wrapper.selection_model.connect_selection_changed(
clone!(@strong sender => move |s,_, _| {
let selection = s.selection();
let (iter, first) = gtk::BitsetIter::init_first(&selection).unwrap();
let mut result = vec![first as usize];
result.extend(iter.map(|v| v as usize));
sender.output(SideBarOutputMsg::SelectLayer(result));
}),
);
// let mut bottom_bar_vec = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
let mut bottom_bar_vec =
FactoryVecDeque::builder()
.launch_default()
.forward(sender.input_sender(), |msg| match msg {
_ => SideBarInputMsg::None,
});
let app = relm4::main_application(); let app = relm4::main_application();
let mut model = SideBarModel { components: None };
{
let mut bottom_bar_vec_guard = bottom_bar_vec.guard();
bottom_bar_vec_guard.push_back(BottomBarModel::new("add-filled".to_string()));
bottom_bar_vec_guard.push_back(BottomBarModel::new("delete-filled".to_string()));
bottom_bar_vec_guard.push_back(BottomBarModel::new("chevron-up-filled".to_string()));
bottom_bar_vec_guard.push_back(BottomBarModel::new("chevron-down-filled".to_string()));
}
let mut meta_list_view = TypedColumnView::new();
meta_list_view.append_column::<TagColumn>();
meta_list_view.append_column::<InfoColumn>();
let mut model = SideBarModel {
meta_list_view,
layers: init,
selected_layer_idx: 0,
counter: 0,
list_view_wrapper,
bottom_bar_vec,
};
let my_view = &model.list_view_wrapper.view;
let counter_box = model.bottom_bar_vec.widget();
let meta_view = &model.meta_list_view.view;
let columns = model.meta_list_view.get_columns();
let info_c = columns.get("info").unwrap();
let widgets = view_output!(); let widgets = view_output!();
{
let mut list = model
.layers
.borrow()
.iter()
.enumerate()
.map(|(idx, v)| {
LayerItem::new(
idx as u32,
v.name.clone(),
v.visiable,
None,
LayerStatus::Instance,
)
})
.collect::<Vec<_>>();
model.list_view_wrapper.extend_from_iter(list);
}
ComponentParts { model, widgets } ComponentParts { model, widgets }
} }
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) { fn update_with_view(
&mut self,
widgets: &mut Self::Widgets,
message: Self::Input,
sender: ComponentSender<Self>,
root: &Self::Root,
) {
match message { match message {
SideBarInputMsg::RefreshList => { SideBarInputMsg::Package(package) => {
let mut list = self let package = package.borrow();
.layers let input_sender = sender.input_sender();
.borrow() let components = package
.iter() .component_builder()
.enumerate() .build(&package, root, input_sender);
.map(|(idx, v)| {
LayerItem::new( self.components = Some(components);
idx as u32,
v.name.clone(), widgets.container.remove_all();
v.visiable, widgets
None, .container
LayerStatus::Instance, // match v.get_associated_element() { .append(&self.components.as_ref().unwrap().widget());
// // AssoElement::TimeSeries(_) => LayerStatus::BindToTime(Utc::now()),
// // AssoElement::Instant(_) => LayerStatus::Instance,
// _ => LayerStatus::Instance,
//
)
})
.collect::<Vec<_>>();
self.list_view_wrapper.clear();
self.list_view_wrapper.extend_from_iter(list);
} }
SideBarInputMsg::AddMetaItems(hs) => {
for (k, v) in hs { SideBarInputMsg::Refresh => {
self.meta_list_view.append(MyListItem::new(k, v)); sender.output(SideBarOutputMsg::QueueDraw).unwrap();
}
}
SideBarInputMsg::ClearMetaItems => {
self.meta_list_view.clear();
} }
_ => {} _ => {}
} }
} }
} }
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
enum LayerStatus {
BindToTime(DateTime<Utc>),
Instance,
BindToOtherLayer(usize),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct LayerItem {
key: u32,
layer_name: String,
visiable: bool,
status: LayerStatus,
img: Option<gtk::gdk::Texture>,
}
impl LayerItem {
fn new(
key: u32,
name: String,
visiable: bool,
img: Option<gtk::gdk::Texture>,
status: LayerStatus,
) -> Self {
Self {
key,
layer_name: name,
visiable,
status,
img,
}
}
}
struct Widgets {
label: gtk::EditableLabel,
screen_shot: gtk::Image,
status_icon: gtk::Image,
status_label: gtk::Label,
visible: gtk::Button,
opacity: gtk::Label,
menu: gtk::Popover,
}
impl RelmListItem for LayerItem {
type Root = gtk::Box;
type Widgets = Widgets;
fn setup(_item: &gtk::ListItem) -> (gtk::Box, Widgets) {
let position = _item.position() as u8;
relm4::menu! {
main_menu: {
custom: "MyWidget",
"Remove" => RemoveLayerAction,
section!{
"test" => RemoveLayerAction,
"select" => AddLayerAction
}
}
}
relm4::view! {
my_box = gtk::Box {
set_valign: gtk::Align::Center,
gtk::Frame{
set_margin_end: 10,
#[name = "screen_shot"]
gtk::Image{
set_size_request: (65, 40),
}
},
gtk::Grid{
set_row_homogeneous: true,
attach[0,0,1,1] = &gtk::Box{
#[name="status_icon"]
gtk::Image{
inline_css: "-gtk-icon-transform: scale(0.8);",
},
#[name="status_label"]
gtk::Label{
add_css_class:"tooltip",
set_halign: gtk::Align::Start,
}
},
#[name="label"]
attach[0,1,1,1] = &gtk::EditableLabel{
set_hexpand: true,
},
#[name="opacity"]
attach[0,2,1,1] = &gtk::Label{
add_css_class:"tooltip",
set_halign: gtk::Align::Start
},
},
#[name="visible"]
gtk::Button{
set_vexpand: false,
set_hexpand: false,
},
#[name = "menu"]
gtk::Popover{}
}
}
let widgets = Widgets {
screen_shot,
label,
status_icon,
status_label,
opacity,
visible,
menu,
};
(my_box, widgets)
}
fn bind(&mut self, widgets: &mut Self::Widgets, _root: &mut Self::Root) {
let Widgets {
label,
visible,
screen_shot,
status_label,
status_icon,
opacity,
menu,
} = widgets;
status_label.set_label(&match self.status {
LayerStatus::BindToTime(t) => format!("Bind To Time: {}", t),
LayerStatus::Instance => "Instance".to_string(),
LayerStatus::BindToOtherLayer(idx) => format!("Bind To Layer: {}", idx),
});
status_icon.set_icon_name(Some(match self.status {
LayerStatus::BindToTime(_) => "timer-filled",
LayerStatus::Instance => "timer-filled",
LayerStatus::BindToOtherLayer(_) => "timer-filled",
}));
opacity.set_markup(&format!("<b>Opacity:</b> 0.5"));
let gesture_click = gtk::GestureClick::new();
gesture_click.set_button(gtk::gdk::BUTTON_SECONDARY);
screen_shot.set_paintable(self.img.as_ref());
let menu = menu.clone();
gesture_click.connect_released(clone!(@weak menu => move |gesture_click, _, x, y| {
menu.set_pointing_to(Some(&gtk::gdk::Rectangle::new(x as i32, y as i32, 1, 1)));
menu.popup();
}));
visible.set_icon_name("eye-filled");
_root.add_controller(gesture_click);
label.set_text(&self.layer_name);
// button.set_active(self.visiable);
}
}

View File

@ -1,12 +0,0 @@
use crate::errors::ConfigError;
use crate::predefined::color_mapper::{
BoundaryNorm, BoundaryNormDiscrete, ColorMapper, ColorMapperComb, Discrete,
};
use dirs;
use gtk::ResponseType::No;
use num_traits::{AsPrimitive, FromPrimitive};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use std::{collections::HashMap, env, io::Write, path::PathBuf};
use toml;

View File

@ -1,7 +1,7 @@
use crate::errors::DataError;
use crate::PLUGIN_MANAGER; use crate::PLUGIN_MANAGER;
use quick_cache::sync::Cache; use quick_cache::sync::Cache;
use radarg_data::Data; use radarg_core::errors::DataError;
use radarg_core::Data;
use std::fmt::Display; use std::fmt::Display;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;

View File

@ -10,20 +10,17 @@ use std::{ptr, sync::Mutex};
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
mod actions; mod actions;
mod components; mod components;
mod config;
mod datapool; mod datapool;
mod errors;
mod plugin_system; mod plugin_system;
use crate::components::app::AppMsg; use crate::components::app::AppMsg;
use components::app::AppModel; use components::app::AppModel;
use gi::{App as GI, Helper, GL};
use once_cell::{sync::Lazy as SafeLazy, unsync::Lazy as UnsafeLazy}; use once_cell::{sync::Lazy as SafeLazy, unsync::Lazy as UnsafeLazy};
use relm4::RelmApp; use relm4::RelmApp;
use surfman::declare_surfman; use surfman::declare_surfman;
use tracing::info; use tracing::info;
use tracing_subscriber; use tracing_subscriber;
use gi::{App as GI, Helper, GL};
mod predefined; mod predefined;
mod widgets; mod widgets;
@ -33,10 +30,13 @@ const APP_ID: &str = "org.tsuki.radar_g";
static RUNTIME: SafeLazy<Runtime> = static RUNTIME: SafeLazy<Runtime> =
SafeLazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed.")); SafeLazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
static PLUGIN_MANAGER: SafeLazy<PluginManager> = SafeLazy::new(|| PluginManager::new().unwrap()); static PLUGIN_MANAGER: SafeLazy<PluginManager> = SafeLazy::new(|| PluginManager::new().unwrap());
static SETTING: SafeLazy<radarg_core::config::Setting> =
SafeLazy::new(|| radarg_core::config::Setting::new());
fn main() { fn main() {
// Load GL pointers from epoxy (GL context management library used by GTK). // Load GL pointers from epoxy (GL context management library used by GTK).
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
{ {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let library = let library =

View File

@ -1,5 +1,3 @@
mod utils;
use crate::errors::DataError;
use abi_stable::{ use abi_stable::{
external_types::crossbeam_channel::{self, RReceiver, RSender}, external_types::crossbeam_channel::{self, RReceiver, RSender},
library::{lib_header_from_path, LibraryError, LibrarySuffix, RawLibrary}, library::{lib_header_from_path, LibraryError, LibrarySuffix, RawLibrary},
@ -7,7 +5,8 @@ use abi_stable::{
std_types::{RBox, RErr, ROk, RResult, RSome, RStr, RString, RVec}, std_types::{RBox, RErr, ROk, RResult, RSome, RStr, RString, RVec},
}; };
use core_extensions::*; use core_extensions::*;
use radarg_data::Data; use radarg_core::errors::DataError;
use radarg_core::Data;
use radarg_plugin_interface::{DataLoaderPlugin, DataLoaderPlugin_TO, PluginId, PluginMod_Ref}; use radarg_plugin_interface::{DataLoaderPlugin, DataLoaderPlugin_TO, PluginId, PluginMod_Ref};
use std::{ use std::{
collections::{HashMap, VecDeque}, collections::{HashMap, VecDeque},

View File

@ -1,5 +1,2 @@
pub mod map_tile;
// pub mod grid_field_renderer;
// pub mod layers;
pub mod color_mapper; pub mod color_mapper;
pub mod widgets; pub mod map_tile;

View File

@ -1,25 +0,0 @@
use crate::predefined::color_mapper::ColorMapper;
use crate::widgets::Layer;
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
use num_traits::*;
use std::any::Any;
use topojson::Arc;
#[derive(Debug)]
pub struct ColorBar {
padding: [f32; 4],
width: f32,
height: f32,
margin: [i32; 4],
}
impl ColorBar {
pub fn new(padding: [f32; 4], size: (f32, f32), margin: [i32; 4]) -> Self {
Self {
padding,
width: size.0,
height: size.1,
margin,
}
}
}

View File

@ -5,6 +5,7 @@ use femtovg::{Canvas, Color, FontId, Paint, Renderer};
use gi::graphics::transforms::plane::PlaneTrans; use gi::graphics::transforms::plane::PlaneTrans;
use gi::pg::layout_type::ViewPort; use gi::pg::layout_type::ViewPort;
use gi::pg::ModulePackage; use gi::pg::ModulePackage;
use gi::ui::io::IO;
use gi::ui::operation::Operation; use gi::ui::operation::Operation;
use gi::{App as GI, Helper, GL}; use gi::{App as GI, Helper, GL};
use glow::HasContext; use glow::HasContext;
@ -59,6 +60,7 @@ pub struct Render {
range_changing: Cell<f64>, range_changing: Cell<f64>,
#[property(get, set)] #[property(get, set)]
scale: Cell<f64>, scale: Cell<f64>,
pub(super) io: RefCell<IO>,
pub(super) opeartion: RefCell<Operation<PlaneTrans>>, pub(super) opeartion: RefCell<Operation<PlaneTrans>>,
pub(super) exterior: RefCell<ExteriorWidget>, pub(super) exterior: RefCell<ExteriorWidget>,
pub(super) interior: RefCell<InteriorWidget>, pub(super) interior: RefCell<InteriorWidget>,
@ -81,6 +83,7 @@ impl Default for Render {
0.1, 0.1,
1000.0, 1000.0,
)), )),
io: RefCell::new(IO::default()),
range_changing: Cell::new(0.0), range_changing: Cell::new(0.0),
render_status: Cell::new(0), render_status: Cell::new(0),
exterior: RefCell::new(ExteriorWidget::default()), exterior: RefCell::new(ExteriorWidget::default()),
@ -167,10 +170,14 @@ impl GLAreaImpl for Render {
} }
if let Some(gi) = gi.as_mut() { if let Some(gi) = gi.as_mut() {
let mut operation = self.opeartion.borrow_mut();
let viewport = self.viewport.borrow();
operation.deal_io(&viewport.as_ref().unwrap(), &self.io.borrow());
gi.render( gi.render(
&mut *self.modules.borrow_mut(), &mut *self.modules.borrow_mut(),
&*self.opeartion.borrow(), &mut operation,
self.viewport.borrow().as_ref().unwrap(), &viewport.as_ref().unwrap(),
); );
} }
@ -248,6 +255,11 @@ impl Render {
)) ))
} }
pub(super) fn set_io<F: FnMut(&mut IO)>(&self, mut f: F) {
let mut io = self.io.borrow_mut();
f(&mut io);
}
fn pointer_loc(&self) -> (f32, f32) { fn pointer_loc(&self) -> (f32, f32) {
let (x, y) = self.status.borrow().pointer_location.clone(); let (x, y) = self.status.borrow().pointer_location.clone();
let (_, h) = self.window_size().unwrap(); let (_, h) = self.window_size().unwrap();

View File

@ -1,7 +1,7 @@
use super::super::Render; use super::super::Render;
use crate::errors::PipelineError;
use crate::RUNTIME; use crate::RUNTIME;
use femtovg::{renderer::OpenGl, Canvas}; use femtovg::{renderer::OpenGl, Canvas};
use radarg_core::errors::PipelineError;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::{ use std::{

View File

@ -9,7 +9,6 @@ pub mod predefined;
pub mod renders; pub mod renders;
pub use self::imp::{RenderConfig, RenderMotion, RenderStatus}; pub use self::imp::{RenderConfig, RenderMotion, RenderStatus};
use crate::errors::PipelineError;
use adw::prelude::{GLAreaExt, GestureDragExt}; use adw::prelude::{GLAreaExt, GestureDragExt};
use femtovg::ImageFlags; use femtovg::ImageFlags;
use geo_types::LineString; use geo_types::LineString;
@ -17,6 +16,7 @@ use gtk::prelude::*;
use gtk::subclass::prelude::ObjectSubclassIsExt; use gtk::subclass::prelude::ObjectSubclassIsExt;
use gtk::EventControllerScrollFlags; use gtk::EventControllerScrollFlags;
pub use interior::*; pub use interior::*;
use radarg_core::errors::PipelineError;
use std::cell::{Ref, RefCell, RefMut}; use std::cell::{Ref, RefCell, RefMut};
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -43,15 +43,80 @@ impl Render {
let dpi = this.scale_factor() as f32; let dpi = this.scale_factor() as f32;
let pointer_location_detecture = gtk::EventControllerMotion::new(); let pointer_location_detecture = gtk::EventControllerMotion::new();
let dpi = this.scale_factor() as f32;
pointer_location_detecture.connect_motion(clone!(
#[weak]
this,
move |_, x, y| {
let hgt = this.height() as f32;
this.imp().set_io(|io| {
io.mouse.position = [x as f32 * dpi, hgt - y as f32 * dpi];
});
}
));
let scale_detecture = gtk::EventControllerScroll::new(EventControllerScrollFlags::VERTICAL); let scale_detecture = gtk::EventControllerScroll::new(EventControllerScrollFlags::VERTICAL);
scale_detecture.connect_scroll(clone!(
#[strong]
this,
move |_, x, y| {
this.imp().set_io(|io| {
io.mouse.wheel_delta = y as f32;
});
this.queue_draw();
glib::Propagation::Proceed
}
));
let drag_detecture = gtk::GestureDrag::new(); let drag_detecture = gtk::GestureDrag::new();
drag_detecture.connect_drag_begin(clone!(
#[weak]
this,
move |slf, _, _| {
let (ox, oy) = slf.offset().unwrap_or((0.0, 0.0));
let (ox, oy) = (ox as f32 * dpi, oy as f32 * dpi);
let hgt = this.height() as f32;
this.imp().set_io(|io| {
io.mouse.drag_sum = [ox, -oy];
io.mouse.drag_delta = Some([ox, -oy]);
io.mouse.is_dragging = true;
});
this.queue_draw();
}
));
drag_detecture.connect_drag_update(clone!(
#[weak]
this,
move |slf, _, _| {
let (ox, oy) = slf.offset().unwrap_or((0.0, 0.0));
let (ox, oy) = (ox as f32 * dpi, oy as f32 * dpi);
this.imp().set_io(|io| {
let last_drag_sum = io.mouse.drag_sum;
io.mouse.drag_delta = Some([ox - last_drag_sum[0], -oy - last_drag_sum[1]]);
io.mouse.drag_sum = [ox, -oy];
});
this.queue_draw();
}
));
drag_detecture.connect_drag_end(clone!( drag_detecture.connect_drag_end(clone!(
#[weak] #[weak]
this, this,
move |slf, _, _| { move |slf, _, _| {
let (ox, oy) = slf.offset().unwrap_or((0.0, 0.0)); this.imp().set_io(|io| {
println!("drag_update: {:?}", (ox, oy)); io.mouse.drag_sum = [0.0, 0.0];
io.mouse.drag_delta = None;
io.mouse.is_dragging = false;
});
this.queue_draw();
} }
)); ));

21
radarg_core/Cargo.toml Normal file
View File

@ -0,0 +1,21 @@
[package]
edition = "2021"
name = "radarg_core"
version = "0.1.0"
[dependencies]
chrono = "0.4.38"
ndarray = "0.16.1"
thiserror = "1.0.56"
rust-embed = "8.5.0"
toml = "0.8.19"
proj-sys = "0.23.1"
proj = "0.27.2"
dirs = "5.0.1"
num-traits = "0.2.19"
serde = { version = "1.0.209", features = ["derive"] }
relm4 = { version = "0.9.0", features = ["libadwaita"] }
[dependencies.radarg_plugin_interface]
version = "0.1"
path = "../radarg_plugin_interface"

View File

@ -1,13 +1,12 @@
use crate::errors::*; use crate::errors::ConfigError;
use radarg_data::ProbeDataType; use crate::radarg_data::ProbeDataType;
use serde::{Deserialize, Serialize};
use std::{
env,
fs::{read, read_to_string},
io::Write,
};
use crate::utils::color_tools::hex_to_rgba_u8; use crate::utils::color_tools::hex_to_rgba_u8;
use crate::Asset;
use dirs;
use num_traits::{AsPrimitive, FromPrimitive};
use serde::{Deserialize, Serialize};
use std::env;
use toml;
macro_rules! find_cmap { macro_rules! find_cmap {
($c:ident,$find_on:ident,$({$b:tt => $name:literal}),*) => { ($c:ident,$find_on:ident,$({$b:tt => $name:literal}),*) => {
@ -16,7 +15,7 @@ macro_rules! find_cmap {
let mut cmap = None; let mut cmap = None;
match $c { match $c {
$( $(
ProbeDataType::$b => { $b => {
let find_v = $find_on.iter().find(|cb| cb.type_name == $name).map(|cb| cb); let find_v = $find_on.iter().find(|cb| cb.type_name == $name).map(|cb| cb);
cmap = find_v; cmap = find_v;
} }
@ -31,41 +30,44 @@ macro_rules! find_cmap {
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct Setting { pub struct Setting {
pub cmap: Vec<CB>, pub cmap: Vec<CB>,
} }
impl Setting { impl Setting {
pub fn new() -> Self {
use std::fs::{read, read_to_string};
use std::io::*;
let current_dir = env::current_dir().unwrap();
if !current_dir.join("config.toml").exists() {
let default_config = Asset::get("config.toml").unwrap();
let mut folder_path = current_dir.clone();
let mut conf = folder_path.join("config.toml");
let mut file = std::fs::File::create_new(&conf).unwrap();
file.write_all(&default_config.data).unwrap();
}
let file = read_to_string(current_dir.join("config.toml")).unwrap();
let setting: Setting = toml::from_str(&file).unwrap();
setting
}
pub fn find(&self, name: &ProbeDataType) -> Option<&CB> { pub fn find(&self, name: &ProbeDataType) -> Option<&CB> {
let cmap = &self.cmap; let cmap = &self.cmap;
use ProbeDataType::*;
find_cmap!( find_cmap!(
name, cmap, name, cmap,
{DBZ => "DBZ"}, {DBZ => "DBZ"},
{V => "VEL"},
{VIL => "VIL"} {VIL => "VIL"}
) )
} }
} }
impl Setting {
pub fn new() -> Self {
let current_dir = env::current_dir().unwrap();
// if !current_dir.join("radar.toml").exists() {
// let default_config = Asset::get("radar.toml").unwrap();
// let mut folder_path = current_dir.clone();
// let mut conf = folder_path.join("radar.toml");
// let mut file = std::fs::File::create_new(&conf).unwrap();
// file.write_all(&default_config.data).unwrap();
// }
let file = read_to_string(current_dir.join("radar.toml")).unwrap();
let setting: Setting = toml::from_str(&file).unwrap();
setting
}
}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct CB { pub struct CB {
#[serde(rename = "type")] #[serde(rename = "type")]
@ -83,9 +85,11 @@ impl CB {
range range
} }
pub fn color(&self) -> Result<Vec<[u8; 4]>> { pub fn color(&self) -> Result<Vec<[u8; 4]>, ConfigError> {
if self.colors.len() != self.levels.len() - 1 { if self.colors.len() != self.levels.len() - 1 {
return Err(Error::SettingError("Color and level mismatch".to_string())); return Err(ConfigError::FormatError(
"The number of colors and levels are not matched".to_string(),
));
} }
let mut result = self let mut result = self
@ -93,7 +97,7 @@ impl CB {
.iter() .iter()
.map(|v| hex_to_rgba_u8(v)) .map(|v| hex_to_rgba_u8(v))
.collect::<std::result::Result<Vec<_>, String>>() .collect::<std::result::Result<Vec<_>, String>>()
.map_err(|v| Error::SettingError(v.to_string()))?; .map_err(|v| ConfigError::FormatError(v.to_string()))?;
let mut span = Vec::with_capacity(self.levels.len() - 1); let mut span = Vec::with_capacity(self.levels.len() - 1);

View File

@ -33,6 +33,8 @@ pub enum ConfigError {
VarError(#[from] std::env::VarError), VarError(#[from] std::env::VarError),
#[error("Can't find and create default Config")] #[error("Can't find and create default Config")]
DefaultConfigError, DefaultConfigError,
#[error("Format Error, {0}")]
FormatError(String),
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -44,13 +46,3 @@ pub enum PoolError {
#[error("Data Pool is not initialized")] #[error("Data Pool is not initialized")]
PoolInitialized(&'static str), PoolInitialized(&'static str),
} }
#[derive(Debug, Error)]
pub enum RenderError {
#[error("")]
PreRenderError(#[from] femtovg::ErrorKind),
#[error("")]
None,
#[error("Canceled")]
Canceled,
}

12
radarg_core/src/lib.rs Normal file
View File

@ -0,0 +1,12 @@
pub mod config;
pub mod errors;
pub mod radarg_data;
use rust_embed::RustEmbed;
pub mod utils;
pub mod widget_interface;
#[derive(RustEmbed)]
#[folder = "statics/"]
pub struct Asset;
pub use radarg_data::*;

View File

@ -0,0 +1,18 @@
pub fn hex_to_rgba_u8(hex: &str) -> Result<[u8; 4], String> {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 && hex.len() != 8 {
return Err("Hex color should be in #RRGGBB or #RRGGBBAA format".to_string());
}
let r = u8::from_str_radix(&hex[0..2], 16).map_err(|e| e.to_string())?;
let g = u8::from_str_radix(&hex[2..4], 16).map_err(|e| e.to_string())?;
let b = u8::from_str_radix(&hex[4..6], 16).map_err(|e| e.to_string())?;
let a = if hex.len() == 8 {
u8::from_str_radix(&hex[6..8], 16).map_err(|e| e.to_string())?
} else {
255 // 默认不透明
};
Ok([r, g, b, a])
}

View File

@ -0,0 +1 @@
pub mod color_tools;

View File

@ -0,0 +1,217 @@
[[cmap]]
type = "DBZ"
levels = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]
colors = [
"#aaaaaa",
"#0022ff",
"#01a0f6",
"#00ecec",
"#00d800",
"#019000",
"#ffff00",
"#e7c000",
"#ff9000",
"#ff0000",
"#d60000",
"#c00000",
"#ff00f0",
"#9600b4",
"#ad90f0",
]
[[cmap]]
type = "VEL"
levels = [
-90,
-45,
-35,
-27,
-20,
-15,
-10,
-5,
-1,
0,
1,
5,
10,
15,
20,
27,
1000,
]
colors = [
"#9fffff",
"#00e0ff",
"#0080ff",
"#320096",
"#00fb90",
"#00bb90",
"#008f00",
"#cdc09f",
"#000000",
"#f88700",
"#ffcf00",
"#ffff00",
"#ae0000",
"#d07000",
"#dd0000",
"#ff0000",
]
[[cmap]]
type = "SW"
colors = [
"#E0E0E0",
"#7CE0E0",
"#00E0E0",
"#00B0B0",
"#00FEFE",
"#00C400",
"#008000",
"#FEFE00",
"#FED200",
"#FE7C00",
"#FEB0B0",
"#FE5858",
"#FE0000",
"#FEFEFE",
]
levels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
[[cmap]]
type = "CC"
colors = [
"#003CFF",
"#00EFEF",
"#00BABF",
"#00837D",
"#008938",
"#00B729",
"#00DA0D",
"#00FF00",
"#FFFF3B",
"#FFF000",
"#FFC600",
"#FFA500",
"#FF7200",
"#FF1F00",
"#C10000",
"#D400AA",
]
levels = [
0,
0.1,
0.3,
0.5,
0.6,
0.7,
0.8,
0.85,
0.9,
0.92,
0.94,
0.95,
0.96,
0.97,
0.98,
0.99,
]
[[cmap]]
type = "KDP"
colors = [
"#00FFFF",
"#00EFEF",
"#00A8AC",
"#B4B4B4",
"#B4B4B4",
"#00C027",
"#00E80A",
"#24FF24",
"#FFFF1E",
"#FFE600",
"#FFBC00",
"#FF9800",
"#FF5E00",
"#F20F00",
"#BB003A",
"#DD009C",
"#FF00FF",
]
levels = [
-0.8,
-0.4,
-0.2,
-0.1,
0.1,
0.15,
0.22,
0.33,
0.5,
0.75,
1.1,
1.7,
2.4,
3.1,
7,
20,
]
[[cmap]]
type = "ZDR"
colors = [
"#464646",
"#505050",
"#5A5A5A",
"#646464",
"#6E6E6E",
"#787878",
"#828282",
"#8C8C8C",
"#969696",
"#AFAFAF",
"#C8C8C8",
"#DCF0DC",
"#00C027",
"#00E80A",
"#24FF24",
"#FFFF1E",
"#FFF20F",
"#FFE600",
"#FFBC00",
"#FF9800",
"#FF5E00",
"#FFFF00",
"#F20F00",
"#BB003A",
"#DD009C",
"#FF00FF",
]
levels = [
-5,
-4.5,
-4,
-3.5,
-3,
-2.5,
-2,
-1.5,
-1,
-0.5,
0,
0.5,
1,
1.5,
2,
2.5,
3,
3.5,
4,
4.5,
5,
5.5,
6,
6.5,
7,
]

View File

@ -1,14 +0,0 @@
[package]
name = "radarg_data"
version = "0.1.0"
authors = ["tsuki <tsuki@keitsuki.top>"]
edition = "2021"
[dependencies]
chrono = "0.4.38"
ndarray = "0.16.1"
thiserror = "1.0.56"
[dependencies.radarg_plugin_interface]
version = "0.1"
path = "../radarg_plugin_interface"

BIN
test2.npz

Binary file not shown.