From 859a9419f316ccfb21a6f09fce081e963e7e714f Mon Sep 17 00:00:00 2001 From: Dominic Clifton Date: Thu, 26 Sep 2024 14:24:05 +0200 Subject: [PATCH] Allow `tab` to have no active tabs. * this is a common scenario when using a tabbed interface with one-tab per document without any documents having yet been loaded. --- src/inspector.rs | 2 +- src/views/tab.rs | 57 ++++++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/inspector.rs b/src/inspector.rs index 87111127..e15e1618 100644 --- a/src/inspector.rs +++ b/src/inspector.rs @@ -1111,7 +1111,7 @@ pub fn capture(window_id: WindowId) { .style(|s| s.background(Color::WHITE)); let tab = tab( - move || selected.get(), + move || Some(selected.get()), move || [0, 1].into_iter(), |it| *it, move |it| match it { diff --git a/src/views/tab.rs b/src/views/tab.rs index 6a1eed8c..78acabae 100644 --- a/src/views/tab.rs +++ b/src/views/tab.rs @@ -1,5 +1,4 @@ use std::{hash::Hash, marker::PhantomData}; - use floem_reactive::{as_child_of_current_scope, create_effect, Scope}; use smallvec::SmallVec; use taffy::style::Display; @@ -18,6 +17,7 @@ type ViewFn = Box (Box, Scope)>; enum TabState { Diff(Box>), Active(usize), + None } pub struct Tab @@ -25,14 +25,14 @@ where T: 'static, { id: ViewId, - active: usize, + active: Option, children: Vec>, view_fn: ViewFn, phatom: PhantomData, } pub fn tab( - active_fn: impl Fn() -> usize + 'static, + active_fn: impl Fn() -> Option + 'static, each_fn: IF, key_fn: KF, view_fn: VF, @@ -72,20 +72,23 @@ where } diff }; - id.update_state(TabState::Diff(Box::new(diff))); + id.update_state(TabState::::Diff(Box::new(diff))); HashRun(hashed_items) }); create_effect(move |_| { - let active = active_fn(); - id.update_state(TabState::Active::(active)); + let active_key = active_fn(); + match active_key { + Some(key) => id.update_state(TabState::Active::(key)), + None => id.update_state(TabState::None::), + } }); let view_fn = Box::new(as_child_of_current_scope(move |e| view_fn(e).into_any())); Tab { id, - active: 0, + active: None, children: Vec::new(), view_fn, phatom: PhantomData, @@ -98,7 +101,7 @@ impl View for Tab { } fn debug_name(&self) -> std::borrow::Cow<'static, str> { - format!("Tab: {}", self.active).into() + format!("Tab: {:?}", self.active).into() } fn update(&mut self, cx: &mut UpdateCx, state: Box) { @@ -114,7 +117,10 @@ impl View for Tab { ); } TabState::Active(active) => { - self.active = active; + self.active.replace(active); + } + TabState::None => { + self.active.take(); } } self.id.request_all(); @@ -131,23 +137,32 @@ impl View for Tab { let mut child_view = child_view.borrow_mut(); child_view.combined_style = child_view.combined_style.clone().set( DisplayProp, - if i != self.active { - // set display to none for non active child - Display::None - } else { - Display::Flex - }, + + match self.active { + None => { + Display::None + } + Some(active_index) if active_index == i => { + Display::Flex + } + Some(_active_index) => { + // set display to none for non-active child + Display::None + } + } ); } } fn paint(&mut self, cx: &mut crate::context::PaintCx) { - if let Some(Some((active, _))) = self - .children - .get(self.active) - .or_else(|| self.children.first()) - { - cx.paint_view(*active); + if let Some(active_index) = self.active { + if let Some(Some((active, _))) = self + .children + .get(active_index) + .or_else(|| self.children.first()) + { + cx.paint_view(*active); + } } } }