-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
185 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use std::fmt::format; | ||
|
||
// Copyright 2024 the Xilem Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
use masonry::widget::{CrossAxisAlignment, MainAxisAlignment}; | ||
use time::{util::days_in_year_month, Date, Month, OffsetDateTime}; | ||
use winit::error::EventLoopError; | ||
use xilem::{ | ||
view::{button, date, flex, label, sized_box, Axis, DateData, FlexExt as _, FlexSpacer}, | ||
EventLoop, WidgetView, Xilem, | ||
}; | ||
use xilem_core::{frozen, map_state}; | ||
|
||
struct Calendar { | ||
// selected_date: Date, | ||
// month: Month, | ||
// year: i32, | ||
date: DateData, | ||
} | ||
|
||
impl Calendar { | ||
fn new() -> Self { | ||
let now = OffsetDateTime::now_utc(); | ||
Self { | ||
// selected_date: , | ||
// month: now.month(), | ||
// year: now.year(), | ||
date: DateData::new(now.date(), now.month(), now.year()), | ||
} | ||
} | ||
} | ||
fn selected_date(selected_date: Date) -> impl WidgetView<Calendar> { | ||
flex((label("Selected date:"), label(format!("{selected_date}")))).direction(Axis::Horizontal) | ||
} | ||
|
||
/// A component to make a bigger than usual button | ||
fn external_controls() -> impl WidgetView<Calendar> { | ||
flex(( | ||
button("Today", |data: &mut Calendar| { | ||
data.date.selected_date = OffsetDateTime::now_utc().date(); | ||
}), | ||
button("Tomorrow", |data: &mut Calendar| { | ||
data.date.selected_date = OffsetDateTime::now_utc().date().next_day().unwrap(); | ||
}), | ||
)) | ||
.direction(Axis::Horizontal) | ||
} | ||
|
||
fn app_logic(data: &mut Calendar) -> impl WidgetView<Calendar> { | ||
flex(( | ||
selected_date(data.date.selected_date), | ||
external_controls(), | ||
map_state( | ||
date( | ||
&mut data.date.selected_date, | ||
&mut data.date.month, | ||
&mut data.date.year, | ||
), | ||
|data: &mut Calendar| &mut data.date, | ||
), | ||
)) | ||
.direction(Axis::Vertical) | ||
.cross_axis_alignment(CrossAxisAlignment::Center) | ||
.main_axis_alignment(MainAxisAlignment::Center) | ||
} | ||
|
||
fn main() -> Result<(), EventLoopError> { | ||
let data = Calendar::new(); | ||
let app = Xilem::new(data, app_logic); | ||
app.run_windowed(EventLoop::with_user_event(), "Calendar".into())?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use masonry::widget::{Axis, CrossAxisAlignment, MainAxisAlignment}; | ||
use time::{format_description::modifier::Year, Date, Month, OffsetDateTime}; | ||
|
||
use crate::{view::sized_box, WidgetView}; | ||
|
||
use super::{button, flex, FlexSpacer}; | ||
|
||
pub struct DateData { | ||
pub selected_date: Date, | ||
pub month: Month, | ||
pub year: i32, | ||
} | ||
|
||
impl DateData { | ||
pub fn new(selected_date: Date, month: Month, year: i32) -> Self { | ||
Self { | ||
selected_date, | ||
month, | ||
year, | ||
} | ||
} | ||
} | ||
|
||
pub fn date( | ||
selected_date: &mut Date, | ||
month: &mut Month, | ||
year: &mut i32, | ||
) -> impl WidgetView<DateData> { | ||
flex(( | ||
date_controls(month, year), | ||
date_grid(selected_date, month, year), | ||
)) | ||
.direction(Axis::Vertical) | ||
.cross_axis_alignment(CrossAxisAlignment::Center) | ||
.main_axis_alignment(MainAxisAlignment::Center) | ||
} | ||
|
||
fn date_controls(month: &mut Month, year: &mut i32) -> impl WidgetView<DateData> { | ||
flex(( | ||
button("<", |data: &mut DateData| { | ||
data.month = data.month.previous(); | ||
}), | ||
sized_box(button(format!("{month}"), |_| {})).width(100.), | ||
button(">", |data: &mut DateData| { | ||
data.month = data.month.next(); | ||
}), | ||
FlexSpacer::Fixed(40.), | ||
button("<", |data: &mut DateData| { | ||
data.year -= 1; | ||
}), | ||
button(format!("{year}"), |_| {}), | ||
button(">", |data: &mut DateData| { | ||
data.year += 1; | ||
}), | ||
)) | ||
.direction(Axis::Horizontal) | ||
.main_axis_alignment(MainAxisAlignment::Center) | ||
} | ||
|
||
// The selected_date in the interface is needed to highlight the currently selected date | ||
// It is currently not implemented | ||
fn date_grid( | ||
selected_date: &mut Date, | ||
month: &mut Month, | ||
year: &mut i32, | ||
) -> impl WidgetView<DateData> { | ||
const COLUMNS: u8 = 7; | ||
const ROWS: u8 = 5; | ||
let mut date = Date::from_calendar_date(*year, *month, 1).unwrap(); | ||
let days_from_monday = date.weekday().number_days_from_monday(); | ||
|
||
for _day in 0..days_from_monday { | ||
date = date.previous_day().unwrap(); | ||
} | ||
|
||
let mut rows = Vec::new(); | ||
for _row in 0..ROWS { | ||
let mut columns = Vec::new(); | ||
for _column in 0..COLUMNS { | ||
// Add buttons of each row into columns vec | ||
let day_number = date.day(); | ||
let date_copy = date.clone(); | ||
columns.push( | ||
sized_box(button( | ||
format!("{day_number}"), | ||
move |data: &mut DateData| { | ||
// Set the selected_date | ||
data.selected_date = date_copy; | ||
}, | ||
)) | ||
.width(50.), | ||
); | ||
date = date.next_day().unwrap(); | ||
} | ||
// Add column vec into flex with horizontal axis | ||
// Add flex into rows vec | ||
rows.push( | ||
flex(columns) | ||
.direction(Axis::Horizontal) | ||
.main_axis_alignment(MainAxisAlignment::Center) | ||
.gap(10.), | ||
); | ||
} | ||
// Add row vec into flex with vertical axis | ||
flex(rows).direction(Axis::Vertical) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,6 @@ pub use textbox::*; | |
|
||
mod portal; | ||
pub use portal::*; | ||
|
||
mod date_selector; | ||
pub use date_selector::*; |