This commit is contained in:
Tsuki 2024-03-16 12:57:30 +08:00
parent 2d95b97e69
commit 2147041b46
28 changed files with 123 additions and 98 deletions

3
Cargo.lock generated
View File

@ -542,9 +542,8 @@ dependencies = [
"geo-types",
"geojson 0.24.1",
"gl",
"glib 0.17.10",
"glib-build-tools",
"glib-macros 0.17.10",
"glib-macros 0.19.2",
"glow",
"glue",
"gtk4",

View File

@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
cairo-rs = { version = "0.17.0" }
glib = "0.17.9"
# glib = "0.17.9"
gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] }
geo-types = "0.7.9"
shapefile = { version = "0.4", features = ["geo-types"] }
@ -18,7 +18,7 @@ npyz = { version = "0.8.0", features = ["npz"] }
ndarray = { version = "0.15.6", features = ["rayon"] }
quadtree_rs = "0.1.2"
proj-sys = "0.23.1"
glib-macros = "0.17.10"
glib-macros = "0.19.2"
svg = "0.13.1"
libloading = "0.8.0"
glue = "0.8.7"

View File

@ -1,4 +1,4 @@
use cairo::{Context as CairoContext, FontSlant, FontWeight};
use gtk::cairo::{Context as CairoContext, FontSlant, FontWeight};
use plotters_backend::text_anchor::{HPos, VPos};
#[allow(unused_imports)]
@ -7,7 +7,6 @@ use plotters_backend::{
FontStyle, FontTransform,
};
/// The drawing backend that is backed with a Cairo context
pub struct CairoBackend<'a> {
context: &'a CairoContext,
@ -78,7 +77,7 @@ impl<'a> CairoBackend<'a> {
}
impl<'a> DrawingBackend for CairoBackend<'a> {
type ErrorType = cairo::Error;
type ErrorType = gtk::cairo::Error;
fn get_size(&self) -> (u32, u32) {
(self.width, self.height)

View File

@ -2,7 +2,6 @@ mod backend;
mod imp;
use self::backend::CairoBackend;
use crate::widgets::render::{Render, RenderConfig, RenderMotion};
use glib::{clone, ObjectExt};
use gtk::prelude::*;
use gtk::{glib, AspectFrame};
use plotters::prelude::*;

View File

@ -28,7 +28,7 @@ use abi_stable::std_types::RStr;
use adw::prelude::*;
use chrono::{prelude::*, Duration};
use futures::future::BoxFuture;
use glib::clone;
use gtk::glib::clone;
use gtk::prelude::*;
use once_cell::sync::Lazy;
use radarg_plugin_interface::PluginResult;
@ -114,7 +114,7 @@ impl Component for AppModel {
set_focus_on_click:true,
connect_close_request[sender] => move |_| {
sender.input(AppMsg::CloseRequest);
gtk::Inhibit(true)
gtk::glib::Propagation::Proceed
},
gtk::Box{
set_orientation: gtk::Orientation::Vertical,
@ -133,7 +133,7 @@ impl Component for AppModel {
},
connect_close_request[sender] => move |_| {
sender.input(AppMsg::CloseRequest);
gtk::Inhibit(true)
gtk::glib::Propagation::Proceed
}
},
popover_child = gtk::Spinner {
@ -189,7 +189,7 @@ impl Component for AppModel {
fn init(
params: Self::Init,
root: &Self::Root,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let layers = Rc::new(RefCell::new(Vec::with_capacity(20)));
@ -248,7 +248,6 @@ impl Component for AppModel {
_ => AppMsg::Close,
});
relm4_icons::initialize_icons();
let buffer: Buffer = Rc::new(RefCell::new(HashMap::new()));
let model = AppModel {
cms,

View File

@ -1,4 +1,3 @@
use std::cell::{Ref, RefCell};
use super::messages::*;
use super::thumbnail::{ImgItem, TypedListView};
use crate::data::{CoordType, Radar2d, RadarData2d};
@ -16,6 +15,8 @@ use radarg_plugin_interface::VecResult;
use relm4::prelude::*;
use relm4_components::open_button::{OpenButton, OpenButtonSettings};
use relm4_components::open_dialog::OpenDialogSettings;
use relm4_icons::icon_names;
use std::cell::{Ref, RefCell};
use std::path::PathBuf;
use std::rc::Rc;
@ -79,7 +80,8 @@ impl SimpleComponent for ControlPanelModel {
set_orientation: gtk::Orientation::Horizontal,
set_spacing:10,
gtk::Button{
set_icon_name: "rewind-filled",
// set_icon_name: "rewind-filled",
set_icon_name: icon_names::REWIND_FILLED,
#[track = "model.changed(ControlPanelModel::enabled()) || model.changed(ControlPanelModel::key())"]
set_sensitive: model.enabled && model.key.is_some(),
connect_clicked[sender] => move |_| {
@ -210,7 +212,7 @@ impl SimpleComponent for ControlPanelModel {
fn init(
init: Self::Init,
root: &Self::Root,
root: Self::Root,
sender: relm4::ComponentSender<Self>,
) -> relm4::ComponentParts<Self> {
let select_model =

View File

@ -1,5 +1,5 @@
use gtk::prelude::*;
pub use relm4::typed_list_view::{RelmListItem, TypedListView};
pub use relm4::typed_view::list::{RelmListItem, TypedListView};
use relm4::RelmWidgetExt;
use std::sync::{Arc, Mutex};
use tokio::sync::oneshot;

View File

@ -12,7 +12,7 @@ use crate::{
widgets::render::{Layer, Render},
};
use geo::k_nearest_concave_hull;
use glib::{clone, PropertyGet};
use gtk::glib::clone;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
@ -200,7 +200,7 @@ impl Component for MonitorModel {
fn init(
init: Self::Init,
root: &Self::Root,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let sidebar_sender = sender.clone();

View File

@ -1,6 +0,0 @@
use crate::widgets::Layer;
relm4::safe_settings_and_actions! {
#[derive(Debug)]
pub(super) Visible(group: "layer", name: "layer-visible");
}

View File

@ -33,7 +33,6 @@ impl BottomBarModel {
#[relm4::factory(pub)]
impl FactoryComponent for BottomBarModel {
type ParentWidget = gtk::Box;
type ParentInput = SideBarInputMsg;
type Input = ();
type Output = TestMsg;
type Init = BottomBarModel;
@ -54,10 +53,4 @@ impl FactoryComponent for BottomBarModel {
}
fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {}
fn forward_to_parent(_output: Self::Output) -> Option<Self::ParentInput> {
Some(match _output {
_ => SideBarInputMsg::None,
})
}
}

View File

@ -4,7 +4,7 @@ use relm4::{
factory::FactoryView,
gtk,
prelude::{DynamicIndex, FactoryComponent},
typed_list_view::{LabelColumn, RelmColumn, TypedColumnView},
typed_view::column::{LabelColumn, RelmColumn, TypedColumnView},
view, FactorySender, RelmObjectExt,
};

View File

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

View File

@ -1,18 +1,20 @@
use super::actions::*;
use crate::widgets::AssoElement;
use abi_stable::type_level::trait_marker::Hash;
use chrono::{DateTime, Utc};
use glib::clone;
use glib_macros::clone;
use gtk::glib;
use gtk::prelude::WidgetExt;
use gtk::prelude::*;
use relm4::actions::{AccelsPlus, RelmAction};
use relm4::safe_settings_and_actions::extensions::SafeSimpleAction;
use relm4::{
binding::{Binding, U8Binding},
factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque},
gtk::gio,
prelude::*,
typed_list_view::{RelmListItem, TypedColumnView, TypedListView},
typed_view::{
column::TypedColumnView,
list::{RelmListItem, TypedListView},
},
RelmObjectExt,
};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
@ -126,13 +128,20 @@ impl SimpleComponent for SideBarModel {
fn init(
init: Self::Init,
root: &Self::Root,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
// Initialize the ListView wrapper
let mut list_view_wrapper: TypedListView<LayerItem, gtk::SingleSelection> =
TypedListView::with_sorting();
let mut bottom_bar_vec = FactoryVecDeque::new(gtk::Box::default(), sender.input_sender());
// 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();

View File

@ -25,7 +25,7 @@ impl PathItem {
#[relm4::factory(pub)]
impl FactoryComponent for PathItem {
type ParentWidget = adw::PreferencesGroup;
type ParentInput = super::SettingMsg;
// type ParentInput = super::SettingMsg;
type Input = ();
type Output = OutputMsg;
type Init = PathItem;
@ -54,12 +54,4 @@ impl FactoryComponent for PathItem {
init
}
fn update(&mut self, message: Self::Input, sender: FactorySender<Self>) {}
fn forward_to_parent(_output: Self::Output) -> Option<Self::ParentInput> {
match _output {
OutputMsg::Update((k, v)) => Some(super::SettingMsg::PathFormats((
"etws_loader".to_string(),
(k, v),
))),
}
}
}

View File

@ -6,10 +6,10 @@ use crate::{
CONFIG, PLUGIN_MANAGER,
};
use adw::prelude::*;
use gtk::{prelude::*, traits::OrientableExt};
use gtk::prelude::*;
use relm4::factory::{DynamicIndex, FactoryComponent, FactorySender, FactoryVecDeque};
use relm4::typed_view::list::TypedListView;
use relm4::{gtk, ComponentParts, ComponentSender, RelmWidgetExt, SimpleComponent};
use relm4::{typed_list_view::TypedListView, *};
use relm4_components::open_dialog::{
OpenDialog, OpenDialogMsg, OpenDialogResponse, OpenDialogSettings,
};
@ -90,11 +90,15 @@ impl SimpleComponent for SettingModel {
fn init(
params: Self::Init,
root: &Self::Root,
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
let mut path_list =
FactoryVecDeque::new(adw::PreferencesGroup::new(), sender.input_sender());
FactoryVecDeque::builder()
.launch_default()
.forward(sender.input_sender(), |msg| match msg {
_ => SettingMsg::SaveConfig,
});
{
let config = CONFIG.lock().unwrap();
let etws_config = config.plugins.get("etws_loader").unwrap();

View File

@ -24,11 +24,11 @@ use components::app::AppModel;
use once_cell::{sync::Lazy as SafeLazy, unsync::Lazy as UnsafeLazy};
use tracing::info;
use tracing_subscriber;
mod widgets;
mod data_utils;
mod predefined;
mod map_tile_utils;
mod map_tile;
mod map_tile_utils;
mod predefined;
mod widgets;
const APP_ID: &str = "org.tsuki.radar_g";
static RUNTIME: SafeLazy<Runtime> =
@ -61,6 +61,7 @@ fn main() {
}
let relm = relm4::RelmApp::new(APP_ID);
initialize_custom_css();
relm4_icons::initialize_icons();
info!("Init plugin system");
let pluginmanager = PluginManager::new();
relm.run::<AppModel>(());

View File

@ -12,7 +12,6 @@ use core_extensions::SelfOps;
use femtovg::rgb::alt::GRAY8;
use femtovg::{renderer::OpenGl, Canvas, ImageFlags, ImageId, ImageInfo, PixelFormat};
use futures::StreamExt;
use glib::PropertyGet;
use radarg_plugin_interface::PluginResult;
use std::any::Any;
use std::borrow::Borrow;
@ -395,8 +394,12 @@ impl Target {
((x2 - x1).abs(), (y2 - y1).abs())
}
pub fn mem_to_native_texture(&self, gl: &glow::Context, flags: ImageFlags) -> glow::NativeTexture {
if let TargetType::Mem(ref mem) = self.target{
pub fn mem_to_native_texture(
&self,
gl: &glow::Context,
flags: ImageFlags,
) -> glow::NativeTexture {
if let TargetType::Mem(ref mem) = self.target {
use glow::*;
let texture = unsafe {
let id = gl.create_texture().unwrap();
@ -443,41 +446,73 @@ impl Target {
}
} else if flags.contains(ImageFlags::NEAREST) {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MIN_FILTER,
glow::NEAREST as i32,
);
}
} else {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MIN_FILTER,
glow::LINEAR as i32,
);
}
}
if flags.contains(ImageFlags::NEAREST) {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MAG_FILTER,
glow::NEAREST as i32,
);
}
} else {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MAG_FILTER,
glow::LINEAR as i32,
);
}
}
if flags.contains(ImageFlags::REPEAT_X) {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::REPEAT as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_S,
glow::REPEAT as i32,
);
}
} else {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_S,
glow::CLAMP_TO_EDGE as i32,
);
}
}
if flags.contains(ImageFlags::REPEAT_Y) {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::REPEAT as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_T,
glow::REPEAT as i32,
);
}
} else {
unsafe {
gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_T,
glow::CLAMP_TO_EDGE as i32,
);
}
}

View File

@ -1,15 +1,14 @@
use adw::subclass::bin::BinImpl;
use glib::Properties;
use gtk::glib::prelude::*;
use gtk::glib::{self, prelude::*};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use std::cell::{Cell, RefCell};
use std::num::NonZeroU32;
#[derive(Properties)]
#[properties(wrapper_type = super::DynamicCol)]
// #[derive(Properties)]
// #[properties(wrapper_type = super::DynamicCol)]
pub struct DynamicCol {
#[property(get, set)]
// #[property(get, set)]
pub(super) child: RefCell<Option<gtk::Paned>>,
pub(super) ratio: RefCell<Option<f64>>,
width: Cell<i32>,
@ -37,7 +36,6 @@ impl ObjectSubclass for DynamicCol {
}
impl ObjectImpl for DynamicCol {
fn constructed(&self) {
self.parent_constructed();
}
@ -76,10 +74,12 @@ impl WidgetImpl for DynamicCol {
let position = if let Some(ratio) = *ratio {
(width as f64 * ratio) as i32
} else {
self.start_width.get().or(Some(width - self.end_width.get().unwrap())).unwrap()
self.start_width
.get()
.or(Some(width - self.end_width.get().unwrap()))
.unwrap()
};
child.set_position(position);
}
}

View File

@ -86,5 +86,4 @@ impl DynamicCol {
// self.queue_resize();
// self.notify("child")
// }
}

View File

@ -2,8 +2,9 @@ mod imp;
use super::super::Render;
use crate::coords::Range;
use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path};
use glib::subclass::types::ObjectSubclassIsExt;
use gtk::glib;
use gtk::prelude::*;
use gtk::subclass::prelude::ObjectSubclassIsExt;
glib::wrapper! {
pub struct ExteriorWidget(ObjectSubclass<imp::ExteriorWidget>);

View File

@ -7,8 +7,8 @@ use crate::map_tile::MapTile;
use crate::pipeline::element::{Target, TargetType};
use femtovg::{Canvas, Color, FontId, Paint, Renderer};
use gtk::glib::{self, prelude::*, Properties};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use gtk::traits::{GLAreaExt, WidgetExt};
use slippy_map_tiles::Tile;
use std::cell::{Cell, RefCell};
use std::collections::HashMap;
@ -98,7 +98,7 @@ impl ObjectImpl for Render {
fn constructed(&self) {
self.parent_constructed();
let area = self.obj();
area.set_has_stencil_buffer(true);
// area.set_has_stencil_buffer(true);
}
fn properties() -> &'static [glib::ParamSpec] {
@ -134,7 +134,7 @@ impl GLAreaImpl for Render {
let scale_rate = self.status.borrow_mut().scale_rate;
if let Some(scale) = scale_rate {
let ((x1,x2), (y1, y2)) = self.view_range().unwrap();
let ((x1, x2), (y1, y2)) = self.view_range().unwrap();
// let (x1, y1) = self.map((x1, y1)).unwrap();
// let (x2, y2) = self.map((x2, y2)).unwrap();
// let scale = ((y2 - y1) / height as f32).min((x2 - x1) / width as f32) as f64;
@ -151,7 +151,7 @@ impl GLAreaImpl for Render {
}
}
fn render(&self, context: &gtk::gdk::GLContext) -> bool {
fn render(&self, context: &gtk::gdk::GLContext) -> glib::Propagation {
self.ensure_canvas();
{
@ -194,7 +194,8 @@ impl GLAreaImpl for Render {
self.exterior.borrow().draw(canvas, &self.obj());
canvas.flush();
}
true
glib::Propagation::Proceed
}
}

View File

@ -8,6 +8,7 @@ use crate::RUNTIME;
use core_extensions::SelfOps;
use femtovg::{renderer::OpenGl, Canvas, ImageFlags};
use femtovg::{Paint, Path};
use gtk::glib;
pub use layers::{AssoElement, Layer, LayerImpl, LayerImplSync};
use relm4::channel;
use std::cell::Ref;

View File

@ -6,7 +6,6 @@ mod interior;
pub mod predefined;
pub mod renders;
pub mod widget;
// pub use self::cms::CMS;
pub use self::imp::{RenderConfig, RenderMotion, RenderStatus};
use crate::components::messages::MonitorInputMsg;
use crate::coords::cms::CMS;
@ -17,10 +16,10 @@ use crate::pipeline::element::{Target, TargetType};
use adw::prelude::{GLAreaExt, GestureDragExt};
use femtovg::ImageFlags;
use geo_types::LineString;
use glib::clone;
pub use glib::subclass::prelude::*;
use gtk::traits::WidgetExt;
use gtk::{EventControllerScrollFlags, Inhibit};
use gtk::glib::{self, clone};
use gtk::prelude::*;
use gtk::subclass::prelude::ObjectSubclassIsExt;
use gtk::EventControllerScrollFlags;
pub use interior::*;
use slippy_map_tiles::Tile;
use std::cell::{Ref, RefCell, RefMut};
@ -86,7 +85,7 @@ impl Render {
});
r.queue_render();
r.set_scale(rate);
Inhibit(true)
glib::Propagation::Proceed
}
));

View File

@ -47,7 +47,7 @@ where
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync,
T: ColorMapper<V> + 'static,
{
fn cairo_render(&self, canvas: &cairo::Context, w: f32, h: f32) {
fn cairo_render(&self, canvas: &gtk::cairo::Context, w: f32, h: f32) {
let bar_width = 10;
let bar_height = h - self.padding[0] - self.padding[2];
let (x, y) = (self.padding[3], self.padding[0]);

View File

@ -1,8 +1,8 @@
use crate::coords::cms::CMS;
use crate::widgets::{Layer, LayerImpl, Render};
use femtovg::{renderer::OpenGl, Canvas};
use gtk::Align;
use std::{fmt::Debug, rc::Rc};
use crate::coords::cms::CMS;
pub enum WidgetType {
OpenGl,
@ -12,7 +12,7 @@ pub enum WidgetType {
pub trait Widget: 'static + Send + Sync {
fn opengl_render(&self, canvas: &mut Canvas<OpenGl>, cms: CMS) {}
fn cairo_render(&self, canvas: &cairo::Context, w: f32, h: f32) {}
fn cairo_render(&self, canvas: &gtk::cairo::Context, w: f32, h: f32) {}
fn widget_type(&self) -> WidgetType;
fn size(&self) -> (f32, f32);

View File

@ -1,9 +1,8 @@
mod imp;
use chrono::{prelude::*, DateTime, Duration, Utc};
use glib::clone;
pub use glib::subclass::prelude::*;
use gtk::glib::{self, clone};
use gtk::prelude::*;
use gtk::traits::WidgetExt;
use gtk::subclass::prelude::ObjectSubclassIsExt;
use gtk::EventControllerMotion;
pub use imp::Selection;
use imp::{draw_cursor, draw_rounded_rectangle, round_to_nearest};

View File

@ -1,6 +1,6 @@
use crate::widgets::widget::Widget;
use chrono::{prelude::*, Duration};
use gtk::glib::{self, prelude::*, ParamSpec, Properties, Property, Value};
use gtk::glib::{self, prelude::*, ParamSpec, Properties, Value};
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use std::cell::{Cell, RefCell};

View File

@ -3,9 +3,9 @@ use self::widget::Widget;
pub use super::*;
mod imp;
use chrono::{prelude::*, DateTime, Duration, Utc};
use glib::clone;
pub use glib::subclass::prelude::*;
use gtk::glib::{self, clone};
use gtk::prelude::*;
use gtk::subclass::prelude::ObjectSubclassIsExt;
glib::wrapper! {
pub struct WidgetFrame(ObjectSubclass<imp::WidgetFrame>)