Don't make user click twice to toggle checkbox in wxGrid.

This commit is contained in:
Jeff Young 2018-03-21 23:25:36 +00:00
parent 29ebca4053
commit a0364a1137
9 changed files with 108 additions and 121 deletions

View File

@ -57,6 +57,8 @@ GRID_TRICKS::GRID_TRICKS( wxGrid* aGrid ):
m_sel_row_count = 0;
m_sel_col_count = 0;
aGrid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), NULL, this );
aGrid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( GRID_TRICKS::onGridCellLeftClick ), NULL, this );
aGrid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( GRID_TRICKS::onGridCellRightClick ), NULL, this );
aGrid->Connect( MYID_FIRST, MYID_LAST, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( GRID_TRICKS::onPopupSelection ), NULL, this );
aGrid->Connect( wxEVT_KEY_DOWN, wxKeyEventHandler( GRID_TRICKS::onKeyDown ), NULL, this );
@ -64,6 +66,57 @@ GRID_TRICKS::GRID_TRICKS( wxGrid* aGrid ):
}
bool GRID_TRICKS::toggleCell( int aRow, int aCol )
{
auto renderer = m_grid->GetCellRenderer( aRow, aCol );
bool isCheckbox = ( dynamic_cast<wxGridCellBoolRenderer*>( renderer ) != nullptr );
renderer->DecRef();
if( isCheckbox )
{
wxGridTableBase* model = m_grid->GetTable();
if( model->CanGetValueAs( aRow, aCol, wxGRID_VALUE_BOOL )
&& model->CanSetValueAs( aRow, aCol, wxGRID_VALUE_BOOL ))
{
model->SetValueAsBool( aRow, aCol, !model->GetValueAsBool( aRow, aCol ));
}
else // fall back to string processing
{
if( model->GetValue( aRow, aCol ) == wxT( "1" ) )
model->SetValue( aRow, aCol, wxT( "0" ) );
else
model->SetValue( aRow, aCol, wxT( "1" ) );
}
return true;
}
return false;
}
void GRID_TRICKS::onGridCellLeftClick( wxGridEvent& aEvent )
{
int row = aEvent.GetRow();
int col = aEvent.GetCol();
// Don't make users click twice to toggle a checkbox
if( !aEvent.GetModifiers() && toggleCell( row, col ) )
{
m_grid->ClearSelection();
m_grid->SetGridCursor( row, col );
// eat event
}
else
{
aEvent.Skip();
}
}
void GRID_TRICKS::getSelectedArea()
{
wxGridCellCoordsArray topLeft = m_grid->GetSelectionBlockTopLeft();
@ -178,26 +231,39 @@ void GRID_TRICKS::onKeyDown( wxKeyEvent& ev )
if( isCtl( 'A', ev ) )
{
m_grid->SelectAll();
return;
}
else if( isCtl( 'C', ev ) )
{
getSelectedArea();
cutcopy( false );
return;
}
else if( isCtl( 'V', ev ) )
{
getSelectedArea();
paste_clipboard();
return;
}
else if( isCtl( 'X', ev ) )
{
getSelectedArea();
cutcopy( true );
return;
}
else
else if( ev.GetKeyCode() == ' ' )
{
ev.Skip( true );
int row = m_grid->GetCursorRow();
int col = m_grid->GetCursorColumn();
if( m_grid->IsVisible( row, col ) && toggleCell( row, col ) )
{
m_grid->ForceRefresh();
return;
}
}
ev.Skip( true );
}

View File

