Tracker: Fix garbled text when dragging cut poses

* Determine whether we're currently dragging by looking at the
  current window message what, dragging replaces direct in a few
  places especially crucial to drawing semi-transparent dragged
  items correctly.
* Export kMsgMouseDragged and kMsgMouseLongDown to the BPoseView
  header to check for dragging (but still in BPrivate).
* Turn on outline label drawing for dragged items and remove TODO.

Fixes #6461

Change-Id: I45cd401299dec408b76cb4b9ce1e9350ed59ef5b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8842
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
John Scipione
2025-02-06 22:08:11 +00:00
committed by waddlesplash
parent 44d74ab075
commit 3527a0ee23
5 changed files with 60 additions and 44 deletions
+10 -4
View File
@@ -569,6 +569,9 @@ BPose::Draw(BRect rect, const BRect& updateRect, BPoseView* poseView, BView* dra
fBackgroundClean = false; fBackgroundClean = false;
bool direct = drawView == poseView; bool direct = drawView == poseView;
bool dragging = false;
if (poseView->Window()->CurrentMessage() != NULL)
dragging = poseView->Window()->CurrentMessage()->what == kMsgMouseDragged;
bool windowActive = poseView->Window()->IsActive(); bool windowActive = poseView->Window()->IsActive();
bool showSelectionWhenInactive = poseView->ShowSelectionWhenInactive(); bool showSelectionWhenInactive = poseView->ShowSelectionWhenInactive();
bool drawIconUnselected = !windowActive && !showSelectionWhenInactive; bool drawIconUnselected = !windowActive && !showSelectionWhenInactive;
@@ -625,8 +628,8 @@ BPose::Draw(BRect rect, const BRect& updateRect, BPoseView* poseView, BView* dra
if (columnRect.Intersects(updateRect)) { if (columnRect.Intersects(updateRect)) {
BRect widgetRect(widget->CalcRect(rect.LeftTop(), column, poseView)); BRect widgetRect(widget->CalcRect(rect.LeftTop(), column, poseView));
// draw all columns after the first one unselected // draw dragged text and all columns after the first one unselected
if (index > 0) if (dragging || index > 0)
selected = false; selected = false;
// draw text // draw text
@@ -648,6 +651,10 @@ BPose::Draw(BRect rect, const BRect& updateRect, BPoseView* poseView, BView* dra
if (widget != NULL && widget->IsVisible()) { if (widget != NULL && widget->IsVisible()) {
BRect widgetRect(widget->CalcRect(location, NULL, poseView)); BRect widgetRect(widget->CalcRect(location, NULL, poseView));
if (widgetRect.Intersects(updateRect)) { if (widgetRect.Intersects(updateRect)) {
// draw dragged text unselected
if (dragging)
selected = false;
// draw text // draw text
DrawTextWidget(widgetRect, widgetRect, column->Width(), widget, poseView, drawView, DrawTextWidget(widgetRect, widgetRect, column->Width(), widget, poseView, drawView,
selected, fClipboardMode, offset); selected, fClipboardMode, offset);
@@ -788,8 +795,7 @@ BPose::WidgetFor(uint32 attr, int32* index) const
BTextWidget* BTextWidget*
BPose::WidgetFor(BColumn* column, BPoseView* poseView, BPose::WidgetFor(BColumn* column, BPoseView* poseView, ModelNodeLazyOpener& opener, int32* index)
ModelNodeLazyOpener &opener, int32* index)
{ {
if (column == NULL) if (column == NULL)
return NULL; return NULL;
+1 -4
View File
@@ -109,8 +109,6 @@ const float kDoubleClickTresh = 6;
const uint32 kAddNewPoses = 'Tanp'; const uint32 kAddNewPoses = 'Tanp';
const uint32 kAddPosesCompleted = 'Tapc'; const uint32 kAddPosesCompleted = 'Tapc';
const int32 kMaxAddPosesChunk = 50; const int32 kMaxAddPosesChunk = 50;
const uint32 kMsgMouseDragged = 'Mdrg';
const uint32 kMsgMouseLongDown = 'Mold';
const int32 kRoomForLine = 2; const int32 kRoomForLine = 2;
@@ -9551,8 +9549,7 @@ BPoseView::ResizeColumnToWidest(BColumn* column)
BPoint BPoint
BPoseView::ResizeColumn(BColumn* column, float newSize, BPoseView::ResizeColumn(BColumn* column, float newSize, float* lastLineDrawPos,
float* lastLineDrawPos,
void (*drawLineFunc)(BPoseView*, BPoint, BPoint), void (*drawLineFunc)(BPoseView*, BPoint, BPoint),
void (*undrawLineFunc)(BPoseView*, BPoint, BPoint)) void (*undrawLineFunc)(BPoseView*, BPoint, BPoint))
{ {
+4
View File
@@ -79,6 +79,10 @@ const uint32 kListMode = 'Tlst';
const uint32 kCheckTypeahead = 'Tcty'; const uint32 kCheckTypeahead = 'Tcty';
const uint32 kMsgMouseDragged = 'Mdrg';
const uint32 kMsgMouseLongDown = 'Mold';
class BPoseView : public BView { class BPoseView : public BView {
public: public:
BPoseView(Model*, uint32 viewMode); BPoseView(Model*, uint32 viewMode);
+42 -34
View File
@@ -643,32 +643,38 @@ BTextWidget::Draw(BRect eraseRect, BRect textRect, float, BPoseView* view, BView
// BPose::Draw before and after calling this function. // BPose::Draw before and after calling this function.
bool direct = drawView == view; bool direct = drawView == view;
bool dragging = false;
if (view->Window()->CurrentMessage() != NULL)
dragging = view->Window()->CurrentMessage()->what == kMsgMouseDragged;
if (selected) { if (!dragging) {
if (direct) { if (selected) {
// erase selection rect background if (direct) {
drawView->SetDrawingMode(B_OP_COPY); // erase selection rect background
drawView->FillRect(textRect, B_SOLID_LOW); drawView->SetDrawingMode(B_OP_COPY);
drawView->FillRect(textRect, B_SOLID_LOW);
}
drawView->SetDrawingMode(B_OP_OVER);
// High color is set to inverted low, then the whole thing is
// inverted again so that the background color "shines through".
drawView->SetHighColor(InvertColorSmart(drawView->LowColor()));
} else if (clipboardMode == kMoveSelectionTo) {
drawView->SetDrawingMode(B_OP_ALPHA);
drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
uint8 alpha = 64; // set the level of opacity by value
if (view->LowColor().IsLight())
drawView->SetHighColor(0, 0, 0, alpha);
else
drawView->SetHighColor(255, 255, 255, alpha);
} else {
drawView->SetDrawingMode(B_OP_OVER);
if (view->IsDesktopView())
drawView->SetHighColor(view->HighColor());
else
drawView->SetHighUIColor(view->HighUIColor());
} }
drawView->SetDrawingMode(B_OP_OVER); drawView->SetDrawingMode(B_OP_OVER);
// High color is set to inverted low, then the whole thing is
// inverted again so that the background color "shines through".
drawView->SetHighColor(InvertColorSmart(drawView->LowColor()));
} else if (clipboardMode == kMoveSelectionTo) {
drawView->SetDrawingMode(B_OP_ALPHA);
drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
uint8 alpha = 64; // set the level of opacity by value
if (view->LowColor().IsLight())
drawView->SetHighColor(0, 0, 0, alpha);
else
drawView->SetHighColor(255, 255, 255, alpha);
} else {
drawView->SetDrawingMode(B_OP_OVER);
if (view->IsDesktopView())
drawView->SetHighColor(view->HighColor());
else
drawView->SetHighUIColor(view->HighUIColor());
} }
BPoint location; BPoint location;
@@ -677,17 +683,16 @@ BTextWidget::Draw(BRect eraseRect, BRect textRect, float, BPoseView* view, BView
const char* fittingText = fText->FittingText(view); const char* fittingText = fText->FittingText(view);
// TODO: Comparing view and drawView here to avoid rendering // Draw text outline unless selected or column resizing.
// the text outline when producing a drag bitmap. The check is // The direct parameter is false when dragging or column resizing.
// not fully correct, since an offscreen view is also used in some if (!selected && (direct || dragging) && view->WidgetTextOutline()) {
// other rare cases (something to do with columns). But for now, this
// fixes the broken drag bitmaps when dragging icons from the Desktop.
if (direct && !selected && view->WidgetTextOutline()) {
// draw a halo around the text by using the "false bold" // draw a halo around the text by using the "false bold"
// feature for text rendering. Either black or white is used for // feature for text rendering. Either black or white is used for
// the glow (whatever acts as contrast) with a some alpha value, // the glow (whatever acts as contrast) with a some alpha value,
drawView->SetDrawingMode(B_OP_ALPHA); if (direct && clipboardMode != kMoveSelectionTo) {
drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); drawView->SetDrawingMode(B_OP_ALPHA);
drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
}
BFont font; BFont font;
drawView->GetFont(&font); drawView->GetFont(&font);
@@ -733,8 +738,10 @@ BTextWidget::Draw(BRect eraseRect, BRect textRect, float, BPoseView* view, BView
drawView->DrawString(fittingText, location + BPoint(1, 1)); drawView->DrawString(fittingText, location + BPoint(1, 1));
} }
drawView->SetDrawingMode(B_OP_OVER); if (direct && clipboardMode != kMoveSelectionTo) {
drawView->SetHighColor(textColor); drawView->SetDrawingMode(B_OP_OVER);
drawView->SetHighColor(textColor);
}
} }
drawView->DrawString(fittingText, location); drawView->DrawString(fittingText, location);
@@ -746,9 +753,10 @@ BTextWidget::Draw(BRect eraseRect, BRect textRect, float, BPoseView* view, BView
if (direct && clipboardMode != kMoveSelectionTo) { if (direct && clipboardMode != kMoveSelectionTo) {
rgb_color underlineColor = drawView->HighColor(); rgb_color underlineColor = drawView->HighColor();
underlineColor.alpha = 180; underlineColor.alpha = 180;
drawView->SetHighColor(underlineColor);
drawView->SetDrawingMode(B_OP_ALPHA); drawView->SetDrawingMode(B_OP_ALPHA);
drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); drawView->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
drawView->SetHighColor(underlineColor);
} }
textRect.right = textRect.left + fText->Width(view); textRect.right = textRect.left + fText->Width(view);
+3 -2
View File
@@ -180,12 +180,13 @@ BTextWidget::SetActive(bool on)
inline void inline void
BTextWidget::Draw(BRect widgetRect, BRect widgetTextRect, float width, BTextWidget::Draw(BRect widgetRect, BRect widgetTextRect, float width, BPoseView* view,
BPoseView* view, bool selected, uint32 clipboardMode) bool selected, uint32 clipboardMode)
{ {
Draw(widgetRect, widgetTextRect, width, view, (BView*)view, selected, clipboardMode, B_ORIGIN); Draw(widgetRect, widgetTextRect, width, view, (BView*)view, selected, clipboardMode, B_ORIGIN);
} }
} // namespace BPrivate } // namespace BPrivate
using namespace BPrivate; using namespace BPrivate;