X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0871417690729a7dfe4f998c367e5b0b6f377459..b96a56e60e65e17704fc66ae9cdbb2444ac987d8:/src/propgrid/editors.cpp diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index d20d1d6137..433a16112d 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -169,10 +169,11 @@ wxString wxPGEditor::GetName() const return GetClassInfo()->GetClassName(); } -void wxPGEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& text ) const +void wxPGEditor::DrawValue( wxDC& dc, const wxRect& rect, + wxPGProperty* WXUNUSED(property), + const wxString& text ) const { - if ( !property->IsValueUnspecified() ) - dc.DrawText( text, rect.x+wxPG_XBEFORETEXT, rect.y ); + dc.DrawText( text, rect.x+wxPG_XBEFORETEXT, rect.y ); } bool wxPGEditor::GetValueFromControl( wxVariant&, wxPGProperty*, wxWindow* ) const @@ -206,6 +207,108 @@ void wxPGEditor::OnFocus( wxPGProperty*, wxWindow* ) const { } +void wxPGEditor::SetControlAppearance( wxPropertyGrid* pg, + wxPGProperty* property, + wxWindow* ctrl, + const wxPGCell& cell, + const wxPGCell& oCell, + bool unspecified ) const +{ + // Get old editor appearance + wxTextCtrl* tc = NULL; + wxComboCtrl* cb = NULL; + if ( ctrl->IsKindOf(CLASSINFO(wxTextCtrl)) ) + { + tc = (wxTextCtrl*) ctrl; + } + else + { + if ( ctrl->IsKindOf(CLASSINFO(wxComboCtrl)) ) + { + cb = (wxComboCtrl*) ctrl; + tc = cb->GetTextCtrl(); + } + } + + if ( tc || cb ) + { + wxString tcText; + bool changeText = false; + + if ( cell.HasText() && !pg->IsEditorFocused() ) + { + tcText = cell.GetText(); + changeText = true; + } + else if ( oCell.HasText() ) + { + tcText = property->GetValueAsString( + property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE); + changeText = true; + } + + if ( changeText ) + { + // This prevents value from being modified + if ( tc ) + { + pg->SetupTextCtrlValue(tcText); + tc->SetValue(tcText); + } + else + { + cb->SetText(tcText); + } + } + } + + // Do not make the mistake of calling GetClassDefaultAttributes() + // here. It is static, while GetDefaultAttributes() is virtual + // and the correct one to use. + wxVisualAttributes vattrs = ctrl->GetDefaultAttributes(); + + // Foreground colour + const wxColour& fgCol = cell.GetFgCol(); + if ( fgCol.IsOk() ) + { + ctrl->SetForegroundColour(fgCol); + } + else if ( oCell.GetFgCol().IsOk() ) + { + ctrl->SetForegroundColour(vattrs.colFg); + } + + // Background colour + const wxColour& bgCol = cell.GetBgCol(); + if ( bgCol.IsOk() ) + { + ctrl->SetBackgroundColour(bgCol); + } + else if ( oCell.GetBgCol().IsOk() ) + { + ctrl->SetBackgroundColour(vattrs.colBg); + } + + // Font + const wxFont& font = cell.GetFont(); + if ( font.IsOk() ) + { + ctrl->SetFont(font); + } + else if ( oCell.GetFont().IsOk() ) + { + ctrl->SetFont(vattrs.font); + } + + // Also call the old SetValueToUnspecified() + if ( unspecified ) + SetValueToUnspecified(property, ctrl); +} + +void wxPGEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property), + wxWindow* WXUNUSED(ctrl) ) const +{ +} bool wxPGEditor::CanContainCustomImage() const { @@ -232,9 +335,11 @@ wxPGWindowList wxPGTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid, property->GetChildCount() ) return NULL; - if ( !property->IsValueUnspecified() ) - text = property->GetValueAsString(property->HasFlag(wxPG_PROP_READONLY) ? - 0 : wxPG_EDITABLE_VALUE); + int argFlags = 0; + if ( !property->HasFlag(wxPG_PROP_READONLY) && + !property->IsValueUnspecified() ) + argFlags |= wxPG_EDITABLE_VALUE; + text = property->GetValueAsString(argFlags); int flags = 0; if ( (property->GetFlags() & wxPG_PROP_PASSWORD) && @@ -363,7 +468,7 @@ bool wxPGTextCtrlEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* } -void wxPGTextCtrlEditor::SetValueToUnspecified( wxPGProperty* property, wxWindow* ctrl ) const +void wxPGTextCtrlEditor::SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const { wxTextCtrl* tc = wxStaticCast(ctrl, wxTextCtrl); @@ -371,35 +476,37 @@ void wxPGTextCtrlEditor::SetValueToUnspecified( wxPGProperty* property, wxWindow wxASSERT(pg); // Really, property grid should exist if editor does if ( pg ) { - wxString unspecValueText; - pg->SetupTextCtrlValue(unspecValueText); - tc->SetValue(unspecValueText); + pg->SetupTextCtrlValue(txt); + tc->SetValue(txt); } } -void wxPGTextCtrlEditor::SetControlStringValue( wxPGProperty* property, wxWindow* ctrl, const wxString& txt ) const +void wxPGTextCtrlEditor_OnFocus( wxPGProperty* property, + wxTextCtrl* tc ) { - wxTextCtrl* tc = wxStaticCast(ctrl, wxTextCtrl); + // Make sure there is correct text (instead of unspecified value + // indicator or hint text) + int flags = property->HasFlag(wxPG_PROP_READONLY) ? + 0 : wxPG_EDITABLE_VALUE; + wxString correctText = property->GetValueAsString(flags); - wxPropertyGrid* pg = property->GetGrid(); - wxASSERT(pg); // Really, property grid should exist if editor does - if ( pg ) + if ( tc->GetValue() != correctText ) { - pg->SetupTextCtrlValue(txt); - tc->SetValue(txt); + property->GetGrid()->SetupTextCtrlValue(correctText); + tc->SetValue(correctText); } -} - -void wxPGTextCtrlEditor::OnFocus( wxPGProperty*, wxWindow* wnd ) const + tc->SetSelection(-1,-1); +} + +void wxPGTextCtrlEditor::OnFocus( wxPGProperty* property, + wxWindow* wnd ) const { wxTextCtrl* tc = wxStaticCast(wnd, wxTextCtrl); - - tc->SetSelection(-1,-1); + wxPGTextCtrlEditor_OnFocus(property, tc); } - wxPGTextCtrlEditor::~wxPGTextCtrlEditor() { } @@ -553,7 +660,17 @@ public: int flags ) const { wxPropertyGrid* pg = GetGrid(); - pg->OnComboItemPaint( this, item, &dc, (wxRect&)rect, flags ); + + // Handle hint text via super class + if ( (flags & wxODCB_PAINTING_CONTROL) && + ShouldUseHintText(flags) ) + { + wxOwnerDrawnComboBox::OnDrawItem(dc, rect, item, flags); + } + else + { + pg->OnComboItemPaint( this, item, &dc, (wxRect&)rect, flags ); + } } virtual wxCoord OnMeasureItem( size_t item ) const @@ -705,20 +822,44 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb, rect.y + 1); int renderFlags = wxPGCellRenderer::DontUseCellColours; + bool useCustomPaintProcedure; + + // If custom image had some size, we will start from the assumption + // that custom paint procedure is required + if ( cis.x > 0 ) + useCustomPaintProcedure = true; + else + useCustomPaintProcedure = false; + + if ( flags & wxODCB_PAINTING_SELECTED ) + renderFlags |= wxPGCellRenderer::Selected; if ( flags & wxODCB_PAINTING_CONTROL ) + { renderFlags |= wxPGCellRenderer::Control; + + // If wxPG_PROP_CUSTOMIMAGE was set, then that means any custom + // image will not appear on the control row (it may be too + // large to fit, for instance). Also do not draw custom image + // if no choice was selected. + if ( !p->HasFlag(wxPG_PROP_CUSTOMIMAGE) || item < 0 ) + useCustomPaintProcedure = false; + } else + { renderFlags |= wxPGCellRenderer::ChoicePopup; + } - if ( flags & wxODCB_PAINTING_SELECTED ) - renderFlags |= wxPGCellRenderer::Selected; + // If not drawing a selected popup item, then give property's + // m_valueBitmap a chance. + if ( p->m_valueBitmap && item != pCb->GetSelection() ) + useCustomPaintProcedure = false; + // If current choice had a bitmap set by the application, then + // use it instead of any custom paint procedure. + else if ( itemBitmap ) + useCustomPaintProcedure = false; - if ( cis.x > 0 && (p->HasFlag(wxPG_PROP_CUSTOMIMAGE) || !(flags & wxODCB_PAINTING_CONTROL)) && - ( !p->m_valueBitmap || item == pCb->GetSelection() ) && - ( item >= 0 || (flags & wxODCB_PAINTING_CONTROL) ) && - !itemBitmap - ) + if ( useCustomPaintProcedure ) { pt.x += wxCC_CUSTOM_IMAGE_MARGIN1; wxRect r(pt.x,pt.y,cis.x,cis.y); @@ -807,6 +948,13 @@ bool wxPGChoiceEditor_SetCustomPaintWidth( wxPropertyGrid* propGrid, wxPGComboBo wxSize imageSize; bool res; + // TODO: Do this always when cell has custom text. + if ( property->IsValueUnspecified() ) + { + cb->SetCustomPaintWidth( 0 ); + return true; + } + if ( cmnVal >= 0 ) { // Yes, a common value is being selected @@ -835,14 +983,21 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, const wxSize& sz, long extraStyle ) const { + // Since it is not possible (yet) to create a read-only combo box in + // the same sense that wxTextCtrl is read-only, simply do not create + // the control in this case. + if ( property->HasFlag(wxPG_PROP_READONLY) ) + return NULL; + const wxPGChoices& choices = property->GetChoices(); wxString defString; int index = property->GetChoiceSelection(); - bool isUnspecified = property->IsValueUnspecified(); - - if ( !isUnspecified ) - defString = property->GetDisplayedString(); + int argFlags = 0; + if ( !property->HasFlag(wxPG_PROP_READONLY) && + !property->IsValueUnspecified() ) + argFlags |= wxPG_EDITABLE_VALUE; + defString = property->GetValueAsString(argFlags); wxArrayString labels = choices.GetLabels(); @@ -868,7 +1023,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, unsigned int cmnVals = property->GetDisplayedCommonValueCount(); if ( cmnVals ) { - if ( !isUnspecified ) + if ( !property->IsValueUnspecified() ) { int cmnVal = property->GetCommonValue(); if ( cmnVal >= 0 ) @@ -897,7 +1052,11 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, cb->SetButtonPosition(si.y,0,wxRIGHT); cb->SetMargins(wxPG_XBEFORETEXT-1); - wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, property->GetCommonValue() ); + // Set hint text + cb->SetHint(property->GetHintText()); + + wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, + property->GetCommonValue() ); if ( index >= 0 && index < (int)cb->GetCount() ) { @@ -987,6 +1146,7 @@ bool wxPGChoiceEditor::OnEvent( wxPropertyGrid* propGrid, wxPGProperty* property if ( !cb->HasFlag(wxCB_READONLY) ) { wxString unspecValueText; + unspecValueText = propGrid->GetUnspecifiedValueText(); propGrid->SetupTextCtrlValue(unspecValueText); cb->GetTextCtrl()->SetValue(unspecValueText); } @@ -1036,10 +1196,13 @@ void wxPGChoiceEditor::SetControlIntValue( wxPGProperty* WXUNUSED(property), wxW } -void wxPGChoiceEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property), wxWindow* ctrl ) const +void wxPGChoiceEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property), + wxWindow* ctrl ) const { wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl; - cb->SetSelection(-1); + + if ( cb->HasFlag(wxCB_READONLY) ) + cb->SetSelection(-1); } @@ -1125,10 +1288,11 @@ bool wxPGComboBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* } -void wxPGComboBoxEditor::OnFocus( wxPGProperty*, wxWindow* ctrl ) const +void wxPGComboBoxEditor::OnFocus( wxPGProperty* property, + wxWindow* ctrl ) const { wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl; - cb->GetTextCtrl()->SetSelection(-1,-1); + wxPGTextCtrlEditor_OnFocus(property, cb->GetTextCtrl()); } @@ -1236,12 +1400,12 @@ const int wxSCB_SETVALUE_CYCLE = 2; static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei, - int state, const wxColour& lineCol ) + int state ) { // Box rectangle. wxRect r(rect.x+wxPG_XBEFORETEXT,rect.y+((rect.height-box_hei)/2), box_hei,box_hei); - wxColour useCol = lineCol; + wxColour useCol = dc.GetTextForeground(); if ( state & wxSCB_STATE_UNSPECIFIED ) { @@ -1365,14 +1529,14 @@ void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) ) dc.SetPen( bgcol ); dc.DrawRectangle( rect ); - wxColour txcol = GetForegroundColour(); + dc.SetTextForeground(GetForegroundColour()); int state = m_state; if ( !(state & wxSCB_STATE_UNSPECIFIED) && GetFont().GetWeight() == wxBOLD ) state |= wxSCB_STATE_BOLD; - DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol); + DrawSimpleCheckBox(dc, rect, m_boxHeight, state); } void wxSimpleCheckBox::OnLeftClick( wxMouseEvent& event ) @@ -1419,6 +1583,9 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid, const wxPoint& pos, const wxSize& size ) const { + if ( property->HasFlag(wxPG_PROP_READONLY) ) + return NULL; + wxPoint pt = pos; pt.x -= wxPG_XBEFOREWIDGET; wxSize sz = size; @@ -1462,7 +1629,6 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, const wxString& WXUNUSED(text) ) const { int state = wxSCB_STATE_UNCHECKED; - wxColour rectCol = dc.GetTextForeground(); if ( !property->IsValueUnspecified() ) { @@ -1475,7 +1641,7 @@ void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, state |= wxSCB_STATE_UNSPECIFIED; } - DrawSimpleCheckBox(dc, rect, dc.GetCharHeight(), state, rectCol); + DrawSimpleCheckBox(dc, rect, dc.GetCharHeight(), state); } void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, @@ -1758,6 +1924,9 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos, tc->AutoComplete(attrVal.GetArrayString()); } + // Set hint text + tc->SetHint(prop->GetHintText()); + return tc; } @@ -1852,6 +2021,28 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrlAndButton( const wxPoint& pos, // ----------------------------------------------------------------------- +void wxPropertyGrid::SetEditorAppearance( const wxPGCell& cell, + bool unspecified ) +{ + wxPGProperty* property = GetSelection(); + if ( !property ) + return; + wxWindow* ctrl = GetEditorControl(); + if ( !ctrl ) + return; + + property->GetEditorClass()->SetControlAppearance( this, + property, + ctrl, + cell, + m_editorAppearance, + unspecified ); + + m_editorAppearance = cell; +} + +// ----------------------------------------------------------------------- + wxTextCtrl* wxPropertyGrid::GetEditorTextCtrl() const { wxWindow* wnd = GetEditorControl();