Added multiple selection feature to wxPropertyGrid (enabled by setting wxPG_EX_MULTIPLE_SELECTION style)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61681 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2009-08-17 18:36:00 +00:00
parent 17a5460272
commit fc72fab6c6
15 changed files with 663 additions and 197 deletions

View File

@@ -428,7 +428,6 @@ void wxPropertyGrid::Init1()
m_iFlags = 0;
m_pState = NULL;
m_wndEditor = m_wndEditor2 = NULL;
m_selected = NULL;
m_selColumn = -1;
m_propHover = NULL;
m_eventObject = this;
@@ -582,7 +581,7 @@ wxPropertyGrid::~wxPropertyGrid()
{
size_t i;
DoSelectProperty(NULL);
DoSelectProperty(NULL, wxPG_SEL_NOVALIDATE|wxPG_SEL_DONT_SEND_EVENT);
// This should do prevent things from going too badly wrong
m_iFlags &= ~(wxPG_FL_INITIALIZED);
@@ -603,8 +602,6 @@ wxPropertyGrid::~wxPropertyGrid()
delete m_doubleBuffer;
#endif
//m_selected = NULL;
if ( m_iFlags & wxPG_FL_CREATEDSTATE )
delete m_pState;
@@ -731,13 +728,153 @@ void wxPropertyGrid::Thaw()
#endif
// Force property re-selection
if ( m_selected )
DoSelectProperty(m_selected, wxPG_SEL_FORCE);
// NB: We must copy the selection.
wxArrayPGProperty selection = m_pState->m_selection;
DoSetSelection(selection, wxPG_SEL_FORCE);
}
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::DoAddToSelection( wxPGProperty* prop, int selFlags )
{
wxCHECK( prop, false );
if ( !(GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION) )
return DoSelectProperty(prop, selFlags);
wxArrayPGProperty& selection = m_pState->m_selection;
if ( !selection.size() )
{
return DoSelectProperty(prop, selFlags);
}
else
{
// For categories, only one can be selected at a time
if ( prop->IsCategory() || selection[0]->IsCategory() )
return true;
selection.push_back(prop);
if ( !(selFlags & wxPG_SEL_DONT_SEND_EVENT) )
{
SendEvent( wxEVT_PG_SELECTED, prop, NULL, selFlags );
}
// For some reason, if we use RefreshProperty(prop) here,
// we may go into infinite drawing loop.
Refresh();
}
return true;
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::DoRemoveFromSelection( wxPGProperty* prop, int selFlags )
{
wxCHECK( prop, false );
bool res;
wxArrayPGProperty& selection = m_pState->m_selection;
if ( selection.size() <= 1 )
{
res = DoSelectProperty(NULL, selFlags);
}
else
{
selection.Remove(prop);
RefreshProperty(prop);
res = true;
}
return res;
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::AddToSelectionFromInputEvent( wxPGProperty* prop,
wxMouseEvent* mouseEvent,
int selFlags )
{
bool alreadySelected = m_pState->DoIsPropertySelected(prop);
bool res = true;
bool addToExistingSelection;
if ( GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION )
{
if ( mouseEvent )
{
if ( mouseEvent->GetEventType() == wxEVT_RIGHT_DOWN ||
mouseEvent->GetEventType() == wxEVT_RIGHT_UP )
{
// Allow right-click for context menu without
// disturbing the selection.
if ( GetSelectedProperties().size() <= 1 ||
!alreadySelected )
return DoSelectProperty(prop, selFlags);
return true;
}
else
{
addToExistingSelection = mouseEvent->ShiftDown();
}
}
else
{
addToExistingSelection = false;
}
}
else
{
addToExistingSelection = false;
}
if ( addToExistingSelection )
{
if ( !alreadySelected )
{
res = DoAddToSelection(prop, selFlags);
}
else if ( GetSelectedProperties().size() > 1 )
{
res = DoRemoveFromSelection(prop, selFlags);
}
}
else
{
res = DoSelectProperty(prop, selFlags);
}
return res;
}
// -----------------------------------------------------------------------
void wxPropertyGrid::DoSetSelection( const wxArrayPGProperty& newSelection,
int selFlags )
{
if ( newSelection.size() > 0 )
{
if ( !DoSelectProperty(newSelection[0], selFlags) )
return;
}
else
{
DoClearSelection(false, selFlags);
}
for ( unsigned int i = 1; i < newSelection.size(); i++ )
{
DoAddToSelection(newSelection[i], selFlags);
}
Refresh();
}
// -----------------------------------------------------------------------
void wxPropertyGrid::SetExtraStyle( long exStyle )
{
if ( exStyle & wxPG_EX_NATIVE_DOUBLE_BUFFERING )
@@ -1684,7 +1821,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0;
bool isEnabled = IsEnabled();
bool isPgEnabled = IsEnabled();
//
// Prepare some pens and brushes that are often changed to.
@@ -1695,6 +1832,12 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
wxBrush capbgbrush(m_colCapBack,wxSOLID);
wxPen linepen(m_colLine,1,wxSOLID);
wxColour selBackCol;
if ( isPgEnabled )
selBackCol = m_colSelBack;
else
selBackCol = m_colMargin;
// pen that has same colour as text
wxPen outlinepen(m_colPropFore,1,wxSOLID);
@@ -1708,7 +1851,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
dc.DrawRectangle(-1-xRelMod,firstItemTopY-1,x+2,lastItemBottomY-firstItemTopY+2);
}
const wxPGProperty* selected = m_selected;
const wxPGProperty* firstSelected = GetSelection();
const wxPropertyGridPageState* state = m_pState;
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
@@ -1808,7 +1951,9 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
wxColour rowFgCol;
wxColour rowBgCol;
if ( p != selected )
bool isSelected = state->DoIsPropertySelected(p);
if ( !isSelected )
{
// Disabled may get different colour.
if ( !p->IsEnabled() )
@@ -1820,6 +1965,11 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
}
else
{
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
if ( p == firstSelected )
wasSelectedPainted = true;
#endif
renderFlags |= wxPGCellRenderer::Selected;
if ( !p->IsCategory() )
@@ -1827,25 +1977,23 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
renderFlags |= wxPGCellRenderer::DontUseCellFgCol |
wxPGCellRenderer::DontUseCellBgCol;
#if wxPG_REFRESH_CONTROLS_AFTER_REPAINT
wasSelectedPainted = true;
#endif
// Selected gets different colour.
if ( reallyFocused )
if ( reallyFocused && p == firstSelected )
{
rowFgCol = m_colSelFore;
rowBgCol = m_colSelBack;
rowBgCol = selBackCol;
}
else if ( isEnabled )
else if ( isPgEnabled )
{
rowFgCol = m_colPropFore;
rowBgCol = m_colMargin;
if ( p == firstSelected )
rowBgCol = m_colMargin;
else
rowBgCol = selBackCol;
}
else
{
rowFgCol = m_colDisPropFore;
rowBgCol = m_colSelBack;
rowBgCol = selBackCol;
}
}
}
@@ -1934,16 +2082,31 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc,
DrawExpanderButton( dc, butRect, p );
// Background
if ( p == selected && m_wndEditor && ci == 1 )
if ( isSelected && ci == 1 )
{
wxColour editorBgCol = GetEditorControl()->GetBackgroundColour();
dc.SetBrush(editorBgCol);
dc.SetPen(editorBgCol);
dc.SetTextForeground(m_colPropFore);
dc.DrawRectangle(cellRect);
if ( p == firstSelected && m_wndEditor )
{
wxColour editorBgCol =
GetEditorControl()->GetBackgroundColour();
dc.SetBrush(editorBgCol);
dc.SetPen(editorBgCol);
dc.SetTextForeground(m_colPropFore);
dc.DrawRectangle(cellRect);
if ( m_dragStatus == 0 && !(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) )
ctrlCell = true;
if ( m_dragStatus == 0 &&
!(m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE) )
ctrlCell = true;
}
else
{
dc.SetBrush(m_colPropBack);
dc.SetPen(m_colPropBack);
dc.SetTextForeground(m_colDisPropFore);
if ( p->IsEnabled() )
dc.SetTextForeground(rowFgCol);
else
dc.SetTextForeground(m_colDisPropFore);
}
}
else
{
@@ -2038,7 +2201,7 @@ wxRect wxPropertyGrid::GetPropertyRect( const wxPGProperty* p1, const wxPGProper
// If seleced property is inside the range, we'll extend the range to include
// control's size.
wxPGProperty* selected = m_selected;
wxPGProperty* selected = GetSelection();
if ( selected )
{
int selectedY = selected->GetY();
@@ -2078,8 +2241,12 @@ void wxPropertyGrid::DrawItems( const wxPGProperty* p1, const wxPGProperty* p2 )
void wxPropertyGrid::RefreshProperty( wxPGProperty* p )
{
if ( p == m_selected )
DoSelectProperty(p, wxPG_SEL_FORCE);
if ( m_pState->DoIsPropertySelected(p) )
{
// NB: We must copy the selection.
wxArrayPGProperty selection = m_pState->m_selection;
DoSetSelection(selection, wxPG_SEL_FORCE);
}
DrawItemAndChildren(p);
}
@@ -2118,7 +2285,8 @@ void wxPropertyGrid::DrawItemAndChildren( wxPGProperty* p )
return;
// Update child control.
if ( m_selected && m_selected->GetParent() == p )
wxPGProperty* selected = GetSelection();
if ( selected && selected->GetParent() == p )
RefreshEditor();
const wxPGProperty* lastDrawn = p->GetLastVisibleSubItem();
@@ -2218,11 +2386,13 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
if ( pNewState == m_pState )
return;
wxPGProperty* oldSelection = m_selected;
wxArrayPGProperty oldSelection = m_pState->m_selection;
DoClearSelection();
// Call ClearSelection() instead of DoClearSelection()
// so that selection clear events are not sent.
ClearSelection();
m_pState->m_selected = oldSelection;
m_pState->m_selection = oldSelection;
bool orig_mode = m_pState->IsInNonCatMode();
bool new_state_mode = pNewState->IsInNonCatMode();
@@ -2263,9 +2433,9 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
// Refresh, if not frozen.
m_pState->PrepareAfterItemsAdded();
// Reselect
if ( m_pState->m_selected )
DoSelectProperty( m_pState->m_selected );
// Reselect (Use SetSelection() instead of Do-variant so that
// events won't be sent).
SetSelection(m_pState->m_selection);
RecalculateVirtualSize(0);
Refresh();
@@ -2289,7 +2459,7 @@ void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, int spli
if ( refresh )
{
if ( m_selected )
if ( GetSelection() )
CorrectEditorWidgetSizeX();
Refresh();
@@ -2360,14 +2530,16 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
return false;
}
wxPGProperty* selected = GetSelection();
if ( m_wndEditor &&
IsEditorsValueModified() &&
(m_iFlags & wxPG_FL_INITIALIZED) &&
m_selected )
selected )
{
m_inCommitChangesFromEditor = 1;
wxVariant variant(m_selected->GetValueRef());
wxVariant variant(selected->GetValueRef());
bool valueIsPending = false;
// JACS - necessary to avoid new focus being found spuriously within OnIdle
@@ -2380,10 +2552,13 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
m_chgInfo_changedProperty = NULL;
// If truly modified, schedule value as pending.
if ( m_selected->GetEditorClass()->GetValueFromControl( variant, m_selected, GetEditorControl() ) )
if ( selected->GetEditorClass()->
GetValueFromControl( variant,
selected,
GetEditorControl() ) )
{
if ( DoEditorValidate() &&
PerformValidation(m_selected, variant) )
PerformValidation(selected, variant) )
{
valueIsPending = true;
}
@@ -2409,18 +2584,18 @@ bool wxPropertyGrid::CommitChangesFromEditor( wxUint32 flags )
m_curFocused = oldFocus;
}
res = OnValidationFailure(m_selected, variant);
res = OnValidationFailure(selected, variant);
// Now prevent further validation failure messages
if ( res )
{
EditorsValueWasNotModified();
OnValidationFailureReset(m_selected);
OnValidationFailureReset(selected);
}
}
else if ( valueIsPending )
{
DoPropertyChanged( m_selected, flags );
DoPropertyChanged( selected, flags );
EditorsValueWasNotModified();
}
@@ -2523,7 +2698,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue
if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) )
{
if ( changedProperty == m_selected )
if ( changedProperty == GetSelection() )
{
wxWindow* editor = GetEditorControl();
wxASSERT( editor->IsKindOf(CLASSINFO(wxTextCtrl)) );
@@ -2617,7 +2792,7 @@ bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property,
//
// For non-wxTextCtrl editors, we do need to revert the value
if ( !editor->IsKindOf(CLASSINFO(wxTextCtrl)) &&
property == m_selected )
property == GetSelection() )
{
property->GetEditorClass()->UpdateControl(property, editor);
}
@@ -2656,7 +2831,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W
DrawItemAndChildren(property);
if ( property == m_selected )
if ( property == GetSelection() )
{
SetInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
@@ -2695,7 +2870,7 @@ void wxPropertyGrid::DoOnValidationFailureReset( wxPGProperty* property )
ClearInternalFlag(wxPG_FL_CELL_OVERRIDES_SEL);
if ( property == m_selected && GetEditorControl() )
if ( property == GetSelection() && GetEditorControl() )
{
// Calling this will recreate the control, thus resetting its colour
RefreshProperty(property);
@@ -2716,6 +2891,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
return true;
wxWindow* editor = GetEditorControl();
wxPGProperty* selected = GetSelection();
m_pState->m_anyModified = 1;
@@ -2742,7 +2918,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
if ( !(p->m_flags & wxPG_PROP_MODIFIED) )
{
p->m_flags |= wxPG_PROP_MODIFIED;
if ( p == m_selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
if ( p == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
{
if ( editor )
SetCurControlBoldFont();
@@ -2759,7 +2935,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, unsigned int selFlags )
{
pwc->m_flags |= wxPG_PROP_MODIFIED;
if ( pwc == m_selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
if ( pwc == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) )
{
if ( editor )
SetCurControlBoldFont();
@@ -2867,11 +3043,11 @@ bool wxPropertyGrid::DoEditorValidate()
void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
{
wxPGProperty* selected = m_selected;
wxPGProperty* selected = GetSelection();
// Somehow, event is handled after property has been deselected.
// Possibly, but very rare.
if ( !selected )
if ( !selected || selected->HasFlag(wxPG_PROP_BEING_DELETED) )
return;
if ( m_iFlags & wxPG_FL_IN_HANDLECUSTOMEDITOREVENT )
@@ -2939,7 +3115,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
if ( DoEditorValidate() )
{
if ( editor->GetValueFromControl( pendingValue,
m_selected,
selected,
wnd ) )
valueIsPending = true;
}
@@ -2966,7 +3142,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event )
}
if ( !validationFailure && valueIsPending )
if ( !PerformValidation(m_selected, pendingValue) )
if ( !PerformValidation(selected, pendingValue) )
validationFailure = true;
if ( validationFailure)
@@ -3260,17 +3436,26 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
m_inDoSelectProperty = 1;
wxPGProperty* prev = m_selected;
if ( !m_pState )
{
m_inDoSelectProperty = 0;
return false;
}
wxArrayPGProperty prevSelection = m_pState->m_selection;
wxPGProperty* prevFirstSel;
if ( prevSelection.size() > 0 )
prevFirstSel = prevSelection[0];
else
prevFirstSel = NULL;
if ( prevFirstSel && prevFirstSel->HasFlag(wxPG_PROP_BEING_DELETED) )
prevFirstSel = NULL;
/*
if (m_selected)
wxPrintf( "Selected %s\n", m_selected->GetClassInfo()->GetClassName() );
if ( prevFirstSel )
wxPrintf( "Selected %s\n", prevFirstSel->GetClassInfo()->GetClassName() );
else
wxPrintf( "None selected\n" );
@@ -3285,9 +3470,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
{
m_iFlags &= ~(wxPG_FL_ABNORMAL_EDITOR);
m_editorFocused = 0;
m_selected = p;
m_selColumn = 1;
m_pState->m_selected = p;
m_pState->DoSetSelection(p);
// If frozen, always free controls. But don't worry, as Thaw will
// recall SelectProperty to recreate them.
@@ -3299,7 +3483,9 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
else
{
// Is it the same?
if ( m_selected == p && !(flags & wxPG_SEL_FORCE) )
if ( prevFirstSel == p &&
prevSelection.size() <= 1 &&
!(flags & wxPG_SEL_FORCE) )
{
// Only set focus if not deselecting
if ( p )
@@ -3324,13 +3510,12 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
//
// First, deactivate previous
if ( m_selected )
if ( prevFirstSel )
{
OnValidationFailureReset(m_selected);
OnValidationFailureReset(prevFirstSel);
// Must double-check if this is an selected in case of forceswitch
if ( p != prev )
if ( p != prevFirstSel )
{
if ( !CommitChangesFromEditor(flags) )
{
@@ -3345,9 +3530,6 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
FreeEditors();
m_selColumn = -1;
m_selected = NULL;
m_pState->m_selected = NULL;
// We need to always fully refresh the grid here
Refresh(false);
@@ -3357,6 +3539,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
SetInternalFlag(wxPG_FL_IN_SELECT_PROPERTY);
m_pState->DoSetSelection(p);
//
// Then, activate the one given.
if ( p )
@@ -3365,10 +3549,8 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
int splitterX = GetSplitterPosition();
m_editorFocused = 0;
m_selected = p;
m_pState->m_selected = p;
m_iFlags |= wxPG_FL_PRIMARY_FILLS_ENTIRE;
if ( p != prev )
if ( p != prevFirstSel )
m_iFlags &= ~(wxPG_FL_VALIDATION_FAILED);
wxASSERT( m_wndEditor == NULL );
@@ -3609,7 +3791,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
// call wx event handler (here so that it also occurs on deselection)
if ( !(flags & wxPG_SEL_DONT_SEND_EVENT) )
SendEvent( wxEVT_PG_SELECTED, m_selected, NULL, flags );
SendEvent( wxEVT_PG_SELECTED, p, NULL, flags );
return true;
}
@@ -3618,14 +3800,16 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags )
bool wxPropertyGrid::UnfocusEditor()
{
if ( !m_selected || !m_wndEditor || m_frozen )
wxPGProperty* selected = GetSelection();
if ( !selected || !m_wndEditor || m_frozen )
return true;
if ( !CommitChangesFromEditor(0) )
return false;
SetFocusOnCanvas();
DrawItem(m_selected);
DrawItem(selected);
return true;
}
@@ -3634,7 +3818,7 @@ bool wxPropertyGrid::UnfocusEditor()
void wxPropertyGrid::RefreshEditor()
{
wxPGProperty* p = m_selected;
wxPGProperty* p = GetSelection();
if ( !p )
return;
@@ -3673,14 +3857,6 @@ bool wxPropertyGrid::SelectProperty( wxPGPropArg id, bool focus )
return DoSelectProperty(p, flags);
}
// -----------------------------------------------------------------------
bool wxPropertyGrid::DoClearSelection()
{
// Unlike ClearSelection(), here we send the wxEVT_PG_SELECTED event.
return DoSelectProperty(NULL, 0);
}
// -----------------------------------------------------------------------
// wxPropertyGrid expand/collapse state
// -----------------------------------------------------------------------
@@ -3688,9 +3864,10 @@ bool wxPropertyGrid::DoClearSelection()
bool wxPropertyGrid::DoCollapse( wxPGProperty* p, bool sendEvents )
{
wxPGProperty* pwc = wxStaticCast(p, wxPGProperty);
wxPGProperty* selected = GetSelection();
// If active editor was inside collapsed section, then disable it
if ( m_selected && m_selected->IsSomeParent(p) )
if ( selected && selected->IsSomeParent(p) )
{
DoClearSelection();
}
@@ -3773,12 +3950,18 @@ bool wxPropertyGrid::DoHideProperty( wxPGProperty* p, bool hide, int flags )
if ( m_frozen )
return m_pState->DoHideProperty(p, hide, flags);
if ( m_selected &&
( m_selected == p || m_selected->IsSomeParent(p) )
)
wxArrayPGProperty selection = m_pState->m_selection; // Must use a copy
int selRemoveCount = 0;
for ( unsigned int i=0; i<selection.size(); i++ )
{
wxPGProperty* selected = selection[i];
if ( selected == p || selected->IsSomeParent(p) )
{
DoClearSelection();
if ( !DoRemoveFromSelection(p, flags) )
return false;
selRemoveCount += 1;
}
}
m_pState->DoHideProperty(p, hide, flags);
@@ -3860,7 +4043,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos )
m_pState->CheckColumnWidths();
if ( m_selected )
if ( GetSelection() )
CorrectEditorWidgetSizeX();
m_iFlags &= ~wxPG_FL_RECALCULATING_VIRTUAL_SIZE;
@@ -4019,7 +4202,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
)
)
{
if ( !DoSelectProperty( p ) )
if ( !AddToSelectionFromInputEvent( p, &event ) )
return res;
// On double-click, expand/collapse.
@@ -4039,7 +4222,7 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
m_iFlags |= wxPG_FL_ACTIVATION_BY_CLICK;
selFlag = wxPG_SEL_FOCUS;
}
if ( !DoSelectProperty( p, selFlag ) )
if ( !AddToSelectionFromInputEvent( p, &event, selFlag ) )
return res;
m_iFlags &= ~(wxPG_FL_ACTIVATION_BY_CLICK);
@@ -4130,15 +4313,15 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even
// -----------------------------------------------------------------------
bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x), unsigned int WXUNUSED(y),
wxMouseEvent& WXUNUSED(event) )
bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x),
unsigned int WXUNUSED(y),
wxMouseEvent& event )
{
if ( m_propHover )
{
// Select property here as well
wxPGProperty* p = m_propHover;
if ( p != m_selected )
DoSelectProperty( p );
AddToSelectionFromInputEvent(p, &event);
// Send right click event.
SendEvent( wxEVT_PG_RIGHT_CLICK, p );
@@ -4150,16 +4333,16 @@ bool wxPropertyGrid::HandleMouseRightClick( int WXUNUSED(x), unsigned int WXUNUS
// -----------------------------------------------------------------------
bool wxPropertyGrid::HandleMouseDoubleClick( int WXUNUSED(x), unsigned int WXUNUSED(y),
wxMouseEvent& WXUNUSED(event) )
bool wxPropertyGrid::HandleMouseDoubleClick( int WXUNUSED(x),
unsigned int WXUNUSED(y),
wxMouseEvent& event )
{
if ( m_propHover )
{
// Select property here as well
wxPGProperty* p = m_propHover;
if ( p != m_selected )
DoSelectProperty( p );
AddToSelectionFromInputEvent(p, &event);
// Send double-click event.
SendEvent( wxEVT_PG_DOUBLE_CLICK, m_propHover );
@@ -4226,7 +4409,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
state->DoSetSplitterPosition( newSplitterX, m_draggedSplitter, false );
state->m_fSplitterX = (float) newSplitterX;
if ( m_selected )
if ( GetSelection() )
CorrectEditorWidgetSizeX();
Update();
@@ -4385,6 +4568,18 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event
CustomSetCursor( wxCURSOR_ARROW );
}
}
//
// Multi select by dragging
//
if ( GetExtraStyle() & wxPG_EX_MULTIPLE_SELECTION &&
event.LeftIsDown() &&
m_propHover &&
GetSelection() &&
!state->DoIsPropertySelected(m_propHover) )
{
DoAddToSelection(m_propHover);
}
}
return true;
}
@@ -4434,8 +4629,9 @@ bool wxPropertyGrid::HandleMouseUp( int x, unsigned int WXUNUSED(y),
m_dragStatus = 0;
// Control background needs to be cleared
if ( !(m_iFlags & wxPG_FL_PRIMARY_FILLS_ENTIRE) && m_selected )
DrawItem( m_selected );
wxPGProperty* selected = GetSelection();
if ( !(m_iFlags & wxPG_FL_PRIMARY_FILLS_ENTIRE) && selected )
DrawItem( selected );
if ( m_wndEditor )
{
@@ -4659,8 +4855,10 @@ void wxPropertyGrid::OnMouseRightClickChild( wxMouseEvent &event )
// but that should not matter (right click is about item, not position).
wxPoint pt = m_wndEditor->GetPosition();
CalcUnscrolledPosition( event.m_x + pt.x, event.m_y + pt.y, &x, &y );
wxASSERT( m_selected );
m_propHover = m_selected;
// FIXME: Used to set m_propHover to selection here. Was it really
// necessary?
bool res = HandleMouseRightClick(x,y,event);
if ( !res ) event.Skip();
}
@@ -4758,6 +4956,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
wxCHECK2(!m_frozen, return);
// Travelsal between items, collapsing/expanding, etc.
wxPGProperty* selected = GetSelection();
int keycode = event.GetKeyCode();
bool editorFocused = IsEditorFocused();
@@ -4774,7 +4973,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
{
if ( !editorFocused && m_wndEditor )
{
DoSelectProperty( m_selected, wxPG_SEL_FOCUS );
DoSelectProperty( selected, wxPG_SEL_FOCUS );
}
else
{
@@ -4833,12 +5032,13 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
EditorsValueWasNotModified();
// Update the control as well
m_selected->GetEditorClass()->SetControlStringValue( m_selected,
GetEditorControl(),
m_selected->GetDisplayedString() );
selected->GetEditorClass()->
SetControlStringValue( selected,
GetEditorControl(),
selected->GetDisplayedString() );
}
OnValidationFailureReset(m_selected);
OnValidationFailureReset(selected);
UnfocusEditor();
return;
@@ -4858,13 +5058,13 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
bool wasHandled = false;
if ( m_selected )
if ( selected )
{
// Show dialog?
if ( ButtonTriggerKeyTest(action, event) )
return;
wxPGProperty* p = m_selected;
wxPGProperty* p = selected;
// Travel and expand/collapse
int selectDir = -2;
@@ -5065,8 +5265,9 @@ void wxPropertyGrid::HandleFocusChange( wxWindow* newFocused )
}
// Redraw selected
if ( m_selected && (m_iFlags & wxPG_FL_INITIALIZED) )
DrawItem( m_selected );
wxPGProperty* selected = GetSelection();
if ( selected && (m_iFlags & wxPG_FL_INITIALIZED) )
DrawItem( selected );
}
}