Implement wxPropertyGrid as wxScrolled

Scrolling operations and related calculations are simpler when wxPG is implemented as wxScrolled instead of wxScrollHelper.
This commit is contained in:
Artur Wieczorek
2019-05-19 22:35:33 +02:00
parent f3e1f72f6d
commit 549acf6e80
4 changed files with 64 additions and 112 deletions

View File

@@ -654,8 +654,7 @@ enum wxPG_INTERNAL_FLAGS
// Use Freeze() and Thaw() respectively to disable and enable drawing. This // Use Freeze() and Thaw() respectively to disable and enable drawing. This
// will also delay sorting etc. miscellaneous calculations to the last // will also delay sorting etc. miscellaneous calculations to the last
// possible moment. // possible moment.
class WXDLLIMPEXP_PROPGRID wxPropertyGrid : public wxControl, class WXDLLIMPEXP_PROPGRID wxPropertyGrid : public wxScrolled<wxControl>,
public wxScrollHelper,
public wxPropertyGridInterface public wxPropertyGridInterface
{ {
friend class wxPropertyGridEvent; friend class wxPropertyGridEvent;

View File

@@ -534,8 +534,7 @@ typedef int (*wxPGSortCallback)(wxPropertyGrid* propGrid,
@category{propgrid} @category{propgrid}
@appearance{propertygrid} @appearance{propertygrid}
*/ */
class wxPropertyGrid : public wxControl, class wxPropertyGrid : public wxScrolled<wxControl>,
public wxScrollHelper,
public wxPropertyGridInterface public wxPropertyGridInterface
{ {
public: public:

View File

@@ -250,19 +250,18 @@ public:
} }
} }
virtual void OnColumnCountChanging(unsigned int count) wxOVERRIDE
{
EnsureColumnCount(count);
}
void OnPageChanged(const wxPropertyGridPage* page) void OnPageChanged(const wxPropertyGridPage* page)
{ {
m_page = page; m_page = page;
OnPageUpdated();
}
void OnPageUpdated()
{
// Get column info from the page // Get column info from the page
unsigned int colCount = m_page->GetColumnCount(); unsigned int colCount = m_page->GetColumnCount();
EnsureColumnCount(colCount);
DetermineAllColumnWidths();
SetColumnCount(colCount); SetColumnCount(colCount);
DetermineAllColumnWidths();
} }
void OnColumWidthsChanged() void OnColumWidthsChanged()
@@ -367,8 +366,8 @@ private:
int colWidth = hcEvent->GetWidth(); int colWidth = hcEvent->GetWidth();
OnSetColumnWidth(col, colWidth); OnSetColumnWidth(col, colWidth);
OnColumWidthsChanged();
pg->SendEvent(wxEVT_PG_COLS_RESIZED, (wxPGProperty*)NULL);
pg->SendEvent(wxEVT_PG_COL_DRAGGING, pg->SendEvent(wxEVT_PG_COL_DRAGGING,
NULL, NULL, 0, NULL, NULL, 0,
(unsigned int)col); (unsigned int)col);
@@ -928,13 +927,23 @@ void wxPropertyGridManager::SetColumnCount( int colCount, int page )
wxASSERT( page >= -1 ); wxASSERT( page >= -1 );
wxASSERT( page < (int)GetPageCount() ); wxASSERT( page < (int)GetPageCount() );
GetPageState(page)->SetColumnCount( colCount ); wxPropertyGridPageState* state = GetPageState(page);
GetGrid()->Refresh();
#if wxUSE_HEADERCTRL #if wxUSE_HEADERCTRL
if ( m_pHeaderCtrl && m_pHeaderCtrl->IsShown() ) // Update header only if column count is set for the currently visible page
m_pHeaderCtrl->OnPageUpdated(); if ( m_pHeaderCtrl && m_pHeaderCtrl->IsShown() && state == m_pState )
#endif {
m_pHeaderCtrl->SetColumnCount(colCount);
}
#endif // wxUSE_HEADERCTRL
state->SetColumnCount( colCount );
GetGrid()->Refresh();
#if wxUSE_HEADERCTRL
// Update header only if column count is set for the currently visible page
if ( m_pHeaderCtrl && m_pHeaderCtrl->IsShown() && state == m_pState )
{
m_pHeaderCtrl->OnColumWidthsChanged();
}
#endif // wxUSE_HEADERCTRL
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------

