X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e005ad1fdc1ce9bdc8b4339f1d58a32e9d9e761..525454303e200c514b6c1078284b86fb73572852:/src/propgrid/propgrid.cpp diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 3b9837b602..67959fbb7a 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -348,6 +348,7 @@ void wxPropertyGrid::Init1() m_eventObject = this; m_curFocused = NULL; m_processedEvent = NULL; + m_tlp = NULL; m_sortFunction = NULL; m_inDoPropertyChanged = false; m_inCommitChangesFromEditor = false; @@ -375,9 +376,7 @@ void wxPropertyGrid::Init1() m_coloursCustomized = 0; m_frozen = 0; -#if wxPG_DOUBLE_BUFFER m_doubleBuffer = NULL; -#endif #ifndef wxPG_ICON_WIDTH m_expandbmp = NULL; @@ -467,7 +466,6 @@ void wxPropertyGrid::Init2() SetBackgroundStyle( wxBG_STYLE_CUSTOM ); // Hook the top-level parent - m_tlp = NULL; m_tlpClosed = NULL; m_tlpClosedTime = 0; @@ -544,10 +542,8 @@ wxPropertyGrid::~wxPropertyGrid() wxS("Close(false).)") ); } -#if wxPG_DOUBLE_BUFFER if ( m_doubleBuffer ) delete m_doubleBuffer; -#endif if ( m_iFlags & wxPG_FL_CREATEDSTATE ) delete m_pState; @@ -672,9 +668,7 @@ void wxPropertyGrid::Thaw() { wxControl::Thaw(); RecalculateVirtualSize(); - #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT Refresh(); - #endif // Force property re-selection // NB: We must copy the selection. @@ -1127,9 +1121,7 @@ void wxPropertyGrid::SetExtraStyle( long exStyle ) } else { - #if wxPG_DOUBLE_BUFFER wxDELETE(m_doubleBuffer); - #endif } } @@ -1688,7 +1680,7 @@ wxPoint wxPropertyGrid::GetGoodEditorDialogPosition( wxPGProperty* p, wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& src_str ) { - if ( src_str.length() == 0 ) + if ( src_str.empty() ) { dst_str = src_str; return src_str; @@ -1747,7 +1739,7 @@ wxString& wxPropertyGrid::ExpandEscapeSequences( wxString& dst_str, wxString& sr wxString& wxPropertyGrid::CreateEscapeSequences( wxString& dst_str, wxString& src_str ) { - if ( src_str.length() == 0 ) + if ( src_str.empty() ) { dst_str = src_str; return src_str; @@ -1965,7 +1957,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc, wxDC* dcPtr = &dc; bool isBuffered = false; - #if wxPG_DOUBLE_BUFFER wxMemoryDC* bufferDC = NULL; if ( !(GetExtraStyle() & wxPG_EX_NATIVE_DOUBLE_BUFFERING) ) @@ -1986,7 +1977,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc, isBuffered = true; } } - #endif if ( dcPtr ) { @@ -2005,7 +1995,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc, } } - #if wxPG_DOUBLE_BUFFER if ( bufferDC ) { dc.Blit( drawRect.x, drawRect.y, drawRect.width, @@ -2013,7 +2002,6 @@ void wxPropertyGrid::DrawItems( wxDC& dc, bufferDC, 0, 0, wxCOPY ); delete bufferDC; } - #endif } else { @@ -2085,10 +2073,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, int xRelMod = 0; // - // With wxPG_DOUBLE_BUFFER, do double buffering + // For now, do some manual calculation for double buffering // - buffer's y = 0, so align itemsRect and coordinates to that // -#if wxPG_DOUBLE_BUFFER + // TODO: In future use wxAutoBufferedPaintDC (for example) + // int yRelMod = 0; wxRect cr2; @@ -2107,9 +2096,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, firstItemTopY -= yRelMod; lastItemBottomY -= yRelMod; } -#else - wxUnusedVar(isBuffered); -#endif int x = m_marginWidth - xRelMod; @@ -2151,10 +2137,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, const wxPropertyGridPageState* state = m_pState; const wxArrayInt& colWidths = state->m_colWidths; -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT - bool wasSelectedPainted = false; -#endif - // TODO: Only render columns that are within clipping region. dc.SetFont(normalFont); @@ -2282,11 +2264,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, } else { -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT - if ( p == firstSelected ) - wasSelectedPainted = true; -#endif - renderFlags |= wxPGCellRenderer::Selected; if ( !p->IsCategory() ) @@ -2523,18 +2500,6 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, y += rowHeight; } - // Refresh editor controls (seems not needed on msw) - // NOTE: This code is mandatory for GTK! -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT - if ( wasSelectedPainted ) - { - if ( m_wndEditor ) - m_wndEditor->Refresh(); - if ( m_wndEditor2 ) - m_wndEditor2->Refresh(); - } -#endif - return y; } @@ -2554,7 +2519,7 @@ wxRect wxPropertyGrid::GetPropertyRect( const wxPGProperty* p1, const wxPGProper // // Return rect which encloses the given property range // (in logical grid coordinates) - // + // int visTop = p1->GetY(); int visBottom; @@ -2612,7 +2577,7 @@ void wxPropertyGrid::DrawItems( const wxPGProperty* p1, const wxPGProperty* p2 ) void wxPropertyGrid::RefreshProperty( wxPGProperty* p ) { - if ( m_pState->DoIsPropertySelected(p) ) + if ( m_pState->DoIsPropertySelected(p) || p->IsChildSelected(true) ) { // NB: We must copy the selection. wxArrayPGProperty selection = m_pState->m_selection; @@ -2674,7 +2639,7 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground), wxWindow::Refresh(false, rect); -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT +#if wxPG_REFRESH_CONTROLS // I think this really helps only GTK+1.2 if ( m_wndEditor ) m_wndEditor->Refresh(); if ( m_wndEditor2 ) m_wndEditor2->Refresh(); @@ -3162,7 +3127,7 @@ wxStatusBar* wxPropertyGrid::GetStatusBar() void wxPropertyGrid::DoShowPropertyError( wxPGProperty* WXUNUSED(property), const wxString& msg ) { - if ( !msg.length() ) + if ( msg.empty() ) return; #if wxUSE_STATUSBAR @@ -3290,7 +3255,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W { wxString msg = m_validationInfo.m_failureMessage; - if ( !msg.length() ) + if ( msg.empty() ) msg = _("You have entered invalid value. Press ESC to cancel editing."); #if wxUSE_STATUSBAR @@ -3441,7 +3406,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags ) } else { -#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT +#if wxPG_REFRESH_CONTROLS if ( m_wndEditor ) m_wndEditor->Refresh(); if ( m_wndEditor2 ) m_wndEditor2->Refresh(); #endif @@ -3542,13 +3507,19 @@ bool wxPropertyGrid::DoEditorValidate() // ----------------------------------------------------------------------- -void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) +bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) { + // + // NB: We should return true if the event was recognized as + // a dedicated wxPropertyGrid event, and as such was + // either properly handled or ignored. + // + // It is possible that this handler receives event even before // the control has been properly initialized. Let's skip the // event handling in that case. if ( !m_pState ) - return; + return false; // Don't care about the event if it originated from the // 'label editor'. In this function we only care about the @@ -3556,7 +3527,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) if ( m_labelEditor && event.GetId() == m_labelEditor->GetId() ) { event.Skip(); - return; + return true; } wxPGProperty* selected = GetSelection(); @@ -3570,10 +3541,10 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) // similar is currently doing something (showing a // message box, for instance). m_processedEvent ) - return; + return true; if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT ) - return; + return true; wxVariant pendingValue(selected->GetValueRef()); wxWindow* wnd = GetEditorControl(); @@ -3597,16 +3568,22 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) wxString newTcValue = tc->GetValue(); if ( m_prevTcValue == newTcValue ) - return; + return true; m_prevTcValue = newTcValue; } else if ( wnd->IsKindOf(CLASSINFO(wxComboCtrl)) ) { + // In some cases we might stumble unintentionally on + // wxComboCtrl's embedded wxTextCtrl's events. Let's + // avoid them. + if ( editorWnd->IsKindOf(CLASSINFO(wxTextCtrl)) ) + return false; + wxComboCtrl* cc = (wxComboCtrl*) wnd; wxString newTcValue = cc->GetTextCtrl()->GetValue(); if ( m_prevTcValue == newTcValue ) - return; + return true; m_prevTcValue = newTcValue; } } @@ -3615,6 +3592,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) bool validationFailure = false; bool buttonWasHandled = false; + bool result = false; // // Try common button handling @@ -3642,6 +3620,8 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) if ( editor->OnEvent( this, selected, editorWnd, event ) ) { + result = true; + // If changes, validate them if ( DoEditorValidate() ) { @@ -3715,12 +3695,15 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) // Let unhandled button click events go to the parent if ( !buttonWasHandled && event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED ) { + result = true; wxCommandEvent evt(wxEVT_COMMAND_BUTTON_CLICKED,GetId()); GetEventHandler()->AddPendingEvent(evt); } } ClearInternalFlag(wxPG_FL_IN_HANDLECUSTOMEDITOREVENT); + + return result; } // ----------------------------------------------------------------------- @@ -3896,6 +3879,14 @@ private: m_propGrid->HandleCustomEditorEvent(event); + // + // NB: We should return true if the event was recognized as + // a dedicated wxPropertyGrid event, and as such was + // either properly handled or ignored. + // + if ( m_propGrid->IsMainButtonEvent(event) ) + return true; + // // NB: On wxMSW, a wxTextCtrl with wxTE_PROCESS_ENTER // may beep annoyingly if that event is skipped @@ -3962,20 +3953,7 @@ void wxPropertyGrid::FreeEditors() // Return focus back to canvas from children (this is required at least for // GTK+, which, unlike Windows, clears focus when control is destroyed // instead of moving it to closest parent). - wxWindow* focus = wxWindow::FindFocus(); - if ( focus ) - { - wxWindow* parent = focus->GetParent(); - while ( parent ) - { - if ( parent == this ) - { - SetFocusOnCanvas(); - break; - } - parent = parent->GetParent(); - } - } + SetFocusOnCanvas(); // Do not free editors immediately if processing events if ( m_wndEditor2 ) @@ -4319,7 +4297,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) wxStatusBar* statusbar = GetStatusBar(); if ( statusbar ) { - if ( pHelpString && pHelpString->length() ) + if ( pHelpString && !pHelpString->empty() ) { // Set help box text. statusbar->SetStatusText( *pHelpString ); @@ -4341,7 +4319,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) // // Show help as a tool tip on the editor control. // - if ( pHelpString && pHelpString->length() && + if ( pHelpString && !pHelpString->empty() && primaryCtrl ) { primaryCtrl->SetToolTip(*pHelpString); @@ -4568,6 +4546,11 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) SetScrollbars( wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT, xAmount, yAmount, xPos, yPos, true ); + // This may be needed in addition to calling SetScrollbars() + // when class inherits from wxScrollHelper instead of + // actual wxScrolled. + AdjustScrollbars(); + // Must re-get size now GetClientSize(&width,&height); @@ -4601,7 +4584,6 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) m_width = width; m_height = height; -#if wxPG_DOUBLE_BUFFER if ( !(GetExtraStyle() & wxPG_EX_NATIVE_DOUBLE_BUFFERING) ) { int dblh = (m_lineHeight*2); @@ -4629,8 +4611,6 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) } } -#endif - m_pState->OnClientWidthChange( width, event.GetSize().x - m_ncWidth, true ); m_ncWidth = event.GetSize().x; @@ -4666,7 +4646,24 @@ void wxPropertyGrid::SetVirtualWidth( int width ) void wxPropertyGrid::SetFocusOnCanvas() { - SetFocus(); + // To prevent wxPropertyGrid from stealing focus from other controls, + // only move focus to the grid if it was already in one if its child + // controls. + wxWindow* focus = wxWindow::FindFocus(); + if ( focus ) + { + wxWindow* parent = focus->GetParent(); + while ( parent ) + { + if ( parent == this ) + { + SetFocus(); + break; + } + parent = parent->GetParent(); + } + } + m_editorFocused = 0; } @@ -4799,7 +4796,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even } // Do not Skip() the event after selection has been made. - // Otherwise default event handling behavior kicks in + // Otherwise default event handling behaviour kicks in // and may revert focus back to the main canvas. res = true; } @@ -4856,7 +4853,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even m_draggedSplitter = splitterHit; m_dragOffset = splitterHitOffset; - #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT + #if wxPG_REFRESH_CONTROLS // Fixes button disappearance bug if ( m_wndEditor2 ) m_wndEditor2->Show ( false ); @@ -5189,7 +5186,7 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y), // Disable splitter auto-centering (but only if moved any - // otherwise we end up disabling auto-center even after a // recentering double-click). - int posDiff = abs(m_startingSplitterX - + int posDiff = abs(m_startingSplitterX - GetSplitterPosition(m_draggedSplitter)); if ( posDiff > 1 ) @@ -5221,7 +5218,7 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y), m_wndEditor->Show ( true ); } - #if wxPG_REFRESH_CONTROLS_AFTER_REPAINT + #if wxPG_REFRESH_CONTROLS // Fixes button disappearance bug if ( m_wndEditor2 ) m_wndEditor2->Show ( true ); @@ -5662,6 +5659,12 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) wxPGProperty* p = selected; + if ( action == wxPG_ACTION_EDIT && !editorFocused ) + { + DoSelectProperty( p, wxPG_SEL_FOCUS ); + wasHandled = true; + } + // Travel and expand/collapse int selectDir = -2; @@ -5989,7 +5992,7 @@ wxPGEditor* wxPropertyGrid::DoRegisterEditorClass( wxPGEditor* editorClass, RegisterDefaultEditors(); wxString name = editorName; - if ( name.length() == 0 ) + if ( name.empty() ) name = editorClass->GetName(); // Existing editor under this name? @@ -6201,6 +6204,7 @@ void wxPropertyGridEvent::Init() m_column = 1; m_canVeto = false; m_wasVetoed = false; + m_pg = NULL; } // ----------------------------------------------------------------------- @@ -6390,7 +6394,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString else { bool found = false; - if ( idString.length() ) + if ( !idString.empty() ) { wxPGHashMapS2P::iterator it = m_dictIdChoices.find(idString); if ( it != m_dictIdChoices.end() ) @@ -6466,7 +6470,7 @@ wxPGChoices wxPropertyGridPopulator::ParseChoices( const wxString& choicesString } // Assign to id - if ( idString.length() ) + if ( !idString.empty() ) m_dictIdChoices[idString] = choices.GetData(); } } @@ -6507,7 +6511,7 @@ bool wxPropertyGridPopulator::AddAttribute( const wxString& name, wxString valuel = value.Lower(); wxVariant variant; - if ( type.length() == 0 ) + if ( type.empty() ) { long v;