BColumnListView: Resolve column resizing drawing glitch (wider than 600px)
* use of a shared bitmap buffer in OutlineView and TitleView * dynamically increase of the bitmap buffer after adding a column or a row Change-Id: I4feddf636fb1446c29e60353b8f70fc084833731 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7176 Reviewed-by: John Scipione <[email protected]> Reviewed-by: Adrien Destugues <[email protected]> Reviewed-by: Stefano Ceccherini <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
4f9df95dc8
commit
5014ac9392
@@ -144,10 +144,34 @@ static const float kDropHighlightLineHeight = 2.0;
|
||||
|
||||
static const uint32 kToggleColumn = 'BTCL';
|
||||
|
||||
|
||||
#ifdef DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
|
||||
class ColumnResizeBufferView : public BView
|
||||
{
|
||||
public:
|
||||
ColumnResizeBufferView();
|
||||
virtual ~ColumnResizeBufferView();
|
||||
void UpdateMaxWidth(float width);
|
||||
void UpdateMaxHeight(float height);
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
const BBitmap* Bitmap();
|
||||
private:
|
||||
void _InitBitmap();
|
||||
void _FreeBitmap();
|
||||
|
||||
BBitmap* fDrawBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class BRowContainer : public BObjectList<BRow>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class TitleView : public BView {
|
||||
typedef BView _inherited;
|
||||
public:
|
||||
@@ -198,10 +222,6 @@ private:
|
||||
// float fColumnsWidth;
|
||||
BRect fVisibleRect;
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
BBitmap* fDrawBuffer;
|
||||
BView* fDrawBufferView;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
INACTIVE,
|
||||
@@ -292,6 +312,10 @@ public:
|
||||
virtual void MouseUp(BPoint where);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
ColumnResizeBufferView* ResizeBufferView();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool SortList(BRowContainer* list, bool isVisible);
|
||||
static int32 DeepSortThreadEntry(void* outlineView);
|
||||
@@ -311,8 +335,7 @@ private:
|
||||
BRect fVisibleRect;
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
BBitmap* fDrawBuffer;
|
||||
BView* fDrawBufferView;
|
||||
ColumnResizeBufferView* fResizeBufferView;
|
||||
#endif
|
||||
|
||||
BRow* fFocusRow;
|
||||
@@ -391,6 +414,101 @@ private:
|
||||
using namespace BPrivate;
|
||||
|
||||
|
||||
#ifdef DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
|
||||
ColumnResizeBufferView::ColumnResizeBufferView()
|
||||
: BView(BRect(0, 0, 600, 35), "double_buffer_view", B_FOLLOW_ALL_SIDES, 0), fDrawBuffer(NULL)
|
||||
{
|
||||
_InitBitmap();
|
||||
}
|
||||
|
||||
|
||||
ColumnResizeBufferView::~ColumnResizeBufferView()
|
||||
{
|
||||
_FreeBitmap();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColumnResizeBufferView::UpdateMaxWidth(float width)
|
||||
{
|
||||
Lock();
|
||||
BRect bounds = Bounds();
|
||||
Unlock();
|
||||
|
||||
if (width > bounds.Width()) {
|
||||
Lock();
|
||||
ResizeTo(width, bounds.Height());
|
||||
Unlock();
|
||||
_InitBitmap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColumnResizeBufferView::UpdateMaxHeight(float height)
|
||||
{
|
||||
Lock();
|
||||
BRect bounds = Bounds();
|
||||
Unlock();
|
||||
|
||||
if (height > bounds.Height()) {
|
||||
Lock();
|
||||
ResizeTo(bounds.Width(), height);
|
||||
Unlock();
|
||||
_InitBitmap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ColumnResizeBufferView::Lock()
|
||||
{
|
||||
return fDrawBuffer->Lock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColumnResizeBufferView::Unlock()
|
||||
{
|
||||
fDrawBuffer->Unlock();
|
||||
}
|
||||
|
||||
|
||||
const BBitmap*
|
||||
ColumnResizeBufferView::Bitmap()
|
||||
{
|
||||
return fDrawBuffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColumnResizeBufferView::_InitBitmap()
|
||||
{
|
||||
_FreeBitmap();
|
||||
|
||||
fDrawBuffer = new BBitmap(Bounds(), B_RGB32, true);
|
||||
fDrawBuffer->Lock();
|
||||
fDrawBuffer->AddChild(this);
|
||||
fDrawBuffer->Unlock();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ColumnResizeBufferView::_FreeBitmap()
|
||||
{
|
||||
if (fDrawBuffer) {
|
||||
fDrawBuffer->Lock();
|
||||
fDrawBuffer->RemoveChild(this);
|
||||
fDrawBuffer->Unlock();
|
||||
delete fDrawBuffer;
|
||||
fDrawBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
BField::BField()
|
||||
{
|
||||
}
|
||||
@@ -2223,17 +2341,6 @@ TitleView::TitleView(BRect rect, OutlineView* horizontalSlave,
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
// xxx this needs to be smart about the size of the backbuffer.
|
||||
BRect doubleBufferRect(0, 0, 600, 35);
|
||||
fDrawBuffer = new BBitmap(doubleBufferRect, B_RGB32, true);
|
||||
fDrawBufferView = new BView(doubleBufferRect, "double_buffer_view",
|
||||
B_FOLLOW_ALL_SIDES, 0);
|
||||
fDrawBuffer->Lock();
|
||||
fDrawBuffer->AddChild(fDrawBufferView);
|
||||
fDrawBuffer->Unlock();
|
||||
#endif
|
||||
|
||||
fUpSortArrow = new BBitmap(BRect(0, 0, 7, 7), B_CMAP8);
|
||||
fDownSortArrow = new BBitmap(BRect(0, 0, 7, 7), B_CMAP8);
|
||||
|
||||
@@ -2254,9 +2361,6 @@ TitleView::~TitleView()
|
||||
delete fColumnPop;
|
||||
fColumnPop = NULL;
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
delete fDrawBuffer;
|
||||
#endif
|
||||
delete fUpSortArrow;
|
||||
delete fDownSortArrow;
|
||||
|
||||
@@ -2270,6 +2374,9 @@ TitleView::~TitleView()
|
||||
void
|
||||
TitleView::ColumnAdded(BColumn* column)
|
||||
{
|
||||
#ifdef DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
fOutlineView->ResizeBufferView()->UpdateMaxWidth(column->MaxWidth());
|
||||
#endif
|
||||
// fColumnsWidth += column->Width();
|
||||
FixScrollBar(false);
|
||||
Invalidate();
|
||||
@@ -2481,13 +2588,14 @@ TitleView::ResizeSelectedColumn(BPoint position, bool preferred)
|
||||
destRect.OffsetBy(fSelectedColumnRect.left, 0);
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
fDrawBuffer->Lock();
|
||||
DrawTitle(fDrawBufferView, sourceRect, fSelectedColumn, false);
|
||||
fDrawBufferView->Sync();
|
||||
fDrawBuffer->Unlock();
|
||||
ColumnResizeBufferView* bufferView = fOutlineView->ResizeBufferView();
|
||||
bufferView->Lock();
|
||||
DrawTitle(bufferView, sourceRect, fSelectedColumn, false);
|
||||
bufferView->Sync();
|
||||
bufferView->Unlock();
|
||||
|
||||
CopyBits(originalRect, movedRect);
|
||||
DrawBitmap(fDrawBuffer, sourceRect, destRect);
|
||||
DrawBitmap(bufferView->Bitmap(), sourceRect, destRect);
|
||||
#else
|
||||
CopyBits(originalRect, movedRect);
|
||||
DrawTitle(this, destRect, fSelectedColumn, false);
|
||||
@@ -3113,15 +3221,7 @@ OutlineView::OutlineView(BRect rect, BList* visibleColumns, BList* sortColumns,
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
// TODO: This needs to be smart about the size of the buffer.
|
||||
// Also, the buffer can be shared with the title's buffer.
|
||||
BRect doubleBufferRect(0, 0, 600, 35);
|
||||
fDrawBuffer = new BBitmap(doubleBufferRect, B_RGB32, true);
|
||||
fDrawBufferView = new BView(doubleBufferRect, "double_buffer_view",
|
||||
B_FOLLOW_ALL_SIDES, 0);
|
||||
fDrawBuffer->Lock();
|
||||
fDrawBuffer->AddChild(fDrawBufferView);
|
||||
fDrawBuffer->Unlock();
|
||||
fResizeBufferView = new ColumnResizeBufferView();
|
||||
#endif
|
||||
|
||||
FixScrollBar(true);
|
||||
@@ -3133,7 +3233,7 @@ OutlineView::OutlineView(BRect rect, BList* visibleColumns, BList* sortColumns,
|
||||
OutlineView::~OutlineView()
|
||||
{
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
delete fDrawBuffer;
|
||||
delete fResizeBufferView;
|
||||
#endif
|
||||
|
||||
Clear();
|
||||
@@ -3275,15 +3375,15 @@ OutlineView::RedrawColumn(BColumn* column, float leftEdge, bool isFirstColumn)
|
||||
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
fDrawBuffer->Lock();
|
||||
fResizeBufferView->Lock();
|
||||
|
||||
fDrawBufferView->SetHighColor(highColor);
|
||||
fDrawBufferView->SetLowColor(lowColor);
|
||||
fResizeBufferView->SetHighColor(highColor);
|
||||
fResizeBufferView->SetLowColor(lowColor);
|
||||
|
||||
BFont font;
|
||||
GetFont(&font);
|
||||
fDrawBufferView->SetFont(&font);
|
||||
fDrawBufferView->FillRect(sourceRect, B_SOLID_LOW);
|
||||
fResizeBufferView->SetFont(&font);
|
||||
fResizeBufferView->FillRect(sourceRect, B_SOLID_LOW);
|
||||
|
||||
if (isFirstColumn) {
|
||||
// If this is the first column, double buffer drawing the latch
|
||||
@@ -3299,7 +3399,7 @@ OutlineView::RedrawColumn(BColumn* column, float leftEdge, bool isFirstColumn)
|
||||
|
||||
BRect latchRect(sourceRect);
|
||||
latchRect.right = latchRect.left + fMasterView->LatchWidth();
|
||||
fMasterView->DrawLatch(fDrawBufferView, latchRect, pos, row);
|
||||
fMasterView->DrawLatch(fResizeBufferView, latchRect, pos, row);
|
||||
}
|
||||
|
||||
BField* field = row->GetField(column->fFieldID);
|
||||
@@ -3310,33 +3410,33 @@ OutlineView::RedrawColumn(BColumn* column, float leftEdge, bool isFirstColumn)
|
||||
|
||||
#if CONSTRAIN_CLIPPING_REGION
|
||||
BRegion clipRegion(fieldRect);
|
||||
fDrawBufferView->PushState();
|
||||
fDrawBufferView->ConstrainClippingRegion(&clipRegion);
|
||||
fResizeBufferView->PushState();
|
||||
fResizeBufferView->ConstrainClippingRegion(&clipRegion);
|
||||
#endif
|
||||
fDrawBufferView->SetHighColor(fMasterView->Color(
|
||||
fResizeBufferView->SetHighColor(fMasterView->Color(
|
||||
row->fNextSelected ? B_COLOR_SELECTION_TEXT
|
||||
: B_COLOR_TEXT));
|
||||
float baseline = floor(fieldRect.top + fh.ascent
|
||||
+ (fieldRect.Height() + 1 - (fh.ascent+fh.descent)) / 2);
|
||||
fDrawBufferView->MovePenTo(fieldRect.left + 8, baseline);
|
||||
column->DrawField(field, fieldRect, fDrawBufferView);
|
||||
fResizeBufferView->MovePenTo(fieldRect.left + 8, baseline);
|
||||
column->DrawField(field, fieldRect, fResizeBufferView);
|
||||
#if CONSTRAIN_CLIPPING_REGION
|
||||
fDrawBufferView->PopState();
|
||||
fResizeBufferView->PopState();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (fFocusRow == row && !fEditMode && fMasterView->IsFocus()
|
||||
&& Window()->IsActive()) {
|
||||
fDrawBufferView->SetHighColor(fMasterView->Color(
|
||||
fResizeBufferView->SetHighColor(fMasterView->Color(
|
||||
B_COLOR_ROW_DIVIDER));
|
||||
fDrawBufferView->StrokeRect(BRect(-1, sourceRect.top,
|
||||
fResizeBufferView->StrokeRect(BRect(-1, sourceRect.top,
|
||||
10000.0, sourceRect.bottom));
|
||||
}
|
||||
|
||||
fDrawBufferView->Sync();
|
||||
fDrawBuffer->Unlock();
|
||||
fResizeBufferView->Sync();
|
||||
fResizeBufferView->Unlock();
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
DrawBitmap(fDrawBuffer, sourceRect, destRect);
|
||||
DrawBitmap(fResizeBufferView->Bitmap(), sourceRect, destRect);
|
||||
|
||||
#else
|
||||
|
||||
@@ -4013,6 +4113,17 @@ OutlineView::MessageReceived(BMessage* message)
|
||||
}
|
||||
|
||||
|
||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
|
||||
ColumnResizeBufferView*
|
||||
OutlineView::ResizeBufferView()
|
||||
{
|
||||
return fResizeBufferView;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
OutlineView::ChangeFocusRow(bool up, bool updateSelection,
|
||||
bool addToCurrentSelection)
|
||||
@@ -4381,6 +4492,10 @@ OutlineView::AddRow(BRow* row, int32 Index, BRow* parentRow)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||
ResizeBufferView()->UpdateMaxHeight(row->Height());
|
||||
#endif
|
||||
|
||||
if (parentRow == 0 || parentRow->fIsExpanded)
|
||||
fItemsHeight += row->Height() + 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user