]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/editors.cpp
Added wxInfoBar::AddButton().
[wxWidgets.git] / src / propgrid / editors.cpp
index 1eddd98fb4e38e87d6a4f4394b8291acd4127c3f..12fa961484ed264398814d1d9d237ccd22cf68fd 100644 (file)
 
 // How many pixels between textctrl and button
 #ifdef __WXMAC__
-    #define wxPG_TEXTCTRL_AND_BUTTON_SPACING        8
+    #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__)
     #define wxPG_NAT_BUTTON_BORDER_X        0
     #define wxPG_NAT_BUTTON_BORDER_Y        0
 
-    #define wxPG_TEXTCTRLYADJUST            3
+    #define wxPG_TEXTCTRLYADJUST            0
 
 #else
     // defaults
 #endif
 
 // for odcombo
+#ifdef __WXMAC__
+#define wxPG_CHOICEXADJUST           -3 // required because wxComboCtrl reserves 3pixels for wxTextCtrl's focus ring
+#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.
@@ -228,17 +230,18 @@ wxPGWindowList wxPGTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid,
     // If has children, and limited editing is specified, then don't create.
     if ( (property->GetFlags() & wxPG_PROP_NOEDITOR) &&
          property->GetChildCount() )
-        return (wxWindow*) NULL;
+        return NULL;
 
     if ( !property->IsValueUnspecified() )
-        text = property->GetValueString(property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE);
+        text = property->GetValueAsString(property->HasFlag(wxPG_PROP_READONLY) ?
+                                            0 : wxPG_EDITABLE_VALUE);
 
     int flags = 0;
     if ( (property->GetFlags() & wxPG_PROP_PASSWORD) &&
          property->IsKindOf(CLASSINFO(wxStringProperty)) )
         flags |= wxTE_PASSWORD;
 
-    wxWindow* wnd = propGrid->GenerateEditorTextCtrl(pos,sz,text,(wxWindow*)NULL,flags,
+    wxWindow* wnd = propGrid->GenerateEditorTextCtrl(pos,sz,text,NULL,flags,
                                                      property->GetMaxLength());
 
     return wnd;
@@ -277,9 +280,13 @@ void wxPGTextCtrlEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl )
     else
         s = property->GetDisplayedString();
 
-    tc->SetValue(s);    
-}
+    tc->SetValue(s);
 
+    //
+    // Fix indentation, just in case (change in font boldness is one good
+    // reason).
+    tc->SetMargins(0);
+}
 
 // Provided so that, for example, ComboBox editor can use the same code
 // (multiple inheritance would get way too messy).
@@ -488,7 +495,7 @@ public:
     wxPGComboBox()
         : wxOwnerDrawnComboBox()
     {
-        m_dclickProcessor = (wxPGDoubleClickProcessor*) NULL;
+        m_dclickProcessor = NULL;
         m_sizeEventCalled = false;
     }
 
@@ -522,31 +529,37 @@ public:
                                             name ) )
             return false;
 
-        m_dclickProcessor = new wxPGDoubleClickProcessor(this, GetGrid()->GetSelection() );
+        m_dclickProcessor = new
+            wxPGDoubleClickProcessor( this, GetGrid()->GetSelection() );
 
         PushEventHandler(m_dclickProcessor);
 
         return true;
     }
 
-    virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const
+    virtual void OnDrawItem( wxDC& dc,
+                             const wxRect& rect,
+                             int item,
+                             int flags ) const
     {
         wxPropertyGrid* pg = GetGrid();
-        pg->OnComboItemPaint((wxPGCustomComboControl*)this,item,dc,(wxRect&)rect,flags);
+        pg->OnComboItemPaint( this, item, &dc, (wxRect&)rect, flags );
     }
