Added wxPropertyGrid::DedicateKey(), which prevents specific key presses from being eaten by editor controls. This is useful for customizing keyboard navigation. Also added utility function wxPGFindInVector<>(), which is used in the new code, and also in some other places.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64562 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Jaakko Salli
2010-06-12 09:30:57 +00:00
parent b589082adc
commit 8d2c70414c
9 changed files with 103 additions and 17 deletions

View File

@@ -494,6 +494,7 @@ All (GUI):
dismissed immediately as text control grabbed the focus). dismissed immediately as text control grabbed the focus).
- wxPropertyGrid: added wxPG_EX_MULTIPLE_SELECTION. - wxPropertyGrid: added wxPG_EX_MULTIPLE_SELECTION.
- wxPropertyGrid: added functions for editing property labels. - wxPropertyGrid: added functions for editing property labels.
- wxPropertyGrid: Added wxPropertyGrid::DedicateKey().
- wxPropertyGridManager: added wxPG_NO_INTERNAL_BORDER, - wxPropertyGridManager: added wxPG_NO_INTERNAL_BORDER,
wxPG_EX_NO_TOOLBAR_DIVIDER and wxPG_EX_TOOLBAR_SEPARATOR styles for finer wxPG_EX_NO_TOOLBAR_DIVIDER and wxPG_EX_TOOLBAR_SEPARATOR styles for finer
control over borders. Borders around property grid are now native for control over borders. Borders around property grid are now native for

View File

@@ -709,12 +709,34 @@ public:
/** Adds given key combination to trigger given action. /** Adds given key combination to trigger given action.
Here is a sample code to make Enter key press move focus to
the next property.
@code
propGrid->AddActionTrigger(wxPG_ACTION_NEXT_PROPERTY,
WXK_RETURN);
propGrid->DedicateKey(WXK_RETURN);
@endcode
@param action @param action
Which action to trigger. See @link pgactions List of list of Which action to trigger. See @link pgactions List of list of
wxPropertyGrid actions@endlink. wxPropertyGrid actions@endlink.
*/ */
void AddActionTrigger( int action, int keycode, int modifiers = 0 ); void AddActionTrigger( int action, int keycode, int modifiers = 0 );
/**
Dedicates a specific keycode to wxPropertyGrid. This means that such
key presses will not be redirected to editor controls.
Using this function allows, for example, navigation between
properties using arrow keys even when the focus is in the editor
control.
*/
void DedicateKey( int keycode )
{
m_dedicatedKeys.push_back(keycode);
}
/** /**
This static function enables or disables automatic use of This static function enables or disables automatic use of
wxGetTranslation for following strings: wxEnumProperty list labels, wxGetTranslation for following strings: wxEnumProperty list labels,
@@ -1814,6 +1836,10 @@ protected:
wxArrayPGProperty m_deletedProperties; wxArrayPGProperty m_deletedProperties;
wxArrayPGProperty m_removedProperties; wxArrayPGProperty m_removedProperties;
/** List of key codes that will not be handed over to editor controls. */
// FIXME: Make this a hash set once there is template-based wxHashSet.
wxVector<int> m_dedicatedKeys;
// //
// Temporary values // Temporary values
// //

View File

@@ -340,6 +340,19 @@ WX_DECLARE_HASH_MAP_WITH_DECL(wxInt32,
wxPGHashMapI2I, wxPGHashMapI2I,
class WXDLLIMPEXP_PROPGRID); class WXDLLIMPEXP_PROPGRID);
// Utility to find if specific item is in a vector. Returns index to
// the item, or wxNOT_FOUND if not present.
template<typename CONTAINER, typename T>
int wxPGFindInVector( CONTAINER vector, const T& item )
{
for ( unsigned int i=0; i<vector.size(); i++ )
{
if ( vector[i] == item )
return (int) i;
}
return wxNOT_FOUND;
}
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
enum wxPG_GETPROPERTYVALUES_FLAGS enum wxPG_GETPROPERTYVALUES_FLAGS

View File

