]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/editors.cpp
'Set to Unspecified' -> 'Set Value to Unspecified'
[wxWidgets.git] / src / propgrid / editors.cpp
index 6184734c484484cd1b8ce1c14d4de955853a8504..3dfbb8a12c472261d2f73abaaa87098464aa3ea9 100644 (file)
     #define wxPG_TEXTCTRL_AND_BUTTON_SPACING        4
 #else
     #define wxPG_TEXTCTRL_AND_BUTTON_SPACING        2
-#endif 
+#endif
 
 #define wxPG_BUTTON_SIZEDEC                         0
 
 #include "wx/odcombo.h"
 
-#ifdef __WXMSW__
-    #include "wx/msw/private.h"
-#endif
-
 // -----------------------------------------------------------------------
 
 #if defined(__WXMSW__)
 // for odcombo
 #ifdef __WXMAC__
 #define wxPG_CHOICEXADJUST           -3 // required because wxComboCtrl reserves 3pixels for wxTextCtrl's focus ring
-#define wxPG_CHOICEYADJUST           -3 
+#define wxPG_CHOICEYADJUST           -3
 #else
 #define wxPG_CHOICEXADJUST           0
 #define wxPG_CHOICEYADJUST           0
 #endif
 
-#define ODCB_CUST_PAINT_MARGIN               6  // Number added to image width for SetCustomPaintWidth
+// Number added to image width for SetCustomPaintWidth
+#define ODCB_CUST_PAINT_MARGIN               6
 
 // Milliseconds to wait for two mouse-ups after focus inorder
 // to trigger a double-click.
@@ -288,12 +285,7 @@ void wxPGTextCtrlEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl )
     //
     // Fix indentation, just in case (change in font boldness is one good
     // reason).
-#if defined(__WXMSW__) && !defined(__WXWINCE__)
-    ::SendMessage(GetHwndOf(tc),
-                  EM_SETMARGINS,
-                  EC_LEFTMARGIN | EC_RIGHTMARGIN,
-                  MAKELONG(0, 0));
-#endif
+    tc->SetMargins(0);
 }
 
 // Provided so that, for example, ComboBox editor can use the same code
