PoseView: improve drag bitmap computations

Tracker creates a drag bitmap containing the selection being dragged.
There is a size limit if the selection is too large to avoid moving a
huge bitmap around.

There were two problems with the way this was done:

- The smaller rectangle was always centered on the cursor, even if that
  was near the edge of the selection being dragged. In that situation,
  most of the drag bitmap would end up being empty. Instead, move the
  rectangle to align it with the edges of the selection if it goes
  outside them. This makes sure we always use as much of the drag
  rectangle as possible for useful data.
- Moreover, there was a regression on the rendering of the
  "fade" at the edge of the rectangle. This is a transparency gradient
  that should be at the edge only, to indicate that the drag bitmap has
  been truncated, and that more (invisible) things are also being
  dragged. In hrev58665, this transparency gradient was changed to cover
  the entire width and height of the dragged bitmap, instead of just the
  edge. This lead to most of the text being almost invisible in a lot of
  cases. Change the code to use a gradient only near edges again.

Fixes #19429.

Change-Id: I395fda191dc61732e4bdc5287a09882cdc2b5f55
Reviewed-on: https://review.haiku-os.org/c/haiku/+/10177
Reviewed-by: John Scipione <[email protected]>
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
PulkoMandy
2026-01-06 13:29:09 +00:00
committed by Adrien Destugues
parent 95225b150f
commit a65ba286ee
+18 -9
View File
@@ -7664,20 +7664,29 @@ BPoseView::MakeDragBitmap(BRect dragRect, BPoint where, int32 poseIndex, BPoint&
if (poseCount == 0)
return NULL;
// Create a drag rectangle of the maximum drag size, centered around the cursor
BRect inner(where.x - roundf(kTransparentDragThreshold.x / 2),
where.y - roundf(kTransparentDragThreshold.y / 2),
where.x + roundf(kTransparentDragThreshold.x / 2),
where.y + roundf(kTransparentDragThreshold.y / 2));
// (BRect & BRect) doesn't work correctly if the rectangles don't intersect
// this catches a bug that is produced somewhere before this function is
// called
// This would mean the cursor is outside the selection rectangle, in which case a drag
// operation should not have been started.
if (!inner.Intersects(dragRect))
return NULL;
inner = inner & dragRect;
// Nudge the inner rectangle if it is outside the selection/drag rectangle.
// Otherwise, we end up wasting a part of its area for showing noting at all.
if (inner.right > dragRect.right)
inner.OffsetBy(dragRect.right - inner.right, 0);
if (inner.bottom > dragRect.bottom)
inner.OffsetBy(0, dragRect.bottom - inner.bottom);
if (inner.left < dragRect.left)
inner.OffsetBy(dragRect.left - inner.left, 0);
if (inner.top < dragRect.top)
inner.OffsetBy(0, dragRect.top - inner.top);
float fadeWidth = be_control_look->ComposeIconSize(64).Width();
float fadeWidth = be_control_look->ComposeIconSize(32).Width();
// not an icon but make this bigger based on font-size
// If the selection is bigger than the specified limit, the
@@ -7769,22 +7778,22 @@ BPoseView::MakeDragBitmap(BRect dragRect, BPoint where, int32 poseIndex, BPoint&
if (fadeLeft) {
FadeRGBA32Horizontal(bits, width, int32(rect.bottom), 0,
bitmap->Bounds().IntegerWidth());
int32(fadeWidth));
}
if (fadeRight) {
FadeRGBA32Horizontal(bits, width, int32(rect.bottom), int32(rect.right),
int32(rect.right) - bitmap->Bounds().IntegerWidth());
int32(rect.right - fadeWidth));
}
if (fadeTop) {
FadeRGBA32Vertical(bits, width, int32(rect.bottom), 0,
bitmap->Bounds().IntegerHeight());
int32(fadeWidth));
}
if (fadeBottom) {
FadeRGBA32Vertical(bits, width, int32(rect.bottom), int32(rect.bottom),
int32(rect.bottom) - bitmap->Bounds().IntegerHeight());
int32(rect.bottom - fadeWidth));
}
}