Add wxGridCellActivatableEditor and show it in the grid sample
Add a helper class making it easier to define activation-only editors and use it to implement MyGridStarEditor in the sample, showing a typical example of using such editor.
This commit is contained in:
@@ -523,6 +523,34 @@ protected:
|
|||||||
// Smart pointer to wxGridCellEditor, calling DecRef() on it automatically.
|
// Smart pointer to wxGridCellEditor, calling DecRef() on it automatically.
|
||||||
typedef wxObjectDataPtr<wxGridCellEditor> wxGridCellEditorPtr;
|
typedef wxObjectDataPtr<wxGridCellEditor> wxGridCellEditorPtr;
|
||||||
|
|
||||||
|
// Base class for editors that can be only activated and not edited normally.
|
||||||
|
class wxGridCellActivatableEditor : public wxGridCellEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// In this class these methods must be overridden.
|
||||||
|
virtual wxGridActivationResult
|
||||||
|
TryActivate(int row, int col, wxGrid* grid,
|
||||||
|
const wxGridActivationSource& actSource) = 0;
|
||||||
|
virtual void DoActivate(int row, int col, wxGrid* grid) = 0;
|
||||||
|
|
||||||
|
// All the other methods that normally must be implemented in an editor are
|
||||||
|
// defined as just stubs below, as they should be never called.
|
||||||
|
|
||||||
|
virtual void Create(wxWindow*, wxWindowID, wxEvtHandler*) wxOVERRIDE
|
||||||
|
{ wxFAIL; }
|
||||||
|
virtual void BeginEdit(int, int, wxGrid*) wxOVERRIDE
|
||||||
|
{ wxFAIL; }
|
||||||
|
virtual bool EndEdit(int, int, const wxGrid*,
|
||||||
|
const wxString&, wxString*) wxOVERRIDE
|
||||||
|
{ wxFAIL; return false; }
|
||||||
|
virtual void ApplyEdit(int, int, wxGrid*) wxOVERRIDE
|
||||||
|
{ wxFAIL; }
|
||||||
|
virtual void Reset() wxOVERRIDE
|
||||||
|
{ wxFAIL; }
|
||||||
|
virtual wxString GetValue() const wxOVERRIDE
|
||||||
|
{ wxFAIL; return wxString(); }
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxGridHeaderRenderer and company: like wxGridCellRenderer but for headers
|
// wxGridHeaderRenderer and company: like wxGridCellRenderer but for headers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -551,7 +551,10 @@ public:
|
|||||||
the cell, but starting with wxWidgets 3.1.4 it's also possible to define
|
the cell, but starting with wxWidgets 3.1.4 it's also possible to define
|
||||||
"activatable" cell editors, that change the value of the cell directly when
|
"activatable" cell editors, that change the value of the cell directly when
|
||||||
it's activated (typically by pressing Space key or clicking on it), see
|
it's activated (typically by pressing Space key or clicking on it), see
|
||||||
TryActivate() method.
|
TryActivate() method. Note that when implementing an editor which is always
|
||||||
|
activatable, i.e. never shows any in-place editor, it is more convenient to
|
||||||
|
derive its class from wxGridCellActivatableEditor than from wxGridCellEditor
|
||||||
|
itself.
|
||||||
|
|
||||||
@library{wxcore}
|
@library{wxcore}
|
||||||
@category{grid}
|
@category{grid}
|
||||||
@@ -767,6 +770,34 @@ protected:
|
|||||||
virtual ~wxGridCellEditor();
|
virtual ~wxGridCellEditor();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Base class for activatable editors.
|
||||||
|
|
||||||
|
Inheriting from this class makes it simpler to implement editors that
|
||||||
|
support only activation, but not in-place editing, as they only need to
|
||||||
|
implement TryActivate(), DoActivate() and Clone() methods, but not all the
|
||||||
|
other pure virtual methods of wxGridCellEditor.
|
||||||
|
|
||||||
|
@since 3.1.4
|
||||||
|
*/
|
||||||
|
class wxGridCellActivatableEditor : public wxGridCellEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Same method as in wxGridCellEditor, but pure virtual.
|
||||||
|
|
||||||
|
Note that the implementation of this method must never return
|
||||||
|
wxGridActivationResult::DoEdit() for the editors inheriting from this
|
||||||
|
class, as it doesn't support normal editing.
|
||||||
|
*/
|
||||||
|
virtual wxGridActivationResult
|
||||||
|
TryActivate(int row, int col, wxGrid* grid,
|
||||||
|
const wxGridActivationSource& actSource) = 0;
|
||||||
|
|
||||||
|
/// Same method as in wxGridCellEditor, but pure virtual.
|
||||||
|
virtual void DoActivate(int row, int col, wxGrid* grid) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Smart pointer wrapping wxGridCellEditor.
|
Smart pointer wrapping wxGridCellEditor.
|
||||||
|
|
||||||
|
@@ -121,6 +121,135 @@ private:
|
|||||||
wxDECLARE_NO_COPY_CLASS(CustomColumnHeadersProvider);
|
wxDECLARE_NO_COPY_CLASS(CustomColumnHeadersProvider);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Custom wxGrid renderer and editor for showing stars as used for rating
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Max number of stars shown by MyGridStarRenderer.
|
||||||
|
static const int MAX_STARS = 5;
|
||||||
|
|
||||||
|
// Helper function returning the number between 0 and MAX_STARS corresponding
|
||||||
|
// to the value of the cell.
|
||||||
|
static int GetStarValue(wxGrid& grid, int row, int col)
|
||||||
|
{
|
||||||
|
unsigned long n = 0;
|
||||||
|
if ( !grid.GetCellValue(row, col).ToULong(&n) || n > MAX_STARS )
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
return static_cast<int>(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Another helper returning the string containing the appropriate number of
|
||||||
|
// black and white stars.
|
||||||
|
static wxString GetStarString(int numBlackStars)
|
||||||
|
{
|
||||||
|
const wxUniChar BLACK_STAR = 0x2605;
|
||||||
|
const wxUniChar WHITE_STAR = 0x2606;
|
||||||
|
|
||||||
|
return wxString(BLACK_STAR, numBlackStars) +
|
||||||
|
wxString(WHITE_STAR, MAX_STARS - numBlackStars);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders the value of the cell, which is supposed to be a number between 1
|
||||||
|
// and 5, as a sequence of that number of black stars followed by the number of
|
||||||
|
// white stars needed to have 5 stars in total.
|
||||||
|
class MyGridStarRenderer : public wxGridCellRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Draw(wxGrid& grid,
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
const wxRect& rect,
|
||||||
|
int row, int col,
|
||||||
|
bool isSelected) wxOVERRIDE
|
||||||
|
{
|
||||||
|
wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
||||||
|
|
||||||
|
grid.DrawTextRectangle(dc, GetStarString(GetStarValue(grid, row, col)),
|
||||||
|
rect, attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual wxSize GetBestSize(wxGrid& WXUNUSED(grid),
|
||||||
|
wxGridCellAttr& attr,
|
||||||
|
wxDC& dc,
|
||||||
|
int WXUNUSED(row),
|
||||||
|
int WXUNUSED(col)) wxOVERRIDE
|
||||||
|
{
|
||||||
|
dc.SetFont(attr.GetFont());
|
||||||
|
return dc.GetTextExtent(GetStarString(MAX_STARS));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual wxGridCellRenderer *Clone() const wxOVERRIDE
|
||||||
|
{
|
||||||
|
return new MyGridStarRenderer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Activatable editor cycling the number of stars on each activation.
|
||||||
|
class MyGridStarEditor : public wxGridCellActivatableEditor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual wxGridActivationResult
|
||||||
|
TryActivate(int row, int col, wxGrid* grid,
|
||||||
|
const wxGridActivationSource& actSource) wxOVERRIDE
|
||||||
|
{
|
||||||
|
int numStars = -1;
|
||||||
|
|
||||||
|
switch ( actSource.GetOrigin() )
|
||||||
|
{
|
||||||
|
case wxGridActivationSource::Program:
|
||||||
|
// It isn't really possible to programmatically start editing a
|
||||||
|
// cell using this editor.
|
||||||
|
return wxGridActivationResult::DoNothing();
|
||||||
|
|
||||||
|
case wxGridActivationSource::Key:
|
||||||
|
switch ( actSource.GetKeyEvent().GetKeyCode() )
|
||||||
|
{
|
||||||
|
case '0': numStars = 0; break;
|
||||||
|
case '1': numStars = 1; break;
|
||||||
|
case '2': numStars = 2; break;
|
||||||
|
case '3': numStars = 3; break;
|
||||||
|
case '4': numStars = 4; break;
|
||||||
|
case '5': numStars = 5; break;
|
||||||
|
case ' ':
|
||||||
|
// Use space key to cycle over the values.
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return wxGridActivationResult::DoNothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wxGridActivationSource::Mouse:
|
||||||
|
// Ideally we should use the mouse event position to determine
|
||||||
|
// on which star the user clicked, but for now keep it simple
|
||||||
|
// and just cycle through the star value.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( numStars == -1 )
|
||||||
|
numStars = (GetStarValue(*grid, row, col) + 1) % (MAX_STARS + 1);
|
||||||
|
|
||||||
|
m_value.Printf("%d", numStars);
|
||||||
|
|
||||||
|
return wxGridActivationResult::DoChange(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void DoActivate(int row, int col, wxGrid* grid) wxOVERRIDE
|
||||||
|
{
|
||||||
|
grid->SetCellValue(row, col, m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual wxGridCellEditor *Clone() const
|
||||||
|
{
|
||||||
|
return new MyGridStarEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString m_value;
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxWin macros
|
// wxWin macros
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -517,6 +646,10 @@ GridFrame::GridFrame()
|
|||||||
grid->SetCellAlignment(4, 4, wxALIGN_CENTRE, wxALIGN_CENTRE);
|
grid->SetCellAlignment(4, 4, wxALIGN_CENTRE, wxALIGN_CENTRE);
|
||||||
grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
|
grid->SetCellRenderer(4, 4, new MyGridCellRenderer);
|
||||||
|
|
||||||
|
grid->SetCellValue(4, 5, "3");
|
||||||
|
grid->SetCellRenderer(4, 5, new MyGridStarRenderer);
|
||||||
|
grid->SetCellEditor(4, 5, new MyGridStarEditor);
|
||||||
|
|
||||||
grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
|
grid->SetCellRenderer(3, 0, new wxGridCellBoolRenderer);
|
||||||
grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
|
grid->SetCellEditor(3, 0, new wxGridCellBoolEditor);
|
||||||
grid->SetCellBackgroundColour(3, 0, wxColour(255, 127, 127));
|
grid->SetCellBackgroundColour(3, 0, wxColour(255, 127, 127));
|
||||||
|
Reference in New Issue
Block a user