added renderers/editors for long/float, not fully tested yet, but seems to
work - see the demo in the (updated) sample git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6210 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -32,6 +32,10 @@
|
||||
#include "wx/dynarray.h"
|
||||
#include "wx/timer.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Default parameters for wxGrid
|
||||
//
|
||||
#define WXGRID_DEFAULT_NUMBER_ROWS 10
|
||||
@@ -49,6 +53,15 @@
|
||||
#define WXGRID_MIN_COL_WIDTH 15
|
||||
#define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16
|
||||
|
||||
// type names for grid table values
|
||||
#define wxGRID_VALUE_STRING _T("string")
|
||||
#define wxGRID_VALUE_BOOL _T("bool")
|
||||
#define wxGRID_VALUE_NUMBER _T("long")
|
||||
#define wxGRID_VALUE_FLOAT _T("double")
|
||||
|
||||
#define wxGRID_VALUE_TEXT wxGRID_VALUE_STRING
|
||||
#define wxGRID_VALUE_LONG wxGRID_VALUE_NUMBER
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// forward declarations
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -65,6 +78,7 @@ class WXDLLEXPORT wxGridTypeRegistry;
|
||||
|
||||
class WXDLLEXPORT wxCheckBox;
|
||||
class WXDLLEXPORT wxTextCtrl;
|
||||
class WXDLLEXPORT wxSpinCtrl;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellRenderer: this class is responsible for actually drawing the cell
|
||||
@@ -90,6 +104,9 @@ public:
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected) = 0;
|
||||
|
||||
// virtual dtor for any base class
|
||||
virtual ~wxGridCellRenderer();
|
||||
};
|
||||
|
||||
// the default renderer for the cells containing string data
|
||||
@@ -103,13 +120,59 @@ public:
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected);
|
||||
|
||||
protected:
|
||||
// set the text colours before drawing
|
||||
void SetTextColoursAndFont(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
bool isSelected);
|
||||
};
|
||||
|
||||
// the default renderer for the cells containing numeric (long) data
|
||||
class WXDLLEXPORT wxGridCellNumberRenderer : public wxGridCellStringRenderer
|
||||
{
|
||||
public:
|
||||
// draw the string right aligned
|
||||
virtual void Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected);
|
||||
};
|
||||
|
||||
class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer
|
||||
{
|
||||
public:
|
||||
wxGridCellFloatRenderer(int width, int precision);
|
||||
|
||||
// get/change formatting parameters
|
||||
int GetWidth() const { return m_width; }
|
||||
void SetWidth(int width) { m_width = width; }
|
||||
int GetPrecision() const { return m_precision; }
|
||||
void SetPrecision(int precision) { m_precision = precision; }
|
||||
|
||||
// draw the string right aligned with given width/precision
|
||||
virtual void Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int row, int col,
|
||||
bool isSelected);
|
||||
|
||||
private:
|
||||
// formatting parameters
|
||||
int m_width,
|
||||
m_precision;
|
||||
|
||||
wxString m_format;
|
||||
};
|
||||
|
||||
// renderer for boolean fields
|
||||
class WXDLLEXPORT wxGridCellBoolRenderer : public wxGridCellRenderer
|
||||
{
|
||||
public:
|
||||
|
||||
// draw a check mark or nothing
|
||||
virtual void Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
@@ -215,10 +278,72 @@ public:
|
||||
protected:
|
||||
wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; }
|
||||
|
||||
// parts of our virtual functions reused by the derived classes
|
||||
void DoBeginEdit(const wxString& startValue);
|
||||
void DoReset(const wxString& startValue);
|
||||
|
||||
private:
|
||||
wxString m_startValue;
|
||||
};
|
||||
|
||||
// the editor for numeric (long) data
|
||||
class WXDLLEXPORT wxGridCellNumberEditor : public wxGridCellTextEditor
|
||||
{
|
||||
public:
|
||||
// allows to specify the range - if min == max == -1, no range checking is
|
||||
// done
|
||||
wxGridCellNumberEditor(int min = -1, int max = -1);
|
||||
|
||||
virtual void Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler);
|
||||
|
||||
virtual void BeginEdit(int row, int col, wxGrid* grid);
|
||||
virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void StartingKey(wxKeyEvent& event);
|
||||
|
||||
protected:
|
||||
wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; }
|
||||
|
||||
// if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl
|
||||
bool HasRange() const { return m_min != m_max; }
|
||||
|
||||
// string representation of m_valueOld
|
||||
wxString GetString() const
|
||||
{ return wxString::Format(_T("%ld"), m_valueOld); }
|
||||
|
||||
private:
|
||||
int m_min,
|
||||
m_max;
|
||||
|
||||
long m_valueOld;
|
||||
};
|
||||
|
||||
// the editor for floating point numbers (double) data
|
||||
class WXDLLEXPORT wxGridCellFloatEditor : public wxGridCellTextEditor
|
||||
{
|
||||
public:
|
||||
virtual void Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler);
|
||||
|
||||
virtual void BeginEdit(int row, int col, wxGrid* grid);
|
||||
virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid);
|
||||
|
||||
virtual void Reset();
|
||||
virtual void StartingKey(wxKeyEvent& event);
|
||||
|
||||
protected:
|
||||
// string representation of m_valueOld
|
||||
wxString GetString() const
|
||||
{ return wxString::Format(_T("%f"), m_valueOld); }
|
||||
|
||||
private:
|
||||
double m_valueOld;
|
||||
};
|
||||
|
||||
// the editor for boolean data
|
||||
class WXDLLEXPORT wxGridCellBoolEditor : public wxGridCellEditor
|
||||
{
|
||||
|
@@ -186,10 +186,8 @@ GridFrame::GridFrame()
|
||||
logger->SetTimestamp( NULL );
|
||||
|
||||
// this will create a grid and, by default, an associated grid
|
||||
// table for string data
|
||||
//
|
||||
//grid->CreateGrid( 100, 100 );
|
||||
grid->SetTable(new SimpleTable(100, 100), TRUE);
|
||||
// table for string gs_dataBugsGrid
|
||||
grid->CreateGrid( 100, 100 );
|
||||
|
||||
grid->SetRowSize( 0, 60 );
|
||||
grid->SetCellValue( 0, 0, "Ctrl+Home\nwill go to\nthis cell" );
|
||||
@@ -695,74 +693,274 @@ BigGridFrame::BigGridFrame(long sizeGrid)
|
||||
// BugsGridFrame: a "realistic" table
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
enum Columns
|
||||
{
|
||||
Col_Id,
|
||||
Col_Summary,
|
||||
Col_Severity,
|
||||
Col_Priority,
|
||||
Col_Platform,
|
||||
Col_Opened,
|
||||
Col_Max
|
||||
};
|
||||
|
||||
enum Severity
|
||||
{
|
||||
Sev_Wish,
|
||||
Sev_Minor,
|
||||
Sev_Normal,
|
||||
Sev_Major,
|
||||
Sev_Critical,
|
||||
Sev_Max
|
||||
};
|
||||
|
||||
static const wxChar* severities[] =
|
||||
{
|
||||
_T("wishlist"),
|
||||
_T("minor"),
|
||||
_T("normal"),
|
||||
_T("major"),
|
||||
_T("critical"),
|
||||
};
|
||||
|
||||
static struct BugsGridData
|
||||
{
|
||||
int id;
|
||||
const wxChar *summary;
|
||||
Severity severity;
|
||||
int prio;
|
||||
const wxChar *platform;
|
||||
bool opened;
|
||||
} gs_dataBugsGrid [] =
|
||||
{
|
||||
{ 18, _T("foo doesn't work"), Sev_Major, 1, _T("wxMSW"), TRUE },
|
||||
{ 27, _T("bar crashes"), Sev_Critical, 1, _T("all"), FALSE },
|
||||
{ 45, _T("printing is slow"), Sev_Minor, 3, _T("wxMSW"), TRUE },
|
||||
{ 68, _T("Rectangle() fails"), Sev_Normal, 1, _T("wxMSW"), FALSE },
|
||||
};
|
||||
|
||||
static const wxChar *headers[Col_Max] =
|
||||
{
|
||||
_T("Id"),
|
||||
_T("Summary"),
|
||||
_T("Severity"),
|
||||
_T("Priority"),
|
||||
_T("Platform"),
|
||||
_T("Opened?"),
|
||||
};
|
||||
|
||||
wxString BugsGridTable::GetTypeName(int WXUNUSED(row), int col)
|
||||
{
|
||||
switch ( col )
|
||||
{
|
||||
case Col_Id:
|
||||
case Col_Priority:
|
||||
return wxGRID_VALUE_NUMBER;;
|
||||
|
||||
case Col_Severity:
|
||||
// fall thorugh (TODO should be a list)
|
||||
|
||||
case Col_Summary:
|
||||
case Col_Platform:
|
||||
return wxGRID_VALUE_STRING;
|
||||
|
||||
case Col_Opened:
|
||||
return wxGRID_VALUE_BOOL;
|
||||
}
|
||||
|
||||
wxFAIL_MSG(_T("unknown column"));
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
long BugsGridTable::GetNumberRows()
|
||||
{
|
||||
return WXSIZEOF(gs_dataBugsGrid);
|
||||
}
|
||||
|
||||
long BugsGridTable::GetNumberCols()
|
||||
{
|
||||
return Col_Max;
|
||||
}
|
||||
|
||||
bool BugsGridTable::IsEmptyCell( int row, int col )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wxString BugsGridTable::GetValue( int row, int col )
|
||||
{
|
||||
const BugsGridData& gd = gs_dataBugsGrid[row];
|
||||
|
||||
switch ( col )
|
||||
{
|
||||
case Col_Id:
|
||||
case Col_Priority:
|
||||
case Col_Opened:
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
break;
|
||||
|
||||
case Col_Severity:
|
||||
return severities[gd.severity];
|
||||
|
||||
case Col_Summary:
|
||||
return gd.summary;
|
||||
|
||||
case Col_Platform:
|
||||
return gd.platform;
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
void BugsGridTable::SetValue( int row, int col, const wxString& value )
|
||||
{
|
||||
BugsGridData& gd = gs_dataBugsGrid[row];
|
||||
|
||||
switch ( col )
|
||||
{
|
||||
case Col_Id:
|
||||
case Col_Priority:
|
||||
case Col_Opened:
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
break;
|
||||
|
||||
case Col_Severity:
|
||||
{
|
||||
size_t n;
|
||||
for ( n = 0; n < WXSIZEOF(severities); n++ )
|
||||
{
|
||||
if ( severities[n] == value )
|
||||
{
|
||||
gd.severity = (Severity)n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( n == WXSIZEOF(severities) )
|
||||
{
|
||||
wxLogWarning(_T("Invalid severity value '%s'."),
|
||||
value.c_str());
|
||||
gd.severity = Sev_Normal;
|
||||
}
|
||||
}
|
||||
|
||||
case Col_Summary:
|
||||
gd.summary = value;
|
||||
break;
|
||||
|
||||
case Col_Platform:
|
||||
gd.platform = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool BugsGridTable::CanGetValueAs( int WXUNUSED(row), int col, const wxString& typeName )
|
||||
{
|
||||
if ( typeName == wxGRID_VALUE_STRING )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if ( typeName == wxGRID_VALUE_BOOL )
|
||||
{
|
||||
return col == Col_Opened;
|
||||
}
|
||||
else if ( typeName == wxGRID_VALUE_NUMBER )
|
||||
{
|
||||
return col == Col_Id || col == Col_Priority || col == Col_Severity;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool BugsGridTable::CanSetValueAs( int row, int col, const wxString& typeName )
|
||||
{
|
||||
return CanGetValueAs(row, col, typeName);
|
||||
}
|
||||
|
||||
long BugsGridTable::GetValueAsLong( int row, int col )
|
||||
{
|
||||
const BugsGridData& gd = gs_dataBugsGrid[row];
|
||||
|
||||
switch ( col )
|
||||
{
|
||||
case Col_Id:
|
||||
return gd.id;
|
||||
|
||||
case Col_Priority:
|
||||
return gd.prio;
|
||||
|
||||
case Col_Severity:
|
||||
return gd.severity;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool BugsGridTable::GetValueAsBool( int row, int col )
|
||||
{
|
||||
if ( col == Col_Opened )
|
||||
{
|
||||
return gs_dataBugsGrid[row].opened;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void BugsGridTable::SetValueAsLong( int row, int col, long value )
|
||||
{
|
||||
BugsGridData& gd = gs_dataBugsGrid[row];
|
||||
|
||||
switch ( col )
|
||||
{
|
||||
case Col_Priority:
|
||||
gd.prio = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
}
|
||||
}
|
||||
|
||||
void BugsGridTable::SetValueAsBool( int row, int col, bool value )
|
||||
{
|
||||
if ( col == Col_Opened )
|
||||
{
|
||||
gs_dataBugsGrid[row].opened = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(_T("unexpected column"));
|
||||
}
|
||||
}
|
||||
|
||||
wxString BugsGridTable::GetColLabelValue( int col )
|
||||
{
|
||||
return headers[col];
|
||||
}
|
||||
|
||||
BugsGridTable::BugsGridTable()
|
||||
{
|
||||
}
|
||||
|
||||
BugsGridFrame::BugsGridFrame()
|
||||
: wxFrame(NULL, -1, "Bugs table",
|
||||
wxDefaultPosition, wxSize(500, 300))
|
||||
{
|
||||
enum Severity
|
||||
{
|
||||
Wish,
|
||||
Minor,
|
||||
Normal,
|
||||
Major,
|
||||
Critical
|
||||
};
|
||||
|
||||
static const wxChar* severities[] =
|
||||
{
|
||||
_T("wishlist"),
|
||||
_T("minor"),
|
||||
_T("normal"),
|
||||
_T("major"),
|
||||
_T("critical"),
|
||||
};
|
||||
|
||||
static const struct GridData
|
||||
{
|
||||
int id;
|
||||
const wxChar *summary;
|
||||
Severity severity;
|
||||
int prio;
|
||||
const wxChar *platform;
|
||||
bool opened;
|
||||
} data [] =
|
||||
{
|
||||
{ 18, _T("foo doesn't work"), Major, 1, _T("wxMSW"), TRUE },
|
||||
{ 27, _T("bar crashes"), Critical, 1, _T("all"), FALSE },
|
||||
{ 45, _T("printing is slow"), Minor, 3, _T("wxMSW"), TRUE },
|
||||
{ 68, _T("Rectangle() fails"), Normal, 1, _T("wxMSW"), FALSE },
|
||||
};
|
||||
|
||||
static const wxChar *headers[] =
|
||||
{
|
||||
_T("Id"),
|
||||
_T("Summary"),
|
||||
_T("Severity"),
|
||||
_T("Priority"),
|
||||
_T("Platform"),
|
||||
_T("Opened?"),
|
||||
};
|
||||
|
||||
// TODO the correct data type must be used for each column
|
||||
|
||||
wxGrid *grid = new wxGrid(this, -1, wxDefaultPosition);
|
||||
wxGridTableBase *table =
|
||||
new wxGridStringTable(WXSIZEOF(data), WXSIZEOF(headers));
|
||||
for ( size_t row = 0; row < WXSIZEOF(data); row++ )
|
||||
{
|
||||
const GridData& gd = data[row];
|
||||
table->SetValue(row, 0, wxString::Format("%d", gd.id));
|
||||
table->SetValue(row, 1, gd.summary);
|
||||
table->SetValue(row, 2, severities[gd.severity]);
|
||||
table->SetValue(row, 3, wxString::Format("%d", gd.prio));
|
||||
table->SetValue(row, 4, gd.platform);
|
||||
table->SetValue(row, 5, gd.opened ? _T("True") : wxEmptyString);
|
||||
}
|
||||
|
||||
for ( size_t col = 0; col < WXSIZEOF(headers); col++ )
|
||||
{
|
||||
table->SetColLabelValue(col, headers[col]);
|
||||
}
|
||||
|
||||
wxGridTableBase *table = new BugsGridTable();
|
||||
grid->SetTable(table, TRUE);
|
||||
|
||||
for ( size_t row = 0; row < WXSIZEOF(gs_dataBugsGrid); row++ )
|
||||
{
|
||||
grid->SetReadOnly(row, Col_Id);
|
||||
}
|
||||
}
|
||||
|
@@ -125,24 +125,6 @@ public:
|
||||
// memory
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class SimpleTable : public wxGridStringTable {
|
||||
public:
|
||||
SimpleTable( int numRows, int numCols )
|
||||
: wxGridStringTable( numRows, numCols ) {}
|
||||
|
||||
// override this to fake a row as all bools
|
||||
wxString GetTypeName( int row, int col )
|
||||
{
|
||||
if (row == 8)
|
||||
return wxT("bool");
|
||||
else if (row == 9 && col == 1)
|
||||
return wxT("unknown type"); // to test fallback
|
||||
else
|
||||
return wxGridStringTable::GetTypeName(row, col);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class BigGridTable : public wxGridTableBase
|
||||
{
|
||||
public:
|
||||
@@ -173,9 +155,33 @@ private:
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// another, more realistic, grid example
|
||||
// another, more realistic, grid example: shows typed columns and more
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class BugsGridTable : public wxGridTableBase
|
||||
{
|
||||
public:
|
||||
BugsGridTable();
|
||||
|
||||
virtual long GetNumberRows();
|
||||
virtual long GetNumberCols();
|
||||
virtual bool IsEmptyCell( int row, int col );
|
||||
virtual wxString GetValue( int row, int col );
|
||||
virtual void SetValue( int row, int col, const wxString& value );
|
||||
|
||||
virtual wxString GetColLabelValue( int col );
|
||||
|
||||
virtual wxString GetTypeName( int row, int col );
|
||||
virtual bool CanGetValueAs( int row, int col, const wxString& typeName );
|
||||
virtual bool CanSetValueAs( int row, int col, const wxString& typeName );
|
||||
|
||||
virtual long GetValueAsLong( int row, int col );
|
||||
virtual bool GetValueAsBool( int row, int col );
|
||||
|
||||
virtual void SetValueAsLong( int row, int col, long value );
|
||||
virtual void SetValueAsBool( int row, int col, bool value );
|
||||
};
|
||||
|
||||
class BugsGridFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
|
@@ -41,10 +41,11 @@
|
||||
#include "wx/log.h"
|
||||
#include "wx/textctrl.h"
|
||||
#include "wx/checkbox.h"
|
||||
#include "wx/valtext.h"
|
||||
#endif
|
||||
|
||||
// this include needs to be outside precomp for BCC
|
||||
#include "wx/textfile.h"
|
||||
#include "wx/spinctrl.h"
|
||||
|
||||
#include "wx/grid.h"
|
||||
|
||||
@@ -500,12 +501,17 @@ void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
wxT("The wxGridCellEditor must be Created first!"));
|
||||
|
||||
m_startValue = grid->GetTable()->GetValue(row, col);
|
||||
Text()->SetValue(m_startValue);
|
||||
|
||||
DoBeginEdit(m_startValue);
|
||||
}
|
||||
|
||||
void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue)
|
||||
{
|
||||
Text()->SetValue(startValue);
|
||||
Text()->SetInsertionPointEnd();
|
||||
Text()->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue,
|
||||
wxGrid* grid)
|
||||
{
|
||||
@@ -532,7 +538,12 @@ void wxGridCellTextEditor::Reset()
|
||||
wxASSERT_MSG(m_control,
|
||||
wxT("The wxGridCellEditor must be Created first!"));
|
||||
|
||||
Text()->SetValue(m_startValue);
|
||||
DoReset(m_startValue);
|
||||
}
|
||||
|
||||
void wxGridCellTextEditor::DoReset(const wxString& startValue)
|
||||
{
|
||||
Text()->SetValue(startValue);
|
||||
Text()->SetInsertionPointEnd();
|
||||
}
|
||||
|
||||
@@ -576,6 +587,187 @@ void wxGridCellTextEditor::HandleReturn(wxKeyEvent& event)
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellNumberEditor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max)
|
||||
{
|
||||
m_min = min;
|
||||
m_max = max;
|
||||
}
|
||||
|
||||
void wxGridCellNumberEditor::Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler)
|
||||
{
|
||||
if ( HasRange() )
|
||||
{
|
||||
// create a spin ctrl
|
||||
m_control = new wxSpinCtrl(parent, -1, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxSP_ARROW_KEYS,
|
||||
m_min, m_max);
|
||||
|
||||
wxGridCellEditor::Create(parent, id, evtHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just a text control
|
||||
wxGridCellTextEditor::Create(parent, id, evtHandler);
|
||||
|
||||
#if wxUSE_VALIDATORS
|
||||
Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC));
|
||||
#endif // wxUSE_VALIDATORS
|
||||
}
|
||||
}
|
||||
|
||||
void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
{
|
||||
// first get the value
|
||||
wxGridTableBase *table = grid->GetTable();
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
|
||||
{
|
||||
m_valueOld = table->GetValueAsLong(row, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG( _T("this cell doesn't have numeric value") );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( HasRange() )
|
||||
{
|
||||
Spin()->SetValue(m_valueOld);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoBeginEdit(GetString());
|
||||
}
|
||||
}
|
||||
|
||||
bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue,
|
||||
wxGrid* grid)
|
||||
{
|
||||
bool changed;
|
||||
long value;
|
||||
|
||||
if ( HasRange() )
|
||||
{
|
||||
value = Spin()->GetValue();
|
||||
changed = value != m_valueOld;
|
||||
}
|
||||
else
|
||||
{
|
||||
changed = Text()->GetValue().ToLong(&value) && (value != m_valueOld);
|
||||
}
|
||||
|
||||
if ( changed )
|
||||
{
|
||||
grid->GetTable()->SetValueAsLong(row, col, value);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void wxGridCellNumberEditor::Reset()
|
||||
{
|
||||
if ( HasRange() )
|
||||
{
|
||||
Spin()->SetValue(m_valueOld);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoReset(GetString());
|
||||
}
|
||||
}
|
||||
|
||||
void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
|
||||
{
|
||||
if ( !HasRange() )
|
||||
{
|
||||
long keycode = event.KeyCode();
|
||||
if ( isdigit(keycode) || keycode == '+' || keycode == '-' )
|
||||
{
|
||||
wxGridCellTextEditor::StartingKey(event);
|
||||
|
||||
// skip Skip() below
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellFloatEditor
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxGridCellFloatEditor::Create(wxWindow* parent,
|
||||
wxWindowID id,
|
||||
wxEvtHandler* evtHandler)
|
||||
{
|
||||
wxGridCellTextEditor::Create(parent, id, evtHandler);
|
||||
|
||||
#if wxUSE_VALIDATORS
|
||||
Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC));
|
||||
#endif // wxUSE_VALIDATORS
|
||||
}
|
||||
|
||||
void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid)
|
||||
{
|
||||
// first get the value
|
||||
wxGridTableBase *table = grid->GetTable();
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
|
||||
{
|
||||
m_valueOld = table->GetValueAsDouble(row, col);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG( _T("this cell doesn't have float value") );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoBeginEdit(GetString());
|
||||
}
|
||||
|
||||
bool wxGridCellFloatEditor::EndEdit(int row, int col, bool saveValue,
|
||||
wxGrid* grid)
|
||||
{
|
||||
double value;
|
||||
if ( Text()->GetValue().ToDouble(&value) && (value != m_valueOld) )
|
||||
{
|
||||
grid->GetTable()->SetValueAsDouble(row, col, value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void wxGridCellFloatEditor::Reset()
|
||||
{
|
||||
DoReset(GetString());
|
||||
}
|
||||
|
||||
void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)
|
||||
{
|
||||
long keycode = event.KeyCode();
|
||||
if ( isdigit(keycode) ||
|
||||
keycode == '+' || keycode == '-' || keycode == '.' )
|
||||
{
|
||||
wxGridCellTextEditor::StartingKey(event);
|
||||
|
||||
// skip Skip() below
|
||||
return;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellBoolEditor
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -738,20 +930,19 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
|
||||
dc.DrawRectangle(rect);
|
||||
}
|
||||
|
||||
wxGridCellRenderer::~wxGridCellRenderer()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellStringRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
int row, int col,
|
||||
bool isSelected)
|
||||
void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
bool isSelected)
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
|
||||
|
||||
// now we only have to draw the text
|
||||
dc.SetBackgroundMode( wxTRANSPARENT );
|
||||
|
||||
// TODO some special colours for attr.IsReadOnly() case?
|
||||
@@ -766,21 +957,107 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
||||
dc.SetTextBackground( attr.GetBackgroundColour() );
|
||||
dc.SetTextForeground( attr.GetTextColour() );
|
||||
}
|
||||
|
||||
dc.SetFont( attr.GetFont() );
|
||||
}
|
||||
|
||||
void wxGridCellStringRenderer::Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
int row, int col,
|
||||
bool isSelected)
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
|
||||
|
||||
// now we only have to draw the text
|
||||
SetTextColoursAndFont(grid, attr, dc, isSelected);
|
||||
|
||||
int hAlign, vAlign;
|
||||
attr.GetAlignment(&hAlign, &vAlign);
|
||||
|
||||
wxRect rect = rectCell;
|
||||
rect.x++;
|
||||
rect.y++;
|
||||
rect.width -= 2;
|
||||
rect.height -= 2;
|
||||
rect.Inflate(-1);
|
||||
|
||||
grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
|
||||
rect, hAlign, vAlign);
|
||||
}
|
||||
|
||||
void wxGridCellNumberRenderer::Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
int row, int col,
|
||||
bool isSelected)
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
|
||||
|
||||
SetTextColoursAndFont(grid, attr, dc, isSelected);
|
||||
|
||||
// draw the text right aligned by default
|
||||
int hAlign, vAlign;
|
||||
attr.GetAlignment(&hAlign, &vAlign);
|
||||
hAlign = wxRIGHT;
|
||||
|
||||
wxRect rect = rectCell;
|
||||
rect.Inflate(-1);
|
||||
|
||||
wxGridTableBase *table = grid.GetTable();
|
||||
wxString text;
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) )
|
||||
{
|
||||
text.Printf(_T("%ld"), table->GetValueAsLong(row, col));
|
||||
}
|
||||
//else: leave the string empty or put 0 into it?
|
||||
|
||||
grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellFloatRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision)
|
||||
{
|
||||
SetWidth(width);
|
||||
SetPrecision(precision);
|
||||
}
|
||||
|
||||
void wxGridCellFloatRenderer::Draw(wxGrid& grid,
|
||||
wxGridCellAttr& attr,
|
||||
wxDC& dc,
|
||||
const wxRect& rectCell,
|
||||
int row, int col,
|
||||
bool isSelected)
|
||||
{
|
||||
wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
|
||||
|
||||
SetTextColoursAndFont(grid, attr, dc, isSelected);
|
||||
|
||||
// draw the text right aligned by default
|
||||
int hAlign, vAlign;
|
||||
attr.GetAlignment(&hAlign, &vAlign);
|
||||
hAlign = wxRIGHT;
|
||||
|
||||
wxRect rect = rectCell;
|
||||
rect.Inflate(-1);
|
||||
|
||||
wxGridTableBase *table = grid.GetTable();
|
||||
wxString text;
|
||||
if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) )
|
||||
{
|
||||
if ( !m_format )
|
||||
{
|
||||
m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision);
|
||||
}
|
||||
|
||||
text.Printf(m_format, table->GetValueAsDouble(row, col));
|
||||
}
|
||||
//else: leave the string empty or put 0 into it?
|
||||
|
||||
grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxGridCellBoolRenderer
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -1475,13 +1752,13 @@ wxString wxGridTableBase::GetColLabelValue( int col )
|
||||
|
||||
wxString wxGridTableBase::GetTypeName( int WXUNUSED(row), int WXUNUSED(col) )
|
||||
{
|
||||
return wxT("string");
|
||||
return wxGRID_VALUE_STRING;
|
||||
}
|
||||
|
||||
bool wxGridTableBase::CanGetValueAs( int WXUNUSED(row), int WXUNUSED(col),
|
||||
const wxString& typeName )
|
||||
{
|
||||
return typeName == wxT("string");
|
||||
return typeName == wxGRID_VALUE_STRING;
|
||||
}
|
||||
|
||||
bool wxGridTableBase::CanSetValueAs( int row, int col, const wxString& typeName )
|
||||
@@ -2288,13 +2565,18 @@ void wxGrid::Create()
|
||||
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
|
||||
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
|
||||
|
||||
// data type registration
|
||||
// data type registration: register all standard data types
|
||||
// TODO: may be allow the app to selectively disable some of them?
|
||||
m_typeRegistry = new wxGridTypeRegistry;
|
||||
RegisterDataType(wxT("string"), new wxGridCellStringRenderer,
|
||||
new wxGridCellTextEditor);
|
||||
RegisterDataType(wxT("bool"), new wxGridCellBoolRenderer,
|
||||
new wxGridCellBoolEditor);
|
||||
|
||||
RegisterDataType(wxGRID_VALUE_STRING,
|
||||
new wxGridCellStringRenderer,
|
||||
new wxGridCellTextEditor);
|
||||
RegisterDataType(wxGRID_VALUE_BOOL,
|
||||
new wxGridCellBoolRenderer,
|
||||
new wxGridCellBoolEditor);
|
||||
RegisterDataType(wxGRID_VALUE_NUMBER,
|
||||
new wxGridCellNumberRenderer,
|
||||
new wxGridCellNumberEditor);
|
||||
|
||||
// subwindow components that make up the wxGrid
|
||||
m_cornerLabelWin = new wxGridCornerLabelWindow( this,
|
||||
|
Reference in New Issue
Block a user