@@ -566,7 +558,7 @@ public:
 
     wxPropertyGrid* GetGrid() const
     {
-        wxPropertyGrid* pg = wxDynamicCast(GetParent()->GetParent(),
+        wxPropertyGrid* pg = wxDynamicCast(GetParent(),
                                            wxPropertyGrid);
         wxASSERT(pg);
         return pg;
@@ -582,13 +574,16 @@ public:
         return rect.width;
     }
 
-    virtual void PositionTextCtrl( int WXUNUSED(textCtrlXAdjust),
+    virtual void PositionTextCtrl( int textCtrlXAdjust,
                                    int WXUNUSED(textCtrlYAdjust) )
     {
         wxPropertyGrid* pg = GetGrid();
+    #ifdef wxPG_TEXTCTRLXADJUST
+        textCtrlXAdjust = wxPG_TEXTCTRLXADJUST -
+                          (wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1) - 1,
+    #endif
         wxOwnerDrawnComboBox::PositionTextCtrl(
-            wxPG_TEXTCTRLXADJUST -
-            (wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1) - 1,
+            textCtrlXAdjust,
             pg->GetSpacingY() + 2
         );
     }
@@ -608,7 +603,7 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
     // Sanity check
     wxASSERT( IsKindOf(CLASSINFO(wxPropertyGrid)) );
 
-    wxPGProperty* p = m_selected;
+    wxPGProperty* p = GetSelection();
     wxString text;
 
     const wxPGChoices& choices = p->GetChoices();
@@ -668,7 +663,7 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
         if ( rect.width < 0 )
         {
             wxCoord x, y;
-            GetTextExtent(text, &x, &y, 0, 0, &m_font);
+            pCb->GetTextExtent(text, &x, &y, 0, 0);
             rect.width = cis.x + wxCC_CUSTOM_IMAGE_MARGIN1 + wxCC_CUSTOM_IMAGE_MARGIN2 + 9 + x;
         }
 
@@ -687,6 +682,9 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
     if ( pDc )
         pDc->SetBrush(*wxWHITE_BRUSH);
 
+    wxPGCellRenderer* renderer = NULL;
+    const wxPGChoiceEntry* cell = NULL;
+
     if ( rect.x >= 0 )
     {
         //
@@ -755,11 +753,13 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
 
             if ( choices.IsOk() && item >= 0 && comValIndex < 0 )
             {
-                const wxPGChoiceEntry& cell = choices.Item(item);
-                wxPGCellRenderer* renderer = wxPGGlobalVars->m_defaultRenderer;
-                int imageOffset = renderer->PreDrawCell( dc, rect, cell, renderFlags );
+                cell = &choices.Item(item);
+                renderer = wxPGGlobalVars->m_defaultRenderer;
+                int imageOffset = renderer->PreDrawCell(dc, rect, *cell,
+                                                        renderFlags );
                 if ( imageOffset )
-                    imageOffset += wxCC_CUSTOM_IMAGE_MARGIN1 + wxCC_CUSTOM_IMAGE_MARGIN2;
+                    imageOffset += wxCC_CUSTOM_IMAGE_MARGIN1 +
+                                   wxCC_CUSTOM_IMAGE_MARGIN2;
                 pt.x += imageOffset;
             }
         }
@@ -773,6 +773,9 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
         pt.x += 1;
 
         dc.DrawText( text, pt.x + wxPG_XBEFORETEXT, pt.y );
+
+        if ( renderer )
+            renderer->PostDrawCell(dc, this, *cell, renderFlags);
     }
     else
     {
@@ -791,23 +794,28 @@ bool wxPGChoiceEditor_SetCustomPaintWidth( wxPropertyGrid* propGrid, wxPGComboBo
     wxPGProperty* property = propGrid->GetSelectedProperty();
     wxASSERT( property );
 
+    wxSize imageSize;
+    bool res;
+
     if ( cmnVal >= 0 )
     {
         // Yes, a common value is being selected
         property->SetCommonValue( cmnVal );
-        wxSize imageSize = propGrid->GetCommonValue(cmnVal)->
+        imageSize = propGrid->GetCommonValue(cmnVal)->
                             GetRenderer()->GetImageSize(property, 1, cmnVal);
-        if ( imageSize.x ) imageSize.x += ODCB_CUST_PAINT_MARGIN;
-        cb->SetCustomPaintWidth( imageSize.x );
-        return false;
+        res = false;
     }
     else
     {
-        wxSize imageSize = propGrid->GetImageSize(property, -1);
-        if ( imageSize.x ) imageSize.x += ODCB_CUST_PAINT_MARGIN;
-        cb->SetCustomPaintWidth( imageSize.x );
-        return true;
+        imageSize = propGrid->GetImageSize(property, -1);
+        res = true;
     }
+
+    if ( imageSize.x )
+        imageSize.x += ODCB_CUST_PAINT_MARGIN;
+    cb->SetCustomPaintWidth( imageSize.x );
+
+    return res;
 }
 
 // CreateControls calls this with CB_READONLY in extraStyle
@@ -841,6 +849,10 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
 
     int odcbFlags = extraStyle | wxBORDER_NONE | wxTE_PROCESS_ENTER;
 
+    if ( (property->GetFlags() & wxPG_PROP_USE_DCC) &&
+         (property->IsKindOf(CLASSINFO(wxBoolProperty)) ) )
+        odcbFlags |= wxODCB_DCLICK_CYCLES;
+
     //
     // If common value specified, use appropriate index
     unsigned int cmnVals = property->GetDisplayedCommonValueCount();
@@ -873,7 +885,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
                odcbFlags);
 
     cb->SetButtonPosition(si.y,0,wxRIGHT);
-    cb->SetTextIndent(wxPG_XBEFORETEXT-1);
+    cb->SetMargins(wxPG_XBEFORETEXT-1);
 
     wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, property->GetCommonValue() );
 
@@ -962,7 +974,7 @@ bool wxPGChoiceEditor::OnEvent( wxPropertyGrid* propGrid, wxPGProperty* property
                 return false;
             }
         }
-        return wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, cmnValIndex );        
+        return wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, cmnValIndex );
     }
     return false;
 }
@@ -1333,7 +1345,7 @@ void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) )
 
     int state = m_state;
     if ( !(state & wxSCB_STATE_UNSPECIFIED) &&
-         m_font.GetWeight() == wxBOLD )
+         GetFont().GetWeight() == wxBOLD )
         state |= wxSCB_STATE_BOLD;
 
     DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol);
@@ -1373,7 +1385,7 @@ void wxSimpleCheckBox::SetValue( int value )
 
     wxCommandEvent evt(wxEVT_COMMAND_CHECKBOX_CLICKED,GetParent()->GetId());
 
