Closing a widget was instant and destructive - one misclick on the X lost its size and position. Close now shows a toast with an undo button that re-adds the very same widget at its captured gs-x/y/w/h, keeping its gs-id. Programmatic close() (fromClient=false) is skipped. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HGRChzremwYCUctf2qMrQz
This commit is contained in:
@@ -312,10 +312,26 @@ public class GridStackItem extends Div {
|
||||
}
|
||||
|
||||
private void close(boolean fromClient) {
|
||||
// Captured before detaching: once removeFromParent() runs, the grid no
|
||||
// longer reports this item, so its position could not be read back from
|
||||
// there afterwards. The gs-* attributes themselves are untouched by the
|
||||
// detach, so a caller that keeps this item around and re-adds it later
|
||||
// (e.g. to undo the close) lands it back at exactly this spot.
|
||||
Position position = capturePosition();
|
||||
// Detach first so listeners observe the layout they are about to see —
|
||||
// getLayout() on the grid no longer counts this item.
|
||||
getElement().removeFromParent();
|
||||
fireEvent(new CloseEvent(this, fromClient));
|
||||
fireEvent(new CloseEvent(this, fromClient, position));
|
||||
}
|
||||
|
||||
private Position capturePosition() {
|
||||
return new Position(getItemId(),
|
||||
attrInt("gs-x"), attrInt("gs-y"), attrInt("gs-w"), attrInt("gs-h"));
|
||||
}
|
||||
|
||||
private int attrInt(String name) {
|
||||
String value = getElement().getAttribute(name);
|
||||
return value == null ? 0 : Integer.parseInt(value);
|
||||
}
|
||||
|
||||
/** Shows or hides the close button (shown by default). */
|
||||
@@ -346,10 +362,23 @@ public class GridStackItem extends Div {
|
||||
return addListener(CloseEvent.class, listener);
|
||||
}
|
||||
|
||||
/** Fired after the item has been removed from its {@link GridStackLayout}. */
|
||||
/** Fired after the item has been removed from its {@link GridStackLayout}.
|
||||
* Carries the {@link Position} it held right before detaching, so a
|
||||
* listener can offer to undo the close (re-adding the item at that exact
|
||||
* spot) without having to track positions itself. {@link #isFromClient()}
|
||||
* tells apart a user-initiated close (button/menu) from a programmatic
|
||||
* {@link GridStackItem#close()} — an undo affordance only makes sense for
|
||||
* the former. */
|
||||
public static class CloseEvent extends ComponentEvent<GridStackItem> {
|
||||
CloseEvent(GridStackItem source, boolean fromClient) {
|
||||
private final Position position;
|
||||
|
||||
CloseEvent(GridStackItem source, boolean fromClient, Position position) {
|
||||
super(source, fromClient);
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user