]> git.saurik.com Git - wxWidgets.git/blobdiff - src/propgrid/propgrid.cpp
Tried to improve look of toogle tool under OS X, adapted from #10346: Nicer drawing...
[wxWidgets.git] / src / propgrid / propgrid.cpp
index d356712b77a7f351ea5d9730f911bdcb68bacab5..4eaae9aedda2933c5dd66d51ca274ed5c2452f0f 100644 (file)
 
 
 //#define wxPG_TEXT_INDENT                4 // For the wxComboControl
-#define wxPG_ALLOW_CLIPPING             1 // If 1, GetUpdateRegion() in OnPaint event handler is not ignored
+//#define wxPG_ALLOW_CLIPPING             1 // If 1, GetUpdateRegion() in OnPaint event handler is not ignored
 #define wxPG_GUTTER_DIV                 3 // gutter is max(iconwidth/gutter_div,gutter_min)
 #define wxPG_GUTTER_MIN                 3 // gutter before and after image of [+] or [-]
 #define wxPG_YSPACING_MIN               1
 #define wxPG_DEFAULT_VSPACING           2 // This matches .NET propertygrid's value,
                                           // but causes normal combobox to spill out under MSW
 
-#define wxPG_OPTIMAL_WIDTH              200 // Arbitrary
+//#define wxPG_OPTIMAL_WIDTH              200 // Arbitrary
 
-#define wxPG_MIN_SCROLLBAR_WIDTH        10 // Smallest scrollbar width on any platform
+//#define wxPG_MIN_SCROLLBAR_WIDTH        10 // Smallest scrollbar width on any platform
                                            // Must be larger than largest control border
                                            // width * 2.
 
 
 //#define wxPG_NAT_CHOICE_BORDER_ANY   0
 
-#define wxPG_HIDER_BUTTON_HEIGHT        25
+//#define wxPG_HIDER_BUTTON_HEIGHT        25
 
 #define wxPG_PIXELS_PER_UNIT            m_lineHeight
 
   #define m_iconHeight m_iconWidth
 #endif
 
-#define wxPG_TOOLTIP_DELAY              1000
+//#define wxPG_TOOLTIP_DELAY              1000
 
 // -----------------------------------------------------------------------
 
@@ -462,6 +462,7 @@ void wxPropertyGrid::Init1()
     m_eventObject = this;
     m_curFocused = (wxWindow*) NULL;
     m_tlwHandler = NULL;
+    m_sortFunction = NULL;
     m_inDoPropertyChanged = 0;
     m_inCommitChangesFromEditor = 0;
     m_inDoSelectProperty = 0;
