diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..60f39c4
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/radar-g.iml b/.idea/radar-g.iml
new file mode 100644
index 0000000..cf84ae4
--- /dev/null
+++ b/.idea/radar-g.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 19d2f45..f74d4c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -72,6 +72,15 @@ dependencies = [
"syn 2.0.29",
]
+[[package]]
+name = "atomic-polyfill"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28"
+dependencies = [
+ "critical-section",
+]
+
[[package]]
name = "atty"
version = "0.2.14"
@@ -273,6 +282,7 @@ dependencies = [
"cairo-rs",
"epoxy",
"femtovg",
+ "geo",
"geo-macros",
"geo-types",
"glib",
@@ -293,6 +303,7 @@ dependencies = [
"quadtree_rs",
"relm4",
"relm4-components",
+ "rstar",
"shapefile",
"svg",
"thiserror",
@@ -373,6 +384,12 @@ dependencies = [
"cfg-if",
]
+[[package]]
+name = "critical-section"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
+
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
@@ -513,6 +530,16 @@ dependencies = [
"subtle",
]
+[[package]]
+name = "earcutr"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0812b44697951d35fde8fcb0da81c9de7e809e825a66bbf1ecb79d9829d4ca3d"
+dependencies = [
+ "itertools",
+ "num-traits",
+]
+
[[package]]
name = "either"
version = "1.8.1"
@@ -628,6 +655,12 @@ dependencies = [
"miniz_oxide",
]
+[[package]]
+name = "float_next_after"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
+
[[package]]
name = "flume"
version = "0.10.14"
@@ -821,6 +854,22 @@ dependencies = [
"version_check",
]
+[[package]]
+name = "geo"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1645cf1d7fea7dac1a66f7357f3df2677ada708b8d9db8e9b043878930095a96"
+dependencies = [
+ "earcutr",
+ "float_next_after",
+ "geo-types",
+ "geographiclib-rs",
+ "log",
+ "num-traits",
+ "robust",
+ "rstar",
+]
+
[[package]]
name = "geo-macros"
version = "0.1.0"
@@ -832,15 +881,25 @@ dependencies = [
[[package]]
name = "geo-types"
-version = "0.7.10"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1019f6d372c5b53143f08deee4168d05c22920fe5e0f51f0dfb0e8ffb67ec11e"
+checksum = "9705398c5c7b26132e74513f4ee7c1d7dafd786004991b375c172be2be0eecaa"
dependencies = [
"approx",
"num-traits",
+ "rstar",
"serde",
]
+[[package]]
+name = "geographiclib-rs"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ea804e7bd3c6a4ca6a01edfa35231557a8a81d4d3f3e1e2b650d028c42592be"
+dependencies = [
+ "lazy_static",
+]
+
[[package]]
name = "getrandom"
version = "0.2.10"
@@ -1127,12 +1186,34 @@ dependencies = [
"crunchy",
]
+[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
[[package]]
name = "hashbrown"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
+[[package]]
+name = "heapless"
+version = "0.7.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "spin",
+ "stable_deref_trait",
+]
+
[[package]]
name = "heck"
version = "0.4.1"
@@ -1219,6 +1300,15 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "jobserver"
version = "0.1.26"
@@ -1997,6 +2087,23 @@ dependencies = [
"bytemuck",
]
+[[package]]
+name = "robust"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30"
+
+[[package]]
+name = "rstar"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73111312eb7a2287d229f06c00ff35b51ddee180f017ab6dec1f69d62ac098d6"
+dependencies = [
+ "heapless",
+ "num-traits",
+ "smallvec",
+]
+
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@@ -2169,6 +2276,12 @@ dependencies = [
"lock_api",
]
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
[[package]]
name = "strsim"
version = "0.7.0"
diff --git a/Cargo.toml b/Cargo.toml
index 600215f..8af6241 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,6 +34,8 @@ anyhow = "1.0.72"
proj5 = { version = "0.1.7", features = ["multithreading"] }
relm4 = "0.6.1"
relm4-components = "0.6.1"
+rstar = "*"
+geo = "0.26.0"
diff --git a/src/components/app.rs b/src/components/app.rs
index 5bdb580..9c38660 100644
--- a/src/components/app.rs
+++ b/src/components/app.rs
@@ -2,6 +2,7 @@ use super::{control_panel::ControlPanelModel, render_panel::RenderPanelModel};
use gtk::{prelude::{
ApplicationExt, ButtonExt, DialogExt, GtkWindowExt, ToggleButtonExt, WidgetExt,
}, traits::OrientableExt};
+use gtk::prelude::GtkApplicationExt;
use relm4::*;
#[derive(Debug)]
@@ -23,6 +24,9 @@ pub struct AppModel {
control: Controller,
render: Controller,
}
+relm4::new_action_group!(WindowActionGroup, "win");
+relm4::new_stateless_action!(ExampleAction, WindowActionGroup, "example");
+relm4::new_stateful_action!(ExampleU8Action, WindowActionGroup, "example2", u8, u8);
#[relm4::component(pub)]
impl SimpleComponent for AppModel {
@@ -31,12 +35,13 @@ impl SimpleComponent for AppModel {
type Output = ();
view! {
- main_window = gtk::Window {
- set_default_width: 1000,
+ main_window = gtk::ApplicationWindow {
+ set_default_width: 1200,
set_default_height: 700,
+ set_focus_on_click:true,
set_titlebar: Some(>k::HeaderBar::new()),
gtk::Box{
- set_orientation: gtk::Orientation::Vertical,
+ set_orientation: gtk::Orientation::Horizontal,
set_valign:gtk::Align::Fill,
model.control.widget(),
model.render.widget(),
@@ -61,6 +66,42 @@ impl SimpleComponent for AppModel {
.launch(0)
.forward(sender.input_sender(), |a| AppMsg::Close);
+ relm4::menu! {
+ main_menu: {
+ custom: "my_widget",
+ "Example" => ExampleAction,
+ "Example2" => ExampleAction,
+ "Example toggle" => ExampleU8Action(1_u8),
+ section! {
+ "Section example" => ExampleAction,
+ "Example toggle" => ExampleU8Action(1_u8),
+ },
+ section! {
+ "Example" => ExampleAction,
+ "Example2" => ExampleAction,
+ "Example Value" => ExampleU8Action(1_u8),
+ },
+ "submenu1" {
+ "Example" => ExampleAction,
+ "Example2" => ExampleAction,
+ "Example toggle" => ExampleU8Action(1_u8),
+ "submenu2" {
+ "Example" => ExampleAction,
+ "Example2" => ExampleAction,
+ "Example toggle" => ExampleU8Action(1_u8),
+ "submenu3" {
+ "Example" => ExampleAction,
+ "Example2" => ExampleAction,
+ "Example toggle" => ExampleU8Action(1_u8),
+ }
+ }
+ }
+ }
+ };
+
+ let app = relm4::main_application();
+ app.set_menubar(Some(&main_menu));
+
let model = AppModel {
mode: AppMode::View,
control: control,
diff --git a/src/coords/mapper.rs b/src/coords/mapper.rs
index b846b90..5538cd8 100644
--- a/src/coords/mapper.rs
+++ b/src/coords/mapper.rs
@@ -49,7 +49,7 @@ impl Mapper {
pub fn fore_map(&self, coord: WindowCoord) -> Result<(f64, f64), ProjError> {
let (x, y) = coord;
let c = (x as f64) * (self.bounds.1 - self.bounds.0) + self.bounds.0;
- let d = (y as f64) * (self.bounds.3 - self.bounds.2) + self.bounds.2;
+ let d = ((1.0 - y) as f64) * (self.bounds.3 - self.bounds.2) + self.bounds.2;
let (lon, lat) = self.proj.project((c, d), true)?;
Ok((lon.to_degrees(), lat.to_degrees()))
}
@@ -75,7 +75,7 @@ impl Mapper {
let x = (p1 - self.bounds.0) / (self.bounds.1 - self.bounds.0);
let y = (p2 - self.bounds.2) / (self.bounds.3 - self.bounds.2);
- Ok((x, y))
+ Ok((x, (1.0 - y)))
}
pub fn set_lon_range(&mut self, range: std::ops::Range) -> &mut Self {
diff --git a/src/main.rs b/src/main.rs
index 84594da..58e95e1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,6 +8,7 @@ use gtk::prelude::*;
use gtk::{gio, glib, Application, ApplicationWindow};
use relm4::RelmApp;
use std::ptr;
+use relm4::menu;
mod components;
mod coords;
mod data;
@@ -50,8 +51,7 @@ fn main() {
// app.connect_activate(build_ui);
// // Run the application
// app.run()
-
- let relm = RelmApp::new(APP_ID);
+ let relm = relm4::RelmApp::new(APP_ID);
relm.run::(AppMode::Edit);
}
diff --git a/src/monitor/mod.rs b/src/monitor/mod.rs
index 8223504..ef59eb5 100644
--- a/src/monitor/mod.rs
+++ b/src/monitor/mod.rs
@@ -23,6 +23,9 @@ impl Monitor {
pointer_location_detecture.connect_motion(
clone!(@weak this as s => move |_context, x, y| {
s.imp().renderer.borrow_mut().change_pointer(x as f32, y as f32);
+ let c = s.imp().renderer.borrow();
+ let cc = c.imp().config.borrow();
+ println!("pointer location: {},{}", cc.pointer_lon_lat.0, cc.pointer_lon_lat.1);
}
),
);
@@ -43,7 +46,7 @@ impl Monitor {
});
r.set_translate((
px as f32 * (scale - 1.0),
- py as f32 * (scale - 1.0)
+ (1.0-py) as f32 * (scale - 1.0)
));
r.queue_render();
Inhibit(false)
diff --git a/src/render/exterior/imp.rs b/src/render/exterior/imp.rs
new file mode 100644
index 0000000..5e4272d
--- /dev/null
+++ b/src/render/exterior/imp.rs
@@ -0,0 +1,17 @@
+use geo_types::MultiPolygon;
+use gtk::glib;
+use gtk::subclass::prelude::*;
+use std::cell::RefCell;
+
+
+#[derive(Default)]
+pub struct ExteriorWidget {
+}
+
+#[glib::object_subclass]
+impl ObjectSubclass for ExteriorWidget {
+ const NAME: &'static str = "ExteriorWidget";
+ type Type = super::ExteriorWidget;
+}
+
+impl ObjectImpl for ExteriorWidget{}
diff --git a/src/render/exterior/mod.rs b/src/render/exterior/mod.rs
new file mode 100644
index 0000000..ce2f0b9
--- /dev/null
+++ b/src/render/exterior/mod.rs
@@ -0,0 +1,38 @@
+mod imp;
+use crate::coords::{Mapper, Range};
+use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
+use geo_types::{line_string, LineString, Point};
+use glib::subclass::types::ObjectSubclassIsExt;
+use std::cell::Ref;
+
+glib::wrapper! {
+ pub struct ExteriorWidget(ObjectSubclass);
+}
+
+impl Default for ExteriorWidget {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl ExteriorWidget {
+ pub fn new() -> Self {
+ let this: Self = glib::Object::new();
+ this
+ }
+
+ pub(super) fn draw(&self, canvas: &mut Canvas, mapper: Ref<'_, Mapper>) {
+ let imp = self.imp();
+ let canvas_width = canvas.width();
+ let canvas_height = canvas.height();
+ let padding = [30.0,30.0,30.0,30.0];
+
+ let w = canvas_width - padding[1] - padding[3];
+ let h = canvas_height - padding[0] - padding[2];
+
+ let paint = Paint::color(Color::white());
+ let mut path = Path::new();
+ path.rect(padding[3], padding[0], w, h);
+ canvas.stroke_path(&path, &paint);
+ }
+}
diff --git a/src/render/imp.rs b/src/render/imp.rs
index f5d9e9c..0e0f91c 100644
--- a/src/render/imp.rs
+++ b/src/render/imp.rs
@@ -1,9 +1,10 @@
use super::background::BackgroundWidget;
+use super::exterior::ExteriorWidget;
use super::foreground::ForegroundWidget;
use super::WindowCoord;
use crate::coords::proj::Mercator;
use crate::coords::Mapper;
-use femtovg::{Color, FontId, Paint, Path};
+use femtovg::{Color, FontId, Paint, Path, Transform2D};
use gtk::glib;
use gtk::prelude::WidgetExtManual;
use gtk::subclass::prelude::*;
@@ -32,6 +33,7 @@ struct Fonts {
pub struct Render {
pub(super) background: RefCell,
pub(super) foreground: RefCell,
+ pub(super) exterior: RefCell,
pub config: RefCell,
pub mapper: RefCell,
pub(super) canvas: RefCell