@@ -445,6 +445,15 @@ public:
/** /**
Adds given key combination to trigger given action. Adds given key combination to trigger given action.
Here is a sample code to make Enter key press move focus to
the next property.
@code
propGrid->AddActionTrigger(wxPG_ACTION_NEXT_PROPERTY,
WXK_RETURN);
propGrid->DedicateKey(WXK_RETURN);
@endcode
@param action @param action
Which action to trigger. See @ref propgrid_keyboard_actions. Which action to trigger. See @ref propgrid_keyboard_actions.
@param keycode @param keycode
@@ -546,6 +555,16 @@ public:
long style = wxPG_DEFAULT_STYLE, long style = wxPG_DEFAULT_STYLE,
const wxChar* name = wxPropertyGridNameStr ); const wxChar* name = wxPropertyGridNameStr );
/**
Dedicates a specific keycode to wxPropertyGrid. This means that such
key presses will not be redirected to editor controls.
Using this function allows, for example, navigation between
properties using arrow keys even when the focus is in the editor
control.
*/
void DedicateKey( int keycode );
/** /**
Enables or disables (shows/hides) categories according to parameter Enables or disables (shows/hides) categories according to parameter
enable. enable.

View File

@@ -691,7 +691,8 @@ enum
ID_RUNMINIMAL, ID_RUNMINIMAL,
ID_ENABLELABELEDITING, ID_ENABLELABELEDITING,
ID_VETOCOLDRAG, ID_VETOCOLDRAG,
ID_SHOWHEADER ID_SHOWHEADER,
ID_ONEXTENDEDKEYNAV
}; };
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -756,6 +757,7 @@ BEGIN_EVENT_TABLE(FormMain, wxFrame)
EVT_MENU( ID_ITERATE2, FormMain::OnIterate2Click ) EVT_MENU( ID_ITERATE2, FormMain::OnIterate2Click )
EVT_MENU( ID_ITERATE3, FormMain::OnIterate3Click ) EVT_MENU( ID_ITERATE3, FormMain::OnIterate3Click )
EVT_MENU( ID_ITERATE4, FormMain::OnIterate4Click ) EVT_MENU( ID_ITERATE4, FormMain::OnIterate4Click )
EVT_MENU( ID_ONEXTENDEDKEYNAV, FormMain::OnExtendedKeyNav )
EVT_MENU( ID_SETBGCOLOUR, FormMain::OnSetBackgroundColour ) EVT_MENU( ID_SETBGCOLOUR, FormMain::OnSetBackgroundColour )
EVT_MENU( ID_SETBGCOLOURRECUR, FormMain::OnSetBackgroundColour ) EVT_MENU( ID_SETBGCOLOURRECUR, FormMain::OnSetBackgroundColour )
EVT_MENU( ID_CLEARMODIF, FormMain::OnClearModifyStatusClick ) EVT_MENU( ID_CLEARMODIF, FormMain::OnClearModifyStatusClick )
@@ -2308,6 +2310,11 @@ FormMain::FormMain(const wxString& title, const wxPoint& pos, const wxSize& size
menuTools2->Append(ID_ITERATE3, wxT("Reverse Iterate Over Properties") ); menuTools2->Append(ID_ITERATE3, wxT("Reverse Iterate Over Properties") );
menuTools2->Append(ID_ITERATE4, wxT("Iterate Over Categories") ); menuTools2->Append(ID_ITERATE4, wxT("Iterate Over Categories") );
menuTools2->AppendSeparator(); menuTools2->AppendSeparator();
menuTools2->Append(ID_ONEXTENDEDKEYNAV, "Extend Keyboard Navigation",
"This will set Enter to navigate to next property, "
"and allows arrow keys to navigate even when in "
"editor control.");
menuTools2->AppendSeparator();
menuTools2->Append(ID_SETPROPERTYVALUE, wxT("Set Property Value") ); menuTools2->Append(ID_SETPROPERTYVALUE, wxT("Set Property Value") );
menuTools2->Append(ID_CLEARMODIF, wxT("Clear Modified Status"), wxT("Clears wxPG_MODIFIED flag from all properties.") ); menuTools2->Append(ID_CLEARMODIF, wxT("Clear Modified Status"), wxT("Clears wxPG_MODIFIED flag from all properties.") );
menuTools2->AppendSeparator(); menuTools2->AppendSeparator();
@@ -2684,6 +2691,25 @@ void FormMain::OnIterate4Click( wxCommandEvent& WXUNUSED(event) )
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void FormMain::OnExtendedKeyNav( wxCommandEvent& WXUNUSED(event) )
{
// Use AddActionTrigger() and DedicateKey() to set up Enter,
// Up, and Down keys for navigating between properties.
wxPropertyGrid* propGrid = m_pPropGridManager->GetGrid();
propGrid->AddActionTrigger(wxPG_ACTION_NEXT_PROPERTY,
WXK_RETURN);
propGrid->DedicateKey(WXK_RETURN);
// Up and Down keys are alredy associated with navigation,
// but we must also prevent them from being eaten by
// editor controls.
propGrid->DedicateKey(WXK_UP);
propGrid->DedicateKey(WXK_DOWN);
}
// -----------------------------------------------------------------------
void FormMain::OnFitColumnsClick( wxCommandEvent& WXUNUSED(event) ) void FormMain::OnFitColumnsClick( wxCommandEvent& WXUNUSED(event) )
{ {
wxPropertyGridPage* page = m_pPropGridManager->GetCurrentPage(); wxPropertyGridPage* page = m_pPropGridManager->GetCurrentPage();

View File

@@ -226,6 +226,8 @@ public:
void OnIterate3Click( wxCommandEvent& event ); void OnIterate3Click( wxCommandEvent& event );
void OnIterate4Click( wxCommandEvent& event ); void OnIterate4Click( wxCommandEvent& event );
void OnExtendedKeyNav( wxCommandEvent& event );
void OnPropertyGridChange( wxPropertyGridEvent& event ); void OnPropertyGridChange( wxPropertyGridEvent& event );
void OnPropertyGridChanging( wxPropertyGridEvent& event ); void OnPropertyGridChanging( wxPropertyGridEvent& event );
void OnPropertyGridSelect( wxPropertyGridEvent& event ); void OnPropertyGridSelect( wxPropertyGridEvent& event );

View File

@@ -692,12 +692,7 @@ wxPropertyGrid* wxPGProperty::GetGrid() const
int wxPGProperty::Index( const wxPGProperty* p ) const int wxPGProperty::Index( const wxPGProperty* p ) const
{ {
for ( unsigned int i = 0; i<m_children.size(); i++ ) return wxPGFindInVector(m_children, p);
{
if ( p == m_children[i] )
return i;
}
return wxNOT_FOUND;
} }
bool wxPGProperty::ValidateValue( wxVariant& WXUNUSED(value), wxPGValidationInfo& WXUNUSED(validationInfo) ) const bool wxPGProperty::ValidateValue( wxVariant& WXUNUSED(value), wxPGValidationInfo& WXUNUSED(validationInfo) ) const

View File

@@ -1022,6 +1022,7 @@ void wxPropertyGrid::OnLabelEditorKeyPress( wxKeyEvent& event )
{ {
int keycode = event.GetKeyCode(); int keycode = event.GetKeyCode();
// If key code was registered as action trigger, then trigger that action
if ( keycode == WXK_ESCAPE ) if ( keycode == WXK_ESCAPE )
{ {
DoEndLabelEdit(false); DoEndLabelEdit(false);
@@ -5553,8 +5554,10 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
return; return;
} }
// Except for TAB and ESC, handle child control events in child control // Except for TAB, ESC, and any keys specifically dedicated to
if ( fromChild ) // wxPropertyGrid itself, handle child control events in child control.
if ( fromChild &&
wxPGFindInVector(m_dedicatedKeys, keycode) == wxNOT_FOUND )
{ {
// Only propagate event if it had modifiers // Only propagate event if it had modifiers
if ( !event.HasModifiers() ) if ( !event.HasModifiers() )
@@ -5608,7 +5611,13 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild )
{ {
p = wxPropertyGridIterator::OneStep( m_pState, wxPG_ITERATE_VISIBLE, p, selectDir ); p = wxPropertyGridIterator::OneStep( m_pState, wxPG_ITERATE_VISIBLE, p, selectDir );
if ( p ) if ( p )
DoSelectProperty(p); {
// If editor was focused, then make the next editor focused as well
int selFlags = 0;
if ( editorFocused )
selFlags |= wxPG_SEL_FOCUS;
DoSelectProperty(p, selFlags);
}
wasHandled = true; wasHandled = true;
} }
} }

View File

@@ -1299,13 +1299,8 @@ bool wxPropertyGridPageState::DoSetPropertyValueWxObjectPtr( wxPGProperty* p, wx
bool wxPropertyGridPageState::DoIsPropertySelected( wxPGProperty* prop ) const bool wxPropertyGridPageState::DoIsPropertySelected( wxPGProperty* prop ) const
{ {
const wxArrayPGProperty& selection = m_selection; if ( wxPGFindInVector(m_selection, prop) != wxNOT_FOUND )
for ( unsigned int i=0; i<selection.size(); i++ )
{
if ( selection[i] == prop )
return true; return true;
}
return false; return false;
} }