Tracker: Unselect all except clicked pose if >1 pose selected

... and we're not extending the selection or dragging.

Done on MouseUp() to allow for drag & drop. Fixes #20043.

More fixes included in this commit:
* Refactor BPoseView::MouseUp() code dealing with selection and
  popping menu. Don't consider fAllowPoseEditing for selection.
* Command **and Shift** extend selection.
* Create BPoseView::ExtendSelection() convenience method
  (also used in mouse down).
* List view/icon view loc "fix". Code worked before because index
  is 0 in icon mode but be explicit about pose location in list mode
  vs. icon mode anyway.
* Add ASSERT() for Window() and CurrentMessage() to BPoseView::MouseUp().
  We were already assuming they weren't NULL and it would have crashed
  if they were.
* Replace pose with clickedPose style fix (meaning is clearer).
* Comment update for "last_buttons" message param.

Change-Id: I3ecb035dbca8b343c230f1e6aee3070939a4a3f6
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10814
Haiku-Format: Haiku-format Bot <[email protected]>
Reviewed-by: John Scipione <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
John Scipione
2026-04-26 20:54:09 +00:00
parent a682ccd899
commit 87dc1df680
2 changed files with 79 additions and 41 deletions
+64 -41
View File
@@ -7162,20 +7162,22 @@ BPoseView::ShowContextMenu(BPoint where)
// handle pose selection // handle pose selection
int32 index; int32 index;
BPose* pose = FindPose(where, &index); BPose* clickedPose = FindPose(where, &index);
if (pose != NULL) { if (clickedPose != NULL) {
if (!pose->IsSelected()) { if (!clickedPose->IsSelected()) {
ClearSelection(); ClearSelection();
pose->Select(true); clickedPose->Select(true);
fSelectionList->AddItem(pose); fSelectionList->AddItem(clickedPose);
DrawPose(pose, index, false); DrawPose(clickedPose, index, false);
} }
} else } else {
ClearSelection(); ClearSelection();
}
window->Activate(); window->Activate();
window->UpdateIfNeeded(); window->UpdateIfNeeded();
window->ShowContextMenu(where, pose == NULL ? NULL : pose->TargetModel()->EntryRef()); const entry_ref* ref = (clickedPose == NULL ? NULL : clickedPose->TargetModel()->EntryRef());
window->ShowContextMenu(where, ref);
if (fSelectionChangedHook) if (fSelectionChangedHook)
window->SelectionChanged(); window->SelectionChanged();
@@ -7380,9 +7382,9 @@ BPoseView::MouseDragged(const BMessage* message)
bool extendSelection = (modifiers() & B_COMMAND_KEY) != 0 && fMultipleSelection; bool extendSelection = (modifiers() & B_COMMAND_KEY) != 0 && fMultipleSelection;
int32 index; int32 index;
BPose* pose = FindPose(where, &index); BPose* clickedPose = FindPose(where, &index);
if (pose != NULL) if (clickedPose != NULL)
DragSelectedPoses(pose, where, buttons); DragSelectedPoses(clickedPose, where, buttons);
else if (buttons == B_PRIMARY_MOUSE_BUTTON) else if (buttons == B_PRIMARY_MOUSE_BUTTON)
_BeginSelectionRect(where, extendSelection); _BeginSelectionRect(where, extendSelection);
} }
@@ -7447,26 +7449,29 @@ BPoseView::MouseDown(BPoint where)
bool secondaryMouseButtonDown = SecondaryMouseButtonDown(mods, buttons); bool secondaryMouseButtonDown = SecondaryMouseButtonDown(mods, buttons);
fTrackRightMouseUp = secondaryMouseButtonDown; fTrackRightMouseUp = secondaryMouseButtonDown;
fTrackMouseUp = !secondaryMouseButtonDown; fTrackMouseUp = !secondaryMouseButtonDown;
bool extendSelection = (mods & B_COMMAND_KEY) != 0 && fMultipleSelection; bool extendSelection = ExtendSelection();
CommitActivePose(); CommitActivePose();
int32 index; int32 index;
BPose* pose = FindPose(where, &index); BPose* clickedPose = FindPose(where, &index);
if (pose != NULL) { if (clickedPose != NULL) {
if (!pose->IsSelected() || !secondaryMouseButtonDown) if (!clickedPose->IsSelected() || !secondaryMouseButtonDown)
AddRemoveSelectionRange(where, extendSelection, pose); AddRemoveSelectionRange(where, extendSelection, clickedPose);
if (fTextWidgetToCheck != NULL && (pose != fLastClickedPose || secondaryMouseButtonDown)) if (fTextWidgetToCheck != NULL
&& (clickedPose != fLastClickedPose || secondaryMouseButtonDown)) {
fTextWidgetToCheck->CancelWait(); fTextWidgetToCheck->CancelWait();
}
if (!extendSelection && WasDoubleClick(pose, where) && buttons == B_PRIMARY_MOUSE_BUTTON if (!extendSelection && WasDoubleClick(clickedPose, where)
&& fLastClickButtons == B_PRIMARY_MOUSE_BUTTON && (mods & B_CONTROL_KEY) == 0) { && buttons == B_PRIMARY_MOUSE_BUTTON && fLastClickButtons == B_PRIMARY_MOUSE_BUTTON
&& (mods & B_CONTROL_KEY) == 0) {
fTrackRightMouseUp = false; fTrackRightMouseUp = false;
fTrackMouseUp = false; fTrackMouseUp = false;
// special handling for path field double-clicks // special handling for path field double-clicks
if (!WasClickInPath(pose, index, where)) if (!WasClickInPath(clickedPose, index, where))
OpenSelection(pose, &index); OpenSelection(clickedPose, &index);
} }
} else { } else {
// click was not in any pose // click was not in any pose
@@ -7502,35 +7507,53 @@ BPoseView::SetTextWidgetToCheck(BTextWidget* widget, BTextWidget* old)
void void
BPoseView::MouseUp(BPoint where) BPoseView::MouseUp(BPoint where)
{ {
if (fSelectionRectInfo.isDragging) ASSERT(Window() != NULL);
ASSERT(Window()->CurrentMessage() != NULL);
bool wasDragging = fDragMessage != NULL;
bool wasRectSelecting = fSelectionRectInfo.isDragging;
if (wasRectSelecting)
_EndSelectionRect(); _EndSelectionRect();
// dispose of drag data from previous drag lazily // dispose of drag data from previous drag lazily
DragStop(); DragStop();
int32 index; int32 index;
BPose* pose = FindPose(where, &index); BPose* clickedPose = FindPose(where, &index);
uint32 lastButtons = Window()->CurrentMessage()->FindInt32("last_buttons"); if (clickedPose != NULL && fLastClickedPose != NULL) {
if (pose != NULL && fLastClickedPose != NULL && fAllowPoseEditing
&& !fTrackRightMouseUp) {
// This handy field has been added by the tracking filter. // This handy field has been added by the tracking filter.
// we need lastButtons for right button mouse-up tracking, // We need to know last buttons for context-click mouse up tracking,
// because there's currently no way to know wich buttons were // because there is no way to know which buttons were released in
// released in BView::MouseUp (unlike BView::KeyUp) // BView::MouseUp() (unlike BView::KeyUp()).
pose->MouseUp(BPoint(0, index * fListElemHeight), this, where, index); uint32 lastButtons = Window()->CurrentMessage()->FindInt32("last_buttons");
}
// Showing the pose context menu is done on mouse up (or long click) if (!fTrackRightMouseUp) {
// to make right button dragging possible bool wasSelected = clickedPose->IsSelected();
if (pose != NULL && fTrackRightMouseUp
&& (SecondaryMouseButtonDown(modifiers(), lastButtons))) { BPoint loc;
if (!pose->IsSelected()) { if (ViewMode() == kListMode)
ClearSelection(); loc = BPoint(0, index * fListElemHeight);
pose->Select(true); else
fSelectionList->AddItem(pose); loc = clickedPose->Location(this);
DrawPose(pose, index, false);
clickedPose->MouseUp(loc, this, where, index);
// reselect clicked pose
bool shouldSelect = wasSelected && !ExtendSelection();
bool dragging = wasDragging || wasRectSelecting;
if (shouldSelect && !dragging)
SelectPose(clickedPose, index);
} else if (SecondaryMouseButtonDown(modifiers(), lastButtons)) {
// Showing the pose context menu is done on mouse up (or long click)
// to make context-click (right-click) drag and drop possible.
if (!clickedPose->IsSelected()) {
ClearSelection();
clickedPose->Select(true);
fSelectionList->AddItem(clickedPose);
DrawPose(clickedPose, index, false);
}
ShowContextMenu(where);
} }
ShowContextMenu(where);
} }
if (fTrackMouseUp) if (fTrackMouseUp)
+15
View File
@@ -309,6 +309,8 @@ public:
void AddRemovePoseFromSelection(BPose* pose, int32 index, void AddRemovePoseFromSelection(BPose* pose, int32 index,
bool select); bool select);
int32 CountSelected() const; int32 CountSelected() const;
bool ExtendSelection() const;
bool SelectedVolumeIsReadOnly() const; bool SelectedVolumeIsReadOnly() const;
bool TargetVolumeIsReadOnly() const; bool TargetVolumeIsReadOnly() const;
bool CanEditName() const; bool CanEditName() const;
@@ -925,12 +927,25 @@ BPoseView::SelectionList() const
return fSelectionList; return fSelectionList;
} }
inline int32 inline int32
BPoseView::CountSelected() const BPoseView::CountSelected() const
{ {
return fSelectionList->CountItems(); return fSelectionList->CountItems();
} }
inline bool
BPoseView::ExtendSelection() const
{
if (!fMultipleSelection)
return false;
uint32 mods = modifiers();
return (mods & B_COMMAND_KEY) != 0 || (mods & B_SHIFT_KEY) != 0;
}
inline BStringList* inline BStringList*
BPoseView::MimeTypesInSelection() BPoseView::MimeTypesInSelection()
{ {