125 lines
4.5 KiB
Rust
125 lines
4.5 KiB
Rust
//! Tables on a slide (SHOW-07).
|
|
|
|
use ely_gpui_component::{
|
|
buttons::{Button, ButtonVariant},
|
|
data_display::{DescriptionList, PropertyGroup},
|
|
forms::NumberInput,
|
|
overlays::Dialog as Card,
|
|
};
|
|
use ely_office::{
|
|
panel::{button, row},
|
|
prelude::*,
|
|
};
|
|
use gpui::{
|
|
AnyElement, App, Context, Entity, IntoElement, ParentElement as _, Styled as _, Window, div,
|
|
};
|
|
|
|
use crate::deck::Deck;
|
|
use crate::design::Panel;
|
|
use crate::dialog::{Dialog, edit};
|
|
|
|
impl Deck {
|
|
pub fn ask_table(&mut self, cx: &mut Context<Self>) {
|
|
if let Some(tab) = self.core.active {
|
|
// Refused while another dialog is open; it says so.
|
|
let _ = self.open_dialog(Dialog::Table { tab, columns: 3, rows: 3 }, cx);
|
|
}
|
|
}
|
|
|
|
pub(crate) fn table_asked(&mut self, cx: &mut Context<Self>) {
|
|
let Some(Dialog::Table { tab, columns, rows }) = self.dialog.take() else {
|
|
return;
|
|
};
|
|
let (columns, rows) = (columns.to_string(), rows.to_string());
|
|
self.run_in(Some(tab), "table.insert", &[&columns, &rows], cx);
|
|
self.force_reread(tab, cx);
|
|
cx.notify();
|
|
}
|
|
|
|
pub fn table_dialog(&self, (columns, rows): (u16, u16), cx: &mut Context<Self>) -> AnyElement {
|
|
let this = cx.entity();
|
|
let label = |key: &str| Deck::text(cx, key, &[]);
|
|
let count = |id: &'static str, key: &str, now: u16, max: f64, across: bool| {
|
|
// A typed draft counts before blur commits it.
|
|
let set = move |this: &Entity<Deck>, n: f64, cx: &mut App| {
|
|
edit(this, cx, |dialog, _| {
|
|
if let Dialog::Table { columns, rows, .. } = dialog {
|
|
*(if across { columns } else { rows }) = n as u16;
|
|
}
|
|
})
|
|
};
|
|
let (typed, committed) = (this.clone(), this.clone());
|
|
let field = NumberInput::new(id, f64::from(now))
|
|
.label(label(key))
|
|
.range(1.0, max)
|
|
.on_change(move |n, _, cx| set(&typed, n, cx))
|
|
.on_commit(move |n, _, cx| set(&committed, n, cx));
|
|
div().w_full().max_w_32().child(field)
|
|
};
|
|
let rows = DescriptionList::new()
|
|
.item(
|
|
label("show.table.columns"),
|
|
count(
|
|
"show-table-columns",
|
|
"show.table.columns",
|
|
columns,
|
|
20.0,
|
|
true,
|
|
),
|
|
)
|
|
.item(
|
|
label("show.table.rows"),
|
|
count("show-table-rows", "show.table.rows", rows, 50.0, false),
|
|
);
|
|
let closing = this.clone();
|
|
let dismiss = move |_: &mut Window, cx: &mut App| {
|
|
closing.update(cx, |deck, cx| {
|
|
deck.dialog = None;
|
|
cx.notify();
|
|
})
|
|
};
|
|
let go = label("show.table.go");
|
|
Card::new("show-table", label("show.table.title"), dismiss)
|
|
.child(rows)
|
|
.action(ely_office::cancel(cx))
|
|
.action(move |_| {
|
|
Button::new("show-table-go", go)
|
|
.variant(ButtonVariant::Primary)
|
|
.on_click(move |_, _, cx| this.update(cx, |deck, cx| deck.table_asked(cx)))
|
|
})
|
|
.into_any_element()
|
|
}
|
|
}
|
|
|
|
impl Panel {
|
|
/// Rows, columns, cells and the table itself.
|
|
pub(crate) fn table_group(&self, cx: &mut Context<Self>) -> PropertyGroup {
|
|
let why = "show.table.why";
|
|
let rows = row([
|
|
button(self, "table.row_above", "show.table.row_above", why, cx),
|
|
button(self, "table.row_below", "show.table.row_below", why, cx),
|
|
button(self, "table.delete_rows", "show.table.delete", why, cx),
|
|
]);
|
|
let columns = row([
|
|
button(self, "table.column_left", "show.table.column_left", why, cx),
|
|
button(
|
|
self,
|
|
"table.column_right",
|
|
"show.table.column_right",
|
|
why,
|
|
cx,
|
|
),
|
|
button(self, "table.delete_columns", "show.table.delete", why, cx),
|
|
]);
|
|
let cells = row([
|
|
button(self, "table.merge", "show.table.merge", why, cx),
|
|
button(self, "table.delete", "show.table.delete_table", why, cx),
|
|
]);
|
|
let tip = |key: &str| Deck::text(cx, key, &[]);
|
|
PropertyGroup::new(tip("show.table.group"))
|
|
.row(tip("show.table.rows"), rows)
|
|
.row(tip("show.table.columns"), columns)
|
|
.row(tip("show.table.cells"), cells)
|
|
}
|
|
}
|