mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 22:53:14 -04:00
Replace chrono with jiff (#8008)
`jiff` is more modern, and seem to be where the ecosystem is heading.
This commit is contained in:
103
Cargo.lock
103
Cargo.lock
@@ -96,7 +96,7 @@ dependencies = [
|
|||||||
"hashbrown 0.16.1",
|
"hashbrown 0.16.1",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"windows",
|
"windows",
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -732,19 +732,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chrono"
|
|
||||||
version = "0.4.42"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
|
||||||
dependencies = [
|
|
||||||
"iana-time-zone",
|
|
||||||
"js-sys",
|
|
||||||
"num-traits",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-link 0.2.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ciborium"
|
name = "ciborium"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@@ -1323,7 +1310,6 @@ dependencies = [
|
|||||||
"accesskit",
|
"accesskit",
|
||||||
"accesskit_consumer",
|
"accesskit_consumer",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"chrono",
|
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
"egui_demo_lib",
|
"egui_demo_lib",
|
||||||
@@ -1332,6 +1318,7 @@ dependencies = [
|
|||||||
"ehttp",
|
"ehttp",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"image",
|
"image",
|
||||||
|
"jiff",
|
||||||
"log",
|
"log",
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"poll-promise",
|
"poll-promise",
|
||||||
@@ -1350,13 +1337,13 @@ dependencies = [
|
|||||||
name = "egui_demo_lib"
|
name = "egui_demo_lib"
|
||||||
version = "0.33.3"
|
version = "0.33.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
|
||||||
"criterion",
|
"criterion",
|
||||||
"document-features",
|
"document-features",
|
||||||
"egui",
|
"egui",
|
||||||
"egui_extras",
|
"egui_extras",
|
||||||
"egui_kittest",
|
"egui_kittest",
|
||||||
"image",
|
"image",
|
||||||
|
"jiff",
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1368,12 +1355,12 @@ name = "egui_extras"
|
|||||||
version = "0.33.3"
|
version = "0.33.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"chrono",
|
|
||||||
"document-features",
|
"document-features",
|
||||||
"egui",
|
"egui",
|
||||||
"ehttp",
|
"ehttp",
|
||||||
"enum-map",
|
"enum-map",
|
||||||
"image",
|
"image",
|
||||||
|
"jiff",
|
||||||
"log",
|
"log",
|
||||||
"mime_guess2",
|
"mime_guess2",
|
||||||
"profiling",
|
"profiling",
|
||||||
@@ -2151,30 +2138,6 @@ version = "1.10.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone"
|
|
||||||
version = "0.1.63"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
|
||||||
dependencies = [
|
|
||||||
"android_system_properties",
|
|
||||||
"core-foundation-sys",
|
|
||||||
"iana-time-zone-haiku",
|
|
||||||
"js-sys",
|
|
||||||
"log",
|
|
||||||
"wasm-bindgen",
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iana-time-zone-haiku"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@@ -2387,22 +2350,25 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jiff"
|
name = "jiff"
|
||||||
version = "0.2.15"
|
version = "0.2.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
|
checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jiff-static",
|
"jiff-static",
|
||||||
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"portable-atomic-util",
|
"portable-atomic-util",
|
||||||
"serde",
|
"serde_core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jiff-static"
|
name = "jiff-static"
|
||||||
version = "0.2.15"
|
version = "0.2.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
|
checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -5282,7 +5248,7 @@ dependencies = [
|
|||||||
"wgpu-naga-bridge",
|
"wgpu-naga-bridge",
|
||||||
"wgpu-types",
|
"wgpu-types",
|
||||||
"windows",
|
"windows",
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5347,7 +5313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-collections",
|
"windows-collections",
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-future",
|
"windows-future",
|
||||||
"windows-numerics",
|
"windows-numerics",
|
||||||
]
|
]
|
||||||
@@ -5358,20 +5324,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-core"
|
|
||||||
version = "0.61.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
|
||||||
dependencies = [
|
|
||||||
"windows-implement",
|
|
||||||
"windows-interface",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-result 0.3.4",
|
|
||||||
"windows-strings 0.4.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5383,8 +5336,8 @@ dependencies = [
|
|||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
"windows-result 0.4.1",
|
"windows-result",
|
||||||
"windows-strings 0.5.1",
|
"windows-strings",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5393,7 +5346,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
"windows-threading",
|
"windows-threading",
|
||||||
]
|
]
|
||||||
@@ -5438,19 +5391,10 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@@ -5460,15 +5404,6 @@ dependencies = [
|
|||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-strings"
|
name = "windows-strings"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ arboard = { version = "3.6.1", default-features = false }
|
|||||||
backtrace = "0.3.76"
|
backtrace = "0.3.76"
|
||||||
bitflags = "2.9.4"
|
bitflags = "2.9.4"
|
||||||
bytemuck = "1.24.0"
|
bytemuck = "1.24.0"
|
||||||
chrono = { version = "0.4.42", default-features = false }
|
|
||||||
cint = "0.3.1"
|
cint = "0.3.1"
|
||||||
color-hex = "0.2.0"
|
color-hex = "0.2.0"
|
||||||
criterion = { version = "0.7.0", default-features = false }
|
criterion = { version = "0.7.0", default-features = false }
|
||||||
@@ -96,6 +95,7 @@ glutin = { version = "0.32.3", default-features = false }
|
|||||||
glutin-winit = { version = "0.5.0", default-features = false }
|
glutin-winit = { version = "0.5.0", default-features = false }
|
||||||
home = "0.5.9"
|
home = "0.5.9"
|
||||||
image = { version = "0.25.6", default-features = false }
|
image = { version = "0.25.6", default-features = false }
|
||||||
|
jiff = { version = "0.2.23", default-features = false }
|
||||||
js-sys = "0.3.77"
|
js-sys = "0.3.77"
|
||||||
kittest = { version = "0.4.0" }
|
kittest = { version = "0.4.0" }
|
||||||
log = { version = "0.4.28", features = ["std"] }
|
log = { version = "0.4.28", features = ["std"] }
|
||||||
|
|||||||
@@ -42,15 +42,15 @@ wayland = ["eframe/wayland"]
|
|||||||
x11 = ["eframe/x11"]
|
x11 = ["eframe/x11"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = { workspace = true, features = ["js-sys", "wasmbind"] }
|
|
||||||
eframe = { workspace = true, default-features = false, features = ["web_screen_reader"] }
|
eframe = { workspace = true, default-features = false, features = ["web_screen_reader"] }
|
||||||
egui = { workspace = true, features = ["callstack", "default"] }
|
egui = { workspace = true, features = ["callstack", "default"] }
|
||||||
egui_demo_lib = { workspace = true, features = ["default", "chrono"] }
|
egui_demo_lib = { workspace = true, features = ["default", "jiff"] }
|
||||||
egui_extras = { workspace = true, features = ["default", "image"] }
|
egui_extras = { workspace = true, features = ["default", "image"] }
|
||||||
image = { workspace = true, default-features = false, features = [
|
image = { workspace = true, default-features = false, features = [
|
||||||
# Ensure we can display the test images
|
# Ensure we can display the test images
|
||||||
"png",
|
"png",
|
||||||
] }
|
] }
|
||||||
|
jiff = { workspace = true, features = ["std", "tz-system", "js"] }
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
profiling.workspace = true
|
profiling.workspace = true
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ pub use wrap_app::{Anchor, WrapApp};
|
|||||||
|
|
||||||
/// Time of day as seconds since midnight. Used for clock in demo app.
|
/// Time of day as seconds since midnight. Used for clock in demo app.
|
||||||
pub(crate) fn seconds_since_midnight() -> f64 {
|
pub(crate) fn seconds_since_midnight() -> f64 {
|
||||||
use chrono::Timelike as _;
|
jiff::Zoned::now()
|
||||||
let time = chrono::Local::now().time();
|
.time()
|
||||||
time.num_seconds_from_midnight() as f64 + 1e-9 * (time.nanosecond() as f64)
|
.duration_since(jiff::civil::Time::midnight())
|
||||||
|
.as_secs_f64()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait that wraps different parts of the demo app.
|
/// Trait that wraps different parts of the demo app.
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ rustdoc-args = ["--generate-link-to-definition"]
|
|||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
chrono = ["egui_extras/datepicker", "dep:chrono"]
|
jiff = ["egui_extras/datepicker", "dep:jiff"]
|
||||||
|
|
||||||
## Allow serialization using [`serde`](https://docs.rs/serde).
|
## Allow serialization using [`serde`](https://docs.rs/serde).
|
||||||
serde = ["egui/serde", "dep:serde", "egui_extras/serde"]
|
serde = ["egui/serde", "dep:serde", "egui_extras/serde"]
|
||||||
@@ -42,7 +42,7 @@ egui_extras = { workspace = true, features = ["image", "svg"] }
|
|||||||
unicode_names2.workspace = true # this old version has fewer dependencies
|
unicode_names2.workspace = true # this old version has fewer dependencies
|
||||||
|
|
||||||
#! ### Optional dependencies
|
#! ### Optional dependencies
|
||||||
chrono = { workspace = true, optional = true, features = ["js-sys", "wasmbind"] }
|
jiff = { workspace = true, optional = true, features = ["std", "js"] }
|
||||||
## Enable this when generating docs.
|
## Enable this when generating docs.
|
||||||
document-features = { workspace = true, optional = true }
|
document-features = { workspace = true, optional = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ pub struct WidgetGallery {
|
|||||||
color: egui::Color32,
|
color: egui::Color32,
|
||||||
animate_progress_bar: bool,
|
animate_progress_bar: bool,
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
#[cfg_attr(feature = "serde", serde(skip))]
|
#[cfg_attr(feature = "serde", serde(skip))]
|
||||||
date: Option<chrono::NaiveDate>,
|
date: Option<jiff::civil::Date>,
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
with_date_button: bool,
|
with_date_button: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,19 +39,19 @@ impl Default for WidgetGallery {
|
|||||||
string: Default::default(),
|
string: Default::default(),
|
||||||
color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5),
|
color: egui::Color32::LIGHT_BLUE.linear_multiply(0.5),
|
||||||
animate_progress_bar: false,
|
animate_progress_bar: false,
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
date: None,
|
date: None,
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
with_date_button: true,
|
with_date_button: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WidgetGallery {
|
impl WidgetGallery {
|
||||||
#[allow(clippy::allow_attributes, unused_mut)] // if not chrono
|
#[allow(clippy::allow_attributes, unused_mut)] // if not jiff
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_date_button(mut self, _with_date_button: bool) -> Self {
|
pub fn with_date_button(mut self, _with_date_button: bool) -> Self {
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
{
|
{
|
||||||
self.with_date_button = _with_date_button;
|
self.with_date_button = _with_date_button;
|
||||||
}
|
}
|
||||||
@@ -140,9 +140,9 @@ impl WidgetGallery {
|
|||||||
string,
|
string,
|
||||||
color,
|
color,
|
||||||
animate_progress_bar,
|
animate_progress_bar,
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
date,
|
date,
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
with_date_button,
|
with_date_button,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
@@ -242,9 +242,9 @@ impl WidgetGallery {
|
|||||||
}
|
}
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
if *with_date_button {
|
if *with_date_button {
|
||||||
let date = date.get_or_insert_with(|| chrono::offset::Utc::now().date_naive());
|
let date = date.get_or_insert_with(|| jiff::Zoned::now().date());
|
||||||
ui.add(doc_link_label_with_crate(
|
ui.add(doc_link_label_with_crate(
|
||||||
"egui_extras",
|
"egui_extras",
|
||||||
"DatePickerButton",
|
"DatePickerButton",
|
||||||
@@ -302,7 +302,7 @@ fn doc_link_label_with_crate<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "jiff")]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -314,7 +314,7 @@ mod tests {
|
|||||||
pub fn should_match_screenshot() {
|
pub fn should_match_screenshot() {
|
||||||
let mut demo = WidgetGallery {
|
let mut demo = WidgetGallery {
|
||||||
// If we don't set a fixed date, the snapshot test will fail.
|
// If we don't set a fixed date, the snapshot test will fail.
|
||||||
date: Some(chrono::NaiveDate::from_ymd_opt(2024, 1, 1).unwrap()),
|
date: Some(jiff::civil::date(2024, 1, 1)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ default = ["dep:mime_guess2"]
|
|||||||
all_loaders = ["file", "http", "image", "svg", "gif", "webp"]
|
all_loaders = ["file", "http", "image", "svg", "gif", "webp"]
|
||||||
|
|
||||||
## Enable [`DatePickerButton`] widget.
|
## Enable [`DatePickerButton`] widget.
|
||||||
datepicker = ["chrono"]
|
datepicker = ["jiff"]
|
||||||
|
|
||||||
## Add support for loading images from `file://` URIs.
|
## Add support for loading images from `file://` URIs.
|
||||||
file = ["dep:mime_guess2"]
|
file = ["dep:mime_guess2"]
|
||||||
@@ -83,7 +83,7 @@ profiling.workspace = true
|
|||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|
||||||
# Date operations needed for datepicker widget
|
# Date operations needed for datepicker widget
|
||||||
chrono = { workspace = true, optional = true, features = ["clock", "js-sys", "std", "wasmbind"] }
|
jiff = { workspace = true, optional = true, features = ["std", "tz-system", "js"] }
|
||||||
|
|
||||||
## Enable this when generating docs.
|
## Enable this when generating docs.
|
||||||
document-features = { workspace = true, optional = true }
|
document-features = { workspace = true, optional = true }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use super::popup::DatePickerPopup;
|
use super::popup::DatePickerPopup;
|
||||||
use chrono::NaiveDate;
|
|
||||||
use egui::{Area, Button, Frame, InnerResponse, Key, Order, RichText, Ui, Widget};
|
use egui::{Area, Button, Frame, InnerResponse, Key, Order, RichText, Ui, Widget};
|
||||||
|
use jiff::civil::Date;
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@@ -11,7 +11,7 @@ pub(crate) struct DatePickerButtonState {
|
|||||||
|
|
||||||
/// Shows a date, and will open a date picker popup when clicked.
|
/// Shows a date, and will open a date picker popup when clicked.
|
||||||
pub struct DatePickerButton<'a> {
|
pub struct DatePickerButton<'a> {
|
||||||
selection: &'a mut NaiveDate,
|
selection: &'a mut Date,
|
||||||
id_salt: Option<&'a str>,
|
id_salt: Option<&'a str>,
|
||||||
combo_boxes: bool,
|
combo_boxes: bool,
|
||||||
arrows: bool,
|
arrows: bool,
|
||||||
@@ -20,13 +20,13 @@ pub struct DatePickerButton<'a> {
|
|||||||
show_icon: bool,
|
show_icon: bool,
|
||||||
format: String,
|
format: String,
|
||||||
highlight_weekends: bool,
|
highlight_weekends: bool,
|
||||||
start_end_years: Option<RangeInclusive<i32>>,
|
start_end_years: Option<RangeInclusive<i16>>,
|
||||||
reverse_years: bool,
|
reverse_years: bool,
|
||||||
year_scroll_to: Option<i32>,
|
year_scroll_to: Option<i16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DatePickerButton<'a> {
|
impl<'a> DatePickerButton<'a> {
|
||||||
pub fn new(selection: &'a mut NaiveDate) -> Self {
|
pub fn new(selection: &'a mut Date) -> Self {
|
||||||
Self {
|
Self {
|
||||||
selection,
|
selection,
|
||||||
id_salt: None,
|
id_salt: None,
|
||||||
@@ -95,7 +95,7 @@ impl<'a> DatePickerButton<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change the format shown on the button. (Default: %Y-%m-%d)
|
/// Change the format shown on the button. (Default: %Y-%m-%d)
|
||||||
/// See [`chrono::format::strftime`] for valid formats.
|
/// See [`jiff::fmt::strtime`] for valid formats.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn format(mut self, format: impl Into<String>) -> Self {
|
pub fn format(mut self, format: impl Into<String>) -> Self {
|
||||||
self.format = format.into();
|
self.format = format.into();
|
||||||
@@ -115,7 +115,7 @@ impl<'a> DatePickerButton<'a> {
|
|||||||
/// For example, if you want to provide the range of years from 2000 to 2035, you can use:
|
/// For example, if you want to provide the range of years from 2000 to 2035, you can use:
|
||||||
/// `start_end_years(2000..=2035)`.
|
/// `start_end_years(2000..=2035)`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn start_end_years(mut self, start_end_years: RangeInclusive<i32>) -> Self {
|
pub fn start_end_years(mut self, start_end_years: RangeInclusive<i16>) -> Self {
|
||||||
self.start_end_years = Some(start_end_years);
|
self.start_end_years = Some(start_end_years);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ impl<'a> DatePickerButton<'a> {
|
|||||||
/// Scroll the year dropdown to this year when the picker first opens.
|
/// Scroll the year dropdown to this year when the picker first opens.
|
||||||
/// Defaults to the currently selected year.
|
/// Defaults to the currently selected year.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn year_scroll_to(mut self, year: i32) -> Self {
|
pub fn year_scroll_to(mut self, year: i16) -> Self {
|
||||||
self.year_scroll_to = Some(year);
|
self.year_scroll_to = Some(year);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -144,9 +144,9 @@ impl Widget for DatePickerButton<'_> {
|
|||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut text = if self.show_icon {
|
let mut text = if self.show_icon {
|
||||||
RichText::new(format!("{} 📆", self.selection.format(&self.format)))
|
RichText::new(format!("{} 📆", self.selection.strftime(&self.format)))
|
||||||
} else {
|
} else {
|
||||||
RichText::new(format!("{}", self.selection.format(&self.format)))
|
RichText::new(format!("{}", self.selection.strftime(&self.format)))
|
||||||
};
|
};
|
||||||
let visuals = ui.visuals().widgets.open;
|
let visuals = ui.visuals().widgets.open;
|
||||||
if button_state.picker_visible {
|
if button_state.picker_visible {
|
||||||
|
|||||||
@@ -4,32 +4,32 @@ mod button;
|
|||||||
mod popup;
|
mod popup;
|
||||||
|
|
||||||
pub use button::DatePickerButton;
|
pub use button::DatePickerButton;
|
||||||
use chrono::{Datelike as _, Duration, NaiveDate, Weekday};
|
use jiff::civil::{Date, ISOWeekDate, Weekday};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Week {
|
struct Week {
|
||||||
number: u8,
|
number: u8,
|
||||||
days: Vec<NaiveDate>,
|
days: Vec<Date>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn month_data(year: i32, month: u32) -> Vec<Week> {
|
fn month_data(year: i16, month: i8) -> Vec<Week> {
|
||||||
let first = NaiveDate::from_ymd_opt(year, month, 1).expect("Could not create NaiveDate");
|
let first = Date::new(year, month, 1).expect("Could not create Date");
|
||||||
let mut start = first;
|
let mut start = first;
|
||||||
while start.weekday() != Weekday::Mon {
|
while start.weekday() != Weekday::Monday {
|
||||||
start = start.checked_sub_signed(Duration::days(1)).unwrap();
|
start = start.yesterday().unwrap();
|
||||||
}
|
}
|
||||||
let mut weeks = vec![];
|
let mut weeks = vec![];
|
||||||
let mut week = vec![];
|
let mut week = vec![];
|
||||||
while start < first || start.month() == first.month() || start.weekday() != Weekday::Mon {
|
while start < first || start.month() == first.month() || start.weekday() != Weekday::Monday {
|
||||||
week.push(start);
|
week.push(start);
|
||||||
|
|
||||||
if start.weekday() == Weekday::Sun {
|
if start.weekday() == Weekday::Sunday {
|
||||||
weeks.push(Week {
|
weeks.push(Week {
|
||||||
number: start.iso_week().week() as u8,
|
number: ISOWeekDate::from(start).week() as u8,
|
||||||
days: std::mem::take(&mut week),
|
days: std::mem::take(&mut week),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
start = start.checked_add_signed(Duration::days(1)).unwrap();
|
start = start.tomorrow().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
weeks
|
weeks
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use chrono::{Datelike as _, NaiveDate, Weekday};
|
use jiff::civil::{Date, Weekday};
|
||||||
|
|
||||||
use egui::{Align, Button, Color32, ComboBox, Direction, Id, Layout, RichText, Ui, Vec2};
|
use egui::{Align, Button, Color32, ComboBox, Direction, Id, Layout, RichText, Ui, Vec2};
|
||||||
|
|
||||||
@@ -9,43 +9,39 @@ use crate::{Column, Size, StripBuilder, TableBuilder};
|
|||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||||
struct DatePickerPopupState {
|
struct DatePickerPopupState {
|
||||||
year: i32,
|
year: i16,
|
||||||
month: u32,
|
month: i8,
|
||||||
day: u32,
|
day: i8,
|
||||||
setup: bool,
|
setup: bool,
|
||||||
year_scroll_needed: bool,
|
year_scroll_needed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatePickerPopupState {
|
impl DatePickerPopupState {
|
||||||
fn last_day_of_month(&self) -> u32 {
|
fn last_day_of_month(&self) -> i8 {
|
||||||
let date: NaiveDate =
|
Date::new(self.year, self.month, 1)
|
||||||
NaiveDate::from_ymd_opt(self.year, self.month, 1).expect("Could not create NaiveDate");
|
.expect("Could not create Date")
|
||||||
date.with_day(31)
|
.days_in_month()
|
||||||
.map(|_| 31)
|
|
||||||
.or_else(|| date.with_day(30).map(|_| 30))
|
|
||||||
.or_else(|| date.with_day(29).map(|_| 29))
|
|
||||||
.unwrap_or(28)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct DatePickerPopup<'a> {
|
pub(crate) struct DatePickerPopup<'a> {
|
||||||
pub selection: &'a mut NaiveDate,
|
pub selection: &'a mut Date,
|
||||||
pub button_id: Id,
|
pub button_id: Id,
|
||||||
pub combo_boxes: bool,
|
pub combo_boxes: bool,
|
||||||
pub arrows: bool,
|
pub arrows: bool,
|
||||||
pub calendar: bool,
|
pub calendar: bool,
|
||||||
pub calendar_week: bool,
|
pub calendar_week: bool,
|
||||||
pub highlight_weekends: bool,
|
pub highlight_weekends: bool,
|
||||||
pub start_end_years: Option<std::ops::RangeInclusive<i32>>,
|
pub start_end_years: Option<std::ops::RangeInclusive<i16>>,
|
||||||
pub reverse_years: bool,
|
pub reverse_years: bool,
|
||||||
pub year_scroll_to: Option<i32>,
|
pub year_scroll_to: Option<i16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DatePickerPopup<'_> {
|
impl DatePickerPopup<'_> {
|
||||||
/// Returns `true` if user pressed `Save` button.
|
/// Returns `true` if user pressed `Save` button.
|
||||||
pub fn draw(&mut self, ui: &mut Ui) -> bool {
|
pub fn draw(&mut self, ui: &mut Ui) -> bool {
|
||||||
let id = ui.make_persistent_id("date_picker");
|
let id = ui.make_persistent_id("date_picker");
|
||||||
let today = chrono::offset::Utc::now().date_naive();
|
let today = jiff::Zoned::now().date();
|
||||||
let mut popup_state = ui
|
let mut popup_state = ui
|
||||||
.data_mut(|data| data.get_persisted::<DatePickerPopupState>(id))
|
.data_mut(|data| data.get_persisted::<DatePickerPopupState>(id))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
@@ -95,7 +91,7 @@ impl DatePickerPopup<'_> {
|
|||||||
};
|
};
|
||||||
let scroll_to_year =
|
let scroll_to_year =
|
||||||
self.year_scroll_to.unwrap_or(popup_state.year);
|
self.year_scroll_to.unwrap_or(popup_state.year);
|
||||||
let years: Vec<i32> = if self.reverse_years {
|
let years: Vec<i16> = if self.reverse_years {
|
||||||
(start_year..=end_year).rev().collect()
|
(start_year..=end_year).rev().collect()
|
||||||
} else {
|
} else {
|
||||||
(start_year..=end_year).collect()
|
(start_year..=end_year).collect()
|
||||||
@@ -132,7 +128,7 @@ impl DatePickerPopup<'_> {
|
|||||||
ComboBox::from_id_salt("date_picker_month")
|
ComboBox::from_id_salt("date_picker_month")
|
||||||
.selected_text(month_name(popup_state.month))
|
.selected_text(month_name(popup_state.month))
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
for month in 1..=12 {
|
for month in 1i8..=12 {
|
||||||
if ui
|
if ui
|
||||||
.selectable_value(
|
.selectable_value(
|
||||||
&mut popup_state.month,
|
&mut popup_state.month,
|
||||||
@@ -156,7 +152,7 @@ impl DatePickerPopup<'_> {
|
|||||||
ComboBox::from_id_salt("date_picker_day")
|
ComboBox::from_id_salt("date_picker_day")
|
||||||
.selected_text(popup_state.day.to_string())
|
.selected_text(popup_state.day.to_string())
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
for day in 1..=popup_state.last_day_of_month() {
|
for day in 1i8..=popup_state.last_day_of_month() {
|
||||||
if ui
|
if ui
|
||||||
.selectable_value(
|
.selectable_value(
|
||||||
&mut popup_state.day,
|
&mut popup_state.day,
|
||||||
@@ -333,9 +329,10 @@ impl DatePickerPopup<'_> {
|
|||||||
&& popup_state.day == day.day()
|
&& popup_state.day == day.day()
|
||||||
{
|
{
|
||||||
ui.visuals().selection.bg_fill
|
ui.visuals().selection.bg_fill
|
||||||
} else if (day.weekday() == Weekday::Sat
|
} else if (matches!(
|
||||||
|| day.weekday() == Weekday::Sun)
|
day.weekday(),
|
||||||
&& self.highlight_weekends
|
Weekday::Saturday | Weekday::Sunday
|
||||||
|
)) && self.highlight_weekends
|
||||||
{
|
{
|
||||||
if ui.visuals().dark_mode {
|
if ui.visuals().dark_mode {
|
||||||
Color32::DARK_RED
|
Color32::DARK_RED
|
||||||
@@ -414,12 +411,12 @@ impl DatePickerPopup<'_> {
|
|||||||
strip.cell(|ui| {
|
strip.cell(|ui| {
|
||||||
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
ui.with_layout(Layout::top_down_justified(Align::Center), |ui| {
|
||||||
if ui.button("Save").clicked() {
|
if ui.button("Save").clicked() {
|
||||||
*self.selection = NaiveDate::from_ymd_opt(
|
*self.selection = Date::new(
|
||||||
popup_state.year,
|
popup_state.year,
|
||||||
popup_state.month,
|
popup_state.month,
|
||||||
popup_state.day,
|
popup_state.day,
|
||||||
)
|
)
|
||||||
.expect("Could not create NaiveDate");
|
.expect("Could not create Date");
|
||||||
saved = true;
|
saved = true;
|
||||||
close = true;
|
close = true;
|
||||||
}
|
}
|
||||||
@@ -442,7 +439,7 @@ impl DatePickerPopup<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn month_name(i: u32) -> &'static str {
|
fn month_name(i: i8) -> &'static str {
|
||||||
match i {
|
match i {
|
||||||
1 => "January",
|
1 => "January",
|
||||||
2 => "February",
|
2 => "February",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#![expect(clippy::manual_range_contains)]
|
#![expect(clippy::manual_range_contains)]
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "datepicker")]
|
||||||
mod datepicker;
|
mod datepicker;
|
||||||
|
|
||||||
pub mod syntax_highlighting;
|
pub mod syntax_highlighting;
|
||||||
@@ -21,7 +21,7 @@ mod sizing;
|
|||||||
mod strip;
|
mod strip;
|
||||||
mod table;
|
mod table;
|
||||||
|
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "datepicker")]
|
||||||
pub use crate::datepicker::DatePickerButton;
|
pub use crate::datepicker::DatePickerButton;
|
||||||
|
|
||||||
pub(crate) use crate::layout::StripLayout;
|
pub(crate) use crate::layout::StripLayout;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ eframe = { workspace = true, default-features = false, features = [
|
|||||||
"glow",
|
"glow",
|
||||||
"android-native-activity",
|
"android-native-activity",
|
||||||
] }
|
] }
|
||||||
egui_demo_lib = { workspace = true, features = ["chrono"] }
|
egui_demo_lib = { workspace = true, features = ["jiff"] }
|
||||||
|
|
||||||
# For image support:
|
# For image support:
|
||||||
egui_extras = { workspace = true, features = ["default", "image"] }
|
egui_extras = { workspace = true, features = ["default", "image"] }
|
||||||
|
|||||||
Reference in New Issue
Block a user