Skip to content

Commit

Permalink
Add tab navigation (lapce#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc authored Nov 6, 2023
1 parent 3552a4e commit afc5f5f
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 114 deletions.
6 changes: 3 additions & 3 deletions examples/counter/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn app_view() -> impl View {
.padding(10.0)
.background(Color::WHITE)
.box_shadow_blur(5.0)
.focus_visible(|s| s.border(2.).border_color(Color::BLUE))
.focus_visible(|s| s.outline(2.).outline_color(Color::BLUE))
.hover(|s| s.background(Color::LIGHT_GREEN))
.active(|s| s.color(Color::WHITE).background(Color::DARK_GREEN))
})
Expand All @@ -43,7 +43,7 @@ fn app_view() -> impl View {
.border_radius(10.0)
.padding(10.0)
.margin_left(10.0)
.focus_visible(|s| s.border(2.).border_color(Color::BLUE))
.focus_visible(|s| s.outline(2.).outline_color(Color::BLUE))
.hover(|s| s.background(Color::rgb8(244, 67, 54)))
.active(|s| s.color(Color::WHITE).background(Color::RED))
})
Expand All @@ -61,7 +61,7 @@ fn app_view() -> impl View {
.padding(10.0)
.margin_left(10.0)
.background(Color::LIGHT_BLUE)
.focus_visible(|s| s.border(2.).border_color(Color::BLUE))
.focus_visible(|s| s.outline(2.).outline_color(Color::BLUE))
.disabled(|s| s.background(Color::LIGHT_GRAY))
.hover(|s| s.background(Color::LIGHT_YELLOW))
.active(|s| s.color(Color::WHITE).background(Color::YELLOW_GREEN))
Expand Down
14 changes: 13 additions & 1 deletion examples/themes/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use floem::{
keyboard::{Key, NamedKey},
peniko::Color,
reactive::create_signal,
style::{Background, BorderColor, Style, TextColor, Transition},
style::{Background, BorderColor, Outline, OutlineColor, Style, TextColor, Transition},
style_class,
view::View,
views::{label, stack, text, Decorators},
Expand All @@ -23,6 +23,11 @@ fn app_view() -> impl View {
.transition(TextColor, Transition::linear(0.06))
.transition(BorderColor, Transition::linear(0.06))
.transition(Background, Transition::linear(0.06))
.transition(Outline, Transition::linear(0.1))
.focus_visible(|s| {
s.outline(2.0)
.outline_color(Color::WHITE.with_alpha_factor(0.7))
})
.disabled(|s| {
s.background(Color::DARK_GRAY.with_alpha_factor(0.1))
.border_color(Color::BLACK.with_alpha_factor(0.2))
Expand Down Expand Up @@ -55,6 +60,13 @@ fn app_view() -> impl View {
.transition(TextColor, Transition::linear(0.3))
.transition(BorderColor, Transition::linear(0.3))
.transition(Background, Transition::linear(0.3))
.transition(Outline, Transition::linear(0.2))
.transition(OutlineColor, Transition::linear(0.2))
.outline_color(Color::rgba8(131, 145, 123, 0))
.focus_visible(|s| {
s.outline(10.0)
.outline_color(Color::rgb8(131, 145, 123).with_alpha_factor(0.3))
})
.border_color(Color::rgb8(131, 145, 123))
.hover(|s| s.background(Color::rgb8(204, 209, 201)))
.padding(8.0)
Expand Down
6 changes: 5 additions & 1 deletion examples/widget-gallery/src/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ pub fn checkbox_view() -> impl View {
stack({
(
checkbox(is_checked)
.on_click(move |_| {
set_is_checked.update(|checked| *checked = !*checked);
true
})
.style(|s| s.focus_visible(|s| s.border(2.).border_color(Color::BLUE))),
label(|| "Check me!"),
)
Expand All @@ -36,12 +40,12 @@ pub fn checkbox_view() -> impl View {
stack({
(
checkbox(is_checked)
.disabled(|| true)
.style(|s| s.focus_visible(|s| s.border(2.).border_color(Color::BLUE))),
label(|| "Check me!"),
)
})
.style(|s| s.color(Color::GRAY))
.disabled(|| true)
.on_click(move |_| {
set_is_checked.update(|checked| *checked = !*checked);
true
Expand Down
20 changes: 15 additions & 5 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use crate::{
responsive::{GridBreakpoints, ScreenSizeBp},
style::{
Background, BorderBottom, BorderColor, BorderLeft, BorderRadius, BorderRight, BorderTop,
BuiltinStyle, CursorStyle, DisplayProp, LayoutProps, Style, StyleClassRef, StyleProp,
StyleSelector, StyleSelectors, ZIndex,
BuiltinStyle, CursorStyle, DisplayProp, LayoutProps, Outline, OutlineColor, Style,
StyleClassRef, StyleProp, StyleSelector, StyleSelectors, ZIndex,
},
unit::PxPct,
view::{paint_bg, paint_border, paint_outline, View},
Expand Down Expand Up @@ -57,6 +57,8 @@ prop_extracter! {
pub border_bottom: BorderBottom,
pub border_radius: BorderRadius,

pub outline: Outline,
pub outline_color: OutlineColor,
pub border_color: BorderColor,
pub background: Background,
}
Expand Down Expand Up @@ -548,7 +550,9 @@ impl AppState {
pub(crate) fn clear_focus(&mut self) {
if let Some(old_id) = self.focus {
// To remove the styles applied by the Focus selector
if self.has_style_for_sel(old_id, StyleSelector::Focus) {
if self.has_style_for_sel(old_id, StyleSelector::Focus)
|| self.has_style_for_sel(old_id, StyleSelector::FocusVisible)
{
self.request_style(old_id);
}
}
Expand All @@ -563,6 +567,12 @@ impl AppState {

self.focus = Some(id);
self.keyboard_navigation = keyboard_navigation;

if self.has_style_for_sel(id, StyleSelector::Focus)
|| self.has_style_for_sel(id, StyleSelector::FocusVisible)
{
self.request_style(id);
}
}

pub(crate) fn has_style_for_sel(&mut self, id: Id, selector_kind: StyleSelector) -> bool {
Expand Down Expand Up @@ -1507,7 +1517,7 @@ impl<'a> PaintCx<'a> {

view.paint(self);
paint_border(self, &view_style_props, size);
paint_outline(self, &style, size)
paint_outline(self, &view_style_props, size)
}

let mut drag_set_to_none = false;
Expand Down Expand Up @@ -1554,7 +1564,7 @@ impl<'a> PaintCx<'a> {

view.paint(self);
paint_border(self, &view_style_props, size);
paint_outline(self, &style, size);
paint_outline(self, &view_style_props, size);

self.restore();
}
Expand Down
57 changes: 52 additions & 5 deletions src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::id::Id;
use crate::style::{Style, StyleMapValue};
use crate::view::{view_children, View};
use crate::views::{
dyn_container, empty, img_dynamic, scroll, stack, static_label, static_list, text, v_stack,
Decorators, Label,
dyn_container, empty, h_stack, img_dynamic, scroll, stack, static_label, static_list, text,
v_stack, Decorators, Label,
};
use crate::window::WindowConfig;
use crate::{new_window, style};
Expand Down Expand Up @@ -34,6 +34,8 @@ pub struct CapturedView {
children: Vec<Rc<CapturedView>>,
direct_style: Style,
requested_changes: ChangeFlags,
keyboard_navigable: bool,
focused: bool,
}

impl CapturedView {
Expand All @@ -42,8 +44,9 @@ impl CapturedView {
let layout = app_state.get_layout_rect(id);
let taffy = app_state.get_layout(id).unwrap();
let computed_style = app_state.get_computed_style(id).clone();
let keyboard_navigable = app_state.keyboard_navigable.contains(&id);
let focused = app_state.focus == Some(id);
let state = app_state.view_state(id);

let clipped = layout.intersect(clip);
Self {
id,
Expand All @@ -53,6 +56,8 @@ impl CapturedView {
clipped,
direct_style: computed_style,
requested_changes: state.requested_changes,
keyboard_navigable,
focused,
children: view_children(view)
.into_iter()
.map(|view| Rc::new(CapturedView::capture(view, app_state, clipped)))
Expand Down Expand Up @@ -119,6 +124,46 @@ impl CaptureState {
}
}

fn captured_view_name(view: &CapturedView) -> impl View {
let name = static_label(view.name.clone());
let id = text(view.id.to_raw()).style(|s| {
s.margin_right(5.0)
.background(Color::BLACK.with_alpha_factor(0.02))
.border(1.0)
.border_radius(5.0)
.border_color(Color::BLACK.with_alpha_factor(0.07))
.padding(3.0)
.padding_top(0.0)
.padding_bottom(0.0)
.font_size(12.0)
.color(Color::BLACK.with_alpha_factor(0.6))
});
let tab: Box<dyn View> = if view.focused {
Box::new(text("Focus").style(|s| {
s.margin_right(5.0)
.background(Color::rgb8(63, 81, 101).with_alpha_factor(0.6))
.border_radius(5.0)
.padding(1.0)
.font_size(10.0)
.color(Color::WHITE.with_alpha_factor(0.8))
}))
} else if view.keyboard_navigable {
Box::new(text("Tab").style(|s| {
s.margin_right(5.0)
.background(Color::rgb8(204, 217, 221).with_alpha_factor(0.4))
.border(1.0)
.border_radius(5.0)
.border_color(Color::BLACK.with_alpha_factor(0.07))
.padding(1.0)
.font_size(10.0)
.color(Color::BLACK.with_alpha_factor(0.4))
}))
} else {
Box::new(empty())
};
h_stack((id, tab, name)).style(|s| s.items_center())
}

// Outlined to reduce stack usage.
#[inline(never)]
fn captured_view_no_children(
Expand All @@ -128,7 +173,7 @@ fn captured_view_no_children(
highlighted: RwSignal<Option<Id>>,
) -> Box<dyn View> {
let offset = depth as f64 * 14.0;
let name = static_label(view.name.clone());
let name = captured_view_name(view);
let height = 20.0;
let id = view.id;

Expand Down Expand Up @@ -174,7 +219,7 @@ fn captured_view_with_children(
children: Vec<Box<dyn View>>,
) -> Box<dyn View> {
let offset = depth as f64 * 14.0;
let name = static_label(view.name.clone());
let name = captured_view_name(view);
let height = 20.0;
let id = view.id;

Expand Down Expand Up @@ -354,6 +399,7 @@ fn selected_view(capture: &Rc<Capture>, selected: RwSignal<Option<Id>>) -> impl
move |current| {
if let Some(view) = current.and_then(|id| capture.root.find(id)) {
let name = info("Type", view.name.clone());
let id = info("Id", view.id.to_raw().to_string());
let count = info("Child Count", format!("{}", view.children.len()));
let beyond = |view: f64, window| {
if view > window {
Expand Down Expand Up @@ -547,6 +593,7 @@ fn selected_view(capture: &Rc<Capture>, selected: RwSignal<Option<Id>>) -> impl
Box::new(
v_stack((
name,
id,
count,
x,
y,
Expand Down
3 changes: 3 additions & 0 deletions src/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ impl StylePropValue for Px {
fn debug_view(&self) -> Option<Box<dyn View>> {
Some(Box::new(text(format!("{} px", self.0))))
}
fn interpolate(&self, other: &Self, value: f64) -> Option<Self> {
self.0.interpolate(&other.0, value).map(Px)
}
}
impl StylePropValue for PxPctAuto {
fn debug_view(&self) -> Option<Box<dyn View>> {
Expand Down
Loading

0 comments on commit afc5f5f

Please sign in to comment.