diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index d47ba6881b..6198c7166a 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -75,8 +75,27 @@ public: // Render flags enum { + // We are painting selected item Selected = 0x00010000, - Control = 0x00020000 + + // We are painting item in choice popup + ChoicePopup = 0x00020000, + + // We are rendering wxOwnerDrawnComboBox control + // (or other owner drawn control, but that is only + // officially supported one ATM). + Control = 0x00040000, + + // We are painting a disable property + Disabled = 0x00080000, + + // We are painting selected, disabled, or similar + // item that dictates fore- and background colours, + // overriding any cell values. + DontUseCellFgCol = 0x00100000, + DontUseCellBgCol = 0x00200000, + DontUseCellColours = DontUseCellFgCol | + DontUseCellBgCol }; virtual void Render( wxDC& dc, @@ -145,14 +164,48 @@ private: }; +class WXDLLIMPEXP_PROPGRID wxPGCellData : public wxObjectRefData +{ + friend class wxPGCell; +public: + wxPGCellData(); + + void SetText( const wxString& text ) + { + m_text = text; + m_hasValidText = true; + } + void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; } + void SetFgCol( const wxColour& col ) { m_fgCol = col; } + void SetBgCol( const wxColour& col ) { m_bgCol = col; } + +protected: + virtual ~wxPGCellData() { } + + wxString m_text; + wxBitmap m_bitmap; + wxColour m_fgCol; + wxColour m_bgCol; + + // True if m_text is valid and specified + bool m_hasValidText; +}; + /** @class wxPGCell Base class for simple wxPropertyGrid cell information. */ -class WXDLLIMPEXP_PROPGRID wxPGCell +class WXDLLIMPEXP_PROPGRID wxPGCell : public wxObject { public: wxPGCell(); + wxPGCell( const wxPGCell& other ) + { + m_refData = other.m_refData; + if ( m_refData ) + m_refData->IncRef(); + } + wxPGCell( const wxString& text, const wxBitmap& bitmap = wxNullBitmap, const wxColour& fgCol = wxNullColour, @@ -160,21 +213,50 @@ public: virtual ~wxPGCell() { } - void SetText( const wxString& text ) { m_text = text; } - void SetBitmap( const wxBitmap& bitmap ) { m_bitmap = bitmap; } - void SetFgCol( const wxColour& col ) { m_fgCol = col; } - void SetBgCol( const wxColour& col ) { m_bgCol = col; } + wxPGCellData* GetData() + { + return (wxPGCellData*) m_refData; + } - const wxString& GetText() const { return m_text; } - const wxBitmap& GetBitmap() const { return m_bitmap; } - const wxColour& GetFgCol() const { return m_fgCol; } - const wxColour& GetBgCol() const { return m_bgCol; } + const wxPGCellData* GetData() const + { + return (const wxPGCellData*) m_refData; + } + + bool HasText() const + { + return (m_refData && GetData()->m_hasValidText); + } + + /** + Merges valid data from srcCell into this. + */ + void MergeFrom( const wxPGCell& srcCell ); + + void SetText( const wxString& text ); + void SetBitmap( const wxBitmap& bitmap ); + void SetFgCol( const wxColour& col ); + void SetBgCol( const wxColour& col ); + + const wxString& GetText() const { return GetData()->m_text; } + const wxBitmap& GetBitmap() const { return GetData()->m_bitmap; } + const wxColour& GetFgCol() const { return GetData()->m_fgCol; } + const wxColour& GetBgCol() const { return GetData()->m_bgCol; } + + wxPGCell& operator=( const wxPGCell& other ) + { + if ( this != &other ) + { + Ref(other); + } + return *this; + } protected: - wxString m_text; - wxBitmap m_bitmap; - wxColour m_fgCol; - wxColour m_bgCol; + virtual wxObjectRefData *CreateRefData() const + { return new wxPGCellData(); } + + virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const; }; @@ -566,31 +648,35 @@ class WXDLLIMPEXP_PROPGRID wxPGChoiceEntry : public wxPGCell { public: wxPGChoiceEntry(); - wxPGChoiceEntry( const wxPGChoiceEntry& entry ); + wxPGChoiceEntry(const wxPGChoiceEntry& other) + { + m_refData = other.m_refData; + if ( m_refData ) + m_refData->IncRef(); + m_value = other.m_value; + } wxPGChoiceEntry( const wxString& label, int value = wxPG_INVALID_VALUE ) : wxPGCell(), m_value(value) { - m_text = label; + SetText(label); } - wxPGChoiceEntry( const wxString& label, - int value, - const wxBitmap& bitmap, - const wxColour& fgCol = wxNullColour, - const wxColour& bgCol = wxNullColour ) - : wxPGCell(label, bitmap, fgCol, bgCol), m_value(value) - { - } - - virtual ~wxPGChoiceEntry() - { - } + virtual ~wxPGChoiceEntry() { } void SetValue( int value ) { m_value = value; } - int GetValue() const { return m_value; } + wxPGChoiceEntry& operator=( const wxPGChoiceEntry& other ) + { + if ( this != &other ) + { + Ref(other); + } + m_value = other.m_value; + return *this; + } + protected: int m_value; }; @@ -607,26 +693,7 @@ public: void CopyDataFrom( wxPGChoicesData* data ); - // Takes ownership of 'item' - void Insert( int index, wxPGChoiceEntry* item ) - { - wxVector::iterator it; - if ( index == -1 ) - { - it = m_items.end(); - index = (int) m_items.size(); - } - else - { - it = m_items.begin() + index; - } - - // Need to fix value? - if ( item->GetValue() == wxPG_INVALID_VALUE ) - item->SetValue(index); - - m_items.insert(it, item); - } + wxPGChoiceEntry& Insert( int index, const wxPGChoiceEntry& item ); // Delete all entries void Clear(); @@ -636,10 +703,15 @@ public: return (unsigned int) m_items.size(); } - wxPGChoiceEntry* Item( unsigned int i ) const + const wxPGChoiceEntry& Item( unsigned int i ) const { - wxCHECK_MSG( i < GetCount(), NULL, "invalid index" ); + wxASSERT_MSG( i < GetCount(), "invalid index" ); + return m_items[i]; + } + wxPGChoiceEntry& Item( unsigned int i ) + { + wxASSERT_MSG( i < GetCount(), "invalid index" ); return m_items[i]; } @@ -652,7 +724,7 @@ public: } private: - wxVector m_items; + wxVector m_items; // So that multiple properties can use the same set int m_refCount; @@ -755,11 +827,8 @@ public: */ void Add( const wxChar** labels, const ValArrItem* values = NULL ); - /** Version that works with wxArrayString. */ - void Add( const wxArrayString& arr, const ValArrItem* values = NULL ); - /** Version that works with wxArrayString and wxArrayInt. */ - void Add( const wxArrayString& arr, const wxArrayInt& arrint ); + void Add( const wxArrayString& arr, const wxArrayInt& arrint = wxArrayInt() ); /** Adds a single choice. @@ -859,13 +928,13 @@ public: const wxPGChoiceEntry& Item( unsigned int i ) const { wxASSERT( IsOk() ); - return *m_data->Item(i); + return m_data->Item(i); } wxPGChoiceEntry& Item( unsigned int i ) { wxASSERT( IsOk() ); - return *m_data->Item(i); + return m_data->Item(i); } /** Removes count items starting at position nIndex. */ @@ -1357,19 +1426,6 @@ public: */ virtual wxPGEditorDialogAdapter* GetEditorDialog() const; - /** Returns wxPGCell of given column, NULL if none. If valid - object is returned, caller will gain its ownership. - */ - wxPGCell* AcquireCell( unsigned int column ) - { - if ( column >= m_cells.size() ) - return NULL; - - wxPGCell* cell = (wxPGCell*) m_cells[column]; - m_cells[column] = NULL; - return cell; - } - /** Append a new choice to property's list of choices. */ int AddChoice( const wxString& label, int value = wxPG_INVALID_VALUE ) @@ -1494,16 +1550,12 @@ public: void UpdateControl( wxWindow* primary ); - /** Returns wxPGCell of given column, NULL if none. wxPGProperty - will retain ownership of the cell object. + /** + Returns wxPGCell of given column. */ - wxPGCell* GetCell( unsigned int column ) const - { - if ( column >= m_cells.size() ) - return NULL; + const wxPGCell& GetCell( unsigned int column ) const; - return (wxPGCell*) m_cells[column]; - } + wxPGCell& GetCell( unsigned int column ); /** Return number of displayed common values for this property. */ @@ -1732,6 +1784,32 @@ public: void SetAttributes( const wxPGAttributeStorage& attributes ); + /** + Sets property's background colour. + + @param colour + Background colour to use. + + @param recursively + If @true, children are affected recursively, and any categories + are not. + */ + void SetBackgroundColour( const wxColour& colour, + bool recursively = false ); + + /** + Sets property's text colour. + + @param colour + Text colour to use. + + @param recursively + If @true, children are affected recursively, and any categories + are not. + */ + void SetTextColour( const wxColour& colour, + bool recursively = false ); + #ifndef SWIG /** Sets editor for a property. @@ -1753,11 +1831,10 @@ public: */ inline void SetEditor( const wxString& editorName ); - /** Sets cell information for given column. - - Note that the property takes ownership of given wxPGCell instance. + /** + Sets cell information for given column. */ - void SetCell( int column, wxPGCell* cellObj ); + void SetCell( int column, const wxPGCell& cell ); /** Sets common value selected for this property. -1 for none. */ @@ -2048,6 +2125,13 @@ public: #ifndef SWIG + // Returns various display-related information for given column + void GetDisplayInfo( unsigned int column, + int choiceIndex, + int flags, + wxString* pString, + const wxPGCell** pCell ); + static wxString* sm_wxPG_LABEL; /** This member is public so scripting language bindings @@ -2056,9 +2140,49 @@ public: void* m_clientData; protected: - /** Returns text for given column. + + /** + Sets property cell in fashion that reduces number of exclusive + copies of cell data. Used when setting, for instance, same + background colour for a number of properties. + + @param firstCol + First column to affect. + + @param lastCol + Last column to affect. + + @param preparedCell + Pre-prepared cell that is used for those which cell data + before this matched unmodCellData. + + @param srcData + If unmodCellData did not match, valid cell data from this + is merged into cell (usually generating new exclusive copy + of cell's data). + + @param unmodCellData + If cell's cell data matches this, its cell is now set to + preparedCell. + + @param ignoreWithFlags + Properties with any one of these flags are skipped. + + @param recursively + If @true, apply this operation recursively in child properties. */ - wxString GetColumnText( unsigned int col ) const; + void AdaptiveSetCell( unsigned int firstCol, + unsigned int lastCol, + const wxPGCell& preparedCell, + const wxPGCell& srcData, + wxPGCellData* unmodCellData, + FlagType ignoreWithFlags, + bool recursively ); + + /** + Makes sure m_cells has size of column+1 (or more). + */ + void EnsureCells( unsigned int column ); /** Returns (direct) child property with given name (or NULL if not found), with hint index. @@ -2103,7 +2227,7 @@ protected: wxString m_label; wxString m_name; wxPGProperty* m_parent; - wxPropertyGridPageState* m_parentState; + wxPropertyGridPageState* m_parentState; wxClientData* m_clientObject; @@ -2123,7 +2247,7 @@ protected: wxArrayPGProperty m_children; // Extended cell information - wxArrayPtrVoid m_cells; + wxVector m_cells; // Choices shown in drop-down list of editor control. wxPGChoices m_choices; @@ -2152,9 +2276,6 @@ protected: // (essentially this is category's depth, if none then equals m_depth). unsigned char m_depthBgCol; - unsigned char m_bgColIndex; // Background brush index. - unsigned char m_fgColIndex; // Foreground colour index. - private: // Called in constructors. void Init(); diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 1c2d8de3f2..9eae5fad80 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -987,11 +987,22 @@ public: /** Sets background colour of margin. */ void SetMarginColour(const wxColour& col); - /** Sets background colour of property and all its children. Colours of - captions are not affected. Background brush cache is optimized for often - set colours to be set last. + /** + Sets background colour of property. + + @param id + Property name or pointer. + + @param colour + New background colour. + + @param recursively + If True, child properties are affected recursively. Property + categories are skipped if this flag is used. */ - void SetPropertyBackgroundColour( wxPGPropArg id, const wxColour& col ); + void SetPropertyBackgroundColour( wxPGPropArg id, + const wxColour& colour, + bool recursively = false); /** Resets text and background colours of given property. */ @@ -1373,6 +1384,16 @@ public: // Control font changer helper. void SetCurControlBoldFont(); + wxPGCell& GetPropertyDefaultCell() + { + return m_propertyDefaultCell; + } + + wxPGCell& GetCategoryDefaultCell() + { + return m_categoryDefaultCell; + } + // // Public methods for semi-public use // (not protected for optimization) @@ -1619,14 +1640,17 @@ protected: // background colour for empty space below the grid wxColour m_colEmptySpace; + // Default property colours + wxPGCell m_propertyDefaultCell; + + // Default property category + wxPGCell m_categoryDefaultCell; + + // Backup of selected property's cells + wxVector m_propCellsBackup; + // NB: These *cannot* be moved to globals. - // Array of background colour brushes. - wxArrayPtrVoid m_arrBgBrushes; - - // Array of foreground colours. - wxArrayPtrVoid m_arrFgCols; - // labels when properties use common values wxVector m_commonValues; @@ -1790,14 +1814,6 @@ protected: static void RegisterDefaultEditors(); - // Sets m_bgColIndex to this property and all its children. - void SetBackgroundColourIndex( wxPGProperty* p, int index ); - - // Sets m_fgColIndex to this property and all its children. - void SetTextColourIndex( wxPGProperty* p, int index, int flags ); - - int CacheColour( const wxColour& colour ); - // Sets up basic event handling for child control void SetupChildEventHandling( wxWindow* wnd ); diff --git a/include/wx/propgrid/propgridiface.h b/include/wx/propgrid/propgridiface.h index 3e4f83eea5..b8f864d52b 100644 --- a/include/wx/propgrid/propgridiface.h +++ b/include/wx/propgrid/propgridiface.h @@ -867,11 +867,7 @@ public: const wxString& text = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, const wxColour& fgCol = wxNullColour, - const wxColour& bgCol = wxNullColour ) - { - wxPG_PROP_ARG_CALL_PROLOG() - p->SetCell( column, new wxPGCell(text, bitmap, fgCol, bgCol) ); - } + const wxColour& bgCol = wxNullColour ); #ifndef SWIG /** Sets client data (void*) of a property. diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index 235d7dc097..fbd27ec033 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -847,12 +847,6 @@ public: */ virtual wxPGEditorDialogAdapter* GetEditorDialog() const; - /** - Returns wxPGCell of given column, @NULL if none. If valid - object is returned, caller will gain its ownership. - */ - wxPGCell* AcquireCell( unsigned int column ); - /** Append a new choice to property's list of choices. @@ -954,10 +948,9 @@ public: const wxString& GetBaseName() const; /** - Returns wxPGCell of given column, @NULL if none. wxPGProperty - will retain ownership of the cell object. + Returns wxPGCell of given column. */ - wxPGCell* GetCell( unsigned int column ) const; + const wxPGCell& GetCell( unsigned int column ) const; /** Returns number of child properties. @@ -1218,6 +1211,19 @@ public: */ void SetAttribute( const wxString& name, wxVariant value ); + /** + Sets property's background colour. + + @param colour + Background colour to use. + + @param recursively + If @true, children are affected recursively, and any categories + are not. + */ + void SetBackgroundColour( const wxColour& colour, + bool recursively = false ); + /** Sets editor for a property. @@ -1236,10 +1242,8 @@ public: /** Sets cell information for given column. - - Note that the property takes ownership of given wxPGCell instance. */ - void SetCell( int column, wxPGCell* cellObj ); + void SetCell( int column, const wxPGCell& cell ); /** Sets new set of choices for property. @@ -1319,6 +1323,19 @@ public: */ void SetParentalType( int flag ); + /** + Sets property's text colour. + + @param colour + Text colour to use. + + @param recursively + If @true, children are affected recursively, and any categories + are not. + */ + void SetTextColour( const wxColour& colour, + bool recursively = false ); + /** Sets wxValidator for a property */ void SetValidator( const wxValidator& validator ); diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index 1c9ef397a5..e8e320529f 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -651,7 +651,8 @@ enum ID_COLOURSCHEME2, ID_COLOURSCHEME3, ID_CATCOLOURS, - ID_SETCOLOUR, + ID_SETBGCOLOUR, + ID_SETBGCOLOURRECUR, ID_STATICLAYOUT, ID_POPULATE1, ID_POPULATE2, @@ -726,11 +727,13 @@ BEGIN_EVENT_TABLE(FormMain, wxFrame) EVT_MENU( ID_DELETEALL, FormMain::OnClearClick ) EVT_MENU( ID_ENABLE, FormMain::OnEnableDisable ) EVT_MENU( ID_HIDE, FormMain::OnHideShow ) + EVT_MENU( ID_ITERATE1, FormMain::OnIterate1Click ) EVT_MENU( ID_ITERATE2, FormMain::OnIterate2Click ) EVT_MENU( ID_ITERATE3, FormMain::OnIterate3Click ) EVT_MENU( ID_ITERATE4, FormMain::OnIterate4Click ) - EVT_MENU( ID_SETCOLOUR, FormMain::OnMisc ) + EVT_MENU( ID_SETBGCOLOUR, FormMain::OnSetBackgroundColour ) + EVT_MENU( ID_SETBGCOLOURRECUR, FormMain::OnSetBackgroundColour ) EVT_MENU( ID_CLEARMODIF, FormMain::OnClearModifyStatusClick ) EVT_MENU( ID_FREEZE, FormMain::OnFreezeClick ) EVT_MENU( ID_DUMPLIST, FormMain::OnDumpList ) @@ -2121,7 +2124,8 @@ FormMain::FormMain(const wxString& title, const wxPoint& pos, const wxSize& size menuTools1->Append(ID_DELETER, wxT("Delete Random") ); menuTools1->Append(ID_DELETEALL, wxT("Delete All") ); menuTools1->AppendSeparator(); - menuTools1->Append(ID_SETCOLOUR, wxT("Set Bg Colour") ); + menuTools1->Append(ID_SETBGCOLOUR, wxT("Set Bg Colour") ); + menuTools1->Append(ID_SETBGCOLOURRECUR, wxT("Set Bg Colour (Recursively)") ); menuTools1->Append(ID_UNSPECIFY, wxT("Set to Unspecified") ); menuTools1->AppendSeparator(); m_itemEnable = menuTools1->Append(ID_ENABLE, wxT("Enable"), @@ -2591,6 +2595,30 @@ void FormMain::OnHideShow( wxCommandEvent& WXUNUSED(event) ) // ----------------------------------------------------------------------- +#include "wx/colordlg.h" + +void +FormMain::OnSetBackgroundColour( wxCommandEvent& event ) +{ + wxPropertyGrid* pg = m_pPropGridManager->GetGrid(); + wxPGProperty* prop = pg->GetSelection(); + if ( !prop ) + { + wxMessageBox(wxT("First select a property.")); + return; + } + + wxColour col = ::wxGetColourFromUser(this, *wxWHITE, "Choose colour"); + + if ( col.IsOk() ) + { + bool recursively = (event.GetId()==ID_SETBGCOLOURRECUR) ? true : false; + pg->SetPropertyBackgroundColour(prop, col, recursively); + } +} + +// ----------------------------------------------------------------------- + void FormMain::OnInsertPage( wxCommandEvent& WXUNUSED(event) ) { m_pPropGridManager->AddPage(wxT("New Page")); @@ -3020,28 +3048,6 @@ void FormMain::OnMisc ( wxCommandEvent& event ) m_pPropGridManager->SetPropertyValueUnspecified(prop); } } - else if ( id == ID_SETCOLOUR ) - { - wxPGProperty* prop = m_pPropGridManager->GetSelection(); - if ( prop ) - { - wxColourData data; - data.SetChooseFull(true); - int i; - for ( i = 0; i < 16; i++) - { - wxColour colour(i*16, i*16, i*16); - data.SetCustomColour(i, colour); - } - - wxColourDialog dialog(this, &data); - if ( dialog.ShowModal() == wxID_OK ) - { - wxColourData retData = dialog.GetColourData(); - m_pPropGridManager->GetGrid()->SetPropertyBackgroundColour(prop,retData.GetColour()); - } - } - } } // ----------------------------------------------------------------------- diff --git a/samples/propgrid/propgrid.h b/samples/propgrid/propgrid.h index a5e3b8910b..c8a6574f34 100644 --- a/samples/propgrid/propgrid.h +++ b/samples/propgrid/propgrid.h @@ -179,6 +179,7 @@ public: void OnEnableDisable( wxCommandEvent& event ); void OnHideShow( wxCommandEvent& event ); + void OnSetBackgroundColour( wxCommandEvent& event ); void OnClearModifyStatusClick( wxCommandEvent& event ); void OnFreezeClick( wxCommandEvent& event ); void OnDumpList( wxCommandEvent& event ); diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index 2ef0d70adb..fb60bdaa5f 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -680,7 +680,7 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc, wxPoint pt(rect.x + wxPG_CONTROL_MARGIN - wxPG_CHOICEXADJUST - 1, rect.y + 1); - int renderFlags = 0; + int renderFlags = wxPGCellRenderer::DontUseCellColours; if ( flags & wxODCB_PAINTING_CONTROL ) renderFlags |= wxPGCellRenderer::Control; diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index 65811cca7a..31f6f9dd9a 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -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; iGetText(); + // 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(); iAdaptiveSetCell( 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 diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 7ea5b3aa9a..fa2baef34a 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -231,90 +231,6 @@ void wxPropertyGridInitGlobalsIfNeeded() { } -// ----------------------------------------------------------------------- -// wxPGBrush -// ----------------------------------------------------------------------- - -// -// This class is a wxBrush derivative used in the background colour -// brush cache. It adds wxPG-type colour-in-long to the class. -// JMS: Yes I know wxBrush doesn't actually hold the value (refcounted -// object does), but this is simpler implementation and equally -// effective. -// - -class wxPGBrush : public wxBrush -{ -public: - wxPGBrush( const wxColour& colour ); - wxPGBrush(); - virtual ~wxPGBrush() { } - void SetColour2( const wxColour& colour ); - inline long GetColourAsLong() const { return m_colAsLong; } -private: - long m_colAsLong; -}; - - -void wxPGBrush::SetColour2( const wxColour& colour ) -{ - wxBrush::SetColour(colour); - m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); -} - - -wxPGBrush::wxPGBrush() : wxBrush() -{ - m_colAsLong = 0; -} - - -wxPGBrush::wxPGBrush( const wxColour& colour ) : wxBrush(colour) -{ - m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); -} - - -// ----------------------------------------------------------------------- -// wxPGColour -// ----------------------------------------------------------------------- - -// -// Same as wxPGBrush, but for wxColour instead. -// - -class wxPGColour : public wxColour -{ -public: - wxPGColour( const wxColour& colour ); - wxPGColour(); - virtual ~wxPGColour() { } - void SetColour2( const wxColour& colour ); - inline long GetColourAsLong() const { return m_colAsLong; } -private: - long m_colAsLong; -}; - - -void wxPGColour::SetColour2( const wxColour& colour ) -{ - *this = colour; - m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); -} - - -wxPGColour::wxPGColour() : wxColour() -{ - m_colAsLong = 0; -} - - -wxPGColour::wxPGColour( const wxColour& colour ) : wxColour(colour) -{ - m_colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); -} - - // ----------------------------------------------------------------------- // wxPGTLWHandler // Intercepts Close-events sent to wxPropertyGrid's top-level parent, @@ -656,15 +572,14 @@ void wxPropertyGrid::Init2() wxScrolledWindow::SetOwnFont( useFont ); } else + { // This should be otherwise called by SetOwnFont CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); + } - // Add base brush item - m_arrBgBrushes.Add((void*)new wxPGBrush()); - - // Add base colour items - m_arrFgCols.Add((void*)new wxPGColour()); - m_arrFgCols.Add((void*)new wxPGColour()); + // Allocate cell datas indirectly by calling setter + m_propertyDefaultCell.SetBgCol(*wxBLACK); + m_categoryDefaultCell.SetBgCol(*wxBLACK); RegainColours(); @@ -739,18 +654,6 @@ wxPropertyGrid::~wxPropertyGrid() delete m_collbmp; #endif - // Delete cached text colours. - for ( i=0; iSetBgCol(m_colCapBack); } if ( !(m_coloursCustomized & 0x0001) ) @@ -1086,27 +990,21 @@ void wxPropertyGrid::RegainColours() #endif wxColour capForeCol = wxPGAdjustColour(m_colCapBack,colDec,5000,5000,true); m_colCapFore = capForeCol; - - // Set the cached colour as well. - ((wxPGColour*)m_arrFgCols.Item(1))->SetColour2(capForeCol); + m_categoryDefaultCell.GetData()->SetFgCol(capForeCol); } if ( !(m_coloursCustomized & 0x0008) ) { wxColour bgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ); m_colPropBack = bgCol; - - // Set the cached brush as well. - ((wxPGBrush*)m_arrBgBrushes.Item(0))->SetColour2(bgCol); + m_propertyDefaultCell.GetData()->SetBgCol(bgCol); } if ( !(m_coloursCustomized & 0x0010) ) { wxColour fgCol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ); m_colPropFore = fgCol; - - // Set the cached colour as well. - ((wxPGColour*)m_arrFgCols.Item(0))->SetColour2(fgCol); + m_propertyDefaultCell.GetData()->SetFgCol(fgCol); } if ( !(m_coloursCustomized & 0x0020) ) @@ -1201,8 +1099,7 @@ void wxPropertyGrid::SetCellBackgroundColour( const wxColour& col ) m_colPropBack = col; m_coloursCustomized |= 0x08; - // Set the cached brush as well. - ((wxPGBrush*)m_arrBgBrushes.Item(0))->SetColour2(col); + m_propertyDefaultCell.GetData()->SetBgCol(col); Refresh(); } @@ -1214,8 +1111,7 @@ void wxPropertyGrid::SetCellTextColour( const wxColour& col ) m_colPropFore = col; m_coloursCustomized |= 0x10; - // Set the cached colour as well. - ((wxPGColour*)m_arrFgCols.Item(0))->SetColour2(col); + m_propertyDefaultCell.GetData()->SetFgCol(col); Refresh(); } @@ -1262,6 +1158,9 @@ void wxPropertyGrid::SetCaptionBackgroundColour( const wxColour& col ) { m_colCapBack = col; m_coloursCustomized |= 0x02; + + m_categoryDefaultCell.GetData()->SetBgCol(col); + Refresh(); } @@ -1272,59 +1171,20 @@ void wxPropertyGrid::SetCaptionTextColour( const wxColour& col ) m_colCapFore = col; m_coloursCustomized |= 0x04; - // Set the cached colour as well. - ((wxPGColour*)m_arrFgCols.Item(1))->SetColour2(col); + m_categoryDefaultCell.GetData()->SetFgCol(col); Refresh(); } // ----------------------------------------------------------------------- -void wxPropertyGrid::SetBackgroundColourIndex( wxPGProperty* p, int index ) -{ - unsigned char ind = index; - - p->m_bgColIndex = ind; - - unsigned int i; - for ( i=0; iGetChildCount(); i++ ) - SetBackgroundColourIndex(p->Item(i),index); -} - -// ----------------------------------------------------------------------- - -void wxPropertyGrid::SetPropertyBackgroundColour( wxPGPropArg id, const wxColour& colour ) +void wxPropertyGrid::SetPropertyBackgroundColour( wxPGPropArg id, + const wxColour& colour, + bool recursively ) { wxPG_PROP_ARG_CALL_PROLOG() - - size_t i; - int colInd = -1; - - long colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); - - // As it is most likely that the previous colour is used, start comparison - // from the end. - for ( i=(m_arrBgBrushes.size()-1); i>0; i-- ) - { - if ( ((wxPGBrush*)m_arrBgBrushes.Item(i))->GetColourAsLong() == colAsLong ) - { - colInd = i; - break; - } - } - - if ( colInd < 0 ) - { - colInd = m_arrBgBrushes.size(); - wxCHECK_RET( colInd < 256, wxT("wxPropertyGrid: Warning - Only 255 different property background colours allowed.") ); - m_arrBgBrushes.Add( (void*)new wxPGBrush(colour) ); - } - - // Set indexes - SetBackgroundColourIndex(p,colInd); - - // If this was on a visible grid, then draw it. - DrawItemAndChildren(p); + p->SetBackgroundColour( colour, recursively ); + DrawItemAndChildren( p ); } // ----------------------------------------------------------------------- @@ -1333,53 +1193,7 @@ wxColour wxPropertyGrid::GetPropertyBackgroundColour( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour()) - return ((wxPGBrush*)m_arrBgBrushes.Item(p->m_bgColIndex))->GetColour(); -} - -// ----------------------------------------------------------------------- - -void wxPropertyGrid::SetTextColourIndex( wxPGProperty* p, int index, int flags ) -{ - unsigned char ind = index; - - p->m_fgColIndex = ind; - - if ( p->GetChildCount() && (flags & wxPG_RECURSE) ) - { - unsigned int i; - for ( i=0; iGetChildCount(); i++ ) - SetTextColourIndex( p->Item(i), index, flags ); - } -} - -// ----------------------------------------------------------------------- - -int wxPropertyGrid::CacheColour( const wxColour& colour ) -{ - unsigned int i; - int colInd = -1; - - long colAsLong = wxPG_COLOUR(colour.Red(),colour.Green(),colour.Blue()); - - // As it is most likely that the previous colour is used, start comparison - // from the end. - for ( i=(m_arrFgCols.size()-1); i>0; i-- ) - { - if ( ((wxPGColour*)m_arrFgCols.Item(i))->GetColourAsLong() == colAsLong ) - { - colInd = i; - break; - } - } - - if ( colInd < 0 ) - { - colInd = m_arrFgCols.size(); - wxCHECK_MSG( colInd < 256, 0, wxT("wxPropertyGrid: Warning - Only 255 different property foreground colours allowed.") ); - m_arrFgCols.Add( (void*)new wxPGColour(colour) ); - } - - return colInd; + return p->GetCell(0).GetBgCol(); } // ----------------------------------------------------------------------- @@ -1388,20 +1202,8 @@ void wxPropertyGrid::SetPropertyTextColour( wxPGPropArg id, const wxColour& colo bool recursively ) { wxPG_PROP_ARG_CALL_PROLOG() - - if ( p->IsCategory() ) - { - wxPropertyCategory* cat = (wxPropertyCategory*) p; - cat->SetTextColIndex(CacheColour(colour)); - } - - // Set indexes - int flags = 0; - if ( recursively ) - flags |= wxPG_RECURSE; - SetTextColourIndex(p, CacheColour(colour), flags); - - DrawItemAndChildren(p); + p->SetTextColour( colour, recursively ); + DrawItemAndChildren( p ); } // ----------------------------------------------------------------------- @@ -1410,21 +1212,16 @@ wxColour wxPropertyGrid::GetPropertyTextColour( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour()) - return wxColour(*((wxPGColour*)m_arrFgCols.Item(p->m_fgColIndex))); + return p->GetCell(0).GetFgCol(); } +// ----------------------------------------------------------------------- + void wxPropertyGrid::SetPropertyColoursToDefault( wxPGPropArg id ) { wxPG_PROP_ARG_CALL_PROLOG() - SetBackgroundColourIndex( p, 0 ); - SetTextColourIndex( p, 0, wxPG_RECURSE ); - - if ( p->IsCategory() ) - { - wxPropertyCategory* cat = (wxPropertyCategory*) p; - cat->SetTextColIndex(1); - } + p->m_cells.clear(); } // ----------------------------------------------------------------------- @@ -2035,7 +1832,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, int rowHeight = m_fontHeight+(m_spacingy*2)+1; int textMarginHere = x; - int renderFlags = wxPGCellRenderer::Control; + int renderFlags = 0; int greyDepth = m_marginWidth; if ( !(windowStyle & wxPG_HIDE_CATEGORIES) ) @@ -2079,58 +1876,80 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, dc.DrawLine( greyDepthX, y2-1, gridWidth-xRelMod, y2-1 ); - if ( p == selected ) - { - renderFlags |= wxPGCellRenderer::Selected; -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT - wasSelectedPainted = true; -#endif - } - - wxColour rowBgCol; + // + // Need to override row colours? wxColour rowFgCol; - wxBrush rowBgBrush; + wxColour rowBgCol; - if ( p->IsCategory() ) - { - if ( p->m_fgColIndex == 0 ) - rowFgCol = m_colCapFore; - else - rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex]; - rowBgBrush = wxBrush(m_colCapBack); - } - else if ( p != selected ) + if ( p != selected ) { // Disabled may get different colour. if ( !p->IsEnabled() ) + { + renderFlags |= wxPGCellRenderer::Disabled | + wxPGCellRenderer::DontUseCellFgCol; rowFgCol = m_colDisPropFore; - else - rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex]; - - rowBgBrush = *(wxPGBrush*)m_arrBgBrushes[p->m_bgColIndex]; + } } else { - // Selected gets different colour. - if ( reallyFocused ) - { - rowFgCol = m_colSelFore; - rowBgBrush = wxBrush(m_colSelBack); + renderFlags |= wxPGCellRenderer::Selected; + + if ( !p->IsCategory() ) + { + renderFlags |= wxPGCellRenderer::DontUseCellFgCol | + wxPGCellRenderer::DontUseCellBgCol; + +#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT + wasSelectedPainted = true; +#endif + + // Selected gets different colour. + if ( reallyFocused ) + { + rowFgCol = m_colSelFore; + rowBgCol = m_colSelBack; + } + else if ( isEnabled ) + { + rowFgCol = m_colPropFore; + rowBgCol = m_colMargin; + } + else + { + rowFgCol = m_colDisPropFore; + rowBgCol = m_colSelBack; + } } - else if ( isEnabled ) + } + + wxBrush rowBgBrush; + + if ( rowBgCol.IsOk() ) + rowBgBrush = wxBrush(rowBgCol); + + if ( HasInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL) ) + renderFlags = renderFlags & ~wxPGCellRenderer::DontUseCellColours; + + // + // Fill additional margin area with background colour of first cell + if ( greyDepthX < textMarginHere ) + { + if ( !(renderFlags & wxPGCellRenderer::DontUseCellBgCol) ) { - rowFgCol = *(wxPGColour*)m_arrFgCols[p->m_fgColIndex]; - rowBgBrush = marginBrush; - } - else - { - rowFgCol = m_colDisPropFore; - rowBgBrush = wxBrush(m_colSelBack); + wxPGCell& cell = p->GetCell(0); + rowBgCol = cell.GetBgCol(); + rowBgBrush = wxBrush(rowBgCol); } + dc.SetBrush(rowBgBrush); + dc.SetPen(rowBgCol); + dc.DrawRectangle(greyDepthX+1, y, + textMarginHere-greyDepthX, lh-1); } bool fontChanged = false; + // Expander button rectangle wxRect butRect( ((p->m_depth - 1) * m_subgroup_extramargin) - xRelMod, y, m_marginWidth, @@ -2138,18 +1957,22 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, if ( p->IsCategory() ) { - // Captions are all cells merged as one + // Captions have their cell areas merged as one dc.SetFont(m_captionFont); fontChanged = true; wxRect cellRect(greyDepthX, y, gridWidth - greyDepth + 2, rowHeight-1 ); - dc.SetBrush(rowBgBrush); - dc.SetPen(rowBgBrush.GetColour()); - dc.SetTextForeground(rowFgCol); + if ( renderFlags & wxPGCellRenderer::DontUseCellBgCol ) + { + dc.SetBrush(rowBgBrush); + dc.SetPen(rowBgCol); + } - dc.DrawRectangle(cellRect); + if ( renderFlags & wxPGCellRenderer::DontUseCellFgCol ) + { + dc.SetTextForeground(rowFgCol); + } - // Foreground wxPGCellRenderer* renderer = p->GetCellRenderer(0); renderer->Render( dc, cellRect, this, p, 0, -1, renderFlags ); @@ -2176,6 +1999,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, cellRect.width = nextCellWidth - 1; bool ctrlCell = false; + int cellRenderFlags = renderFlags; + + // Tree Item Button + if ( ci == 0 && !HasFlag(wxPG_HIDE_MARGIN) && p->HasVisibleChildren() ) + DrawExpanderButton( dc, butRect, p ); // Background if ( p == selected && m_wndEditor && ci == 1 ) @@ -2184,23 +2012,25 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, dc.SetBrush(editorBgCol); dc.SetPen(editorBgCol); dc.SetTextForeground(m_colPropFore); + dc.DrawRectangle(cellRect); if ( m_dragStatus == 0 && !(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) ) ctrlCell = true; } else { - dc.SetBrush(rowBgBrush); - dc.SetPen(rowBgBrush.GetColour()); - dc.SetTextForeground(rowFgCol); + if ( renderFlags & wxPGCellRenderer::DontUseCellBgCol ) + { + dc.SetBrush(rowBgBrush); + dc.SetPen(rowBgCol); + } + + if ( renderFlags & wxPGCellRenderer::DontUseCellFgCol ) + { + dc.SetTextForeground(rowFgCol); + } } - dc.DrawRectangle(cellRect); - - // Tree Item Button - if ( ci == 0 && !HasFlag(wxPG_HIDE_MARGIN) && p->HasVisibleChildren() ) - DrawExpanderButton( dc, butRect, p ); - dc.SetClippingRegion(cellRect); cellRect.x += textXAdd; @@ -2214,12 +2044,14 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, if ( cmnVal == -1 || ci != 1 ) { renderer = p->GetCellRenderer(ci); - renderer->Render( dc, cellRect, this, p, ci, -1, renderFlags ); + renderer->Render( dc, cellRect, this, p, ci, -1, + cellRenderFlags ); } else { renderer = GetCommonValue(cmnVal)->GetRenderer(); - renderer->Render( dc, cellRect, this, p, ci, -1, renderFlags ); + renderer->Render( dc, cellRect, this, p, ci, -1, + cellRenderFlags ); } } @@ -2891,28 +2723,34 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W if ( (vfb & wxPG_VFB_MARK_CELL) && !property->HasFlag(wxPG_PROP_INVALID_VALUE) ) { - wxASSERT_MSG( !property->GetCell(0) && !property->GetCell(1), - wxT("Currently wxPG_VFB_MARK_CELL only works with properties with standard first two cells") ); + unsigned int colCount = m_pState->GetColumnCount(); - if ( !property->GetCell(0) && !property->GetCell(1) ) + // We need backup marked property's cells + m_propCellsBackup = property->m_cells; + + wxColour vfbFg = *wxWHITE; + wxColour vfbBg = *wxRED; + + property->EnsureCells(colCount); + + for ( unsigned int i=0; iSetCell(0, new wxPGCell(property->GetLabel(), wxNullBitmap, vfbFg, vfbBg)); - property->SetCell(1, new wxPGCell(property->GetDisplayedString(), wxNullBitmap, vfbFg, vfbBg)); + wxPGCell& cell = property->m_cells[i]; + cell.SetFgCol(vfbFg); + cell.SetBgCol(vfbBg); + } - DrawItemAndChildren(property); + DrawItemAndChildren(property); - if ( property == m_selected ) + if ( property == m_selected ) + { + SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL); + + wxWindow* editor = GetEditorControl(); + if ( editor ) { - SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL); - - wxWindow* editor = GetEditorControl(); - if ( editor ) - { - editor->SetForegroundColour(vfbFg); - editor->SetBackgroundColour(vfbBg); - } + editor->SetForegroundColour(vfbFg); + editor->SetBackgroundColour(vfbBg); } } } @@ -2938,8 +2776,8 @@ void wxPropertyGrid::DoOnValidationFailureReset( wxPGProperty* property ) if ( vfb & wxPG_VFB_MARK_CELL ) { - property->SetCell(0, NULL); - property->SetCell(1, NULL); + // Revert cells + property->m_cells = m_propCellsBackup; ClearInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL); @@ -5433,12 +5271,6 @@ wxPGChoiceEntry::wxPGChoiceEntry() { } -wxPGChoiceEntry::wxPGChoiceEntry( const wxPGChoiceEntry& entry ) - : wxPGCell( entry.GetText(), entry.GetBitmap(), - entry.GetFgCol(), entry.GetBgCol() ), m_value(entry.GetValue()) -{ -} - // ----------------------------------------------------------------------- // wxPGChoicesData // ----------------------------------------------------------------------- @@ -5455,13 +5287,6 @@ wxPGChoicesData::~wxPGChoicesData() void wxPGChoicesData::Clear() { - unsigned int i; - - for ( i=0; im_items; +} - for ( i=0; iGetCount(); i++ ) - m_items.push_back( new wxPGChoiceEntry(*data->Item(i)) ); +wxPGChoiceEntry& wxPGChoicesData::Insert( int index, + const wxPGChoiceEntry& item ) +{ + wxVector::iterator it; + if ( index == -1 ) + { + it = m_items.end(); + index = (int) m_items.size(); + } + else + { + it = m_items.begin() + index; + } + + m_items.insert(it, item); + + wxPGChoiceEntry& ownEntry = m_items[index]; + + // Need to fix value? + if ( ownEntry.GetValue() == wxPG_INVALID_VALUE ) + ownEntry.SetValue(index); + + return ownEntry; } // ----------------------------------------------------------------------- @@ -5483,9 +5330,8 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, int value ) { EnsureData(); - wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value); - m_data->Insert( -1, p ); - return *p; + wxPGChoiceEntry entry(label, value); + return m_data->Insert( -1, entry ); } // ----------------------------------------------------------------------- @@ -5494,10 +5340,9 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap { EnsureData(); - wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value); - p->SetBitmap(bitmap); - m_data->Insert( -1, p ); - return *p; + wxPGChoiceEntry entry(label, value); + entry.SetBitmap(bitmap); + return m_data->Insert( -1, entry ); } // ----------------------------------------------------------------------- @@ -5505,10 +5350,7 @@ wxPGChoiceEntry& wxPGChoices::Add( const wxString& label, const wxBitmap& bitmap wxPGChoiceEntry& wxPGChoices::Insert( const wxPGChoiceEntry& entry, int index ) { EnsureData(); - - wxPGChoiceEntry* p = new wxPGChoiceEntry(entry); - m_data->Insert(index, p); - return *p; + return m_data->Insert( index, entry ); } // ----------------------------------------------------------------------- @@ -5517,9 +5359,8 @@ wxPGChoiceEntry& wxPGChoices::Insert( const wxString& label, int index, int valu { EnsureData(); - wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value); - m_data->Insert( index, p ); - return *p; + wxPGChoiceEntry entry(label, value); + return m_data->Insert( index, entry ); } // ----------------------------------------------------------------------- @@ -5538,9 +5379,8 @@ wxPGChoiceEntry& wxPGChoices::AddAsSorted( const wxString& label, int value ) index++; } - wxPGChoiceEntry* p = new wxPGChoiceEntry(label, value); - m_data->Insert( index, p ); - return *p; + wxPGChoiceEntry entry(label, value); + return m_data->Insert( index, entry ); } // ----------------------------------------------------------------------- @@ -5556,28 +5396,11 @@ void wxPGChoices::Add( const wxChar** labels, const ValArrItem* values ) unsigned int i; for ( i = 0; i < itemcount; i++ ) { - int value = wxPG_INVALID_VALUE; + int value = i; if ( values ) value = values[i]; - m_data->Insert( -1, new wxPGChoiceEntry(labels[i], value) ); - } -} - -// ----------------------------------------------------------------------- - -void wxPGChoices::Add( const wxArrayString& arr, const ValArrItem* values ) -{ - EnsureData(); - - unsigned int i; - unsigned int itemcount = arr.size(); - - for ( i = 0; i < itemcount; i++ ) - { - int value = wxPG_INVALID_VALUE; - if ( values ) - value = values[i]; - m_data->Insert( -1, new wxPGChoiceEntry(arr[i], value) ); + wxPGChoiceEntry entry(labels[i], value); + m_data->Insert( i, entry ); } } @@ -5592,10 +5415,11 @@ void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint ) for ( i = 0; i < itemcount; i++ ) { - int value = wxPG_INVALID_VALUE; + int value = i; if ( &arrint && arrint.size() ) value = arrint[i]; - m_data->Insert( -1, new wxPGChoiceEntry(arr[i], value) ); + wxPGChoiceEntry entry(arr[i], value); + m_data->Insert( i, entry ); } } @@ -5604,9 +5428,6 @@ void wxPGChoices::Add( const wxArrayString& arr, const wxArrayInt& arrint ) void wxPGChoices::RemoveAt(size_t nIndex, size_t count) { wxASSERT( m_data->m_refCount != 0xFFFFFFF ); - unsigned int i; - for ( i=nIndex; i<(nIndex+count); i++) - delete m_data->Item(i); m_data->m_items.erase(m_data->m_items.begin()+nIndex, m_data->m_items.begin()+nIndex+count); } @@ -5620,7 +5441,8 @@ int wxPGChoices::Index( const wxString& str ) const unsigned int i; for ( i=0; i< m_data->GetCount(); i++ ) { - if ( m_data->Item(i)->GetText() == str ) + const wxPGChoiceEntry& entry = m_data->Item(i); + if ( entry.HasText() && entry.GetText() == str ) return i; } } @@ -5636,7 +5458,8 @@ int wxPGChoices::Index( int val ) const unsigned int i; for ( i=0; i< m_data->GetCount(); i++ ) { - if ( m_data->Item(i)->GetValue() == val ) + const wxPGChoiceEntry& entry = m_data->Item(i); + if ( entry.GetValue() == val ) return i; } } diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 4a7d70d486..9d679284e8 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -772,6 +772,28 @@ bool wxPropertyGridInterface::SetPropertyMaxLength( wxPGPropArg id, int maxLen ) return true; } +// ----------------------------------------------------------------------- + +void wxPropertyGridInterface::SetPropertyCell( wxPGPropArg id, + int column, + const wxString& text, + const wxBitmap& bitmap, + const wxColour& fgCol, + const wxColour& bgCol ) +{ + wxPG_PROP_ARG_CALL_PROLOG() + + wxPGCell& cell = p->GetCell(column); + if ( text.length() && text != wxPG_LABEL ) + cell.SetText(text); + if ( bitmap.IsOk() ) + cell.SetBitmap(bitmap); + if ( fgCol != wxNullColour ) + cell.SetFgCol(fgCol); + if ( bgCol != wxNullColour ) + cell.SetBgCol(bgCol); +} + // ----------------------------------------------------------------------- // GetPropertyValueAsXXX methods diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index 1b2f47a091..c1ccec0c23 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -697,7 +697,10 @@ int wxPropertyGridPageState::GetColumnFitWidth(wxClientDC& dc, wxPGProperty* p = pwc->Item(i); if ( !p->IsCategory() ) { - dc.GetTextExtent( p->GetColumnText(col), &w, &h ); + const wxPGCell* cell = NULL; + wxString text; + p->GetDisplayInfo(col, -1, 0, &text, &cell); + dc.GetTextExtent(text, &w, &h); if ( col == 0 ) w += ( ((int)p->m_depth-1) * pg->m_subgroup_extramargin );