SASAN2XCWDQ2VEHZ7TAQEN2R3Y7AG7JUGEFVRL4DZAGHXDFEZFRQC 6YZAVBWU6E5FYOI5JGEIPXGZLIKAW6LS2AOFIQWEE5DMOPPCD5PQC WT3GA27PQ2AOAIGK65O3Q4DMX4AZDVNULBLRL6GF4QW6QCASUEAAC 4WO3ZJM2RNYZCBPS7FGYAEBELYD57OSS7LEUYCWGZBCAY272SNQQC AMPZ2BXK4IGUZO3OPBRSJ6Z4GI5K4PRFMLUGTR6AP4FKKRWQG7LQC HOJZI52YIXKAYF766WR3SAOIFZH6YRMDOUE23VWEYNBZRBGEU25AC B4RMW5AEGAJX5CFC4RFPI6Y3NBSDM7GZKNBPPTTICRZSDZSYNXHQC ZVI4AWERNOTDJ3765HJXRBZT57XPNKVONQ6TGOGNPOL2VN42KMJQC QMAUTRB6R5R7ABWT2JIDEA7LMILZOS3PGPZIF3YUFKRVLW6HGKTQC NWJD6VM6POMYKQTTPP3X6LVCWU3FHLDRIHMCSC2PPUT7JWNY42LAC DCSUCH6RRRQU4TQYO3K3HRC7SXAIBYP5R3ZOWAWS2LOXWNHEJM6AC FR52XEMWD22VH3GKSARXJUJXOGO7ZSQEHWPXFRWHLGRAJU3WRKCAC CALXOZXANFZ64NBZBTR2KYTZ6ZLLCJXNFAEALBB2EYAVDVJJ6X6AC L6KSEFQIWICZJ6HJUFKLZQDEH6X2QMFM4Z7ZZUGMLDMFF7EHRXWAC BFN2VHZS7VCBUHQ4S3CQ3LFQV2V4M6VANNAF32XMRFQVWRGYSZ6AC GWZGYNIBQP2AA7WYULNBS2BCV4B36IHK4OS7XHVOTUUG27E76XFQC 3SYSJKYLVCXR54LRUPL6GOQISSJS6XWK4M6PRQRCKZN7F23NNVEAC 23SFYK4Q5NKBPJG53PQNPWQH6UOUU2YKJEL7RLXYBRLJOJYV7AWQC OPXFZKEBDHZZLXEJ2JRDYBOJH6YIN7UZNZYHVHMWMQVDTE2ZD53QC MYGIBRRHHXPKVRAMQQRJTZH74L2XOK3SF7J57JPCRKSVRLZ2D6NQC XSZZB47UXR6KGYFZZQFQR63X2LDKOH6TPNNBRRGHUCI5JJ4JIWVAC 3BK22XE5LPOH2EK5AMRXFXHNQNCJ54HEPYRINHJT4DA7INT32I7AC WGID4LS4EISIOXB5Y5SOFGEF5PLBJSCPFCETH2CGRTFN3NC4WGJQC VCNKFNUF7OWVSWC6I5D25KUZ3XZZICZ3LHWVPF2N5ZSP7LQ2JOUQC ACDXXAX26ZJJFKJDGRC2GOSJY5JHQWCSTP55SYI6D6LH5UIRYUBAC I56UGW7UUKLSR4753EYRGNROZB5PD522REEOGHVAQOZZTSVRUEEQC KMB6FND35LWT4XTRUNEJZ7SQXFZEUYIJAADGWJVB4RY4IIAT4KSQC ESMM3FELOBYIX7FUNOU37FYKRJHFU2IMX6LY6EGJTVPTBDU3SEEQC TSFQFCB2NXDOBLBRUSAT63VJIXLPPTJGSTIDNOTLGHVVWSHITRNQC 7SSBM4UQMYVRL6L3ICYZQPSMYLZZQNMDWH6JKA3KOOSXZDJHESHQC ZD56BUSUGTPPDSHHTOC2H5RJJG4FUUUPOSM2BHRY3UA5D6OA43XQC I2AG42PAVOII4V4TWDJV5ZVNDIHKBRDT254BFQLFUIY723TW6CCQC WW36JYLR4AILV7RHQEDJWMX74P74B7G7DRBHH3O2V5TCHRTZJWZQC WIFVLV376GIMVTGVXBFWIPU7FR5O3SGIQ343KIJEBWB6UURTJZJQC MJDGPSHGF62FTVWZBE7MFNJTUQD42OBVJEOSVPBT553UFJLTEMXQC file::update(&mut state.files, state.repo.as_ref(), msg);
let loaded =file::update(&mut state.files, state.repo.as_ref(), msg);if let Some(file::Loaded { id, contents_count }) = loaded {let diff_state =state.diffs_state.entry(id.clone()).or_default();let (nav, tasks) = iced_nav_scrollable::init(contents_count);diff_state.nav = Some(nav);let id_clone = id.clone();return tasks.map(move |msg| Msg::DiffStateNav {id: id_clone.clone(),msg: diff::Msg::NavScrollable(msg),});}Task::none()}Msg::DiffStateNav { id, msg } => {if let Some(diff_state) = state.diffs_state.get_mut(&id) {let task = diff::update(diff_state, msg);let id_clone = id.clone();return task.map(move |msg| Msg::DiffStateNav {id: id_clone.clone(),msg,});}Task::none()}Msg::LogChangeDiff { hash, file, msg } => {if let Some(inflorescence_view::cursor::Selection::LogChange {ix: _,hash: selection_hash,message: _,diffs: Some(diffs),file: _,}) = state.cursor.selection.as_mut(){if selection_hash == &hash {if let Some((_file, diff_state)) = diffs.get_mut(&file) {let task = diff::update(diff_state, msg);return task.map(move |msg| Msg::LogChangeDiff {hash,file: file.clone(),msg,});}}}
app::Msg::Cursor(msg) => cursor::update(&mut state.cursor,&mut state.files,state.repo.as_ref(),msg,).map(|msg| Msg::View(app::Msg::ToRepo(msg))),
app::Msg::Cursor(msg) => {let log_file_selection_before =if let Some(cursor::Selection::LogChange {file: Some(file),..}) = state.cursor.selection.as_ref(){Some(file.ix)} else {None};let cursor_task = cursor::update(&mut state.cursor,&mut state.files,state.repo.as_ref(),msg,).map(|msg| Msg::View(app::Msg::ToRepo(msg)));// If the log file selection has changed, initialize a nav for itif let Some(cursor::Selection::LogChange {hash,diffs: Some(diffs),file: Some(cursor::LogChangeFileSelection { ix, path }),..}) = state.cursor.selection.as_mut(){if Some(*ix) != log_file_selection_before {let (_file,diff::State {contents_count,nav,..},) = diffs.get_mut(path).unwrap();let (new_nav, nav_tasks) =iced_nav_scrollable::init(contents_count.unwrap());*nav = Some(new_nav);let hash = *hash;let path_clone = path.clone();return Task::batch([cursor_task,nav_tasks.map(move |msg| Msg::LogChangeDiff {hash,file: path_clone.clone(),msg: diff::Msg::NavScrollable(msg),}),]);}}cursor_task}
let diffs = state.diffs_state.entry(id).or_default();diff::update(diffs, action);
let diffs = state.diffs_state.entry(id.clone()).or_default();let task = diff::update(diffs, action);return task.map(move |msg| Msg::DiffStateNav {id: id.clone(),msg,});
pub fn update(_state: &mut State, _msg: Msg) {}
pub fn update(state: &mut State, msg: Msg) -> Task<Msg> {match msg {Msg::NavScrollable(msg) => {if let Some(nav) = state.nav.as_mut() {iced_nav_scrollable::update(nav, msg).map(Msg::NavScrollable)} else {Task::none()}}}}
use iced::widget::scrollable;use iced::{advanced, window};/// Produces a [`Task`] that scrolls the [`scrollable::Scrollable`] with the/// given [`scrollable::Id`] to the provided [`scrollable::AbsoluteOffset`].pub fn scroll_to<T>(id: impl Into<scrollable::Id>,offset: scrollable::AbsoluteOffset,) -> Task<T> {#[cfg(not(any(test, feature = "testing")))]let task = scrollable::scroll_to(id, offset);#[cfg(any(test, feature = "testing"))]let task = {let _ = (id, offset);Task::none()};
use iced::window;
task}/// Focuses the next focusable widget.pub fn widget_focus_next<T>() -> Task<T> {#[cfg(not(any(test, feature = "testing")))]let task = iced::widget::focus_next();#[cfg(any(test, feature = "testing"))]let task = Task::none();task}/// Creates a new [`Task`] that runs the given [`advanced::widget::Operation`]/// and produces its output.pub fn widget_operate<T>(operation: impl advanced::widget::Operation<T> + 'static,) -> Task<T>whereT: Send + 'static,{#[cfg(not(any(test, feature = "testing")))]let task = advanced::widget::operate(operation);#[cfg(any(test, feature = "testing"))]let task = {let _ = operation;Task::none()};task}
/// Opens a new window with the given [`Settings`]; producing the [`Id`]/// of the new window on completion.pub fn open_window(
/// Opens a new window with the given [`window::Settings`]; producing the/// [`window::Id`] of the new window on completion.pub fn window_open(
pub mod task;#[doc(inline)]pub use task::Task;
[package]name = "iced-utils"version.workspace = trueedition.workspace = truelicense.workspace = trueauthors.workspace = true[features]testing = [][dependencies]# External dependencies[dependencies.iced]workspace = true[dependencies.tokio]workspace = true[dev-dependencies]# External dependencies[dev-dependencies.tokio]workspace = truefeatures = ["macros"]
pub fn update<Message, MapFn, OnReady>(nav: &mut NavScrollable,msg: Msg,map_msg: MapFn,on_ready: OnReady,) -> Task<Message>whereMessage: MaybeSend + 'static,MapFn: Fn(Msg) -> Message + MaybeSend + 'static,OnReady: Fn(NeedsScrolling) -> Message,{
pub fn update(nav: &mut NavScrollable, msg: Msg) -> Task<Msg> {
if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);if nav.pending_tasks.is_none() {return Task::done(on_ready(nav.needs_scrolling));
if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);
if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);if nav.pending_tasks.is_none() {return Task::done(on_ready(nav.needs_scrolling));
if let Some(offsets) = nav.pending_tasks.as_mut() {*offsets -= 1;update_offsets_if_ready(nav);
/// Produces a [`Task`] that queries the height of the contents of [`Scrollable`] with the/// given [`Id`].fn scrollable_height_task(id: impl Into<scrollable::Id>) -> Task<f32> {
/// Produces a [`Task`] that queries the height of the contents of/// [`Scrollable`] with the given [`Id`].fn scrollable_height_task(id: impl Into<scrollable::Id>) -> Task<Option<f32>> {
fn finish(&self) -> advanced::widget::operation::Outcome<f32> {advanced::widget::operation::Outcome::Some(self.height.expect("Must be able to determine the size. If this even panics, make the height optional and re-try the task when None"),)
fn finish(&self) -> advanced::widget::operation::Outcome<Option<f32>> {advanced::widget::operation::Outcome::Some(self.height)
fn finish(&self) -> advanced::widget::operation::Outcome<f32> {advanced::widget::operation::Outcome::Some(self.height.expect("Must be able to determine the size. If this even panics, make the height optional and re-try the task when None"),)
fn finish(&self) -> advanced::widget::operation::Outcome<Option<f32>> {advanced::widget::operation::Outcome::Some(self.height)
features = ["testing"]