+
     virtual wxCoord OnMeasureItem( size_t item ) const
     {
         wxPropertyGrid* pg = GetGrid();
         wxRect rect;
         rect.x = -1;
         rect.width = 0;
-        pg->OnComboItemPaint((wxPGCustomComboControl*)this,item,*((wxDC*)NULL),rect,0);
+        pg->OnComboItemPaint( this, item, NULL, rect, 0 );
         return rect.height;
     }
 
     wxPropertyGrid* GetGrid() const
     {
-        wxPropertyGrid* pg = wxDynamicCast(GetParent()->GetParent(),wxPropertyGrid);
+        wxPropertyGrid* pg = wxDynamicCast(GetParent()->GetParent(),
+                                           wxPropertyGrid);
         wxASSERT(pg);
         return pg;
     }
@@ -557,15 +570,20 @@ public:
         wxRect rect;
         rect.x = -1;
         rect.width = -1;
-        pg->OnComboItemPaint((wxPGCustomComboControl*)this,item,*((wxDC*)NULL),rect,0);
+        pg->OnComboItemPaint( this, item, NULL, rect, 0 );
         return rect.width;
     }
 
-    virtual void PositionTextCtrl( int WXUNUSED(textCtrlXAdjust), int WXUNUSED(textCtrlYAdjust) )
+    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
         );
     }
@@ -576,18 +594,16 @@ private:
 };
 
 
-void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
+void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb,
                                        int item,
-                                       wxDC& dc,
+                                       wxDC* pDc,
                                        wxRect& rect,
                                        int flags )
 {
-    wxPGComboBox* pCb = (wxPGComboBox*)pCc;
-
     // Sanity check
     wxASSERT( IsKindOf(CLASSINFO(wxPropertyGrid)) );
 
-    wxPGProperty* p = m_selected;
+    wxPGProperty* p = GetSelection();
     wxString text;
 
     const wxPGChoices& choices = p->GetChoices();
@@ -615,7 +631,7 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
         else
         {
             if ( !p->IsValueUnspecified() )
-                text = p->GetValueString(0);
+                text = p->GetValueAsString(0);
         }
     }
 
@@ -647,7 +663,7 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
         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;
         }
 
@@ -663,21 +679,24 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
     if ( (flags & wxODCB_PAINTING_CONTROL) )
         paintdata.m_choiceItem = -1;
 