@ -182,8 +182,8 @@ DIALOG_SYMBOL_LIB_TABLE::DIALOG_SYMBOL_LIB_TABLE( wxTopLevelWindow* aParent,
g->SetColAttr( COL_TYPE, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellBoolEditor() );
attr->SetRenderer( new wxGridCellBoolRenderer() );
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
g->SetColAttr( COL_ENABLED, attr );
// all but COL_OPTIONS, which is edited with Option Editor anyways.

View File

@ -70,6 +70,8 @@ protected:
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && !e.ShiftDown() && !e.MetaDown();
}
void onGridCellLeftClick( wxGridEvent& event );
void onGridCellRightClick( wxGridEvent& event )
{
showPopupMenu();
@ -87,6 +89,8 @@ protected:
void onKeyDown( wxKeyEvent& ev );
bool toggleCell( int aRow, int aCol );
virtual void paste_clipboard();
virtual void paste_text( const wxString& cb_text );

View File

@ -24,19 +24,19 @@
#include <wx/grid.h>
const wxColour COLOUR_ROW_ENABLED( 0, 0, 0 );
const wxColour COLOUR_ROW_DISABLED( 100, 100, 100 );
const wxColour COLOUR_ROW_ENABLED( 0, 0, 0 );
const wxColour COLOUR_ROW_DISABLED( 100, 100, 100 );
/// The library table grid column order is established by this sequence.
enum COL_ORDER
{
COL_ENABLED,
COL_ENABLED,
COL_NICKNAME,
COL_URI,
COL_TYPE,
COL_OPTIONS,
COL_DESCR,
COL_COUNT // keep as last
};
@ -67,8 +67,8 @@ public:
case COL_TYPE: return r->GetType();
case COL_OPTIONS: return r->GetOptions();
case COL_DESCR: return r->GetDescr();
// Render a boolean value as its text equivalent
case COL_ENABLED: return r->GetIsEnabled() ? "1" : "";
// Render a boolean value as its text equivalent
case COL_ENABLED: return r->GetIsEnabled() ? wxT( "1" ) : wxT( "0" );
default:
; // fall thru to wxEmptyString
}
@ -77,6 +77,14 @@ public:
return wxEmptyString;
}
bool GetValueAsBool( int aRow, int aCol ) override
{
if( aRow < (int) size() && aCol == COL_ENABLED )
return at( (size_t) aRow )->GetIsEnabled();
else
return false;
}
void SetValue( int aRow, int aCol, const wxString &aValue ) override
{
if( aRow < (int) size() )
@ -90,14 +98,19 @@ public:
case COL_TYPE: r->SetType( aValue ); break;
case COL_OPTIONS: r->SetOptions( aValue ); break;
case COL_DESCR: r->SetDescr( aValue ); break;
case COL_ENABLED:
// Any non-empty string will set enabled to true
r->SetEnabled( !aValue.IsEmpty() );
break;
case COL_ENABLED:
r->SetEnabled( aValue == wxT( "1" ) );
break;
}
}
}
void SetValueAsBool( int aRow, int aCol, bool aValue ) override
{
if( aRow < (int) size() && aCol == COL_ENABLED )
at( (size_t) aRow )->SetEnabled( aValue );
}
bool IsEmptyCell( int aRow, int aCol ) override
{
return !GetValue( aRow, aCol );
@ -183,12 +196,12 @@ public:
case COL_TYPE: return _( "Plugin Type" );
case COL_OPTIONS: return _( "Options" );
case COL_DESCR: return _( "Description" );
case COL_ENABLED: return _( "Active" );
case COL_ENABLED: return _( "Active" );
default: return wxEmptyString;
}
}
}
protected:
virtual LIB_TABLE_ROW* at( size_t aIndex ) = 0;

View File

@ -66,7 +66,6 @@ DIALOG_FOOTPRINT_WIZARD_LIST::DIALOG_FOOTPRINT_WIZARD_LIST( wxWindow* aParent )
SetSize( size );
}
m_sdbSizerOK->SetDefault();
FinishDialogSettings();

View File

@ -208,8 +208,8 @@ public:
g->SetColAttr( COL_TYPE, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellBoolEditor() );
attr->SetRenderer( new wxGridCellBoolRenderer() );
attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
g->SetColAttr( COL_ENABLED, attr );
// all but COL_OPTIONS, which is edited with Option Editor anyways.

View File

