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';
|
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 BRowContainer : public BObjectList<BRow>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TitleView : public BView {
|
class TitleView : public BView {
|
||||||
typedef BView _inherited;
|
typedef BView _inherited;
|
||||||
public:
|
public:
|
||||||
@@ -198,10 +222,6 @@ private:
|
|||||||
// float fColumnsWidth;
|
// float fColumnsWidth;
|
||||||
BRect fVisibleRect;
|
BRect fVisibleRect;
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
|
||||||
BBitmap* fDrawBuffer;
|
|
||||||
BView* fDrawBufferView;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
INACTIVE,
|
INACTIVE,
|
||||||
@@ -292,6 +312,10 @@ public:
|
|||||||
virtual void MouseUp(BPoint where);
|
virtual void MouseUp(BPoint where);
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
|
ColumnResizeBufferView* ResizeBufferView();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool SortList(BRowContainer* list, bool isVisible);
|
bool SortList(BRowContainer* list, bool isVisible);
|
||||||
static int32 DeepSortThreadEntry(void* outlineView);
|
static int32 DeepSortThreadEntry(void* outlineView);
|
||||||
@@ -311,8 +335,7 @@ private:
|
|||||||
BRect fVisibleRect;
|
BRect fVisibleRect;
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
BBitmap* fDrawBuffer;
|
ColumnResizeBufferView* fResizeBufferView;
|
||||||
BView* fDrawBufferView;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BRow* fFocusRow;
|
BRow* fFocusRow;
|
||||||
@@ -391,6 +414,101 @@ private:
|
|||||||
using namespace BPrivate;
|
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()
|
BField::BField()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -2223,17 +2341,6 @@ TitleView::TitleView(BRect rect, OutlineView* horizontalSlave,
|
|||||||
{
|
{
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
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);
|
fUpSortArrow = new BBitmap(BRect(0, 0, 7, 7), B_CMAP8);
|
||||||
fDownSortArrow = 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;
|
delete fColumnPop;
|
||||||
fColumnPop = NULL;
|
fColumnPop = NULL;
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
|
||||||
delete fDrawBuffer;
|
|
||||||
#endif
|
|
||||||
delete fUpSortArrow;
|
delete fUpSortArrow;
|
||||||
delete fDownSortArrow;
|
delete fDownSortArrow;
|
||||||
|
|
||||||
@@ -2270,6 +2374,9 @@ TitleView::~TitleView()
|
|||||||
void
|
void
|
||||||
TitleView::ColumnAdded(BColumn* column)
|
TitleView::ColumnAdded(BColumn* column)
|
||||||
{
|
{
|
||||||
|
#ifdef DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
|
fOutlineView->ResizeBufferView()->UpdateMaxWidth(column->MaxWidth());
|
||||||
|
#endif
|
||||||
// fColumnsWidth += column->Width();
|
// fColumnsWidth += column->Width();
|
||||||
FixScrollBar(false);
|
FixScrollBar(false);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
@@ -2481,13 +2588,14 @@ TitleView::ResizeSelectedColumn(BPoint position, bool preferred)
|
|||||||
destRect.OffsetBy(fSelectedColumnRect.left, 0);
|
destRect.OffsetBy(fSelectedColumnRect.left, 0);
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
fDrawBuffer->Lock();
|
ColumnResizeBufferView* bufferView = fOutlineView->ResizeBufferView();
|
||||||
DrawTitle(fDrawBufferView, sourceRect, fSelectedColumn, false);
|
bufferView->Lock();
|
||||||
fDrawBufferView->Sync();
|
DrawTitle(bufferView, sourceRect, fSelectedColumn, false);
|
||||||
fDrawBuffer->Unlock();
|
bufferView->Sync();
|
||||||
|
bufferView->Unlock();
|
||||||
|
|
||||||
CopyBits(originalRect, movedRect);
|
CopyBits(originalRect, movedRect);
|
||||||
DrawBitmap(fDrawBuffer, sourceRect, destRect);
|
DrawBitmap(bufferView->Bitmap(), sourceRect, destRect);
|
||||||
#else
|
#else
|
||||||
CopyBits(originalRect, movedRect);
|
CopyBits(originalRect, movedRect);
|
||||||
DrawTitle(this, destRect, fSelectedColumn, false);
|
DrawTitle(this, destRect, fSelectedColumn, false);
|
||||||
@@ -3113,15 +3221,7 @@ OutlineView::OutlineView(BRect rect, BList* visibleColumns, BList* sortColumns,
|
|||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
// TODO: This needs to be smart about the size of the buffer.
|
fResizeBufferView = new ColumnResizeBufferView();
|
||||||
// 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();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FixScrollBar(true);
|
FixScrollBar(true);
|
||||||
@@ -3133,7 +3233,7 @@ OutlineView::OutlineView(BRect rect, BList* visibleColumns, BList* sortColumns,
|
|||||||
OutlineView::~OutlineView()
|
OutlineView::~OutlineView()
|
||||||
{
|
{
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
delete fDrawBuffer;
|
delete fResizeBufferView;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Clear();
|
Clear();
|
||||||
@@ -3275,15 +3375,15 @@ OutlineView::RedrawColumn(BColumn* column, float leftEdge, bool isFirstColumn)
|
|||||||
|
|
||||||
|
|
||||||
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
fDrawBuffer->Lock();
|
fResizeBufferView->Lock();
|
||||||
|
|
||||||
fDrawBufferView->SetHighColor(highColor);
|
fResizeBufferView->SetHighColor(highColor);
|
||||||
fDrawBufferView->SetLowColor(lowColor);
|
fResizeBufferView->SetLowColor(lowColor);
|
||||||
|
|
||||||
BFont font;
|
BFont font;
|
||||||
GetFont(&font);
|
GetFont(&font);
|
||||||
fDrawBufferView->SetFont(&font);
|
fResizeBufferView->SetFont(&font);
|
||||||
fDrawBufferView->FillRect(sourceRect, B_SOLID_LOW);
|
fResizeBufferView->FillRect(sourceRect, B_SOLID_LOW);
|
||||||
|
|
||||||
if (isFirstColumn) {
|
if (isFirstColumn) {
|
||||||
// If this is the first column, double buffer drawing the latch
|
// 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);
|
BRect latchRect(sourceRect);
|
||||||
latchRect.right = latchRect.left + fMasterView->LatchWidth();
|
latchRect.right = latchRect.left + fMasterView->LatchWidth();
|
||||||
fMasterView->DrawLatch(fDrawBufferView, latchRect, pos, row);
|
fMasterView->DrawLatch(fResizeBufferView, latchRect, pos, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
BField* field = row->GetField(column->fFieldID);
|
BField* field = row->GetField(column->fFieldID);
|
||||||
@@ -3310,33 +3410,33 @@ OutlineView::RedrawColumn(BColumn* column, float leftEdge, bool isFirstColumn)
|
|||||||
|
|
||||||
#if CONSTRAIN_CLIPPING_REGION
|
#if CONSTRAIN_CLIPPING_REGION
|
||||||
BRegion clipRegion(fieldRect);
|
BRegion clipRegion(fieldRect);
|
||||||
fDrawBufferView->PushState();
|
fResizeBufferView->PushState();
|
||||||
fDrawBufferView->ConstrainClippingRegion(&clipRegion);
|
fResizeBufferView->ConstrainClippingRegion(&clipRegion);
|
||||||
#endif
|
#endif
|
||||||
fDrawBufferView->SetHighColor(fMasterView->Color(
|
fResizeBufferView->SetHighColor(fMasterView->Color(
|
||||||
row->fNextSelected ? B_COLOR_SELECTION_TEXT
|
row->fNextSelected ? B_COLOR_SELECTION_TEXT
|
||||||
: B_COLOR_TEXT));
|
: B_COLOR_TEXT));
|
||||||
float baseline = floor(fieldRect.top + fh.ascent
|
float baseline = floor(fieldRect.top + fh.ascent
|
||||||
+ (fieldRect.Height() + 1 - (fh.ascent+fh.descent)) / 2);
|
+ (fieldRect.Height() + 1 - (fh.ascent+fh.descent)) / 2);
|
||||||
fDrawBufferView->MovePenTo(fieldRect.left + 8, baseline);
|
fResizeBufferView->MovePenTo(fieldRect.left + 8, baseline);
|
||||||
column->DrawField(field, fieldRect, fDrawBufferView);
|
column->DrawField(field, fieldRect, fResizeBufferView);
|
||||||
#if CONSTRAIN_CLIPPING_REGION
|
#if CONSTRAIN_CLIPPING_REGION
|
||||||
fDrawBufferView->PopState();
|
fResizeBufferView->PopState();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fFocusRow == row && !fEditMode && fMasterView->IsFocus()
|
if (fFocusRow == row && !fEditMode && fMasterView->IsFocus()
|
||||||
&& Window()->IsActive()) {
|
&& Window()->IsActive()) {
|
||||||
fDrawBufferView->SetHighColor(fMasterView->Color(
|
fResizeBufferView->SetHighColor(fMasterView->Color(
|
||||||
B_COLOR_ROW_DIVIDER));
|
B_COLOR_ROW_DIVIDER));
|
||||||
fDrawBufferView->StrokeRect(BRect(-1, sourceRect.top,
|
fResizeBufferView->StrokeRect(BRect(-1, sourceRect.top,
|
||||||
10000.0, sourceRect.bottom));
|
10000.0, sourceRect.bottom));
|
||||||
}
|
}
|
||||||
|
|
||||||
fDrawBufferView->Sync();
|
fResizeBufferView->Sync();
|
||||||
fDrawBuffer->Unlock();
|
fResizeBufferView->Unlock();
|
||||||
SetDrawingMode(B_OP_COPY);
|
SetDrawingMode(B_OP_COPY);
|
||||||
DrawBitmap(fDrawBuffer, sourceRect, destRect);
|
DrawBitmap(fResizeBufferView->Bitmap(), sourceRect, destRect);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -4013,6 +4113,17 @@ OutlineView::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if DOUBLE_BUFFERED_COLUMN_RESIZE
|
||||||
|
|
||||||
|
ColumnResizeBufferView*
|
||||||
|
OutlineView::ResizeBufferView()
|
||||||
|
{
|
||||||
|
return fResizeBufferView;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
OutlineView::ChangeFocusRow(bool up, bool updateSelection,
|
OutlineView::ChangeFocusRow(bool up, bool updateSelection,
|
||||||
bool addToCurrentSelection)
|
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)
|
if (parentRow == 0 || parentRow->fIsExpanded)
|
||||||
fItemsHeight += row->Height() + 1;
|
fItemsHeight += row->Height() + 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user