-    if ( &dc )
-        dc.SetBrush(*wxWHITE_BRUSH);
+    if ( pDc )
+        pDc->SetBrush(*wxWHITE_BRUSH);
 
     if ( rect.x >= 0 )
     {
         //
         // DrawItem call
+        wxDC& dc = *pDc;
 
         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;
+        else
+            renderFlags |= wxPGCellRenderer::ChoicePopup;
 
         if ( flags & wxODCB_PAINTING_SELECTED )
             renderFlags |= wxPGCellRenderer::Selected;
@@ -754,6 +773,7 @@ void wxPropertyGrid::OnComboItemPaint( wxPGCustomComboControl* pCc,
     {
         //
         // MeasureItem call
+        wxDC& dc = *pDc;
 
         p->OnCustomPaint( dc, rect, paintdata );
         rect.height = paintdata.m_drawnHeight + 2;
@@ -766,23 +786,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
@@ -816,6 +841,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();
@@ -848,7 +877,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() );
 
@@ -863,15 +892,6 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid,
     else
         cb->SetSelection( -1 );
 
-    // Connect event handling
-    wxWindowID id = cb->GetId();
-    propGrid->Connect(id, wxEVT_COMMAND_COMBOBOX_SELECTED,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-    propGrid->Connect(id, wxEVT_COMMAND_TEXT_UPDATED,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-    propGrid->Connect(id, wxEVT_COMMAND_TEXT_ENTER,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-
 #ifdef __WXMSW__
     cb->Show();
 #endif
@@ -946,7 +966,7 @@ bool wxPGChoiceEditor::OnEvent( wxPropertyGrid* propGrid, wxPGProperty* property
                 return false;
             }
         }
-        return wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, cmnValIndex );        
+        return wxPGChoiceEditor_SetCustomPaintWidth( propGrid, cb, cmnValIndex );
     }
     return false;
 }
@@ -1015,7 +1035,7 @@ WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(ComboBox,
 void wxPGComboBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const
 {
     wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl;
-    cb->SetValue(property->GetValueString(wxPG_EDITABLE_VALUE));
+    cb->SetValue(property->GetValueAsString(wxPG_EDITABLE_VALUE));
 
     // TODO: If string matches any selection, then select that.
 }
@@ -1035,8 +1055,8 @@ bool wxPGComboBoxEditor::OnEvent( wxPropertyGrid* propGrid,
                                   wxWindow* ctrl,
                                   wxEvent& event ) const
 {
-    wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*) NULL;
-    wxWindow* textCtrl = (wxWindow*) NULL;
+    wxOwnerDrawnComboBox* cb = NULL;
+    wxWindow* textCtrl = NULL;
 
     if ( ctrl )
     {
@@ -1171,17 +1191,34 @@ WX_PG_IMPLEMENT_INTERNAL_EDITOR_CLASS(CheckBox,
                                       wxPGEditor)
 
 
-// state argument: 0x01 = set if checked
-//                 0x02 = set if rectangle should be bold
-static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei, int state, const wxColour& linecol )
+// Check box state flags
+enum
 {
+    wxSCB_STATE_UNCHECKED   = 0,
+    wxSCB_STATE_CHECKED     = 1,
+    wxSCB_STATE_BOLD        = 2,
+    wxSCB_STATE_UNSPECIFIED = 4
+};
+
+const int wxSCB_SETVALUE_CYCLE = 2;
+
 
+static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei,
+                                int state, const wxColour& lineCol )
+{
     // Box rectangle.
-    wxRect r(rect.x+wxPG_XBEFORETEXT,rect.y+((rect.height-box_hei)/2),box_hei,box_hei);
+    wxRect r(rect.x+wxPG_XBEFORETEXT,rect.y+((rect.height-box_hei)/2),
+             box_hei,box_hei);
+    wxColour useCol = lineCol;
+
+    if ( state & wxSCB_STATE_UNSPECIFIED )
+    {
+        useCol = wxColour(220, 220, 220);
+    }
 
     // Draw check mark first because it is likely to overdraw the
     // surrounding rectangle.
-    if ( state & 1 )
+    if ( state & wxSCB_STATE_CHECKED )
     {
         wxRect r2(r.x+wxPG_CHECKMARK_XADJ,
                   r.y+wxPG_CHECKMARK_YADJ,
@@ -1195,18 +1232,17 @@ static void DrawSimpleCheckBox( wxDC& dc, const wxRect& rect, int box_hei, int s
         // This would draw a simple cross check mark.
         // dc.DrawLine(r.x,r.y,r.x+r.width-1,r.y+r.height-1);
         // dc.DrawLine(r.x,r.y+r.height-1,r.x+r.width-1,r.y);
-
     }
 
-    if ( !(state & 2) )
+    if ( !(state & wxSCB_STATE_BOLD) )
     {
         // Pen for thin rectangle.
-        dc.SetPen(linecol);
+        dc.SetPen(useCol);
     }
     else
     {
         // Pen for bold rectangle.
-        wxPen linepen(linecol,2,wxSOLID);
+        wxPen linepen(useCol,2,wxSOLID);
         linepen.SetJoin(wxJOIN_MITER); // This prevents round edges.
         dc.SetPen(linepen);
         r.x++;
@@ -1240,39 +1276,98 @@ public:
         SetFont( parent->GetFont() );
 
         m_state = 0;
-        wxPropertyGrid* pg = (wxPropertyGrid*) parent->GetParent();
-        wxASSERT( pg->IsKindOf(CLASSINFO(wxPropertyGrid)) );
-        m_boxHeight = pg->GetFontHeight();
-        SetBackgroundStyle( wxBG_STYLE_COLOUR );
+        m_boxHeight = 12;
+
+        SetBackgroundStyle( wxBG_STYLE_CUSTOM );
     }
 
     virtual ~wxSimpleCheckBox();
 
-    virtual bool ProcessEvent(wxEvent& event);
-
     int m_state;
     int m_boxHeight;
 
+private:
+    void OnPaint( wxPaintEvent& event );
+    void OnLeftClick( wxMouseEvent& event );
+    void OnKeyDown( wxKeyEvent& event );
+
+    void OnResize( wxSizeEvent& event )
+    {
+        Refresh();
+        event.Skip();
+    }
+
     static wxBitmap* ms_doubleBuffer;
 
+    DECLARE_EVENT_TABLE()
 };
 
+BEGIN_EVENT_TABLE(wxSimpleCheckBox, wxControl)
+    EVT_PAINT(wxSimpleCheckBox::OnPaint)
+    EVT_LEFT_DOWN(wxSimpleCheckBox::OnLeftClick)
+    EVT_LEFT_DCLICK(wxSimpleCheckBox::OnLeftClick)
+    EVT_KEY_DOWN(wxSimpleCheckBox::OnKeyDown)
+    EVT_SIZE(wxSimpleCheckBox::OnResize)
+END_EVENT_TABLE()
+
 wxSimpleCheckBox::~wxSimpleCheckBox()
 {
     delete ms_doubleBuffer;
     ms_doubleBuffer = NULL;
 }
 
+wxBitmap* wxSimpleCheckBox::ms_doubleBuffer = NULL;
+
+void wxSimpleCheckBox::OnPaint( wxPaintEvent& WXUNUSED(event) )
+{
+    wxSize clientSize = GetClientSize();
+    wxAutoBufferedPaintDC dc(this);
+
+    dc.Clear();
+    wxRect rect(0,0,clientSize.x,clientSize.y);
+    rect.y += 1;
+    rect.width += 1;
+
+    wxColour bgcol = GetBackgroundColour();
+    dc.SetBrush( bgcol );
+    dc.SetPen( bgcol );
+    dc.DrawRectangle( rect );
+
+    wxColour txcol = GetForegroundColour();
+
+    int state = m_state;
+    if ( !(state & wxSCB_STATE_UNSPECIFIED) &&
+         GetFont().GetWeight() == wxBOLD )
+        state |= wxSCB_STATE_BOLD;
+
+    DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol);
+}
+
+void wxSimpleCheckBox::OnLeftClick( wxMouseEvent& event )
+{
+    if ( (event.m_x > (wxPG_XBEFORETEXT-2)) &&
+         (event.m_x <= (wxPG_XBEFORETEXT-2+m_boxHeight)) )
+    {
+        SetValue(wxSCB_SETVALUE_CYCLE);
+    }
+}
 
-wxBitmap* wxSimpleCheckBox::ms_doubleBuffer = (wxBitmap*) NULL;
+void wxSimpleCheckBox::OnKeyDown( wxKeyEvent& event )
+{
+    if ( event.GetKeyCode() == WXK_SPACE )
+    {
+        SetValue(wxSCB_SETVALUE_CYCLE);
+    }
+}
 
-// value = 2 means toggle (sorry, too lazy to do constants)
 void wxSimpleCheckBox::SetValue( int value )
 {
-    if ( value > 1 )
+    if ( value == wxSCB_SETVALUE_CYCLE )
     {
-        m_state++;
-        if ( m_state > 1 ) m_state = 0;
+        if ( m_state & wxSCB_STATE_CHECKED )
+            m_state &= ~wxSCB_STATE_CHECKED;
+        else
+            m_state |= wxSCB_STATE_CHECKED;
     }
     else
     {
@@ -1284,95 +1379,9 @@ void wxSimpleCheckBox::SetValue( int value )
 
     wxPropertyGrid* propGrid = (wxPropertyGrid*) GetParent()->GetParent();
     wxASSERT( propGrid->IsKindOf(CLASSINFO(wxPropertyGrid)) );
-    propGrid->OnCustomEditorEvent(evt);
-}
-
-
-bool wxSimpleCheckBox::ProcessEvent(wxEvent& event)
-{
-    wxPropertyGrid* propGrid = (wxPropertyGrid*) GetParent()->GetParent();
-    wxASSERT( propGrid->IsKindOf(CLASSINFO(wxPropertyGrid)) );
-
-    if ( ( (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK)
-          && ((wxMouseEvent&)event).m_x > (wxPG_XBEFORETEXT-2)
-          && ((wxMouseEvent&)event).m_x <= (wxPG_XBEFORETEXT-2+m_boxHeight) )
-       )
-    {
-        SetValue(2);
-        return true;
-    }
-    else if ( event.GetEventType() == wxEVT_PAINT )
-    {
-        wxSize clientSize = GetClientSize();
-        wxPaintDC dc(this);
-
-        /*
-        // Buffered paint DC doesn't seem to do much good
-        if ( !ms_doubleBuffer ||
-             clientSize.x > ms_doubleBuffer->GetWidth() ||
-             clientSize.y > ms_doubleBuffer->GetHeight() )
-        {
-            delete ms_doubleBuffer;
-            ms_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
-        }
-
-        wxBufferedPaintDC dc(this,*ms_doubleBuffer);
-        */
-
-        wxRect rect(0,0,clientSize.x,clientSize.y);
-        //rect.x -= 1;
-        rect.y += 1;
-        rect.width += 1;
-
-        m_boxHeight = propGrid->GetFontHeight();
-
-        wxColour bgcol = GetBackgroundColour();
-        dc.SetBrush( bgcol );
-        dc.SetPen( bgcol );
-        dc.DrawRectangle( rect );
-
-        wxColour txcol = GetForegroundColour();
-
-        int state = m_state;
-        if ( m_font.GetWeight() == wxBOLD )
-            state |= 2;
-
-        DrawSimpleCheckBox(dc,rect,m_boxHeight,state,txcol);
-
-        // If focused, indicate it somehow.
-        /*
-        if ( wxWindow::FindFocus() == this )
-        {
-            rect.x += 1;
-            rect.width -= 1;
-
-            wxPGDrawFocusRect(dc,rect);
-        }
-        */
-
-        return true;
-    }
-    else if ( event.GetEventType() == wxEVT_SIZE ||
-              event.GetEventType() == wxEVT_SET_FOCUS ||
-              event.GetEventType() == wxEVT_KILL_FOCUS
-            )
-    {
-        Refresh();
-    }
-    else if ( event.GetEventType() == wxEVT_KEY_DOWN )
-    {
-        wxKeyEvent& keyEv = (wxKeyEvent&) event;
-
-        if ( keyEv.GetKeyCode() == WXK_SPACE )
-        {
-            SetValue(2);
-            return true;
-        }
-    }
-    return wxControl::ProcessEvent(event);
+    propGrid->HandleCustomEditorEvent(evt);
 }
 
-
 wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
                                                    wxPGProperty* property,
                                                    const wxPoint& pos,
@@ -1383,35 +1392,31 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
     wxSize sz = size;
     sz.x = propGrid->GetFontHeight() + (wxPG_XBEFOREWIDGET*2) + 4;
 
-    wxSimpleCheckBox* cb = new wxSimpleCheckBox(propGrid->GetPanel(),wxPG_SUBID1,pt,sz);
+    wxSimpleCheckBox* cb = new wxSimpleCheckBox(propGrid->GetPanel(),
+                                                wxPG_SUBID1, pt, sz);
 
     cb->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
 
-    cb->Connect( wxPG_SUBID1, wxEVT_LEFT_DOWN,
-            (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
-            &wxPropertyGrid::OnCustomEditorEvent, NULL, propGrid );
-
-    cb->Connect( wxPG_SUBID1, wxEVT_LEFT_DCLICK,
-            (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction)
-            &wxPropertyGrid::OnCustomEditorEvent, NULL, propGrid );
-
-    if ( property->GetChoiceSelection() > 0 &&
-         !property->IsValueUnspecified() )
-        cb->m_state = 1;
+    UpdateControl(property, cb);
 
-    // If mouse cursor was on the item, toggle the value now.
-    if ( propGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
+    if ( !property->IsValueUnspecified() )
     {
-        wxPoint pt = cb->ScreenToClient(::wxGetMousePosition());
-        if ( pt.x <= (wxPG_XBEFORETEXT-2+cb->m_boxHeight) )
+        // If mouse cursor was on the item, toggle the value now.
+        if ( propGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
         {
-            cb->m_state++;
-
-            if ( cb->m_state > 1 )
-                cb->m_state = 0;
-
-            // Makes sure wxPG_EVT_CHANGING etc. is sent for this initial click 
-            propGrid->ChangePropertyValue(property, wxPGVariant_Bool(cb->m_state));
+            wxPoint pt = cb->ScreenToClient(::wxGetMousePosition());
+            if ( pt.x <= (wxPG_XBEFORETEXT-2+cb->m_boxHeight) )
+            {
+                if ( cb->m_state & wxSCB_STATE_CHECKED )
+                    cb->m_state &= ~wxSCB_STATE_CHECKED;
+                else
+                    cb->m_state |= wxSCB_STATE_CHECKED;
+
+                // Makes sure wxPG_EVT_CHANGING etc. is sent for this initial
+                // click
+                propGrid->ChangePropertyValue(property,
+                                              wxPGVariant_Bool(cb->m_state));
+            }
         }
     }
 
@@ -1420,53 +1425,43 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid,
     return cb;
 }
 
-/*
-class wxPGCheckBoxRenderer : public wxPGDefaultRenderer
+void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect,
+                                    wxPGProperty* property,
+                                    const wxString& WXUNUSED(text) ) const
 {
-public:
+    int state = wxSCB_STATE_UNCHECKED;
+    wxColour rectCol = dc.GetTextForeground();
 
-    virtual void Render( wxDC& dc, const wxRect& rect,
-                         const wxPropertyGrid* WXUNUSED(propertyGrid), wxPGProperty* property,
-                         int WXUNUSED(column), int WXUNUSED(item), int WXUNUSED(flags) ) const
+    if ( !property->IsValueUnspecified() )
     {
-        int state = 0;
-        if ( !(property->GetFlags() & wxPG_PROP_UNSPECIFIED) )
-        {
-            state = ((wxPGProperty*)property)->GetChoiceInfo((wxPGChoiceInfo*)NULL);
-            if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2;
-        }
-        DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground());
+        state = property->GetChoiceSelection();
+        if ( dc.GetFont().GetWeight() == wxBOLD )
+            state |= wxSCB_STATE_BOLD;
+    }
+    else
+    {
+        state |= wxSCB_STATE_UNSPECIFIED;
     }
 
-protected:
-};
-
-wxPGCheckBoxRenderer g_wxPGCheckBoxRenderer;
-
-wxPGCellRenderer* wxPGCheckBoxEditor::GetCellRenderer() const
-{
-    return &g_wxPGCheckBoxRenderer;
+    DrawSimpleCheckBox(dc, rect, dc.GetCharHeight(), state, rectCol);
 }
-*/
 
-void wxPGCheckBoxEditor::DrawValue( wxDC& dc, const wxRect& rect, wxPGProperty* property, const wxString& WXUNUSED(text) ) const
+void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property,
+                                        wxWindow* ctrl ) const
 {
-    int state = 0;
+    wxSimpleCheckBox* cb = (wxSimpleCheckBox*) ctrl;
+    wxASSERT( cb );
+
     if ( !property->IsValueUnspecified() )
-    {
-        state = property->GetChoiceSelection();
-        if ( dc.GetFont().GetWeight() == wxBOLD ) state |= 2;
-    }
-    DrawSimpleCheckBox(dc,rect,dc.GetCharHeight(),state,dc.GetTextForeground());
-}
+        cb->m_state = property->GetChoiceSelection();
+    else
+        cb->m_state = wxSCB_STATE_UNSPECIFIED;
 
-void wxPGCheckBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) const
-{
-    wxASSERT( ctrl );
-    ((wxSimpleCheckBox*)ctrl)->m_state = property->GetChoiceSelection();
-    ctrl->Refresh();
-}
+    wxPropertyGrid* propGrid = property->GetGrid();
+    cb->m_boxHeight = propGrid->GetFontHeight();
 
+    cb->Refresh();
+}
 
 bool wxPGCheckBoxEditor::OnEvent( wxPropertyGrid* WXUNUSED(propGrid), wxPGProperty* WXUNUSED(property),
     wxWindow* WXUNUSED(ctrl), wxEvent& event ) const
@@ -1533,9 +1528,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];
@@ -1578,9 +1570,9 @@ void wxPropertyGrid::CorrectEditorWidgetSizeX()
 
 void wxPropertyGrid::CorrectEditorWidgetPosY()
 {
-    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 )
         {
@@ -1605,7 +1597,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();
@@ -1618,7 +1612,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;
@@ -1636,15 +1637,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);
@@ -1652,10 +1654,14 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
 
    // Need to reduce width of text control on Mac
 #if defined(__WXMAC__)
-   s.x -= 8;
+    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);
@@ -1681,14 +1687,18 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
     SetupTextCtrlValue(value);
     tc->Create(ctrlParent,id,value, p, s,tcFlags);
 
