Reworked wxPGCell. It is now reference counted, and therefore much more user friendly, and is used internally as basis for most property colour values instead of separate row text and bg colours.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56622 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2008-10-31 18:53:37 +00:00
parent 42632bcee1
commit d7e2b52235
11 changed files with 852 additions and 607 deletions

View File

@@ -137,26 +137,25 @@ int wxPGCellRenderer::PreDrawCell( wxDC& dc, const wxRect& rect, const wxPGCell&
{
int imageOffset = 0;
if ( !(flags & Selected) )
// If possible, use cell colours
if ( !(flags & DontUseCellBgCol) )
{
// Draw using wxPGCell information, if available
wxColour fgCol = cell.GetFgCol();
if ( fgCol.Ok() )
dc.SetTextForeground(fgCol);
wxColour bgCol = cell.GetBgCol();
if ( bgCol.Ok() )
{
dc.SetPen(bgCol);
dc.SetBrush(bgCol);
dc.DrawRectangle(rect);
}
dc.SetPen(cell.GetBgCol());
dc.SetBrush(cell.GetBgCol());
}
if ( !(flags & DontUseCellFgCol) )
{
dc.SetTextForeground(cell.GetFgCol());
}
// Draw Background
dc.DrawRectangle(rect);
const wxBitmap& bmp = cell.GetBitmap();
if ( bmp.Ok() &&
// In control, do not draw oversized bitmap
(!(flags & Control) || bmp.GetHeight() < rect.height )
// Do not draw oversized bitmap outside choice popup
((flags & ChoicePopup) || bmp.GetHeight() < rect.height )
)
{
dc.DrawBitmap( bmp,
@@ -192,51 +191,17 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect,
}
const wxPGEditor* editor = NULL;
const wxPGCell* cell = property->GetCell(column);
const wxPGCell* cell = NULL;
wxString text;
int imageOffset = 0;
int preDrawFlags = flags;
// Use choice cell?
if ( column == 1 && (flags & Control) )
{
int selectedIndex = property->GetChoiceSelection();
if ( selectedIndex != wxNOT_FOUND )
{
const wxPGChoices& choices = property->GetChoices();
const wxPGCell* ccell = &choices[selectedIndex];
if ( ccell &&
( ccell->GetBitmap().IsOk() || ccell->GetFgCol().IsOk() || ccell->GetBgCol().IsOk() )
)
cell = ccell;
}
}
property->GetDisplayInfo(column, item, flags, &text, &cell);
if ( cell )
{
int preDrawFlags = flags;
imageOffset = PreDrawCell( dc, rect, *cell, preDrawFlags );
if ( propertyGrid->GetInternalFlags() & wxPG_FL_CELL_OVERRIDES_SEL )
preDrawFlags = preDrawFlags & ~(Selected);
imageOffset = PreDrawCell( dc, rect, *cell, preDrawFlags );
text = cell->GetText();
if ( text == wxS("@!") )
{
if ( column == 0 )
text = property->GetLabel();
else if ( column == 1 )
text = property->GetValueAsString();
else
text = wxEmptyString;
}
}
else if ( column == 0 )
{
// Caption
DrawText( dc, rect, 0, property->GetLabel() );
}
else if ( column == 1 )
if ( column == 1 )
{
if ( !isUnspecified )
{
@@ -257,11 +222,6 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect,
wxPG_CUSTOM_IMAGE_WIDTH,
rect.height-(wxPG_CUSTOM_IMAGE_SPACINGY*2));
/*if ( imageSize.x == wxPG_FULL_CUSTOM_PAINT_WIDTH )
{
imageRect.width = m_width - imageRect.x;
}*/
dc.SetPen( wxPen(propertyGrid->GetCellTextColour(), 1, wxSOLID) );
paintdata.m_drawnWidth = imageSize.x;
@@ -302,12 +262,6 @@ void wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect,
}
}
}
else if ( column == 2 )
{
// Add units string?
if ( !text.length() )
text = property->GetAttribute(wxPGGlobalVars->m_strUnits, wxEmptyString);
}
DrawEditorValue( dc, rect, imageOffset, text, property, editor );
@@ -347,11 +301,22 @@ wxSize wxPGDefaultRenderer::GetImageSize( const wxPGProperty* property,
return wxSize(0,0);
}
// -----------------------------------------------------------------------
// wxPGCellData
// -----------------------------------------------------------------------
wxPGCellData::wxPGCellData()
: wxObjectRefData()
{
m_hasValidText = false;
}
// -----------------------------------------------------------------------
// wxPGCell
// -----------------------------------------------------------------------
wxPGCell::wxPGCell()
: wxObject()
{
}
@@ -359,9 +324,74 @@ wxPGCell::wxPGCell( const wxString& text,
const wxBitmap& bitmap,
const wxColour& fgCol,
const wxColour& bgCol )
: m_bitmap(bitmap), m_fgCol(fgCol), m_bgCol(bgCol)
: wxObject()
{
m_text = text;
wxPGCellData* data = new wxPGCellData();
m_refData = data;
data->m_text = text;
data->m_bitmap = bitmap;
data->m_fgCol = fgCol;
data->m_bgCol = bgCol;
data->m_hasValidText = true;
}
wxObjectRefData *wxPGCell::CloneRefData( const wxObjectRefData *data ) const
{
wxPGCellData* c = new wxPGCellData();
const wxPGCellData* o = (const wxPGCellData*) data;
c->m_text = o->m_text;
c->m_bitmap = o->m_bitmap;
c->m_fgCol = o->m_fgCol;
c->m_bgCol = o->m_bgCol;
c->m_hasValidText = o->m_hasValidText;
return c;
}
void wxPGCell::SetText( const wxString& text )
{
AllocExclusive();
GetData()->SetText(text);
}
void wxPGCell::SetBitmap( const wxBitmap& bitmap )
{
AllocExclusive();
GetData()->SetBitmap(bitmap);
}
void wxPGCell::SetFgCol( const wxColour& col )
{
AllocExclusive();
GetData()->SetFgCol(col);
}
void wxPGCell::SetBgCol( const wxColour& col )
{
AllocExclusive();
GetData()->SetBgCol(col);
}
void wxPGCell::MergeFrom( const wxPGCell& srcCell )
{
AllocExclusive();
wxPGCellData* data = GetData();
if ( srcCell.HasText() )
data->SetText(srcCell.GetText());
if ( srcCell.GetFgCol().IsOk() )
data->SetFgCol(srcCell.GetFgCol());
if ( srcCell.GetBgCol().IsOk() )
data->SetBgCol(srcCell.GetBgCol());
if ( srcCell.GetBitmap().IsOk() )
data->SetBitmap(srcCell.GetBitmap());
}
// -----------------------------------------------------------------------
@@ -394,8 +424,6 @@ void wxPGProperty::Init()
m_flags = wxPG_PROP_PROPERTY;
m_depth = 1;
m_bgColIndex = 0;
m_fgColIndex = 0;
SetExpanded(true);
}
@@ -436,10 +464,9 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState,
"Implement ValueToString() instead of GetValueAsString()" );
#endif
if ( !parentIsRoot )
if ( !parentIsRoot && !parent->IsCategory() )
{
m_bgColIndex = parent->m_bgColIndex;
m_fgColIndex = parent->m_fgColIndex;
m_cells = parent->m_cells;
}
// If in hideable adding mode, or if assigned parent is hideable, then
@@ -575,11 +602,6 @@ wxPGProperty::~wxPGProperty()
delete m_validator;
#endif
unsigned int i;
for ( i=0; i<m_cells.size(); i++ )
delete (wxPGCell*) m_cells[i];
// This makes it easier for us to detect dangling pointers
m_parent = NULL;
}
@@ -644,25 +666,87 @@ void wxPGProperty::RefreshChildren ()
{
}
wxString wxPGProperty::GetColumnText( unsigned int col ) const
void wxPGProperty::GetDisplayInfo( unsigned int column,
int choiceIndex,
int flags,
wxString* pString,
const wxPGCell** pCell )
{
wxPGCell* cell = GetCell(col);
if ( cell )
const wxPGCell* cell = NULL;
if ( !(flags & wxPGCellRenderer::ChoicePopup) )
{
return cell->GetText();
// Not painting listi of choice popups, so get text from property
cell = &GetCell(column);
if ( cell->HasText() )
{
*pString = cell->GetText();
}
else
{
if ( column == 0 )
*pString = GetLabel();
else if ( column == 1 )
*pString = GetDisplayedString();
else if ( column == 2 )
*pString = GetAttribute(wxPGGlobalVars->m_strUnits, wxEmptyString);
}
}
else
{
if ( col == 0 )
return GetLabel();
else if ( col == 1 )
return GetDisplayedString();
else if ( col == 2 )
return GetAttribute(wxPGGlobalVars->m_strUnits, wxEmptyString);
wxASSERT( column == 1 );
if ( choiceIndex != wxNOT_FOUND )
{
const wxPGChoiceEntry& entry = m_choices[choiceIndex];
if ( entry.GetBitmap().IsOk() ||
entry.GetFgCol().IsOk() ||
entry.GetBgCol().IsOk() )
cell = &entry;
*pString = m_choices.GetLabel(choiceIndex);
}
}
if ( !cell )
cell = &GetCell(column);
wxASSERT_MSG( cell->GetData(),
wxString::Format("Invalid cell for property %s",
GetName().c_str()) );
*pCell = cell;
}
/*
wxString wxPGProperty::GetColumnText( unsigned int col, int choiceIndex ) const
{
if ( col != 1 || choiceIndex == wxNOT_FOUND )
{
const wxPGCell& cell = GetCell(col);
if ( cell->HasText() )
{
return cell->GetText();
}
else
{
if ( col == 0 )
return GetLabel();
else if ( col == 1 )
return GetDisplayedString();
else if ( col == 2 )
return GetAttribute(wxPGGlobalVars->m_strUnits, wxEmptyString);
}
}
else
{
// Use choice
return m_choices.GetLabel(choiceIndex);
}
return wxEmptyString;
}
*/
void wxPGProperty::DoGenerateComposedValue( wxString& text,
int argFlags,
@@ -1326,13 +1410,169 @@ wxVariant wxPGProperty::GetDefaultValue() const
return wxVariant();
}
void wxPGProperty::SetCell( int column, wxPGCell* cellObj )
void wxPGProperty::EnsureCells( unsigned int column )
{
if ( column >= (int)m_cells.size() )
m_cells.SetCount(column+1, NULL);
if ( column >= m_cells.size() )
{
// Fill empty slots with default cells
wxPropertyGrid* pg = GetGrid();
wxPGCell defaultCell;
delete (wxPGCell*) m_cells[column];
m_cells[column] = cellObj;
if ( !HasFlag(wxPG_PROP_CATEGORY) )
defaultCell = pg->GetPropertyDefaultCell();
else
defaultCell = pg->GetCategoryDefaultCell();
// TODO: Replace with resize() call
unsigned int cellCountMax = column+1;
for ( unsigned int i=m_cells.size(); i<cellCountMax; i++ )
m_cells.push_back(defaultCell);
}
}
void wxPGProperty::SetCell( int column,
const wxPGCell& cell )
{
EnsureCells(column);
m_cells[column] = cell;
}
void wxPGProperty::AdaptiveSetCell( unsigned int firstCol,
unsigned int lastCol,
const wxPGCell& cell,
const wxPGCell& srcData,
wxPGCellData* unmodCellData,
FlagType ignoreWithFlags,
bool recursively )
{
//
// Sets cell in memory optimizing fashion. That is, if
// current cell data matches unmodCellData, we will
// simply get reference to data from cell. Otherwise,
// cell information from srcData is merged into current.
//
if ( !(m_flags & ignoreWithFlags) && !IsRoot() )
{
EnsureCells(lastCol);
for ( unsigned int col=firstCol; col<=lastCol; col++ )
{
if ( m_cells[col].GetData() == unmodCellData )
{
// Data matches... use cell directly
m_cells[col] = cell;
}
else
{
// Data did not match... merge valid information
m_cells[col].MergeFrom(srcData);
}
}
}
if ( recursively )
{
for ( unsigned int i=0; i<GetChildCount(); i++ )
Item(i)->AdaptiveSetCell( firstCol,
lastCol,
cell,
srcData,
unmodCellData,
ignoreWithFlags,
recursively );
}
}
const wxPGCell& wxPGProperty::GetCell( unsigned int column ) const
{
if ( m_cells.size() > column )
return m_cells[column];
wxPropertyGrid* pg = GetGrid();
if ( IsCategory() )
return pg->GetCategoryDefaultCell();
return pg->GetPropertyDefaultCell();
}
wxPGCell& wxPGProperty::GetCell( unsigned int column )
{
EnsureCells(column);
return m_cells[column];
}
void wxPGProperty::SetBackgroundColour( const wxColour& colour,
bool recursively )
{
wxPGProperty* firstProp = this;
//
// If category is tried to set recursively, skip it and only
// affect the children.
if ( recursively )
{
while ( firstProp->IsCategory() )
{
if ( !firstProp->GetChildCount() )
return;
firstProp = firstProp->Item(0);
}
}
wxPGCell& firstCell = firstProp->GetCell(0);
wxPGCellData* firstCellData = firstCell.GetData();
wxPGCell newCell(firstCell);
newCell.SetBgCol(colour);
wxPGCell srcCell;
srcCell.SetBgCol(colour);
AdaptiveSetCell( 0,
GetParentState()->GetColumnCount()-1,
newCell,
srcCell,
firstCellData,
recursively ? wxPG_PROP_CATEGORY : 0,
recursively );
}
void wxPGProperty::SetTextColour( const wxColour& colour,
bool recursively )
{
wxPGProperty* firstProp = this;
//
// If category is tried to set recursively, skip it and only
// affect the children.
if ( recursively )
{
while ( firstProp->IsCategory() )
{
if ( !firstProp->GetChildCount() )
return;
firstProp = firstProp->Item(0);
}
}
wxPGCell& firstCell = firstProp->GetCell(0);
wxPGCellData* firstCellData = firstCell.GetData();
wxPGCell newCell(firstCell);
newCell.SetFgCol(colour);
wxPGCell srcCell;
srcCell.SetFgCol(colour);
AdaptiveSetCell( 0,
GetParentState()->GetColumnCount()-1,
newCell,
srcCell,
firstCellData,
recursively ? wxPG_PROP_CATEGORY : 0,
recursively );
}
wxPGEditorDialogAdapter* wxPGProperty::GetEditorDialog() const