add support for a sidebar

* button to toggle the sidebar
* currently no content, in future a list of calendars will
  be displayed, with options to show/hide single calendars
This commit is contained in:
Fabrizio Iannetti 2024-09-15 14:33:26 +02:00
parent 4058623bdd
commit e9a002ccc1
2 changed files with 92 additions and 11 deletions

View File

@ -23,6 +23,9 @@ use iced::{
widget::{ widget::{
Column, Column,
Container, Container,
button,
text,
pane_grid::{self, PaneGrid}
}, },
}; };
@ -35,15 +38,41 @@ pub enum Message {
NextYear, NextYear,
PrevYear, PrevYear,
ViewModeSelected(ViewMode), ViewModeSelected(ViewMode),
ToggleSidebar,
Resized(pane_grid::ResizeEvent),
}
#[derive(PartialEq, Eq)]
enum PaneType {
Calendar,
Sidebar,
}
struct PaneGridState {
pane_type: PaneType,
} }
#[derive(Default)]
pub struct CalendarApp { pub struct CalendarApp {
view_date: NaiveDate, view_date: NaiveDate,
controls: Controls, controls: Controls,
grid_state: pane_grid::State<PaneGridState>,
events: EventsCollection, events: EventsCollection,
} }
impl Default for CalendarApp {
fn default() -> Self {
let (grid_state, _) = pane_grid::State::new(PaneGridState{pane_type: PaneType::Calendar});
CalendarApp {
view_date: NaiveDate::default(),
controls: Controls::default(),
grid_state,
events: EventsCollection::default(),
}
}
}
impl CalendarApp { impl CalendarApp {
pub fn with_files(calendar_paths: std::vec::Vec<path::PathBuf>) -> Self { pub fn with_files(calendar_paths: std::vec::Vec<path::PathBuf>) -> Self {
let view_date = Utc::now().date_naive(); let view_date = Utc::now().date_naive();
@ -81,18 +110,69 @@ impl CalendarApp {
Message::ViewModeSelected(mode) => { Message::ViewModeSelected(mode) => {
self.controls.mode = Some(mode); self.controls.mode = Some(mode);
} }
Message::ToggleSidebar => {
self.toggle_sidebar();
},
Message::Resized(pane_grid::ResizeEvent { split, ratio }) => {
self.grid_state.resize(split, ratio);
},
} }
Task::none() Task::none()
} }
fn toggle_sidebar(&mut self) {
if let Some(sidebar_pane) = self.get_sidebar_pane() {
// close the sidebar
self.grid_state.close(sidebar_pane);
} else {
// no sidebar: split the main pane (calendar) and move the new pane to the left
let pane = self.get_main_pane();
if let Some((new_pane, split)) = self.grid_state.split(pane_grid::Axis::Vertical, pane, PaneGridState{pane_type: PaneType::Sidebar}) {
self.grid_state.move_to_edge(new_pane, pane_grid::Edge::Left);
self.grid_state.resize(split, 0.25);
};
}
}
fn get_sidebar_pane(&self) -> Option<pane_grid::Pane> {
let sb_pane = self.grid_state.iter().find(|&(_, pgs)| {pgs.pane_type == PaneType::Sidebar});
if let Some((pane, _)) = sb_pane {
Some(*pane)
} else {
None
}
}
fn get_main_pane(&self) -> pane_grid::Pane {
// TODO: assuming there is always a calendar pane
*(self.grid_state.iter().find(|&(_, pgs)| {pgs.pane_type == PaneType::Calendar}).unwrap().0)
}
fn get_calendar_view(&self) -> CalendarView {
CalendarView::new(
self.controls.mode.unwrap_or(ViewMode::Year),
&CalendarParams::new(),
self.view_date,
&self.events)
}
fn get_sidebar_view(&self) -> Container<Message> {
Container::new(text("TODO"))
}
pub fn view(&self) -> Element<Message> { pub fn view(&self) -> Element<Message> {
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
tracepoints::calendar::view_entry(); tracepoints::calendar::view_entry();
let main_content = PaneGrid::new(&self.grid_state, |id, pane, is_maximized| {
match pane.pane_type {
PaneType::Calendar => pane_grid::Content::new(self.get_calendar_view()),
PaneType::Sidebar => pane_grid::Content::new(self.get_sidebar_view()),
}
}).on_resize(10, Message::Resized);
let content = Column::new() let content = Column::new()
.align_x(Alignment::Center) .align_x(Alignment::Center)
.push(self.controls.view(self.view_date)) .push(self.controls.view(self.view_date))
.push(CalendarView::new(self.controls.mode.unwrap_or(ViewMode::Year), &CalendarParams::new(), self.view_date, &self.events)) .push(main_content);
;
let container = Container::new(content) let container = Container::new(content)
.width(Length::Fill) .width(Length::Fill)

View File

@ -16,7 +16,7 @@ use iced::{
alignment, alignment,
theme::palette, theme::palette,
border, border,
widget::{Button, Row, Text, button::{Status, Style, secondary}, row, text} widget::{Row, button::{Status, Style, secondary}, row, text, button}
}; };
//#[derive(Default)] //#[derive(Default)]
@ -45,24 +45,25 @@ impl Controls {
.align_y(Alignment::Center) .align_y(Alignment::Center)
.padding(5) .padding(5)
.spacing(10) .spacing(10)
.push(button(text("=")).on_press(Message::ToggleSidebar).style(secondary))
.push(row![ .push(row![
Button::new(text("Week")).on_press(Message::ViewModeSelected(ViewMode::Week)).style(self.get_mode_style(ViewMode::Week)), button(text("Week")).on_press(Message::ViewModeSelected(ViewMode::Week)).style(self.get_mode_style(ViewMode::Week)),
Button::new(text("Month")).on_press(Message::ViewModeSelected(ViewMode::Month)).style(self.get_mode_style(ViewMode::Month)), button(text("Month")).on_press(Message::ViewModeSelected(ViewMode::Month)).style(self.get_mode_style(ViewMode::Month)),
Button::new(text("Year")).on_press(Message::ViewModeSelected(ViewMode::Year)).style(self.get_mode_style(ViewMode::Year)), button(text("Year")).on_press(Message::ViewModeSelected(ViewMode::Year)).style(self.get_mode_style(ViewMode::Year)),
]) ])
.push(row![ .push(row![
Button::new(Text::new("<")).on_press(self.get_msg_prev()).style(secondary), button(text("<")).on_press(self.get_msg_prev()).style(secondary),
Button::new(Text::new(">")).on_press(self.get_msg_next()).style(secondary), button(text(">")).on_press(self.get_msg_next()).style(secondary),
].spacing(0).padding(0) ].spacing(0).padding(0)
) )
.push( .push(
Text::new(description) text(description)
.width(Length::Fill) .width(Length::Fill)
.align_x(alignment::Horizontal::Left) .align_x(alignment::Horizontal::Left)
.size(24), .size(24),
) )
.push( .push(
Text::new(view_date.year().to_string()) text(view_date.year().to_string())
.width(Length::Fill) .width(Length::Fill)
.align_x(alignment::Horizontal::Right) .align_x(alignment::Horizontal::Right)
.size(40), .size(40),