-    wxWindow* ed = tc;
-
     // 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
@@ -1697,14 +1707,14 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos,
     if ( maxLen > 0 )
         tc->SetMaxLength( maxLen );
 
-    // Connect event handling
-    id = ed->GetId();
-    this->Connect(id, wxEVT_COMMAND_TEXT_UPDATED,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-    this->Connect(id, wxEVT_COMMAND_TEXT_ENTER,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
+    wxVariant attrVal = prop->GetAttribute(wxPG_ATTR_AUTOCOMPLETE);
+    if ( !attrVal.IsNull() )
+    {
+        wxASSERT(attrVal.GetType() == wxS("arrstring"));
+        tc->AutoComplete(attrVal.GetArrayString());
+    }
 
-    return (wxWindow*) ed;
+    return tc;
 }
 
 // -----------------------------------------------------------------------
@@ -1712,7 +1722,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__
@@ -1730,7 +1740,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));
 
@@ -1765,11 +1775,6 @@ wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize
     if ( selected->HasFlag(wxPG_PROP_READONLY) )
         but->Disable();
 
-    // Connect event handling
-    id = but->GetId();
-    this->Connect(id, wxEVT_COMMAND_BUTTON_CLICKED,
-        wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-
     return but;
 }
 
@@ -1790,13 +1795,13 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrlAndButton( const wxPoint& pos,
         // There is button Show in GenerateEditorTextCtrl as well
         but->Show();
     #endif
-        return (wxWindow*) NULL;
+        return NULL;
     }
 
     wxString text;
 
     if ( !property->IsValueUnspecified() )
-        text = property->GetValueString(property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE);
+        text = property->GetValueAsString(property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE);
 
     return GenerateEditorTextCtrl(pos,sz,text,but,property->m_maxLen);
 }
@@ -1867,17 +1872,10 @@ wxPGMultiButton::wxPGMultiButton( wxPropertyGrid* pg, const wxSize& sz )
     SetBackgroundColour(pg->GetCellBackgroundColour());
 }
 
-void wxPGMultiButton::Finalize( wxPropertyGrid* propGrid, const wxPoint& pos )
+void wxPGMultiButton::Finalize( wxPropertyGrid* WXUNUSED(propGrid),
+                                const wxPoint& pos )
 {
     Move( pos.x + m_fullEditorSize.x - m_buttonsWidth, pos.y );
-
-    // Connect event handling
-    for ( int i=0; i<GetCount(); i++ )
-    {
-        wxWindowID id = GetButtonId(i);
-        propGrid->Connect(id, wxEVT_COMMAND_BUTTON_CLICKED,
-            wxCommandEventHandler(wxPropertyGrid::OnCustomEditorEvent));
-    }
 }
 
 int wxPGMultiButton::GenId( int id ) const
@@ -1897,11 +1895,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
 
@@ -1909,7 +1906,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));