Skip to content

Add table view #774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/widget-gallery/src/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub fn form<VTF: ViewTupleFlat + 'static>(children: VTF) -> impl IntoView {
.row_gap(20)
.col_gap(10)
.padding(30)
.max_size_full()
})
.debug_name("Form")
}
Expand Down
3 changes: 3 additions & 0 deletions examples/widget-gallery/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod lists;
pub mod radio_buttons;
pub mod rich_text;
pub mod slider;
pub mod table;

use floem::{
event::{Event, EventListener},
Expand All @@ -33,6 +34,7 @@ fn app_view() -> impl IntoView {
"Radio",
"Input",
"List",
"Table",
"Menu",
"RichText",
"Image",
Expand All @@ -53,6 +55,7 @@ fn app_view() -> impl IntoView {
"Radio" => radio_buttons::radio_buttons_view().into_any(),
"Input" => inputs::text_input_view().into_any(),
"List" => lists::virt_list_view().into_any(),
"Table" => table::table_view().into_any(),
"Menu" => context_menu::menu_view().into_any(),
"RichText" => rich_text::rich_text_view().into_any(),
"Image" => images::img_view().into_any(),
Expand Down
76 changes: 76 additions & 0 deletions examples/widget-gallery/src/table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use floem::prelude::*;

use crate::form::{form, form_item};

pub fn table_view() -> impl IntoView {
form((form_item(
"Virtualized Tip Percentage Table",
percentage_table(),
),))
}

fn percentage_table() -> impl IntoView {
let base_prices = im::vector![
20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99, 15.49, 89.99, 67.50, 23.99,
129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25, 149.99, 28.75, 95.00, 82.49, 17.99,
165.00, 39.99, 72.50, 19.99, 20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99,
15.49, 89.99, 67.50, 23.99, 129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25, 149.99,
28.75, 95.00, 82.49, 17.99, 165.00, 39.99, 72.50, 19.99, 20.00, 50.00, 75.00, 36.00, 52.00,
99.00, 105.00, 42.99, 15.49, 89.99, 67.50, 23.99, 129.99, 8.99, 45.75, 12.99, 199.99,
55.50, 33.25, 149.99, 28.75, 95.00, 82.49, 17.99, 165.00, 39.99, 72.50, 19.99, 20.00,
50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99, 15.49, 89.99, 67.50, 23.99, 129.99, 8.99,
45.75, 12.99, 199.99, 55.50, 33.25, 149.99, 28.75, 95.00, 82.49, 17.99, 165.00, 39.99,
72.50, 19.99, 20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99, 15.49, 89.99, 67.50,
23.99, 129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25, 149.99, 28.75, 95.00, 82.49,
17.99, 165.00, 39.99, 72.50, 19.99, 20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00,
42.99, 15.49, 89.99, 67.50, 23.99, 129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25,
149.99, 28.75, 95.00, 82.49, 17.99, 165.00, 39.99, 72.50, 19.99, 20.00, 50.00, 75.00,
36.00, 52.00, 99.00, 105.00, 42.99, 15.49, 89.99, 67.50, 23.99, 129.99, 8.99, 45.75, 12.99,
199.99, 55.50, 33.25, 149.99, 28.75, 95.00, 82.49, 17.99, 165.00, 39.99, 72.50, 19.99,
20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99, 15.49, 89.99, 67.50, 23.99,
129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25, 149.99, 28.75, 95.00, 82.49, 17.99,
165.00, 39.99, 72.50, 19.99, 20.00, 50.00, 75.00, 36.00, 52.00, 99.00, 105.00, 42.99,
15.49, 89.99, 67.50, 23.99, 129.99, 8.99, 45.75, 12.99, 199.99, 55.50, 33.25, 149.99,
28.75, 95.00, 82.49, 17.99, 165.00, 39.99, 72.50, 19.99,
];

// create a slice of tip percentages and then create a column from each
let columns = [15, 20, 25, 50, 75].iter().map(move |pc| {
// a column needs
// 1. a header which can be any view
// 2. a closure that can generate the data for the column given the row as input
// It is assumed that all rows, including the column headers have the same height.
// There wil be layout issues if this isn't respected
Column::new(format!("With {pc}% tip"), |(_idx, v)| {
let percent = *v * (*pc as f64 / 100. + 1.);
format!("${percent:.2}")
})
});

// create a table by supplying the input data and a `key_fn`.
// The key function is used to determine if items are unique.
// Here we use the index of the item in the table as it's unique identifier.
// In other situations, other unique identifiers will need to be used
let table = table(move || base_prices.clone().enumerate(), |(idx, _p)| *idx)
// there are two ways to add colums. First by adding an individual column by passing in the title and closure
.column("Base price", |(_idx, p)| format!("${p:.2}"))
// or by supplying an iterator of columns
.columns(columns);

table
.style(|s| {
s.row_gap(10)
.col_gap(30)
.flex_grow(1.)
.items_start()
// it is important that all rows have the same height. You can include gaps, padding, margins, etc but all rows must be the same height.
.class(LabelClass, |s| s.height(15))
})
.scroll()
.style(|s| {
s.border(1.0)
.padding_horiz(15)
.padding_right(20 + 15)
.height(400.)
})
}
2 changes: 1 addition & 1 deletion reactive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use derived::{create_derived_rw_signal, DerivedRwSignal};
pub use effect::{batch, create_effect, create_stateful_updater, create_updater, untrack};
pub use memo::{create_memo, Memo};
pub use read::{ReadSignalValue, SignalGet, SignalRead, SignalTrack, SignalWith};
pub use scope::{as_child_of_current_scope, with_scope, Scope};
pub use scope::{as_child_of_current_scope, as_child_of_current_scope2, with_scope, Scope};
pub use signal::{create_rw_signal, create_signal, ReadSignal, RwSignal, WriteSignal};
pub use trigger::{create_trigger, Trigger};
pub use write::{SignalUpdate, SignalWrite, WriteSignalValue};
24 changes: 24 additions & 0 deletions reactive/src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,27 @@ where
(result, scope)
}
}

pub fn as_child_of_current_scope2<T, U>(f: impl Fn(&T) -> U + 'static) -> impl Fn(&T) -> (U, Scope)
where
T: 'static,
{
let current_scope = Scope::current();
move |t| {
let scope = current_scope.create_child();
let prev_scope = RUNTIME.with(|runtime| {
let mut current_scope = runtime.current_scope.borrow_mut();
let prev_scope = *current_scope;
*current_scope = scope.0;
prev_scope
});

let result = f(t);

RUNTIME.with(|runtime| {
*runtime.current_scope.borrow_mut() = prev_scope;
});

(result, scope)
}
}
16 changes: 16 additions & 0 deletions src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,22 @@ impl IntoView for i32 {
}
}

impl IntoView for f32 {
type V = crate::views::Label;

fn into_view(self) -> Self::V {
crate::views::text(self)
}
}

impl IntoView for f64 {
type V = crate::views::Label;

fn into_view(self) -> Self::V {
crate::views::text(self)
}
}

impl IntoView for usize {
type V = crate::views::Label;

Expand Down
3 changes: 3 additions & 0 deletions src/views/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,6 @@ pub use checkbox::*;

mod toggle_button;
pub use toggle_button::*;

mod table;
pub use table::*;
Loading
Loading