View File

@@ -287,7 +287,7 @@ wxEND_EVENT_TABLE()
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
wxPropertyGrid::wxPropertyGrid() wxPropertyGrid::wxPropertyGrid()
: wxControl(), wxScrollHelper(this) : wxScrolled<wxControl>()
{ {
Init1(); Init1();
} }
@@ -300,7 +300,7 @@ wxPropertyGrid::wxPropertyGrid( wxWindow *parent,
const wxSize& size, const wxSize& size,
long style, long style,
const wxString& name ) const wxString& name )
: wxControl(), wxScrollHelper(this) : wxScrolled<wxControl>()
{ {
Init1(); Init1();
Create(parent,id,pos,size,style,name); Create(parent,id,pos,size,style,name);
@@ -494,13 +494,14 @@ void wxPropertyGrid::Init2()
m_tlpClosedTime = 0; m_tlpClosedTime = 0;
// set virtual size to this window size // set virtual size to this window size
wxSize wndsize = GetSize(); wxSize clientSize = GetClientSize();
SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth()); SetVirtualSize(clientSize);
m_timeCreated = ::wxGetLocalTimeMillis(); m_timeCreated = ::wxGetLocalTimeMillis();
m_iFlags |= wxPG_FL_INITIALIZED; m_iFlags |= wxPG_FL_INITIALIZED;
wxSize wndsize = GetSize();
m_ncWidth = wndsize.GetWidth(); m_ncWidth = wndsize.GetWidth();
// Need to call OnResize handler or size given in constructor/Create // Need to call OnResize handler or size given in constructor/Create
@@ -1295,7 +1296,7 @@ void wxPropertyGrid::SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
{ {
int oldX; int oldX;
CalcUnscrolledPosition(0, 0, &oldX, NULL); CalcUnscrolledPosition(0, 0, &oldX, NULL);
wxScrollHelper::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, wxScrolled<wxControl>::SetScrollbars(pixelsPerUnitX, pixelsPerUnitY,
noUnitsX, noUnitsY, xPos, yPos, noRefresh); noUnitsX, noUnitsY, xPos, yPos, noRefresh);
int newX; int newX;
CalcUnscrolledPosition(0, 0, &newX, NULL); CalcUnscrolledPosition(0, 0, &newX, NULL);
@@ -1359,6 +1360,8 @@ void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing )
if ( m_pState ) if ( m_pState )
m_pState->CalculateFontAndBitmapStuff(vspacing); m_pState->CalculateFontAndBitmapStuff(vspacing);
SetScrollRate(wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT);
if ( m_iFlags & wxPG_FL_INITIALIZED ) if ( m_iFlags & wxPG_FL_INITIALIZED )
RecalculateVirtualSize(); RecalculateVirtualSize();
@@ -2013,18 +2016,13 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
itemsRect = &tempItemsRect; itemsRect = &tempItemsRect;
} }
int vx, vy;
GetViewStart(&vx, &vy);
vx *= wxPG_PIXELS_PER_UNIT;
vy *= wxPG_PIXELS_PER_UNIT;
// items added check // items added check
if ( m_pState->m_itemsAdded ) PrepareAfterItemsAdded(); if ( m_pState->m_itemsAdded ) PrepareAfterItemsAdded();
if ( m_pState->DoGetRoot()->GetChildCount() > 0 ) if ( m_pState->DoGetRoot()->GetChildCount() > 0 )
{ {
int paintFinishY = DoDrawItems(dc, itemsRect) + 1 - vy; int paintFinishY = DoDrawItems(dc, itemsRect) + 1;
int drawBottomY = itemsRect->y + itemsRect->height - 1 - vy; int drawBottomY = itemsRect->GetBottom();
// Clear area beyond last painted property // Clear area beyond last painted property
if ( paintFinishY < drawBottomY ) if ( paintFinishY < drawBottomY )
@@ -2038,15 +2036,10 @@ void wxPropertyGrid::DrawItems( wxDC& dc,
} }
else else
{ {
// itemRect is in virtual grid space
wxRect drawRect(itemsRect->x - vx,
itemsRect->y - vy,
itemsRect->width,
itemsRect->height);
// Just clear the area // Just clear the area
dc.SetPen(m_colEmptySpace); dc.SetPen(m_colEmptySpace);
dc.SetBrush(m_colEmptySpace); dc.SetBrush(m_colEmptySpace);
dc.DrawRectangle(drawRect); dc.DrawRectangle(*itemsRect);
} }
} }
@@ -2064,25 +2057,16 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
const wxPGProperty* firstItem; const wxPGProperty* firstItem;
firstItem = DoGetItemAtY(itemsRect->y); firstItem = DoGetItemAtY(itemsRect->y);
int vx, vy;
GetViewStart(&vx, &vy);
vx *= wxPG_PIXELS_PER_UNIT;
vy *= wxPG_PIXELS_PER_UNIT;
if ( IsFrozen() || m_height < 1 || firstItem == NULL ) if ( IsFrozen() || m_height < 1 || firstItem == NULL )
return vy - 1; return itemsRect->GetBottom();
wxCHECK_MSG( !m_pState->m_itemsAdded, vy - 1, wxCHECK_MSG( !m_pState->m_itemsAdded, itemsRect->GetBottom(),
wxS("no items added") ); wxS("no items added") );
wxASSERT( m_pState->DoGetRoot()->GetChildCount() ); wxASSERT( m_pState->DoGetRoot()->GetChildCount() );
int lh = m_lineHeight; int lh = m_lineHeight;
int firstItemTopY = itemsRect->y;
int firstItemTopY; int lastItemBottomY = itemsRect->GetBottom();
int lastItemBottomY;
firstItemTopY = itemsRect->y;
lastItemBottomY = itemsRect->y + itemsRect->height - 1;
// Align y coordinates to item boundaries // Align y coordinates to item boundaries
firstItemTopY -= firstItemTopY % lh; firstItemTopY -= firstItemTopY % lh;
@@ -2092,10 +2076,10 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
// Entire range outside scrolled, visible area? // Entire range outside scrolled, visible area?
if ( firstItemTopY >= (int)m_pState->GetVirtualHeight() || if ( firstItemTopY >= (int)m_pState->GetVirtualHeight() ||
lastItemBottomY <= 0 ) lastItemBottomY <= 0 )
return itemsRect->y; return itemsRect->GetBottom();
wxCHECK_MSG( firstItemTopY < lastItemBottomY, wxCHECK_MSG( firstItemTopY < lastItemBottomY,
itemsRect->y, itemsRect->GetBottom(),
wxS("invalid y values") ); wxS("invalid y values") );
/* /*
@@ -2112,12 +2096,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
long windowStyle = m_windowStyle; long windowStyle = m_windowStyle;
int xRelMod = vx; int x = m_marginWidth;
// itemsRect conversion
firstItemTopY -= vy;
lastItemBottomY -= vy;
int x = m_marginWidth - xRelMod;
wxFont normalFont = GetFont(); wxFont normalFont = GetFont();
@@ -2146,7 +2125,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
if ( !(windowStyle & wxPG_HIDE_MARGIN) ) if ( !(windowStyle & wxPG_HIDE_MARGIN) )
{ {
dc.SetPen( *wxTRANSPARENT_PEN ); dc.SetPen( *wxTRANSPARENT_PEN );
dc.DrawRectangle(-1-xRelMod,firstItemTopY-1,x+2,lastItemBottomY-firstItemTopY+2); dc.DrawRectangle(-1,firstItemTopY-1,x+2,lastItemBottomY-firstItemTopY+2);
} }
const wxPGProperty* firstSelected = GetSelection(); const wxPGProperty* firstSelected = GetSelection();
@@ -2194,7 +2173,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
splitterPos.push_back(sx); splitterPos.push_back(sx);
} }
int viewLeftEdge = itemsRect->x - vx; int viewLeftEdge = itemsRect->x;
int viewRightEdge = viewLeftEdge + itemsRect->width - 1; int viewRightEdge = viewLeftEdge + itemsRect->width - 1;
// Determine columns range to be drawn // Determine columns range to be drawn
unsigned int firstCol = 0; unsigned int firstCol = 0;
@@ -2219,9 +2198,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
int greyDepth = m_marginWidth; int greyDepth = m_marginWidth;
if ( !(windowStyle & wxPG_HIDE_CATEGORIES) ) if ( !(windowStyle & wxPG_HIDE_CATEGORIES) )
greyDepth = (((int)p->m_depthBgCol)-1) * m_subgroup_extramargin + m_marginWidth; greyDepth += (((int)p->m_depthBgCol)-1) * m_subgroup_extramargin;
int greyDepthX = greyDepth - xRelMod;
// Use basic depth if in non-categoric mode and parent is base array. // Use basic depth if in non-categoric mode and parent is base array.
if ( !(windowStyle & wxPG_HIDE_CATEGORIES) || p->GetParent() != m_pState->DoGetRoot() ) if ( !(windowStyle & wxPG_HIDE_CATEGORIES) || p->GetParent() != m_pState->DoGetRoot() )
@@ -2232,7 +2209,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
// Paint margin area // Paint margin area
dc.SetBrush(marginBrush); dc.SetBrush(marginBrush);
dc.SetPen(marginPen); dc.SetPen(marginPen);
dc.DrawRectangle( -xRelMod, y, greyDepth, lh ); dc.DrawRectangle( 0, y, greyDepth, lh );
dc.SetPen( linepen ); dc.SetPen( linepen );
@@ -2252,12 +2229,12 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
bool suppressMarginEdge = false; bool suppressMarginEdge = false;
#endif #endif
if (!suppressMarginEdge) if (!suppressMarginEdge)
dc.DrawLine( greyDepthX, y, greyDepthX, y2 ); dc.DrawLine( greyDepth, y, greyDepth, y2 );
else else
{ {
// Blank out the margin edge // Blank out the margin edge
dc.SetPen(wxPen(GetBackgroundColour())); dc.SetPen(wxPen(GetBackgroundColour()));
dc.DrawLine( greyDepthX, y, greyDepthX, y2 ); dc.DrawLine( greyDepth, y, greyDepth, y2 );
dc.SetPen( linepen ); dc.SetPen( linepen );
} }
@@ -2273,7 +2250,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
nextP && nextP->IsCategory() ) nextP && nextP->IsCategory() )
dc.SetPen(m_colCapBack); dc.SetPen(m_colCapBack);
dc.DrawLine(greyDepthX, y2 - 1, cellX, y2 - 1); dc.DrawLine(greyDepth, y2 - 1, cellX, y2 - 1);
// //
// Need to override row colours? // Need to override row colours?
@@ -2329,7 +2306,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
// //
// Fill additional margin area with background colour of first cell // Fill additional margin area with background colour of first cell
if ( greyDepthX < textMarginHere ) if ( greyDepth < textMarginHere )
{ {
if ( !(renderFlags & wxPGCellRenderer::DontUseCellBgCol) ) if ( !(renderFlags & wxPGCellRenderer::DontUseCellBgCol) )
{ {
@@ -2339,20 +2316,20 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
} }
dc.SetBrush(rowBgBrush); dc.SetBrush(rowBgBrush);
dc.SetPen(rowBgCol); dc.SetPen(rowBgCol);
dc.DrawRectangle(greyDepthX+1, y, dc.DrawRectangle(greyDepth+1, y,
textMarginHere-greyDepthX, lh-1); textMarginHere-greyDepth, lh-1);
} }
bool fontChanged = false; bool fontChanged = false;
// Expander button rectangle // Expander button rectangle
wxRect butRect( ((p->GetDepth() - 1) * m_subgroup_extramargin) - xRelMod, wxRect butRect( ((p->GetDepth() - 1) * m_subgroup_extramargin),
y, y,
m_marginWidth, m_marginWidth,
lh ); lh );
// Default cell rect fill the entire row // Default cell rect fill the entire row
wxRect cellRect(greyDepthX, y, cellX - greyDepthX, lh-1); wxRect cellRect(greyDepth, y, cellX - greyDepth, lh-1);
bool isCategory = p->IsCategory(); bool isCategory = p->IsCategory();
@@ -2407,7 +2384,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
if ( ci == 0 ) if ( ci == 0 )
{ {
textXAdd = textMarginHere - greyDepthX; textXAdd = textMarginHere - greyDepth;
cellRect.width = firstCellWidth; cellRect.width = firstCellWidth;
cellRect.x = firstCellX; cellRect.x = firstCellX;
} }
@@ -2524,7 +2501,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
dc.SetBrush(wxBrush(m_colEmptySpace)); dc.SetBrush(wxBrush(m_colEmptySpace));
dc.DrawRectangle(cellX, firstItemTopY, viewRightEdge - cellX + 1, lastItemBottomY - firstItemTopY); dc.DrawRectangle(cellX, firstItemTopY, viewRightEdge - cellX + 1, lastItemBottomY - firstItemTopY);
return y - 1 + vy; return y - 1;
} }
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -4561,54 +4538,22 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
m_iFlags |= wxPG_FL_RECALCULATING_VIRTUAL_SIZE; m_iFlags |= wxPG_FL_RECALCULATING_VIRTUAL_SIZE;
int x = m_pState->GetVirtualWidth(); int w = m_pState->GetVirtualWidth();
int y = m_pState->m_virtualHeight; int h = m_pState->m_virtualHeight;
int width, height;
GetClientSize(&width,&height);
// Now adjust virtual size. // Now adjust virtual size.
SetVirtualSize(x, y); SetVirtualSize(w, h);
if ( forceXPos != -1 )
int xAmount = 0;
int xPos = 0;
//
// Adjust scrollbars
if ( HasVirtualWidth() )
{ {
xAmount = x/wxPG_PIXELS_PER_UNIT; Scroll(forceXPos, wxDefaultCoord);
xPos = GetScrollPos( wxHORIZONTAL );
} }
if ( forceXPos != -1 )
xPos = forceXPos;
// xPos too high?
else if ( xPos > (xAmount-(width/wxPG_PIXELS_PER_UNIT)) )
xPos = 0;
int yAmount = y / wxPG_PIXELS_PER_UNIT;
int yPos = GetScrollPos( wxVERTICAL );
SetScrollbars( wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT,
xAmount, yAmount, xPos, yPos, true );
// This may be needed in addition to calling SetScrollbars()
// when class inherits from wxScrollHelper instead of
// actual wxScrolled<T>.
AdjustScrollbars();
// Must re-get size now // Must re-get size now
GetClientSize(&width,&height); GetClientSize(&m_width, &m_height);
if ( !HasVirtualWidth() ) if ( !HasVirtualWidth() )
{ {
m_pState->SetVirtualWidth(width); m_pState->SetVirtualWidth(m_width);
} }
m_width = width;
m_height = height;
m_pState->CheckColumnWidths(); m_pState->CheckColumnWidths();
if ( GetSelection() ) if ( GetSelection() )