Ask for the collection's name before there is a collection to name
"New collection from selection" created the collection under a placeholder name and then opened the sidebar tree's rename field to correct it. On a tablet that field is not on screen. The collections panel is always instantiated — app.slint collapses it to zero width and `visible: false` rather than using an `if`, because an `if` there is a layout loop Slint panics on — so the rename TextInput was created all the same, its `init` called `self.focus()`, and Android raised the on-screen keyboard for a box nobody could see. Nothing else on the screen is focusable, so the keyboard had nowhere to go back to: it stayed up, the name could not be typed, and the collection was already written under the name the user did not want. Asked in a sheet instead, on the same card, scrim and dismissal the filing and keywording sheets use. The field takes the keyboard as the sheet appears — over a field that is actually drawn, which is the whole difference — and the card sits a third of the way down rather than centred, because on a tablet the keyboard is the bottom half of the window. Nothing reaches the catalog until Create. That also ends a second bug the old order could not avoid: an abandoned rename used to leave a collection called "New collection" behind, because creating came first. `Field` grows a `take-focus()` for this. A function rather than a property: focus is an event, and bound to a property it would fight whatever took focus next and re-take it on every unrelated re-evaluation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1586,13 +1586,20 @@ pub fn wire<S, R, P, C>(
|
||||
// the tree's "+". A selection can be gathered from anywhere, including
|
||||
// across collections, so filing it under whichever one happens to be open
|
||||
// would put it somewhere its contents did not come from.
|
||||
//
|
||||
// The name arrives already chosen. It used to be a placeholder, with the
|
||||
// sidebar's rename field opened straight afterwards to correct it — which
|
||||
// on a tablet meant opening a field inside a panel that is instantiated but
|
||||
// never drawn, so it took the on-screen keyboard for a box nobody could see
|
||||
// and had nowhere to give it back to. `library.slint`'s naming sheet asks
|
||||
// first, and nothing reaches the catalog until it is answered.
|
||||
{
|
||||
let weak = window.as_weak();
|
||||
let ctl = ctl.clone();
|
||||
let catalog = catalog.clone();
|
||||
let visible = visible_ids.clone();
|
||||
let reload = on_scope_changed.clone();
|
||||
window.on_library_collection_from_selection(move || {
|
||||
window.on_library_collection_from_selection(move |name| {
|
||||
let Some(w) = weak.upgrade() else { return };
|
||||
let images = ctl.selected();
|
||||
if images.is_empty() {
|
||||
@@ -1605,12 +1612,25 @@ pub fn wire<S, R, P, C>(
|
||||
return;
|
||||
};
|
||||
|
||||
let name = unique_name(cat.connection(), None);
|
||||
// The sheet refuses an empty name in both of its two ways in, so
|
||||
// this is belt-and-braces rather than a path the UI can reach. But
|
||||
// a collection with no name at all is unfindable in the tree, and
|
||||
// falling back to the placeholder is recoverable where an unnamed
|
||||
// row is not.
|
||||
let name = match name.trim() {
|
||||
"" => unique_name(cat.connection(), None),
|
||||
typed => typed.to_string(),
|
||||
};
|
||||
|
||||
// The id is no longer carried out of here. It used to be, to open
|
||||
// the rename field on the row it names; the name is now right
|
||||
// before the row exists, and `refresh_tree` redraws the tree from
|
||||
// the catalog either way.
|
||||
let made = coll::create(cat.connection(), &name, None, CollectionKind::Manual)
|
||||
.and_then(|id| coll::add_images(cat.connection(), id, &images).map(|n| (id, n)));
|
||||
.and_then(|id| coll::add_images(cat.connection(), id, &images));
|
||||
|
||||
match made {
|
||||
Ok((id, added)) => {
|
||||
Ok(added) => {
|
||||
w.set_collection_error(slint::SharedString::new());
|
||||
w.set_library_status(
|
||||
format!(
|
||||
@@ -1628,11 +1648,10 @@ pub fn wire<S, R, P, C>(
|
||||
ctl.clear_selection();
|
||||
sync_selection(&w, &ctl, &visible());
|
||||
|
||||
// Into the name field, for the same reason `collection_new`
|
||||
// does it: "New collection" is a placeholder nobody wants
|
||||
// to keep, and making them find the rename afterwards is
|
||||
// asking them to finish a job we started.
|
||||
w.set_collection_renaming(id.0 as i32);
|
||||
// No rename opened here. The name was chosen before the
|
||||
// collection existed, so there is nothing left to correct
|
||||
// — and opening the sidebar's field is precisely what
|
||||
// stranded the keyboard on a tablet.
|
||||
reload();
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
Reference in New Issue
Block a user