-    wxPropertyGrid* propGrid = (wxPropertyGrid*) GetParent()->GetParent();
+    wxPropertyGrid* propGrid = (wxPropertyGrid*) GetParent();
     wxASSERT( propGrid->IsKindOf(CLASSINFO(wxPropertyGrid)) );
     propGrid->HandleCustomEditorEvent(evt);
 }
@@ -1409,7 +1421,7 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
                     cb->m_state |= wxSCB_STATE_CHECKED;
 
                 // Makes sure wxPG_EVT_CHANGING etc. is sent for this initial
-                // click 
+                // click
                 propGrid->ChangePropertyValue(property,
                                               wxPGVariant_Bool(cb->m_state));
             }
@@ -1498,7 +1510,7 @@ void wxPGCheckBoxEditor::SetControlIntValue( wxPGProperty* WXUNUSED(property), w
 
 void wxPGCheckBoxEditor::SetValueToUnspecified( wxPGProperty* WXUNUSED(property), wxWindow* ctrl ) const
 {
-    ((wxSimpleCheckBox*)ctrl)->m_state = 0;
+    ((wxSimpleCheckBox*)ctrl)->m_state = wxSCB_STATE_UNSPECIFIED;
     ctrl->Refresh();
 }
 
@@ -1524,9 +1536,6 @@ wxWindow* wxPropertyGrid::GetEditorControl() const
 
 void wxPropertyGrid::CorrectEditorWidgetSizeX()
 {
-    if ( m_selColumn == -1 )
-        return;
-
     int secWid = 0;
     int newSplitterx = m_pState->DoGetSplitterPosition(m_selColumn-1);
     int newWidth = newSplitterx + m_pState->m_colWidths[m_selColumn];
@@ -1569,12 +1578,9 @@ void wxPropertyGrid::CorrectEditorWidgetSizeX()
 
 void wxPropertyGrid::CorrectEditorWidgetPosY()
 {
-    if ( m_selColumn == -1 )
-        return;
-
-    if ( m_selected && (m_wndEditor || m_wndEditor2) ) 
+    if ( GetSelection() && (m_wndEditor || m_wndEditor2) )
     {
-        wxRect r = GetEditorWidgetRect(m_selected, m_selColumn);
+        wxRect r = GetEditorWidgetRect(GetSelection(), m_selColumn);
 
         if ( m_wndEditor )
         {
@@ -1599,7 +1605,9 @@ void wxPropertyGrid::CorrectEditorWidgetPosY()
 
 // Fixes position of wxTextCtrl-like control (wxSpinCtrl usually
 // fits into that category as well).
-void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl, const wxPoint& offset )
+void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl,
+                                        unsigned int WXUNUSED(forColumn),
+                                        const wxPoint& offset )
 {
     // Center the control vertically
     wxRect finalPos = ctrl->GetRect();
@@ -1612,7 +1620,14 @@ void wxPropertyGrid::FixPosForTextCtrl( wxWindow* ctrl, const wxPoint& offset )
     finalPos.y += y_adj;
     finalPos.height -= (y_adj+sz_dec);
 
-    const int textCtrlXAdjust = wxPG_TEXTCTRLXADJUST;
+#ifndef wxPG_TEXTCTRLXADJUST
+    int textCtrlXAdjust = wxPG_XBEFORETEXT - 1;
+
+    wxTextCtrl* tc = static_cast<wxTextCtrl*>(ctrl);
+    tc->SetMargins(0);
+#else
+    int textCtrlXAdjust = wxPG_TEXTCTRLXADJUST;
+#endif
 
     finalPos.x += textCtrlXAdjust;
     finalPos.width -= textCtrlXAdjust;
@@ -1630,15 +1645,16 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
                                                   const wxString& value,
                                                   wxWindow* secondary,
                                                   int extraStyle,
-                                                  int maxLen )
+                                                  int maxLen,
+                                                  unsigned int forColumn )
 {
     wxWindowID id = wxPG_SUBID1;
-    wxPGProperty* selected = m_selected;
-    wxASSERT(selected);
+    wxPGProperty* prop = GetSelection();
+    wxASSERT(prop);
 
     int tcFlags = wxTE_PROCESS_ENTER | extraStyle;
 
-    if ( selected->HasFlag(wxPG_PROP_READONLY) )
+    if ( prop->HasFlag(wxPG_PROP_READONLY) && forColumn == 1 )
         tcFlags |= wxTE_READONLY;
 
     wxPoint p(pos.x,pos.y);
@@ -1649,7 +1665,11 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
     s.x -= 8;
 #endif
 
-     // Take button into acccount
+    // For label editors, trim the size to allow better splitter grabbing
+    if ( forColumn != 1 )
+        s.x -= 2;
+
+    // Take button into acccount
     if ( secondary )
     {
         s.x -= (secondary->GetSize().x + wxPG_TEXTCTRL_AND_BUTTON_SPACING);
@@ -1674,15 +1694,31 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
 #endif
     SetupTextCtrlValue(value);
     tc->Create(ctrlParent,id,value, p, s,tcFlags);
-    
-    wxWindow* ed = tc;
+
+#if defined(__WXMSW__)
+    // On Windows, we need to override read-only text ctrl's background
+    // colour to white. One problem with native 'grey' background is that
+    // tc->GetBackgroundColour() doesn't seem to return correct value
+    // for it.
+    if ( tcFlags & wxTE_READONLY )
+    {
+        wxVisualAttributes vattrs = tc->GetDefaultAttributes();
+        tc->SetBackgroundColour(vattrs.colBg);
+    }
+#endif
 
     // Center the control vertically
     if ( !hasSpecialSize )
-        FixPosForTextCtrl(ed);
+        FixPosForTextCtrl(tc, forColumn);
+
+    if ( forColumn != 1 )
+    {
+        tc->SetBackgroundColour(m_colSelBack);
+        tc->SetForegroundColour(m_colSelFore);
+    }
 
 #ifdef __WXMSW__
-    ed->Show();
+    tc->Show();
     if ( secondary )
         secondary->Show();
 #endif
@@ -1691,7 +1727,14 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
     if ( maxLen > 0 )
         tc->SetMaxLength( maxLen );
 
-    return (wxWindow*) ed;
+    wxVariant attrVal = prop->GetAttribute(wxPG_ATTR_AUTOCOMPLETE);
+    if ( !attrVal.IsNull() )
+    {
+        wxASSERT(attrVal.GetType() == wxS("arrstring"));
+        tc->AutoComplete(attrVal.GetArrayString());
+    }
+
+    return tc;
 }
 
 // -----------------------------------------------------------------------
@@ -1699,7 +1742,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
 wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize& sz )
 {
     wxWindowID id = wxPG_SUBID2;
-    wxPGProperty* selected = m_selected;
+    wxPGProperty* selected = GetSelection();
     wxASSERT(selected);
 
 #ifdef __WXMAC__
@@ -1717,7 +1760,7 @@ wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize
    p.x = pos.x + sz.x - but->GetSize().x - 2;
    but->Move(p);
 
-#else 
+#else
     wxSize s(sz.y-(wxPG_BUTTON_SIZEDEC*2)+(wxPG_NAT_BUTTON_BORDER_Y*2),
         sz.y-(wxPG_BUTTON_SIZEDEC*2)+(wxPG_NAT_BUTTON_BORDER_Y*2));
 
@@ -1872,11 +1915,10 @@ void wxPGMultiButton::Add( const wxBitmap& bitmap, int id )
 {
     id = GenId(id);
     wxSize sz = GetSize();
-    wxButton* button = new wxBitmapButton( this, id, bitmap, wxPoint(sz.x, 0), wxSize(sz.y, sz.y) );
-    m_buttons.push_back(button);
-    int bw = button->GetSize().x;
-    SetSize(wxSize(sz.x+bw,sz.y));
-    m_buttonsWidth += bw;
+    wxButton* button = new wxBitmapButton( this, id, bitmap,
+                                           wxPoint(sz.x, 0),
+                                           wxSize(sz.y, sz.y) );
+    DoAddButton( button, sz );
 }
 #endif
 
@@ -1884,7 +1926,14 @@ void wxPGMultiButton::Add( const wxString& label, int id )
 {
     id = GenId(id);
     wxSize sz = GetSize();
-    wxButton* button = new wxButton( this, id, label, wxPoint(sz.x, 0), wxSize(sz.y, sz.y) );
+    wxButton* button = new wxButton( this, id, label, wxPoint(sz.x, 0),
+                                     wxSize(sz.y, sz.y) );
+    DoAddButton( button, sz );
+}
+
+void wxPGMultiButton::DoAddButton( wxWindow* button,
+                                   const wxSize& sz )
+{
     m_buttons.push_back(button);
     int bw = button->GetSize().x;
     SetSize(wxSize(sz.x+bw,sz.y));