add support for sorting to grid columns
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57323 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1749,6 +1749,31 @@ public:
|
|||||||
#endif // wxUSE_DRAG_AND_DROP
|
#endif // wxUSE_DRAG_AND_DROP
|
||||||
|
|
||||||
|
|
||||||
|
// ------- sorting support
|
||||||
|
|
||||||
|
// wxGrid doesn't support sorting on its own but it can indicate the sort
|
||||||
|
// order in the column header (currently only if native header control is
|
||||||
|
// used though)
|
||||||
|
|
||||||
|
// return the column currently displaying the sort indicator or wxNOT_FOUND
|
||||||
|
// if none
|
||||||
|
int GetSortingColumn() const { return m_sortCol; }
|
||||||
|
|
||||||
|
// return true if this column is currently used for sorting
|
||||||
|
bool IsSortingBy(int col) const { return GetSortingColumn() == col; }
|
||||||
|
|
||||||
|
// return the current sorting order (on GetSortingColumn()): true for
|
||||||
|
// ascending sort and false for descending; it doesn't make sense to call
|
||||||
|
// it if GetSortingColumn() returns wxNOT_FOUND
|
||||||
|
bool IsSortOrderAscending() const { return m_sortIsAscending; }
|
||||||
|
|
||||||
|
// set the sorting column (or unsets any existing one if wxNOT_FOUND) and
|
||||||
|
// the order in which to sort
|
||||||
|
void SetSortingColumn(int col, bool ascending = true);
|
||||||
|
|
||||||
|
// unset any existing sorting column
|
||||||
|
void UnsetSortingColumn() { SetSortingColumn(wxNOT_FOUND); }
|
||||||
|
|
||||||
#ifdef WXWIN_COMPATIBILITY_2_8
|
#ifdef WXWIN_COMPATIBILITY_2_8
|
||||||
// ------ For compatibility with previous wxGrid only...
|
// ------ For compatibility with previous wxGrid only...
|
||||||
//
|
//
|
||||||
@@ -1998,6 +2023,9 @@ protected:
|
|||||||
wxArrayInt m_colWidths;
|
wxArrayInt m_colWidths;
|
||||||
wxArrayInt m_colRights;
|
wxArrayInt m_colRights;
|
||||||
|
|
||||||
|
int m_sortCol;
|
||||||
|
bool m_sortIsAscending;
|
||||||
|
|
||||||
bool m_useNativeHeader,
|
bool m_useNativeHeader,
|
||||||
m_nativeColumnLabels;
|
m_nativeColumnLabels;
|
||||||
|
|
||||||
@@ -2244,6 +2272,13 @@ private:
|
|||||||
// common part of Clip{Horz,Vert}GridLines
|
// common part of Clip{Horz,Vert}GridLines
|
||||||
void DoClipGridLines(bool& var, bool clip);
|
void DoClipGridLines(bool& var, bool clip);
|
||||||
|
|
||||||
|
// update the sorting indicator shown in the specified column (whose index
|
||||||
|
// must be valid)
|
||||||
|
//
|
||||||
|
// this will use GetSortingColumn() and IsSortOrderAscending() to determine
|
||||||
|
// the sorting indicator to effectively show
|
||||||
|
void UpdateColumnSortingIndicator(int col);
|
||||||
|
|
||||||
|
|
||||||
// return the position (not index) of the column at the given logical pixel
|
// return the position (not index) of the column at the given logical pixel
|
||||||
// position
|
// position
|
||||||
@@ -2289,6 +2324,8 @@ private:
|
|||||||
void ProcessColLabelMouseEvent(wxMouseEvent& event);
|
void ProcessColLabelMouseEvent(wxMouseEvent& event);
|
||||||
void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
|
void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
|
||||||
|
|
||||||
|
void DoColHeaderClick(int col);
|
||||||
|
|
||||||
void DoStartResizeCol(int col);
|
void DoStartResizeCol(int col);
|
||||||
void DoUpdateResizeCol(int x);
|
void DoUpdateResizeCol(int x);
|
||||||
void DoUpdateResizeColWidth(int w);
|
void DoUpdateResizeColWidth(int w);
|
||||||
@@ -2608,6 +2645,7 @@ extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_HIDDEN;
|
|||||||
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_CREATED;
|
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_EDITOR_CREATED;
|
||||||
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_BEGIN_DRAG;
|
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_CELL_BEGIN_DRAG;
|
||||||
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_MOVE;
|
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_MOVE;
|
||||||
|
extern WXDLLIMPEXP_ADV const wxEventType wxEVT_GRID_COL_SORT;
|
||||||
|
|
||||||
|
|
||||||
typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
|
typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&);
|
||||||
@@ -2650,6 +2688,7 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
|
|||||||
#define EVT_GRID_CMD_ROW_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(ROW_SIZE, id, fn)
|
#define EVT_GRID_CMD_ROW_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(ROW_SIZE, id, fn)
|
||||||
#define EVT_GRID_CMD_COL_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(COL_SIZE, id, fn)
|
#define EVT_GRID_CMD_COL_SIZE(id, fn) wx__DECLARE_GRIDSIZEEVT(COL_SIZE, id, fn)
|
||||||
#define EVT_GRID_CMD_COL_MOVE(id, fn) wx__DECLARE_GRIDEVT(COL_MOVE, id, fn)
|
#define EVT_GRID_CMD_COL_MOVE(id, fn) wx__DECLARE_GRIDEVT(COL_MOVE, id, fn)
|
||||||
|
#define EVT_GRID_CMD_COL_SORT(id, fn) wx__DECLARE_GRIDEVT(COL_SORT, id, fn)
|
||||||
#define EVT_GRID_CMD_RANGE_SELECT(id, fn) wx__DECLARE_GRIDRANGESELEVT(RANGE_SELECT, id, fn)
|
#define EVT_GRID_CMD_RANGE_SELECT(id, fn) wx__DECLARE_GRIDRANGESELEVT(RANGE_SELECT, id, fn)
|
||||||
#define EVT_GRID_CMD_CELL_CHANGE(id, fn) wx__DECLARE_GRIDEVT(CELL_CHANGE, id, fn)
|
#define EVT_GRID_CMD_CELL_CHANGE(id, fn) wx__DECLARE_GRIDEVT(CELL_CHANGE, id, fn)
|
||||||
#define EVT_GRID_CMD_SELECT_CELL(id, fn) wx__DECLARE_GRIDEVT(SELECT_CELL, id, fn)
|
#define EVT_GRID_CMD_SELECT_CELL(id, fn) wx__DECLARE_GRIDEVT(SELECT_CELL, id, fn)
|
||||||
@@ -2671,6 +2710,7 @@ typedef void (wxEvtHandler::*wxGridEditorCreatedEventFunction)(wxGridEditorCreat
|
|||||||
#define EVT_GRID_ROW_SIZE(fn) EVT_GRID_CMD_ROW_SIZE(wxID_ANY, fn)
|
#define EVT_GRID_ROW_SIZE(fn) EVT_GRID_CMD_ROW_SIZE(wxID_ANY, fn)
|
||||||
#define EVT_GRID_COL_SIZE(fn) EVT_GRID_CMD_COL_SIZE(wxID_ANY, fn)
|
#define EVT_GRID_COL_SIZE(fn) EVT_GRID_CMD_COL_SIZE(wxID_ANY, fn)
|
||||||
#define EVT_GRID_COL_MOVE(fn) EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn)
|
#define EVT_GRID_COL_MOVE(fn) EVT_GRID_CMD_COL_MOVE(wxID_ANY, fn)
|
||||||
|
#define EVT_GRID_COL_SORT(fn) EVT_GRID_CMD_COL_SORT(wxID_ANY, fn)
|
||||||
#define EVT_GRID_RANGE_SELECT(fn) EVT_GRID_CMD_RANGE_SELECT(wxID_ANY, fn)
|
#define EVT_GRID_RANGE_SELECT(fn) EVT_GRID_CMD_RANGE_SELECT(wxID_ANY, fn)
|
||||||
#define EVT_GRID_CELL_CHANGE(fn) EVT_GRID_CMD_CELL_CHANGE(wxID_ANY, fn)
|
#define EVT_GRID_CELL_CHANGE(fn) EVT_GRID_CMD_CELL_CHANGE(wxID_ANY, fn)
|
||||||
#define EVT_GRID_SELECT_CELL(fn) EVT_GRID_CMD_SELECT_CELL(wxID_ANY, fn)
|
#define EVT_GRID_SELECT_CELL(fn) EVT_GRID_CMD_SELECT_CELL(wxID_ANY, fn)
|
||||||
|
@@ -3056,6 +3056,77 @@ protected:
|
|||||||
called for this row.
|
called for this row.
|
||||||
*/
|
*/
|
||||||
int GetRowMinimalHeight(int col) const;
|
int GetRowMinimalHeight(int col) const;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@name Sorting support.
|
||||||
|
|
||||||
|
wxGrid doesn't provide any support for sorting the data but it does
|
||||||
|
generate events allowing the user code to sort it and supports
|
||||||
|
displaying the sort indicator in the column used for sorting.
|
||||||
|
|
||||||
|
To use wxGrid sorting support you need to handle wxEVT_GRID_COL_SORT
|
||||||
|
event (and not veto it) and resort the data displayed in the grid. The
|
||||||
|
grid will automatically update the sorting indicator on the column
|
||||||
|
which was clicked.
|
||||||
|
|
||||||
|
You can also call the functions in this section directly to update the
|
||||||
|
sorting indicator. Once again, they don't do anything with the grid
|
||||||
|
data, it remains your responsibility to actually sort it appropriately.
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the column in which the sorting indicator is currently
|
||||||
|
displayed.
|
||||||
|
|
||||||
|
Returns @c wxNOT_FOUND if sorting indicator is not currently displayed
|
||||||
|
at all.
|
||||||
|
|
||||||
|
@see SetSortingColumn()
|
||||||
|
*/
|
||||||
|
int GetSortingColumn() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return @true if this column is currently used for sorting.
|
||||||
|
|
||||||
|
@see GetSortingColumn()
|
||||||
|
*/
|
||||||
|
bool IsSortingBy(int col) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return @true if the current sorting order is ascending or @false if it
|
||||||
|
is descending.
|
||||||
|
|
||||||
|
It only makes sense to call this function if GetSortingColumn() returns
|
||||||
|
a valid column index and not @c wxNOT_FOUND.
|
||||||
|
|
||||||
|
@see SetSortingColumn()
|
||||||
|
*/
|
||||||
|
bool IsSortOrderAscending() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the column to display the sorting indicator in and its direction.
|
||||||
|
|
||||||
|
@param col
|
||||||
|
The column to display the sorting indicator in or @c wxNOT_FOUND to
|
||||||
|
remove any currently displayed sorting indicator.
|
||||||
|
@param ascending
|
||||||
|
If @true, display the ascending sort indicator, otherwise display
|
||||||
|
the descending sort indicator.
|
||||||
|
|
||||||
|
@see GetSortingColumn(), IsSortOrderAscending()
|
||||||
|
*/
|
||||||
|
void SetSortingColumn(int col, bool ascending = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remove any currently shown sorting indicator.
|
||||||
|
|
||||||
|
This is equivalent to calling SetSortingColumn() with @c wxNOT_FOUND
|
||||||
|
first argument.
|
||||||
|
*/
|
||||||
|
void UnsetSortingColumn();
|
||||||
|
//@}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -3183,7 +3254,19 @@ public:
|
|||||||
proceed in which case wxGrid::SetColPos() is used to reorder the
|
proceed in which case wxGrid::SetColPos() is used to reorder the
|
||||||
columns display order without affecting the use of the column indices
|
columns display order without affecting the use of the column indices
|
||||||
otherwise.
|
otherwise.
|
||||||
|
|
||||||
This event macro corresponds to @c wxEVT_GRID_COL_MOVE event type.
|
This event macro corresponds to @c wxEVT_GRID_COL_MOVE event type.
|
||||||
|
@event{EVT_GRID_COL_SORT(func)}
|
||||||
|
This event is generated when a column is clicked by the user and its
|
||||||
|
name is explained by the fact that the custom reaction to a click on a
|
||||||
|
column is to sort the grid contents by this column. However the grid
|
||||||
|
itself has no special support for sorting and it's up to the handler of
|
||||||
|
this event to update the associated table. But if the event is handled
|
||||||
|
(and not vetoed) the grid supposes that the table was indeed resorted
|
||||||
|
and updates the column to indicate the new sort order and refreshes
|
||||||
|
itself.
|
||||||
|
|
||||||
|
This event macro corresponds to @c wxEVT_GRID_COL_SORT event type.
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@library{wxadv}
|
@library{wxadv}
|
||||||
|
@@ -1565,22 +1565,34 @@ public:
|
|||||||
ROW_MAX = 3
|
ROW_MAX = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TabularGridTable() { m_sortOrder = NULL; }
|
||||||
|
|
||||||
virtual int GetNumberRows() { return ROW_MAX; }
|
virtual int GetNumberRows() { return ROW_MAX; }
|
||||||
virtual int GetNumberCols() { return COL_MAX; }
|
virtual int GetNumberCols() { return COL_MAX; }
|
||||||
|
|
||||||
virtual wxString GetValue(int row, int col)
|
virtual wxString GetValue(int row, int col)
|
||||||
{
|
{
|
||||||
// notice that column parameter here always refers to the internal
|
if ( m_sortOrder )
|
||||||
// column index, independently of its position on the screen
|
row = m_sortOrder[row];
|
||||||
static const char *filedata[][COL_MAX] =
|
|
||||||
{
|
|
||||||
{ "autoexec", "bat", "412", "Apr 17 2004" },
|
|
||||||
{ "boot", "ini", "604", "May 27 2006" },
|
|
||||||
{ "io", "sys", "40774", "May 31 1994" },
|
|
||||||
};
|
|
||||||
wxCOMPILE_TIME_ASSERT( WXSIZEOF(filedata) == ROW_MAX, Mismatch );
|
|
||||||
|
|
||||||
return filedata[row][col];
|
switch ( col )
|
||||||
|
{
|
||||||
|
case COL_NAME:
|
||||||
|
case COL_EXT:
|
||||||
|
return GetNameOrExt(row, col);
|
||||||
|
|
||||||
|
case COL_SIZE:
|
||||||
|
return wxString::Format("%lu", GetSize(row));
|
||||||
|
|
||||||
|
case COL_DATE:
|
||||||
|
return GetDate(row).FormatDate();
|
||||||
|
|
||||||
|
case COL_MAX:
|
||||||
|
default:
|
||||||
|
wxFAIL_MSG( "unknown column" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxString();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetValue(int, int, const wxString&)
|
virtual void SetValue(int, int, const wxString&)
|
||||||
@@ -1590,8 +1602,10 @@ public:
|
|||||||
|
|
||||||
virtual wxString GetColLabelValue(int col)
|
virtual wxString GetColLabelValue(int col)
|
||||||
{
|
{
|
||||||
|
// notice that column parameter here always refers to the internal
|
||||||
|
// column index, independently of its position on the screen
|
||||||
static const char *labels[] = { "Name", "Extension", "Size", "Date" };
|
static const char *labels[] = { "Name", "Extension", "Size", "Date" };
|
||||||
wxCOMPILE_TIME_ASSERT( WXSIZEOF(labels) == COL_MAX, Mismatch );
|
wxCOMPILE_TIME_ASSERT( WXSIZEOF(labels) == COL_MAX, LabelsMismatch );
|
||||||
|
|
||||||
return labels[col];
|
return labels[col];
|
||||||
}
|
}
|
||||||
@@ -1600,6 +1614,54 @@ public:
|
|||||||
{
|
{
|
||||||
wxFAIL_MSG( "shouldn't be called" );
|
wxFAIL_MSG( "shouldn't be called" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sort(int col, bool ascending)
|
||||||
|
{
|
||||||
|
// we hardcode all sorting orders for simplicity here
|
||||||
|
static int sortOrders[COL_MAX][2][ROW_MAX] =
|
||||||
|
{
|
||||||
|
// descending ascending
|
||||||
|
{ { 2, 1, 0 }, { 0, 1, 2 } },
|
||||||
|
{ { 2, 1, 0 }, { 0, 1, 2 } },
|
||||||
|
{ { 2, 1, 0 }, { 0, 1, 2 } },
|
||||||
|
{ { 1, 0, 2 }, { 2, 0, 1 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
m_sortOrder = col == wxNOT_FOUND ? NULL : sortOrders[col][ascending];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxString GetNameOrExt(int row, int col) const
|
||||||
|
{
|
||||||
|
static const char *
|
||||||
|
names[] = { "autoexec.bat", "boot.ini", "io.sys" };
|
||||||
|
wxCOMPILE_TIME_ASSERT( WXSIZEOF(names) == ROW_MAX, NamesMismatch );
|
||||||
|
|
||||||
|
const wxString s(names[row]);
|
||||||
|
return col == COL_NAME ? s.BeforeFirst('.') : s.AfterLast('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long GetSize(int row) const
|
||||||
|
{
|
||||||
|
static const unsigned long
|
||||||
|
sizes[] = { 412, 604, 40774 };
|
||||||
|
wxCOMPILE_TIME_ASSERT( WXSIZEOF(sizes) == ROW_MAX, SizesMismatch );
|
||||||
|
|
||||||
|
return sizes[row];
|
||||||
|
}
|
||||||
|
|
||||||
|
wxDateTime GetDate(int row) const
|
||||||
|
{
|
||||||
|
static const char *
|
||||||
|
dates[] = { "2004-04-17", "2006-05-27", "1994-05-31" };
|
||||||
|
wxCOMPILE_TIME_ASSERT( WXSIZEOF(dates) == ROW_MAX, DatesMismatch );
|
||||||
|
|
||||||
|
wxDateTime dt;
|
||||||
|
dt.ParseISODate(dates[row]);
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *m_sortOrder;
|
||||||
};
|
};
|
||||||
|
|
||||||
// specialized text control for column indexes entry
|
// specialized text control for column indexes entry
|
||||||
@@ -1690,6 +1752,13 @@ private:
|
|||||||
UpdateOrder();
|
UpdateOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnGridColSort(wxGridEvent& event)
|
||||||
|
{
|
||||||
|
const int col = event.GetCol();
|
||||||
|
m_table->Sort(col, !(m_grid->IsSortingBy(col) &&
|
||||||
|
m_grid->IsSortOrderAscending()));
|
||||||
|
}
|
||||||
|
|
||||||
void OnGridColMove(wxGridEvent& event)
|
void OnGridColMove(wxGridEvent& event)
|
||||||
{
|
{
|
||||||
// can't update it yet as the order hasn't been changed, so do it a bit
|
// can't update it yet as the order hasn't been changed, so do it a bit
|
||||||
@@ -1721,6 +1790,7 @@ private:
|
|||||||
|
|
||||||
// controls
|
// controls
|
||||||
wxGrid *m_grid;
|
wxGrid *m_grid;
|
||||||
|
TabularGridTable *m_table;
|
||||||
wxCheckBox *m_chkUseNative,
|
wxCheckBox *m_chkUseNative,
|
||||||
*m_chkDrawNative,
|
*m_chkDrawNative,
|
||||||
*m_chkShowRowLabels,
|
*m_chkShowRowLabels,
|
||||||
@@ -1753,6 +1823,7 @@ BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame)
|
|||||||
|
|
||||||
EVT_BUTTON(wxID_APPLY, TabularGridFrame::OnMoveColumn)
|
EVT_BUTTON(wxID_APPLY, TabularGridFrame::OnMoveColumn)
|
||||||
|
|
||||||
|
EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort)
|
||||||
EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
|
EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
|
||||||
|
|
||||||
EVT_IDLE(TabularGridFrame::OnIdle)
|
EVT_IDLE(TabularGridFrame::OnIdle)
|
||||||
@@ -1766,10 +1837,11 @@ TabularGridFrame::TabularGridFrame()
|
|||||||
wxPanel * const panel = new wxPanel(this);
|
wxPanel * const panel = new wxPanel(this);
|
||||||
|
|
||||||
// create and initialize the grid with the specified data
|
// create and initialize the grid with the specified data
|
||||||
|
m_table = new TabularGridTable;
|
||||||
m_grid = new wxGrid(panel, wxID_ANY,
|
m_grid = new wxGrid(panel, wxID_ANY,
|
||||||
wxDefaultPosition, wxDefaultSize,
|
wxDefaultPosition, wxDefaultSize,
|
||||||
wxBORDER_STATIC | wxWANTS_CHARS);
|
wxBORDER_STATIC | wxWANTS_CHARS);
|
||||||
m_grid->SetTable(new TabularGridTable, true, wxGrid::wxGridSelectRows);
|
m_grid->SetTable(m_table, true, wxGrid::wxGridSelectRows);
|
||||||
|
|
||||||
m_grid->EnableDragColMove();
|
m_grid->EnableDragColMove();
|
||||||
m_grid->UseNativeColHeader();
|
m_grid->UseNativeColHeader();
|
||||||
@@ -1841,3 +1913,10 @@ void GridFrame::OnTabularTable(wxCommandEvent&)
|
|||||||
{
|
{
|
||||||
new TabularGridFrame;
|
new TabularGridFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GridApp::OnInit()
|
||||||
|
{
|
||||||
|
new TabularGridFrame();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -146,6 +146,7 @@ DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK)
|
|||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE)
|
||||||
|
DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SORT)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGE)
|
||||||
DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL)
|
DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL)
|
||||||
@@ -192,9 +193,15 @@ public:
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: currently there is no support for sorting
|
virtual bool IsSortKey() const
|
||||||
virtual bool IsSortKey() const { return false; }
|
{
|
||||||
virtual bool IsSortOrderAscending() const { return false; }
|
return m_grid->IsSortingBy(m_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool IsSortOrderAscending() const
|
||||||
|
{
|
||||||
|
return m_grid->IsSortOrderAscending();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// these really should be const but are not because the column needs to be
|
// these really should be const but are not because the column needs to be
|
||||||
@@ -249,6 +256,8 @@ private:
|
|||||||
// override to implement column auto sizing
|
// override to implement column auto sizing
|
||||||
virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
|
virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
|
||||||
{
|
{
|
||||||
|
// TODO: currently grid doesn't support computing the column best width
|
||||||
|
// from its contents so we just use the best label width as is
|
||||||
GetOwner()->SetColSize(idx, widthTitle);
|
GetOwner()->SetColSize(idx, widthTitle);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -256,6 +265,11 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
// event handlers forwarding wxHeaderCtrl events to wxGrid
|
// event handlers forwarding wxHeaderCtrl events to wxGrid
|
||||||
|
void OnClick(wxHeaderCtrlEvent& event)
|
||||||
|
{
|
||||||
|
GetOwner()->DoColHeaderClick(event.GetColumn());
|
||||||
|
}
|
||||||
|
|
||||||
void OnBeginResize(wxHeaderCtrlEvent& event)
|
void OnBeginResize(wxHeaderCtrlEvent& event)
|
||||||
{
|
{
|
||||||
GetOwner()->DoStartResizeCol(event.GetColumn());
|
GetOwner()->DoStartResizeCol(event.GetColumn());
|
||||||
@@ -292,6 +306,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl)
|
BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl)
|
||||||
|
EVT_HEADER_CLICK(wxID_ANY, wxGridHeaderCtrl::OnClick)
|
||||||
|
|
||||||
EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize)
|
EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize)
|
||||||
EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing)
|
EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing)
|
||||||
EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize)
|
EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize)
|
||||||
@@ -4884,6 +4900,9 @@ void wxGrid::Init()
|
|||||||
m_isDragging = false;
|
m_isDragging = false;
|
||||||
m_startDragPos = wxDefaultPosition;
|
m_startDragPos = wxDefaultPosition;
|
||||||
|
|
||||||
|
m_sortCol = wxNOT_FOUND;
|
||||||
|
m_sortIsAscending = true;
|
||||||
|
|
||||||
m_useNativeHeader =
|
m_useNativeHeader =
|
||||||
m_nativeColumnLabels = false;
|
m_nativeColumnLabels = false;
|
||||||
|
|
||||||
@@ -5849,6 +5868,60 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxGrid::UpdateColumnSortingIndicator(int col)
|
||||||
|
{
|
||||||
|
wxCHECK_RET( col != wxNOT_FOUND, "invalid column index" );
|
||||||
|
|
||||||
|
if ( m_useNativeHeader )
|
||||||
|
GetColHeader()->UpdateColumn(col);
|
||||||
|
else if ( m_nativeColumnLabels )
|
||||||
|
m_colWindow->Refresh();
|
||||||
|
//else: sorting indicator display not yet implemented in grid version
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGrid::SetSortingColumn(int col, bool ascending)
|
||||||
|
{
|
||||||
|
if ( col == m_sortCol )
|
||||||
|
{
|
||||||
|
// we are already using this column for sorting (or not sorting at all)
|
||||||
|
// but we might still change the sorting order, check for it
|
||||||
|
if ( m_sortCol != wxNOT_FOUND && ascending != m_sortIsAscending )
|
||||||
|
{
|
||||||
|
m_sortIsAscending = ascending;
|
||||||
|
|
||||||
|
UpdateColumnSortingIndicator(m_sortCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // we're changing the column used for sorting
|
||||||
|
{
|
||||||
|
const int sortColOld = m_sortCol;
|
||||||
|
|
||||||
|
// change it before updating the column as we want GetSortingColumn()
|
||||||
|
// to return the correct new value
|
||||||
|
m_sortCol = col;
|
||||||
|
|
||||||
|
if ( sortColOld != wxNOT_FOUND )
|
||||||
|
UpdateColumnSortingIndicator(sortColOld);
|
||||||
|
|
||||||
|
if ( m_sortCol != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
m_sortIsAscending = ascending;
|
||||||
|
UpdateColumnSortingIndicator(m_sortCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxGrid::DoColHeaderClick(int col)
|
||||||
|
{
|
||||||
|
// we consider that the grid was resorted if this event is processed and
|
||||||
|
// not vetoed
|
||||||
|
if ( SendEvent(wxEVT_GRID_COL_SORT, -1, col) == 1 )
|
||||||
|
{
|
||||||
|
SetSortingColumn(col, IsSortingBy(col) ? !m_sortIsAscending : true);
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wxGrid::DoStartResizeCol(int col)
|
void wxGrid::DoStartResizeCol(int col)
|
||||||
{
|
{
|
||||||
m_dragRowOrCol = col;
|
m_dragRowOrCol = col;
|
||||||
@@ -5882,10 +5955,11 @@ void wxGrid::DoUpdateResizeColWidth(int w)
|
|||||||
|
|
||||||
void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
||||||
{
|
{
|
||||||
int x, y, col;
|
int x, y;
|
||||||
wxPoint pos( event.GetPosition() );
|
wxPoint pos( event.GetPosition() );
|
||||||
CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
|
CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
|
||||||
|
|
||||||
|
int col = XToCol(x);
|
||||||
if ( event.Dragging() )
|
if ( event.Dragging() )
|
||||||
{
|
{
|
||||||
if (!m_isDragging)
|
if (!m_isDragging)
|
||||||
@@ -5893,8 +5967,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
m_isDragging = true;
|
m_isDragging = true;
|
||||||
GetColLabelWindow()->CaptureMouse();
|
GetColLabelWindow()->CaptureMouse();
|
||||||
|
|
||||||
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL )
|
if ( m_cursorMode == WXGRID_CURSOR_MOVE_COL && col != -1 )
|
||||||
DoStartMoveCol(XToCol(x));
|
DoStartMoveCol(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( event.LeftIsDown() )
|
if ( event.LeftIsDown() )
|
||||||
@@ -5907,7 +5981,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
|
|
||||||
case WXGRID_CURSOR_SELECT_COL:
|
case WXGRID_CURSOR_SELECT_COL:
|
||||||
{
|
{
|
||||||
if ( (col = XToCol( x )) >= 0 )
|
if ( col != -1 )
|
||||||
{
|
{
|
||||||
if ( m_selection )
|
if ( m_selection )
|
||||||
m_selection->SelectCol(col, event);
|
m_selection->SelectCol(col, event);
|
||||||
@@ -6005,7 +6079,6 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
//
|
//
|
||||||
if ( XToEdgeOfCol(x) < 0 )
|
if ( XToEdgeOfCol(x) < 0 )
|
||||||
{
|
{
|
||||||
col = XToCol(x);
|
|
||||||
if ( col >= 0 &&
|
if ( col >= 0 &&
|
||||||
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
|
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
|
||||||
{
|
{
|
||||||
@@ -6059,10 +6132,9 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
//
|
//
|
||||||
if ( event.LeftDClick() )
|
if ( event.LeftDClick() )
|
||||||
{
|
{
|
||||||
col = XToEdgeOfCol(x);
|
const int colEdge = XToEdgeOfCol(x);
|
||||||
if ( col < 0 )
|
if ( colEdge == -1 )
|
||||||
{
|
{
|
||||||
col = XToCol(x);
|
|
||||||
if ( col >= 0 &&
|
if ( col >= 0 &&
|
||||||
! SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event ) )
|
! SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event ) )
|
||||||
{
|
{
|
||||||
@@ -6072,7 +6144,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// adjust column width depending on label text
|
// adjust column width depending on label text
|
||||||
AutoSizeColLabelSize( col );
|
AutoSizeColLabelSize( colEdge );
|
||||||
|
|
||||||
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
|
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
|
||||||
m_dragLastPos = -1;
|
m_dragLastPos = -1;
|
||||||
@@ -6090,9 +6162,11 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WXGRID_CURSOR_MOVE_COL:
|
case WXGRID_CURSOR_MOVE_COL:
|
||||||
if ( m_dragLastPos == -1 )
|
if ( m_dragLastPos == -1 || col == m_dragRowOrCol )
|
||||||
{
|
{
|
||||||
// The user clicked on the column but didn't actually drag
|
// the column didn't actually move anywhere
|
||||||
|
if ( col != -1 )
|
||||||
|
DoColHeaderClick(col);
|
||||||
m_colWindow->Refresh(); // "unpress" the column
|
m_colWindow->Refresh(); // "unpress" the column
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -6105,7 +6179,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
case WXGRID_CURSOR_SELECT_CELL:
|
case WXGRID_CURSOR_SELECT_CELL:
|
||||||
case WXGRID_CURSOR_RESIZE_ROW:
|
case WXGRID_CURSOR_RESIZE_ROW:
|
||||||
case WXGRID_CURSOR_SELECT_ROW:
|
case WXGRID_CURSOR_SELECT_ROW:
|
||||||
// nothing to do (?)
|
if ( col != -1 )
|
||||||
|
DoColHeaderClick(col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6117,7 +6192,6 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
//
|
//
|
||||||
else if ( event.RightDown() )
|
else if ( event.RightDown() )
|
||||||
{
|
{
|
||||||
col = XToCol(x);
|
|
||||||
if ( col >= 0 &&
|
if ( col >= 0 &&
|
||||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, col, event ) )
|
!SendEvent( wxEVT_GRID_LABEL_RIGHT_CLICK, -1, col, event ) )
|
||||||
{
|
{
|
||||||
@@ -6129,7 +6203,6 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
|
|||||||
//
|
//
|
||||||
else if ( event.RightDClick() )
|
else if ( event.RightDClick() )
|
||||||
{
|
{
|
||||||
col = XToCol(x);
|
|
||||||
if ( col >= 0 &&
|
if ( col >= 0 &&
|
||||||
!SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, col, event ) )
|
!SendEvent( wxEVT_GRID_LABEL_RIGHT_DCLICK, -1, col, event ) )
|
||||||
{
|
{
|
||||||
@@ -8185,7 +8258,18 @@ void wxGrid::DrawColLabel(wxDC& dc, int col)
|
|||||||
|
|
||||||
if ( m_nativeColumnLabels )
|
if ( m_nativeColumnLabels )
|
||||||
{
|
{
|
||||||
wxRendererNative::Get().DrawHeaderButton(GetColLabelWindow(), dc, rect, 0);
|
wxRendererNative::Get().DrawHeaderButton
|
||||||
|
(
|
||||||
|
GetColLabelWindow(),
|
||||||
|
dc,
|
||||||
|
rect,
|
||||||
|
0,
|
||||||
|
IsSortingBy(col)
|
||||||
|
? IsSortOrderAscending()
|
||||||
|
? wxHDR_SORT_ICON_UP
|
||||||
|
: wxHDR_SORT_ICON_DOWN
|
||||||
|
: wxHDR_SORT_ICON_NONE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user