mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
Merge PR #1657: Cell editor: the caret contrasts with the cell's fill
This commit is contained in:
@@ -2935,6 +2935,9 @@ fn in_cell_editor(app: &mut SheetApp, ui: &mut egui::Ui, geo: &Geo, sh: &Sheet,
|
||||
let id = egui::Id::new("gridcraft.cell_editor");
|
||||
let mut child = ui.new_child(egui::UiBuilder::new().max_rect(erect.shrink2(vec2(2.0, 1.0))));
|
||||
child.set_clip_rect(clip);
|
||||
// The theme's caret is meant for the UI chrome and vanishes on some fills (and, in the dark
|
||||
// theme, on the white paper): pick black or white against the fill, like Excel.
|
||||
child.visuals_mut().text_cursor.stroke.color = ink_on(fill);
|
||||
crate::formula_bar::editor_widget(app, &mut child, id, font, false, erect.width() - 4.0);
|
||||
}
|
||||
|
||||
@@ -2944,6 +2947,12 @@ fn popup_dismissed(response: &egui::Response, was_open: bool) -> bool {
|
||||
response.ctx.input(|i| !i.focused || i.key_pressed(egui::Key::Escape)) || (was_open && response.clicked_elsewhere())
|
||||
}
|
||||
|
||||
/// Black or white, whichever reads on `fill` (the threshold chart labels use).
|
||||
fn ink_on(fill: Color32) -> Color32 {
|
||||
let l = 0.299 * fill.r() as f32 + 0.587 * fill.g() as f32 + 0.114 * fill.b() as f32;
|
||||
if l < 150.0 { Color32::WHITE } else { Color32::BLACK }
|
||||
}
|
||||
|
||||
/// The table whose header cell (`row`, `col`) was clicked, not just the first table in the column.
|
||||
fn filter_table_range(sh: &Sheet, col: u32, row: u32) -> Option<RangeRef> {
|
||||
sh.tables.iter().find(|t| t.range.start.row == row && col >= t.range.start.col && col <= t.range.end.col).map(|t| t.range)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
//! The caret of the in-cell editor stays visible on the cell's fill, whatever the theme.
|
||||
use egui::{Color32, Context, RawInput, Rect, Shape, pos2, vec2};
|
||||
use gridcraft_engine::Session;
|
||||
use gridcraft_ui_egui::{SheetApp, theme};
|
||||
use serde_json::json;
|
||||
|
||||
fn frame(ctx: &Context, app: &mut SheetApp) -> egui::FullOutput {
|
||||
let mut output =
|
||||
ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(1200.0, 800.0))), ..Default::default() }, |ui| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
});
|
||||
output.textures_delta.clear();
|
||||
output
|
||||
}
|
||||
|
||||
/// The caret painted while editing A1 over `fill` (`None`: no fill), with the app in `dark` mode.
|
||||
fn caret(fill: Option<&str>, dark: bool) -> Color32 {
|
||||
let ctx = Context::default();
|
||||
theme::apply(&ctx, dark);
|
||||
let mut session = Session::new();
|
||||
session.new_workbook();
|
||||
let mut app = SheetApp::new(session, Default::default());
|
||||
if let Some(color) = fill {
|
||||
app.run("home.fillColor", json!({"range": "A1", "color": color})).unwrap();
|
||||
}
|
||||
for _ in 0..4 {
|
||||
frame(&ctx, &mut app);
|
||||
}
|
||||
app.begin_edit(Some("abc".into()), false);
|
||||
for _ in 0..4 {
|
||||
frame(&ctx, &mut app);
|
||||
}
|
||||
let output = frame(&ctx, &mut app);
|
||||
// The editor paints its backdrop first; the caret is the vertical segment after it.
|
||||
let paper = fill.map_or(Color32::WHITE, |c| Color32::from_hex(c).unwrap());
|
||||
let backdrop = output
|
||||
.shapes
|
||||
.iter()
|
||||
.rposition(|s| matches!(&s.shape, Shape::Rect(r) if r.fill == paper && r.rect.width() > 20.0))
|
||||
.expect("editor backdrop painted");
|
||||
output.shapes[backdrop..]
|
||||
.iter()
|
||||
.find_map(|s| match &s.shape {
|
||||
Shape::LineSegment { points, stroke } if points[0].x == points[1].x => Some(stroke.color),
|
||||
_ => None,
|
||||
})
|
||||
.expect("caret painted")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn caret_contrasts_with_the_cell_fill() {
|
||||
assert_eq!(caret(Some("#1F3864"), false), Color32::WHITE, "dark fill, light theme");
|
||||
assert_eq!(caret(Some("#1F3864"), true), Color32::WHITE, "dark fill, dark theme");
|
||||
assert_eq!(caret(Some("#FFFF00"), true), Color32::BLACK, "light fill, dark theme");
|
||||
assert_eq!(caret(None, true), Color32::BLACK, "no fill, dark theme: the cell is still white paper");
|
||||
assert_eq!(caret(None, false), Color32::BLACK, "no fill, light theme");
|
||||
}
|
||||
Reference in New Issue
Block a user