@ -37,6 +37,7 @@
#include <msgpanel.h>
#include <macros.h>
#include <bitmaps.h>
#include <grid_tricks.h>
#include <class_board.h>
#include <class_module.h>
@ -85,8 +86,6 @@ BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList )
EVT_GRID_CMD_CELL_CHANGED( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
EVT_GRID_CMD_CELL_LEFT_CLICK( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::OnParameterCellClick )
EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
END_EVENT_TABLE()
@ -164,6 +163,7 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
// Creates the list of parameters for the current parameter page
m_parameterGridPage = -1;
initParameterGrid();
m_parameterGrid->PushEventHandler( new GRID_TRICKS( m_parameterGrid ) );
ReCreatePageList();
@ -229,6 +229,9 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME()
{
// Delete the GRID_TRICKS.
m_parameterGrid->PopEventHandler( true );
EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame();
if( draw3DFrame )
@ -311,9 +314,6 @@ void FOOTPRINT_WIZARD_FRAME::initParameterGrid()
m_parameterGrid->Connect( wxEVT_SIZE,
wxSizeEventHandler( FOOTPRINT_WIZARD_FRAME::OnGridSize ),
NULL, this );
m_parameterGrid->Connect( wxEVT_KEY_UP,
wxKeyEventHandler( FOOTPRINT_WIZARD_FRAME::OnParameterGridKeyPress ),
NULL, this );
}
@ -391,14 +391,10 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
m_parameterGrid->SetReadOnly( i, WIZ_COL_NAME );
m_parameterGrid->SetCellAlignment( i, WIZ_COL_NAME, wxALIGN_LEFT, wxALIGN_CENTRE );
// Set the editor type of the
// Boolean parameters are displayed using a checkbox
if( units == WIZARD_PARAM_UNITS_BOOL )
{
// NOTE: Not using wxGridCellBoolEditor because it doesn't work well
// Setting read-only to disable the grid editor; value will be
// updated by the OnParameterCellClick event handler.
// Set to ReadOnly as we delegate interactivity to GRID_TRICKS
m_parameterGrid->SetReadOnly( i, WIZ_COL_VALUE );
m_parameterGrid->SetCellRenderer( i, WIZ_COL_VALUE, new wxGridCellBoolRenderer );
}

View File

@ -195,10 +195,6 @@ private:
*/
void ParametersUpdated( wxGridEvent& event );
void OnParameterCellClick( wxGridEvent& event );
void OnParameterGridKeyPress( wxKeyEvent& event );
bool OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu ) override;
/**

View File

@ -290,93 +290,6 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
}
void FOOTPRINT_WIZARD_FRAME::OnParameterCellClick( wxGridEvent& event )
{
auto footprintWizard = GetMyWizard();
if( !footprintWizard )
return;
if( m_parameterGridPage < 0 )
return;
if( event.GetCol() != WIZ_COL_VALUE )
return;
auto types = footprintWizard->GetParameterTypes( m_parameterGridPage );
auto values = footprintWizard->GetParameterValues( m_parameterGridPage );
int row = event.GetRow();
bool has_changed = false;
// Handle toggling of boolean parameters
if( types[row] == WIZARD_PARAM_UNITS_BOOL )
{
has_changed = true;
values[row] = ( values[row] == "1" ) ? "0" : "1";
m_parameterGrid->SetCellValue( row, WIZ_COL_VALUE, values[row] );
}
else
{
event.Skip();
}
if( has_changed )
{
wxString res = footprintWizard->SetParameterValues( m_parameterGridPage, values );
if( !res.IsEmpty() )
wxMessageBox( res );
ReloadFootprint();
DisplayWizardInfos();
}
}
void FOOTPRINT_WIZARD_FRAME::OnParameterGridKeyPress( wxKeyEvent& event )
{
auto footprintWizard = GetMyWizard();
int row = m_parameterGrid->GetGridCursorRow();
int col = m_parameterGrid->GetGridCursorCol();
bool has_changed = false;
if( !footprintWizard || m_parameterGridPage < 0 ||
col != WIZ_COL_VALUE || event.GetKeyCode() != ' ' )
{
event.Skip();
return;
}
auto types = footprintWizard->GetParameterTypes( m_parameterGridPage );
auto values = footprintWizard->GetParameterValues( m_parameterGridPage );
// Handle toggling of boolean parameters when user presses space
if( types[row] == WIZARD_PARAM_UNITS_BOOL )
{
has_changed = true;
values[row] = ( values[row] == "1" ) ? "0" : "1";
m_parameterGrid->SetCellValue( row, WIZ_COL_VALUE, values[row] );
}
else
{
m_parameterGrid->EnableCellEditControl();
}
if( has_changed )
{
wxString res = footprintWizard->SetParameterValues( m_parameterGridPage, values );
if( !res.IsEmpty() )
wxMessageBox( res );
ReloadFootprint();
DisplayWizardInfos();
}
}
/**
* Function RedrawActiveWindow
* Display the current selected component.