add calendar and new render_cfg
This commit is contained in:
parent
cb68877099
commit
87bb8e6c95
@ -1,6 +1,7 @@
|
|||||||
use crate::timeline::TimeLine;
|
use crate::timeline::TimeLine;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use chrono::{prelude::*, DateTime, Duration, TimeZone, Utc};
|
use chrono::{prelude::*, DateTime, Duration, TimeZone, Utc};
|
||||||
|
use gtk::glib::clone;
|
||||||
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt, ToggleButtonExt};
|
use gtk::prelude::{BoxExt, ButtonExt, GtkWindowExt, OrientableExt, ToggleButtonExt};
|
||||||
use relm4::typed_list_view::{RelmListItem, TypedListView};
|
use relm4::typed_list_view::{RelmListItem, TypedListView};
|
||||||
use relm4::*;
|
use relm4::*;
|
||||||
@ -78,6 +79,7 @@ pub enum HeaderOutput {
|
|||||||
pub enum TimelineMsg {
|
pub enum TimelineMsg {
|
||||||
Rewind(Duration),
|
Rewind(Duration),
|
||||||
FastForward(Duration),
|
FastForward(Duration),
|
||||||
|
SetStart(DateTime<Utc>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -85,6 +87,8 @@ pub enum AppMsg {
|
|||||||
Open(PathBuf),
|
Open(PathBuf),
|
||||||
TimeLine(TimelineMsg),
|
TimeLine(TimelineMsg),
|
||||||
Selection(Option<DateTime<Utc>>),
|
Selection(Option<DateTime<Utc>>),
|
||||||
|
SelectionRewind,
|
||||||
|
SelectionFastForward,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[relm4::component(pub)]
|
#[relm4::component(pub)]
|
||||||
@ -131,13 +135,19 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
set_spacing:10,
|
set_spacing:10,
|
||||||
gtk::Button{
|
gtk::Button{
|
||||||
set_icon_name: "rewind-filled"
|
set_icon_name: "rewind-filled",
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(AppMsg::SelectionRewind);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
gtk::Button{
|
gtk::Button{
|
||||||
set_icon_name: "play-filled"
|
set_icon_name: "play-filled"
|
||||||
},
|
},
|
||||||
gtk::Button{
|
gtk::Button{
|
||||||
set_icon_name: "fast-forward-filled"
|
set_icon_name: "fast-forward-filled",
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(AppMsg::SelectionFastForward);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,8 +167,37 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
gtk::Box{
|
gtk::Box{
|
||||||
set_orientation: gtk::Orientation::Horizontal,
|
set_orientation: gtk::Orientation::Horizontal,
|
||||||
set_spacing:5,
|
set_spacing:5,
|
||||||
|
|
||||||
|
#[name="pop"]
|
||||||
|
gtk::Popover{
|
||||||
|
set_position: gtk::PositionType::Bottom,
|
||||||
|
set_pointing_to: Some(>k::gdk::Rectangle::new(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
80,
|
||||||
|
40,
|
||||||
|
)),
|
||||||
|
gtk::Calendar{
|
||||||
|
connect_day_selected[sender,pop] => move |cal| {
|
||||||
|
let date = cal.date().ymd();
|
||||||
|
let date = Utc.with_ymd_and_hms(date.0, date.1 as u32, date.2 as u32, 0,0,0).unwrap();
|
||||||
|
sender.input(AppMsg::TimeLine(
|
||||||
|
TimelineMsg::SetStart(date)
|
||||||
|
));
|
||||||
|
pop.popdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
gtk::Button{
|
||||||
|
#[track = "model.changed(ControlPanelModel::timeline_start())"]
|
||||||
|
set_label:&model.timeline_start.format("%Y-%m-%d").to_string(),
|
||||||
|
connect_clicked[sender,pop] => move |_| {
|
||||||
|
pop.popup();
|
||||||
|
},
|
||||||
|
},
|
||||||
gtk::Button{
|
gtk::Button{
|
||||||
set_icon_name: "rewind-filled",
|
set_icon_name: "rewind-filled",
|
||||||
|
// add_controller: fastforward_long_press_detector,
|
||||||
connect_clicked[sender] => move |_| {
|
connect_clicked[sender] => move |_| {
|
||||||
sender.input(AppMsg::TimeLine(
|
sender.input(AppMsg::TimeLine(
|
||||||
TimelineMsg::Rewind(-Duration::minutes(12))
|
TimelineMsg::Rewind(-Duration::minutes(12))
|
||||||
@ -170,6 +209,8 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
set_width_request: 400,
|
set_width_request: 400,
|
||||||
#[track = "model.changed(ControlPanelModel::timeline_start())"]
|
#[track = "model.changed(ControlPanelModel::timeline_start())"]
|
||||||
set_time_start: model.timeline_start,
|
set_time_start: model.timeline_start,
|
||||||
|
#[track = "model.changed(ControlPanelModel::selection())"]
|
||||||
|
set_selection: model.selection.map(|p| crate::timeline::Selection::Point(p)),
|
||||||
connect_start_time_notify[sender] => move |time| {
|
connect_start_time_notify[sender] => move |time| {
|
||||||
let time = time.start_time();
|
let time = time.start_time();
|
||||||
sender.input(
|
sender.input(
|
||||||
@ -211,8 +252,7 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
set_height_request: 140,
|
set_height_request: 140,
|
||||||
set_width_request: 300,
|
set_width_request: 300,
|
||||||
set_orientation:gtk::Orientation::Horizontal,
|
set_orientation:gtk::Orientation::Horizontal,
|
||||||
gtk::Calendar{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -239,11 +279,9 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
|
|
||||||
let mut list_img_wrapper: TypedListView<ImgItem, gtk::SingleSelection> =
|
let mut list_img_wrapper: TypedListView<ImgItem, gtk::SingleSelection> =
|
||||||
TypedListView::with_sorting();
|
TypedListView::with_sorting();
|
||||||
|
|
||||||
list_img_wrapper.append(ImgItem::new("00:00:00".to_string(), None, true));
|
list_img_wrapper.append(ImgItem::new("00:00:00".to_string(), None, true));
|
||||||
|
|
||||||
let timeline_start = Utc::now();
|
let timeline_start = Utc::now();
|
||||||
|
|
||||||
let model = ControlPanelModel {
|
let model = ControlPanelModel {
|
||||||
selection: None,
|
selection: None,
|
||||||
timeline_start,
|
timeline_start,
|
||||||
@ -266,10 +304,25 @@ impl SimpleComponent for ControlPanelModel {
|
|||||||
let current = self.get_timeline_start().clone();
|
let current = self.get_timeline_start().clone();
|
||||||
self.set_timeline_start(current + c);
|
self.set_timeline_start(current + c);
|
||||||
}
|
}
|
||||||
|
TimelineMsg::SetStart(time) => {
|
||||||
|
self.set_timeline_start(time);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
AppMsg::Selection(selection) => {
|
AppMsg::Selection(selection) => {
|
||||||
self.set_selection(selection);
|
self.set_selection(selection);
|
||||||
}
|
}
|
||||||
|
AppMsg::SelectionRewind => {
|
||||||
|
let current = self.get_selection().clone();
|
||||||
|
if let Some(current) = current {
|
||||||
|
self.set_selection(Some(current - Duration::minutes(12)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppMsg::SelectionFastForward => {
|
||||||
|
let current = self.get_selection().clone();
|
||||||
|
if let Some(current) = current {
|
||||||
|
self.set_selection(Some(current + Duration::minutes(12)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,32 @@
|
|||||||
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
|
use crate::pipeline::offscreen_renderer::OffscreenRenderer;
|
||||||
use crate::render::{Target, CMS};
|
use crate::render::{RenderConfig, Target, CMS};
|
||||||
// use crate::OFFSCREEN;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
|
||||||
coords::{proj::Mercator, Mapper},
|
coords::{proj::Mercator, Mapper},
|
||||||
data::Npz,
|
|
||||||
dynamic_col::DynamicCol,
|
dynamic_col::DynamicCol,
|
||||||
render::{predefined::color_mapper::BoundaryNorm, Layer, Render},
|
render::{Layer, Render},
|
||||||
RUNTIME,
|
|
||||||
};
|
};
|
||||||
use glib::clone;
|
use glib::clone;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
|
use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use gtk::prelude::StyleContextExt;
|
use relm4::{component::Component, *};
|
||||||
use gtk::subclass::root;
|
|
||||||
use relm4::{
|
|
||||||
component::{AsyncComponent, AsyncComponentParts, Component},
|
|
||||||
loading_widgets::LoadingWidgets,
|
|
||||||
*,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MonitorCommand {
|
pub enum MonitorCommand {
|
||||||
NewLayer(Layer),
|
NewLayer(Layer),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
#[tracker::track]
|
||||||
pub struct MonitorModel {
|
pub struct MonitorModel {
|
||||||
|
render_cfg: RenderConfig,
|
||||||
|
render_range: (f64, f64, f64, f64),
|
||||||
sidebar_open: bool,
|
sidebar_open: bool,
|
||||||
sidebar_width: i32,
|
sidebar_width: i32,
|
||||||
|
#[no_eq]
|
||||||
layers: Vec<Layer>,
|
layers: Vec<Layer>,
|
||||||
|
#[no_eq]
|
||||||
sidebar: Controller<SideBarModel>,
|
sidebar: Controller<SideBarModel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +65,12 @@ impl Component for MonitorModel {
|
|||||||
gtk::Overlay{
|
gtk::Overlay{
|
||||||
#[wrap(Some)]
|
#[wrap(Some)]
|
||||||
set_child = &Render{
|
set_child = &Render{
|
||||||
add_css_class: "rb",
|
|
||||||
#[watch]
|
#[watch]
|
||||||
set_interior_layers: model.layers.clone(),
|
set_interior_layers: model.layers.clone(),
|
||||||
|
#[track = "model.changed(MonitorModel::render_cfg())"]
|
||||||
|
set_cfg: model.render_cfg,
|
||||||
|
#[track = "model.changed(MonitorModel::render_range())"]
|
||||||
|
set_range: model.render_range,
|
||||||
},
|
},
|
||||||
add_overlay=>k::Button{
|
add_overlay=>k::Button{
|
||||||
set_label:"Add",
|
set_label:"Add",
|
||||||
@ -160,11 +159,17 @@ impl Component for MonitorModel {
|
|||||||
SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer),
|
SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer),
|
||||||
_ => MonitorInputMsg::None,
|
_ => MonitorInputMsg::None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let render_cfg = RenderConfig { padding: [20.0; 4] };
|
||||||
|
|
||||||
let model = MonitorModel {
|
let model = MonitorModel {
|
||||||
|
render_range: (4.0, 53.3, 73.3, 135.0),
|
||||||
|
render_cfg,
|
||||||
sidebar_open: true,
|
sidebar_open: true,
|
||||||
sidebar_width: 400,
|
sidebar_width: 400,
|
||||||
layers: vec![],
|
layers: vec![],
|
||||||
sidebar,
|
sidebar,
|
||||||
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let widgets = view_output! {};
|
let widgets = view_output! {};
|
||||||
@ -177,12 +182,14 @@ impl Component for MonitorModel {
|
|||||||
_sender: ComponentSender<Self>,
|
_sender: ComponentSender<Self>,
|
||||||
_root: &Self::Root,
|
_root: &Self::Root,
|
||||||
) {
|
) {
|
||||||
|
self.reset();
|
||||||
match msg {
|
match msg {
|
||||||
MonitorCommand::NewLayer(layer) => {
|
MonitorCommand::NewLayer(layer) => {
|
||||||
self.layers.push(layer);
|
self.layers.push(layer);
|
||||||
|
self.set_render_range((29.13, 30.16, 119.53, 121.13));
|
||||||
self.sidebar
|
self.sidebar
|
||||||
.sender()
|
.sender()
|
||||||
.send(Msg::RefreshList(self.layers.clone()));
|
.send(Msg::RefreshList(self.layers.clone())).unwrap();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use gtk::traits::{GLAreaExt, WidgetExt};
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
pub struct RenderConfig {
|
pub struct RenderConfig {
|
||||||
pub padding: [f32; 4],
|
pub padding: [f32; 4],
|
||||||
}
|
}
|
||||||
|
|||||||
@ -192,4 +192,13 @@ impl Render {
|
|||||||
let new_mapper = borrowed_mapper.clone();
|
let new_mapper = borrowed_mapper.clone();
|
||||||
CMS::new(new_mapper, (500.0, 500.0))
|
CMS::new(new_mapper, (500.0, 500.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_range(&self, range: (f64, f64, f64, f64)) {
|
||||||
|
let (lat1, lat2, lon1, lon2) = range;
|
||||||
|
let mut mapper = self.imp().mapper.borrow_mut();
|
||||||
|
println!("set range: {:?}", range);
|
||||||
|
mapper.set_lat_range(lat1..lat2);
|
||||||
|
mapper.set_lon_range(lon1..lon2);
|
||||||
|
self.queue_render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,6 +73,9 @@ impl TimeLine {
|
|||||||
let minor_tick_interval = major_tick_interval / (major_tick_step / minor_tick_step) as f64;
|
let minor_tick_interval = major_tick_interval / (major_tick_step / minor_tick_step) as f64;
|
||||||
let border_radius = self_.border_radius.get();
|
let border_radius = self_.border_radius.get();
|
||||||
|
|
||||||
|
self_.width.set(w as u32);
|
||||||
|
self_.height.set(h as u32);
|
||||||
|
|
||||||
let start = (&self_.start_time).get();
|
let start = (&self_.start_time).get();
|
||||||
|
|
||||||
let mut nearst_rounded_time = round_to_nearest(start, minor_tick_step);
|
let mut nearst_rounded_time = round_to_nearest(start, minor_tick_step);
|
||||||
@ -120,6 +123,11 @@ impl TimeLine {
|
|||||||
let d_format = if d.hour() ==0 {d.format("%Y/%m/%d %H:%M").to_string()} else { d.format("%H:%M").to_string()};
|
let d_format = if d.hour() ==0 {d.format("%Y/%m/%d %H:%M").to_string()} else { d.format("%H:%M").to_string()};
|
||||||
let extents = cr.text_extents(&d_format).unwrap();
|
let extents = cr.text_extents(&d_format).unwrap();
|
||||||
let x = time_cursor - (extents.width() / 2.0 + extents.x_bearing());
|
let x = time_cursor - (extents.width() / 2.0 + extents.x_bearing());
|
||||||
|
|
||||||
|
if x < margin_horizontal {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cr.move_to(x + margin_horizontal, h / 2.0 + 15.0);
|
cr.move_to(x + margin_horizontal, h / 2.0 + 15.0);
|
||||||
cr.show_text(&d_format).unwrap();
|
cr.show_text(&d_format).unwrap();
|
||||||
}
|
}
|
||||||
@ -233,6 +241,11 @@ impl TimeLine {
|
|||||||
pub fn set_time_start(&self, start_time: DateTime<Utc>) {
|
pub fn set_time_start(&self, start_time: DateTime<Utc>) {
|
||||||
self.imp().set_start(start_time);
|
self.imp().set_start(start_time);
|
||||||
}
|
}
|
||||||
|
pub fn set_selection(&self, selection: Option<Selection>) {
|
||||||
|
self.imp().selection.replace(selection);
|
||||||
|
self.imp().drawing_area.borrow().as_ref().map(|d| d.queue_draw());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_border_radius(&self) {}
|
pub fn set_border_radius(&self) {}
|
||||||
pub fn set_margin_horizontal(&self) {}
|
pub fn set_margin_horizontal(&self) {}
|
||||||
pub fn set_margin_vertical(&self) {}
|
pub fn set_margin_vertical(&self) {}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user