@@ -959,8 +960,6 @@ static int wxPGGetColAvg( const wxColour& col )
 
 void wxPropertyGrid::RegainColours()
 {
-    wxColour def_bgcol = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
-
     if ( !(m_coloursCustomized & 0x0002) )
     {
         wxColour col = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
@@ -1038,13 +1037,7 @@ void wxPropertyGrid::ResetColours()
 bool wxPropertyGrid::SetFont( const wxFont& font )
 {
     // Must disable active editor.
-    if ( m_selected )
-    {
-        bool selRes = ClearSelection();
-        wxPG_CHECK_MSG_DBG( selRes,
-                            false,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     // TODO: Following code is disabled with wxMac because
     //   it is reported to fail. I (JMS) cannot debug it
@@ -1176,54 +1169,6 @@ void wxPropertyGrid::SetCaptionTextColour( const wxColour& col )
     Refresh();
 }
 
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetPropertyBackgroundColour( wxPGPropArg id,
-                                                  const wxColour& colour,
-                                                  bool recursively )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-    p->SetBackgroundColour( colour, recursively );
-    DrawItemAndChildren( p );
-}
-
-// -----------------------------------------------------------------------
-
-wxColour wxPropertyGrid::GetPropertyBackgroundColour( wxPGPropArg id ) const
-{
-    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour())
-
-    return p->GetCell(0).GetBgCol();
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetPropertyTextColour( wxPGPropArg id, const wxColour& colour,
-                                            bool recursively )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-    p->SetTextColour( colour, recursively );
-    DrawItemAndChildren( p );
-}
-
-// -----------------------------------------------------------------------
-
-wxColour wxPropertyGrid::GetPropertyTextColour( wxPGPropArg id ) const
-{
-    wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxColour())
-
-    return p->GetCell(0).GetFgCol();
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::SetPropertyColoursToDefault( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    p->m_cells.clear();
-}
-
 // -----------------------------------------------------------------------
 // wxPropertyGrid property adding and removal
 // -----------------------------------------------------------------------
@@ -1378,7 +1323,7 @@ wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& sr
 
     dst_str.clear();
 
-    for ( ; i != src_str.end(); i++ )
+    for ( ; i != src_str.end(); ++i )
     {
         wxUniChar a = *i;
 
@@ -1436,7 +1381,7 @@ wxString& wxPropertyGrid::CreateEscapeSequences( wxString& dst_str, wxString& sr
 
     dst_str.clear();
 
-    for ( ; i != src_str.end(); i++ )
+    for ( ; i != src_str.end(); ++i )
     {
         wxChar a = *i;
 
@@ -1737,13 +1682,10 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
         //
         // clipRect conversion
-        if ( clipRect )
-        {
-            cr2 = *clipRect;
-            cr2.x -= xRelMod;
-            cr2.y -= yRelMod;
-            clipRect = &cr2;
-        }
+        cr2 = *clipRect;
+        cr2.x -= xRelMod;
+        cr2.y -= yRelMod;
+        clipRect = &cr2;
         firstItemTopY -= yRelMod;
         lastItemBottomY -= yRelMod;
     }
@@ -1755,7 +1697,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
 
     const wxFont& normalfont = m_font;
 
-    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) ? true : false;
+    bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0;
 
     bool isEnabled = IsEnabled();
 
@@ -1893,10 +1835,10 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
         }
         else
         {
-             renderFlags |= wxPGCellRenderer::Selected;
+            renderFlags |= wxPGCellRenderer::Selected;
 
-             if ( !p->IsCategory() )
-             {
+            if ( !p->IsCategory() )
+            {
                 renderFlags |= wxPGCellRenderer::DontUseCellFgCol |
                                wxPGCellRenderer::DontUseCellBgCol;
 
@@ -2189,11 +2131,9 @@ void wxPropertyGrid::DrawItemAndChildren( wxPGProperty* p )
     if ( m_pState->m_itemsAdded || m_frozen )
         return;
 
-    wxWindow* wndPrimary = GetEditorControl();
-
     // Update child control.
     if ( m_selected && m_selected->GetParent() == p )
-        m_selected->UpdateControl(wndPrimary);
+        RefreshEditor();
 
     const wxPGProperty* lastDrawn = p->GetLastVisibleSubItem();
 
@@ -2225,12 +2165,7 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground),
 
 void wxPropertyGrid::Clear()
 {
-    if ( m_selected )
-    {
-        bool selRes = DoSelectProperty(NULL, wxPG_SEL_DELETING);  // This must be before state clear
-        wxPG_CHECK_RET_DBG( selRes,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     m_pState->DoClear();
 
@@ -2249,8 +2184,7 @@ void wxPropertyGrid::Clear()
 
 bool wxPropertyGrid::EnableCategories( bool enable )
 {
-    if ( !ClearSelection() )
-        return false;
+    ClearSelection(false);
 
     if ( enable )
     {
@@ -2302,13 +2236,7 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
     wxPGProperty* oldSelection = m_selected;
 
-    // Deselect
-    if ( m_selected )
-    {
-        bool selRes = ClearSelection();
-        wxPG_CHECK_RET_DBG( selRes,
-                            wxT("failed to deselect a property (editor probably had invalid value)") );
-    }
+    ClearSelection(false);
 
     m_pState->m_selected = oldSelection;
 
@@ -2365,26 +2293,6 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
 // -----------------------------------------------------------------------
 
-void wxPropertyGrid::SortChildren( wxPGPropArg id )
-{
-    wxPG_PROP_ARG_CALL_PROLOG()
-
-    m_pState->SortChildren( p );
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::Sort()
-{
-    bool selRes = ClearSelection();  // This must be before state clear
-    wxPG_CHECK_RET_DBG( selRes,
-                        wxT("failed to deselect a property (editor probably had invalid value)") );
-
-    m_pState->Sort();
-}
-
-// -----------------------------------------------------------------------
-
 // Call to SetSplitterPosition will always disable splitter auto-centering
 // if parent window is shown.
 void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, int splitterIndex, bool allPages )
@@ -2461,7 +2369,7 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
 
     // Don't do this if already processing editor event. It might
     // induce recursive dialogs and crap like that.
-    if ( m_iFlags & wxPG_FL_IN_ONCUSTOMEDITOREVENT )
+    if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
     {
         if ( m_inDoPropertyChanged )
             return true;
@@ -2863,8 +2771,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
     // control.
     if ( selFlags & wxPG_SEL_DIALOGVAL )
     {
-        if ( editor )
-            p->GetEditorClass()->UpdateControl(p, editor);
+        RefreshEditor();
     }
     else
     {
@@ -2952,27 +2859,7 @@ bool wxPropertyGrid::DoEditorValidate()
 
 // -----------------------------------------------------------------------
 
-bool wxPropertyGrid::ProcessEvent(wxEvent& event)
-{
-    wxWindow* wnd = (wxWindow*) event.GetEventObject();
-    if ( wnd && wnd->IsKindOf(CLASSINFO(wxWindow)) )
-    {
-        wxWindow* parent = wnd->GetParent();
-
-        if ( parent &&
-             (parent == m_canvas ||
-              parent->GetParent() == m_canvas) )
-        {
-            OnCustomEditorEvent(event);
-            return true;
-        }
-    }
-    return wxPanel::ProcessEvent(event);
-}
-
-// -----------------------------------------------------------------------
-
-void wxPropertyGrid::OnCustomEditorEvent( wxEvent &event )
+void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
 {
     wxPGProperty* selected = m_selected;
 
@@ -2981,7 +2868,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxEvent &event )
     if ( !selected )
         return;
 
-    if ( m_iFlags & wxPG_FL_IN_ONCUSTOMEDITOREVENT )
+    if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
         return;
 
     wxVariant pendingValue(selected->GetValueRef());
@@ -3011,7 +2898,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxEvent &event )
         m_prevTcValue = newTcValue;
     }
 
-    SetInternalFlag(wxPG_FL_IN_ONCUSTOMEDITOREVENT);
+    SetInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT);
 
     bool validationFailure = false;
     bool buttonWasHandled = false;
@@ -3111,7 +2998,7 @@ void wxPropertyGrid::OnCustomEditorEvent( wxEvent &event )
         }
     }
 
-    ClearInternalFlag(wxPG_FL_IN_ONCUSTOMEDITOREVENT);
+    ClearInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT);
 }
 
 // -----------------------------------------------------------------------
@@ -3236,9 +3123,37 @@ void wxPropertyGrid::CustomSetCursor( int type, bool override )
 }
 
 // -----------------------------------------------------------------------
-// wxPropertyGrid property selection
+// wxPropertyGrid property selection, editor creation
 // -----------------------------------------------------------------------
 
+//
+// This class forwards events from property editor controls to wxPropertyGrid.
+class wxPropertyGridEditorEventForwarder : public wxEvtHandler
+{
+public:
+    wxPropertyGridEditorEventForwarder( wxPropertyGrid* propGrid )
+        : wxEvtHandler(), m_propGrid(propGrid)
+    {
+    }
+
+    virtual ~wxPropertyGridEditorEventForwarder()
+    {
+    }
+
+private:
+    bool ProcessEvent( wxEvent& event )
+    {
+        // Always skip
+        event.Skip();
+
+        m_propGrid->HandleCustomEditorEvent(event);
+
+        return wxEvtHandler::ProcessEvent(event);
+    }
+
+    wxPropertyGrid*         m_propGrid;
+};
+
 // Setups event handling for child control
 void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
 {
@@ -3266,6 +3181,10 @@ void wxPropertyGrid::SetupChildEventHandling( wxWindow* argWnd )
             NULL, this);
     }
 
+    wxPropertyGridEditorEventForwarder* forwarder;
+    forwarder = new wxPropertyGridEditorEventForwarder(this);
+    argWnd->PushEventHandler(forwarder);
+
     argWnd->Connect(id, wxEVT_KEY_DOWN,
         wxCharEventHandler(wxPropertyGrid::OnChildKeyDown),
         NULL, this);
@@ -3295,6 +3214,7 @@ void wxPropertyGrid::FreeEditors()
     // Do not free editors immediately if processing events
     if ( m_wndEditor2 )
     {
+        m_wndEditor2->PopEventHandler(true);
         m_wndEditor2->Hide();
         wxPendingDelete.Append( m_wndEditor2 );
         m_wndEditor2 = (wxWindow*) NULL;
@@ -3302,6 +3222,7 @@ void wxPropertyGrid::FreeEditors()
 
     if ( m_wndEditor )
     {
+        m_wndEditor->PopEventHandler(true);
         m_wndEditor->Hide();
         wxPendingDelete.Append( m_wndEditor );
         m_wndEditor = (wxWindow*) NULL;
@@ -3437,9 +3358,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
 
             wxASSERT( m_wndEditor == (wxWindow*) NULL );
 
-            // Do we need OnMeasureCalls?
-            wxSize imsz = p->OnMeasureImage();
-
             //
             // Only create editor for non-disabled non-caption
             if ( !p->IsCategory() && !(p->m_flags & wxPG_PROP_DISABLED) )
@@ -3698,6 +3616,31 @@ bool wxPropertyGrid::UnfocusEditor()
 
 // -----------------------------------------------------------------------
 
+void wxPropertyGrid::RefreshEditor()
+{
+    wxPGProperty* p = m_selected;
+    if ( !p ) 
+        return;
+
+    wxWindow* wnd = GetEditorControl();
+    if ( !wnd )
+        return;
+
+    // Set editor font boldness - must do this before
+    // calling UpdateControl().
+    if ( HasFlag(wxPG_BOLD_MODIFIED) )
+    {
+        if ( p->HasFlag(wxPG_PROP_MODIFIED) )
+            wnd->SetFont(GetCaptionFont());
+        else
+            wnd->SetFont(GetFont());
+    }
+
+    p->GetEditorClass()->UpdateControl(p, wnd);
+}
+
+// -----------------------------------------------------------------------
+
 // This method is not inline because it called dozens of times
 // (i.e. two-arg function calls create smaller code size).
 bool wxPropertyGrid::DoClearSelection()
@@ -3714,10 +3657,9 @@ bool wxPropertyGrid::DoCollapse( wxPGProperty* p, bool sendEvents )
     wxPGProperty* pwc = wxStaticCast(p, wxPGProperty);
 
     // If active editor was inside collapsed section, then disable it
-    if ( m_selected && m_selected->IsSomeParent (p) )
+    if ( m_selected && m_selected->IsSomeParent(p) )
     {
-        if ( !ClearSelection() )
-            return false;
+        ClearSelection(false);
     }
 
     // Store dont-center-splitter flag 'cause we need to temporarily set it
@@ -3786,7 +3728,7 @@ bool wxPropertyGrid::DoExpand( wxPGProperty* p, bool sendEvents )
     }
 
     // Clear dont-center-splitter flag if it wasn't set
-    m_iFlags = m_iFlags & ~(wxPG_FL_DONT_CENTER_SPLITTER) | old_flag;
+    m_iFlags = (m_iFlags & ~wxPG_FL_DONT_CENTER_SPLITTER) | old_flag;
 
     return res;
 }
@@ -3802,8 +3744,7 @@ bool wxPropertyGrid::DoHideProperty( wxPGProperty* p, bool hide, int flags )
          ( m_selected == p || m_selected->IsSomeParent(p) )
        )
         {
-            if ( !ClearSelection() )
-                return false;
+            ClearSelection(false);
         }
 
     m_pState->DoHideProperty(p, hide, flags);
@@ -3837,8 +3778,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
     if ( by1 != by2 )
     {
         wxString s = wxString::Format(wxT("VirtualHeight=%i, ActualVirtualHeight=%i, should match!"), by1, by2);
-        wxASSERT_MSG( false,
-                      s.c_str() );
+        wxFAIL_MSG(s.c_str());
         wxLogDebug(s);
     }
 #endif
@@ -4284,9 +4224,9 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
         int curPropHoverY = y - (y % ih);
 
         // On which item it hovers
-        if ( ( !m_propHover )
+        if ( !m_propHover
              ||
-             ( m_propHover && ( sy < m_propHoverY || sy >= (m_propHoverY+ih) ) )
+             ( sy < m_propHoverY || sy >= (m_propHoverY+ih) )
            )
         {
             // Mouse moves on another property
@@ -4398,8 +4338,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
             // (also not if we were dragging and its started
             // outside the splitter region)
 
-            if ( m_propHover &&
-                 !m_propHover->IsCategory() &&
+            if ( !m_propHover->IsCategory() &&
                  !event.Dragging() )
             {
 
@@ -4774,7 +4713,7 @@ void wxPropertyGrid::ClearActionTriggers( int action )
 {
     wxPGHashMapI2I::iterator it;
 
-    for ( it = m_actionTriggers.begin(); it != m_actionTriggers.end(); it++ )
+    for ( it = m_actionTriggers.begin(); it != m_actionTriggers.end(); ++it )
     {
         if ( it->second == action )
         {
@@ -4789,9 +4728,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
     // Handles key event when editor control is not focused.
     //
 
-    wxASSERT( !m_frozen );
-    if ( m_frozen )
-        return;
+    wxCHECK2(!m_frozen, return);
 
     // Travelsal between items, collapsing/expanding, etc.
     int keycode = event.GetKeyCode();
@@ -5232,7 +5169,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 }
                 else
                 {
-                    i++;
+                    ++i;
                     m_curPos = i;
                     return true;
                 }
@@ -5244,7 +5181,7 @@ bool wxPGStringTokenizer::HasMoreTokens()
                 prev_a = wxT('\0');
             }
         }
-        i++;
+        ++i;
     }
 
     m_curPos = str.end();
@@ -5755,7 +5692,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString
             int state = 0;
             bool labelValid = false;
 
-            for ( ; it != choicesString.end(); it++ )
+            for ( ; it != choicesString.end(); ++it )
             {
                 wxChar c = *it;