implement column reordering support in wxMSW wxHeaderCtrl; use it in wxDataViewCtrl (and make difference between column indices and positions more clear in it)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57232 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -485,6 +485,12 @@ public: // utility functions not part of the API
|
|||||||
|
|
||||||
wxWindow *GetMainWindow() { return (wxWindow*) m_clientArea; }
|
wxWindow *GetMainWindow() { return (wxWindow*) m_clientArea; }
|
||||||
|
|
||||||
|
// return the index of the given column in m_cols
|
||||||
|
int GetColumnIndex(const wxDataViewColumn *column) const;
|
||||||
|
|
||||||
|
// return the column displayed at the given position in the control
|
||||||
|
wxDataViewColumn *GetColumnAt(unsigned int pos) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxDataViewColumnList m_cols;
|
wxDataViewColumnList m_cols;
|
||||||
wxDataViewModelNotifier *m_notifier;
|
wxDataViewModelNotifier *m_notifier;
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "wx/control.h"
|
#include "wx/control.h"
|
||||||
|
|
||||||
|
#include "wx/dynarray.h"
|
||||||
#include "wx/vector.h"
|
#include "wx/vector.h"
|
||||||
|
|
||||||
#include "wx/headercol.h"
|
#include "wx/headercol.h"
|
||||||
@@ -85,6 +86,18 @@ public:
|
|||||||
DoUpdate(idx);
|
DoUpdate(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set the columns order: the array defines the column index which appears
|
||||||
|
// the given position, it must have GetColumnCount() elements and contain
|
||||||
|
// all indices exactly once
|
||||||
|
void SetColumnsOrder(const wxArrayInt& order);
|
||||||
|
wxArrayInt GetColumnsOrder() const;
|
||||||
|
|
||||||
|
// get the index of the column at the given display position
|
||||||
|
unsigned int GetColumnAt(unsigned int pos) const;
|
||||||
|
|
||||||
|
// get the position at which this column is currently displayed
|
||||||
|
unsigned int GetColumnPos(unsigned int idx) const;
|
||||||
|
|
||||||
|
|
||||||
// implementation only from now on
|
// implementation only from now on
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
@@ -120,6 +133,9 @@ private:
|
|||||||
|
|
||||||
virtual void DoScrollHorz(int dx) = 0;
|
virtual void DoScrollHorz(int dx) = 0;
|
||||||
|
|
||||||
|
virtual void DoSetColumnsOrder(const wxArrayInt& order) = 0;
|
||||||
|
virtual wxArrayInt DoGetColumnsOrder() const = 0;
|
||||||
|
|
||||||
// this window doesn't look nice with the border so don't use it by default
|
// this window doesn't look nice with the border so don't use it by default
|
||||||
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
|
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
|
||||||
|
|
||||||
@@ -272,6 +288,7 @@ public:
|
|||||||
: wxNotifyEvent(commandType, winid),
|
: wxNotifyEvent(commandType, winid),
|
||||||
m_col(-1),
|
m_col(-1),
|
||||||
m_width(0),
|
m_width(0),
|
||||||
|
m_order(static_cast<unsigned int>(-1)),
|
||||||
m_cancelled(false)
|
m_cancelled(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -280,6 +297,7 @@ public:
|
|||||||
: wxNotifyEvent(event),
|
: wxNotifyEvent(event),
|
||||||
m_col(event.m_col),
|
m_col(event.m_col),
|
||||||
m_width(event.m_width),
|
m_width(event.m_width),
|
||||||
|
m_order(event.m_order),
|
||||||
m_cancelled(event.m_cancelled)
|
m_cancelled(event.m_cancelled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -292,6 +310,10 @@ public:
|
|||||||
int GetWidth() const { return m_width; }
|
int GetWidth() const { return m_width; }
|
||||||
void SetWidth(int width) { m_width = width; }
|
void SetWidth(int width) { m_width = width; }
|
||||||
|
|
||||||
|
// the new position of the column: for end reorder events only
|
||||||
|
unsigned int GetNewOrder() const { return m_order; }
|
||||||
|
void SetNewOrder(unsigned int order) { m_order = order; }
|
||||||
|
|
||||||
// was the drag operation cancelled or did it complete successfully?
|
// was the drag operation cancelled or did it complete successfully?
|
||||||
bool IsCancelled() const { return m_cancelled; }
|
bool IsCancelled() const { return m_cancelled; }
|
||||||
void SetCancelled() { m_cancelled = true; }
|
void SetCancelled() { m_cancelled = true; }
|
||||||
@@ -305,6 +327,9 @@ protected:
|
|||||||
// the current width for the dragging events
|
// the current width for the dragging events
|
||||||
int m_width;
|
int m_width;
|
||||||
|
|
||||||
|
// the new column position for end reorder event
|
||||||
|
unsigned int m_order;
|
||||||
|
|
||||||
// was the drag operation cancelled?
|
// was the drag operation cancelled?
|
||||||
bool m_cancelled;
|
bool m_cancelled;
|
||||||
|
|
||||||
@@ -327,6 +352,9 @@ extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_BEGIN_RESIZE;
|
|||||||
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_RESIZING;
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_RESIZING;
|
||||||
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_END_RESIZE;
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_END_RESIZE;
|
||||||
|
|
||||||
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_BEGIN_REORDER;
|
||||||
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_END_REORDER;
|
||||||
|
|
||||||
typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
||||||
|
|
||||||
#define wxHeaderCtrlEventHandler(func) \
|
#define wxHeaderCtrlEventHandler(func) \
|
||||||
@@ -350,4 +378,7 @@ typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
|||||||
#define EVT_HEADER_RESIZING(id, fn) wx__DECLARE_HEADER_EVT(RESIZING, id, fn)
|
#define EVT_HEADER_RESIZING(id, fn) wx__DECLARE_HEADER_EVT(RESIZING, id, fn)
|
||||||
#define EVT_HEADER_END_RESIZE(id, fn) wx__DECLARE_HEADER_EVT(END_RESIZE, id, fn)
|
#define EVT_HEADER_END_RESIZE(id, fn) wx__DECLARE_HEADER_EVT(END_RESIZE, id, fn)
|
||||||
|
|
||||||
|
#define EVT_HEADER_BEGIN_REORDER(id, fn) wx__DECLARE_HEADER_EVT(BEGIN_REORDER, id, fn)
|
||||||
|
#define EVT_HEADER_END_REORDER(id, fn) wx__DECLARE_HEADER_EVT(END_REORDER, id, fn)
|
||||||
|
|
||||||
#endif // _WX_HEADERCTRL_H_
|
#endif // _WX_HEADERCTRL_H_
|
||||||
|
@@ -55,6 +55,9 @@ private:
|
|||||||
|
|
||||||
virtual void DoScrollHorz(int dx);
|
virtual void DoScrollHorz(int dx);
|
||||||
|
|
||||||
|
virtual void DoSetColumnsOrder(const wxArrayInt& order);
|
||||||
|
virtual wxArrayInt DoGetColumnsOrder() const;
|
||||||
|
|
||||||
// override wxWindow methods which must be implemented by a new control
|
// override wxWindow methods which must be implemented by a new control
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
|
|
||||||
@@ -66,8 +69,8 @@ private:
|
|||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// wrapper around Header_InsertItem(): insert the item by using information
|
// wrapper around Header_InsertItem(): insert the item by using information
|
||||||
// from GetColumn(idx)
|
// from GetColumn(idx) and at the given display position if order != -1
|
||||||
void DoInsertItem(unsigned int idx);
|
void DoInsertItem(unsigned int idx, int order);
|
||||||
|
|
||||||
// get the event type corresponding to a click or double click event
|
// get the event type corresponding to a click or double click event
|
||||||
// (depending on dblclk value) with the specified (using MSW convention)
|
// (depending on dblclk value) with the specified (using MSW convention)
|
||||||
|
@@ -86,6 +86,20 @@
|
|||||||
or the resizing was cancelled. If wxHeaderCtrlEvent::IsCancelled()
|
or the resizing was cancelled. If wxHeaderCtrlEvent::IsCancelled()
|
||||||
returns @true, nothing should be done, otherwise the column should
|
returns @true, nothing should be done, otherwise the column should
|
||||||
normally be resized to the value of wxHeaderCtrlEvent::GetWidth().
|
normally be resized to the value of wxHeaderCtrlEvent::GetWidth().
|
||||||
|
|
||||||
|
@event{EVT_HEADER_BEGIN_REORDER(id, func)}
|
||||||
|
The user started to drag the column with the specified index (this
|
||||||
|
can only happen for the controls with wxHD_DRAGDROP style). This
|
||||||
|
event can be vetoed to prevent the column from being reordered,
|
||||||
|
otherwise the end reorder message will be generated later.
|
||||||
|
@event{EVT_HEADER_END_REORDER(id, func)}
|
||||||
|
Either the user dropped the column in its new location or the
|
||||||
|
drag operation was cancelled. If wxHeaderCtrlEvent::IsCancelled()
|
||||||
|
returns @true, nothing should be done, otherwise the event can be
|
||||||
|
vetoed to prevent the column from being placed at the new position
|
||||||
|
or handled to update the display of the data in the associated
|
||||||
|
control to match the new column location (available from
|
||||||
|
wxHeaderCtrlEvent::GetNewOrder()).
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@library{wxcore}
|
@library{wxcore}
|
||||||
@@ -195,6 +209,62 @@ public:
|
|||||||
*/
|
*/
|
||||||
void UpdateColumn(unsigned int idx);
|
void UpdateColumn(unsigned int idx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change the columns display order.
|
||||||
|
|
||||||
|
The display order defines the order in which the columns appear on the
|
||||||
|
screen and does @em not affect the interpretation of indices by all the
|
||||||
|
other class methods.
|
||||||
|
|
||||||
|
The @a order array specifies the column indices corresponding to the
|
||||||
|
display positions.
|
||||||
|
|
||||||
|
@param order
|
||||||
|
A permutation of all column indices, i.e. an array of size
|
||||||
|
GetColumnsOrder() containing all column indices exactly once. The
|
||||||
|
n-th element of this array defines the index of the column shown at
|
||||||
|
the n-th position from left (for the default left-to-right writing
|
||||||
|
direction).
|
||||||
|
|
||||||
|
@see wxListCtrl::SetColumnsOrder()
|
||||||
|
*/
|
||||||
|
void SetColumnsOrder(const wxArrayInt& order);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the array describing the columns display order.
|
||||||
|
|
||||||
|
For the controls without wxHD_DRAGDROP style the returned array will be
|
||||||
|
the same as was passed to SetColumnsOrder() previously or define the
|
||||||
|
default order (with n-th element being n) if it hadn't been called. But
|
||||||
|
for the controls with wxHD_DRAGDROP style, the columns can be also
|
||||||
|
reordered by user.
|
||||||
|
*/
|
||||||
|
wxArrayInt GetColumnsOrder() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the index of the column displayed at the given position.
|
||||||
|
|
||||||
|
@param pos
|
||||||
|
The display position, e.g. 0 for the left-most column, 1 for the
|
||||||
|
next one and so on until GetColumnCount() - 1.
|
||||||
|
|
||||||
|
@see GetColumnPos()
|
||||||
|
*/
|
||||||
|
unsigned int GetColumnAt(unsigned int pos) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the position at which this column is currently displayed.
|
||||||
|
|
||||||
|
Notice that a valid position is returned even for the hidden columns
|
||||||
|
currently.
|
||||||
|
|
||||||
|
@param idx
|
||||||
|
The column index, must be less than GetColumnCount().
|
||||||
|
|
||||||
|
@see GetColumnAt()
|
||||||
|
*/
|
||||||
|
unsigned int GetColumnPos(unsigned int idx) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
Method to be implemented by the derived classes to return the
|
Method to be implemented by the derived classes to return the
|
||||||
@@ -430,6 +500,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
int GetWidth() const;
|
int GetWidth() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the new order of the column.
|
||||||
|
|
||||||
|
This method can only be called for end reorder event for which it
|
||||||
|
indicates the tentative new position for the column GetColumn()
|
||||||
|
selected by the user. If the event is not vetoed, this will become the
|
||||||
|
new column position in wxHeaderCtrl::GetColumnsOrder().
|
||||||
|
*/
|
||||||
|
unsigned int GetNewOrder() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return @true if the drag operation was cancelled.
|
Return @true if the drag operation was cancelled.
|
||||||
|
|
||||||
|
@@ -64,6 +64,10 @@ void wxHeaderCtrlBase::ScrollWindow(int dx,
|
|||||||
DoScrollHorz(dx);
|
DoScrollHorz(dx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxHeaderCtrlBase event handling
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
|
void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
|
||||||
{
|
{
|
||||||
const unsigned col = event.GetColumn();
|
const unsigned col = event.GetColumn();
|
||||||
@@ -77,6 +81,65 @@ void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
|
|||||||
UpdateColumn(col);
|
UpdateColumn(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxHeaderCtrlBase column reordering
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxHeaderCtrlBase::SetColumnsOrder(const wxArrayInt& order)
|
||||||
|
{
|
||||||
|
const unsigned count = GetColumnCount();
|
||||||
|
wxCHECK_RET( order.size() == count, "wrong number of columns" );
|
||||||
|
|
||||||
|
// check the array validity
|
||||||
|
wxArrayInt seen(count, 0);
|
||||||
|
for ( unsigned n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
const unsigned idx = order[n];
|
||||||
|
wxCHECK_RET( idx < count, "invalid column index" );
|
||||||
|
wxCHECK_RET( !seen[idx], "duplicate column index" );
|
||||||
|
|
||||||
|
seen[idx] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoSetColumnsOrder(order);
|
||||||
|
|
||||||
|
// TODO-RTL: do we need to reverse the array?
|
||||||
|
}
|
||||||
|
|
||||||
|
wxArrayInt wxHeaderCtrlBase::GetColumnsOrder() const
|
||||||
|
{
|
||||||
|
const wxArrayInt order = DoGetColumnsOrder();
|
||||||
|
|
||||||
|
wxASSERT_MSG( order.size() == GetColumnCount(), "invalid order array" );
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int wxHeaderCtrlBase::GetColumnAt(unsigned int pos) const
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( pos < GetColumnCount(), wxNO_COLUMN, "invalid position" );
|
||||||
|
|
||||||
|
return GetColumnsOrder()[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int wxHeaderCtrlBase::GetColumnPos(unsigned int idx) const
|
||||||
|
{
|
||||||
|
const unsigned count = GetColumnCount();
|
||||||
|
|
||||||
|
wxCHECK_MSG( idx < count, wxNO_COLUMN, "invalid index" );
|
||||||
|
|
||||||
|
const wxArrayInt order = GetColumnsOrder();
|
||||||
|
for ( unsigned n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
if ( (unsigned)order[n] == idx )
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFAIL_MSG( "column unexpectedly not displayed at all" );
|
||||||
|
|
||||||
|
return wxNO_COLUMN;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// wxHeaderCtrlSimple implementation
|
// wxHeaderCtrlSimple implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -181,3 +244,6 @@ const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK = wxNewEventType();
|
|||||||
const wxEventType wxEVT_COMMAND_HEADER_BEGIN_RESIZE = wxNewEventType();
|
const wxEventType wxEVT_COMMAND_HEADER_BEGIN_RESIZE = wxNewEventType();
|
||||||
const wxEventType wxEVT_COMMAND_HEADER_RESIZING = wxNewEventType();
|
const wxEventType wxEVT_COMMAND_HEADER_RESIZING = wxNewEventType();
|
||||||
const wxEventType wxEVT_COMMAND_HEADER_END_RESIZE = wxNewEventType();
|
const wxEventType wxEVT_COMMAND_HEADER_END_RESIZE = wxNewEventType();
|
||||||
|
|
||||||
|
const wxEventType wxEVT_COMMAND_HEADER_BEGIN_REORDER = wxNewEventType();
|
||||||
|
const wxEventType wxEVT_COMMAND_HEADER_END_REORDER = wxNewEventType();
|
||||||
|
@@ -184,6 +184,13 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnEndReorder(wxHeaderCtrlEvent& event)
|
||||||
|
{
|
||||||
|
wxDataViewCtrl * const owner = GetOwner();
|
||||||
|
owner->ColumnMoved(owner->GetColumn(event.GetColumn()),
|
||||||
|
event.GetNewOrder());
|
||||||
|
}
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
|
DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
|
||||||
};
|
};
|
||||||
@@ -193,6 +200,8 @@ BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
|
|||||||
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
|
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
|
||||||
|
|
||||||
EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
|
EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
|
||||||
|
|
||||||
|
EVT_HEADER_END_REORDER(wxID_ANY, wxDataViewHeaderWindow::OnEndReorder)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -1227,7 +1236,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
unsigned int x_start;
|
unsigned int x_start;
|
||||||
for (x_start = 0; col_start < cols; col_start++)
|
for (x_start = 0; col_start < cols; col_start++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *col = GetOwner()->GetColumn(col_start);
|
wxDataViewColumn *col = GetOwner()->GetColumnAt(col_start);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -1242,7 +1251,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
unsigned int x_last = x_start;
|
unsigned int x_last = x_start;
|
||||||
for (; col_last < cols; col_last++)
|
for (; col_last < cols; col_last++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *col = GetOwner()->GetColumn(col_last);
|
wxDataViewColumn *col = GetOwner()->GetColumnAt(col_last);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -1274,7 +1283,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
int x = x_start;
|
int x = x_start;
|
||||||
for (unsigned int i = col_start; i < col_last; i++)
|
for (unsigned int i = col_start; i < col_last; i++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *col = GetOwner()->GetColumn(i);
|
wxDataViewColumn *col = GetOwner()->GetColumnAt(i);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue; // skip it
|
continue; // skip it
|
||||||
|
|
||||||
@@ -1315,8 +1324,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
wxDataViewColumn *expander = GetOwner()->GetExpanderColumn();
|
wxDataViewColumn *expander = GetOwner()->GetExpanderColumn();
|
||||||
if (!expander)
|
if (!expander)
|
||||||
{
|
{
|
||||||
// TODO: last column for RTL support
|
// TODO-RTL: last column for RTL support
|
||||||
expander = GetOwner()->GetColumn( 0 );
|
expander = GetOwner()->GetColumnAt( 0 );
|
||||||
GetOwner()->SetExpanderColumn(expander);
|
GetOwner()->SetExpanderColumn(expander);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1326,7 +1335,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
|||||||
for (unsigned int i = col_start; i < col_last; i++)
|
for (unsigned int i = col_start; i < col_last; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
wxDataViewColumn *col = GetOwner()->GetColumn( i );
|
wxDataViewColumn *col = GetOwner()->GetColumnAt( i );
|
||||||
wxDataViewRenderer *cell = col->GetRenderer();
|
wxDataViewRenderer *cell = col->GetRenderer();
|
||||||
cell_rect.width = col->GetWidth();
|
cell_rect.width = col->GetWidth();
|
||||||
|
|
||||||
@@ -1476,7 +1485,7 @@ void wxDataViewMainWindow::OnRenameTimer()
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < cols; i++)
|
for (i = 0; i < cols; i++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *c = GetOwner()->GetColumn( i );
|
wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
|
||||||
if (c->IsHidden())
|
if (c->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -1787,7 +1796,7 @@ void wxDataViewMainWindow::ScrollTo( int rows, int column )
|
|||||||
m_owner->CalcUnscrolledPosition( rect.x, rect.y, &xx, &yy );
|
m_owner->CalcUnscrolledPosition( rect.x, rect.y, &xx, &yy );
|
||||||
for (x_start = 0; colnum < column; colnum++)
|
for (x_start = 0; colnum < column; colnum++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *col = GetOwner()->GetColumn(colnum);
|
wxDataViewColumn *col = GetOwner()->GetColumnAt(colnum);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -1822,7 +1831,7 @@ int wxDataViewMainWindow::GetEndOfLastCol() const
|
|||||||
for (i = 0; i < GetOwner()->GetColumnCount(); i++)
|
for (i = 0; i < GetOwner()->GetColumnCount(); i++)
|
||||||
{
|
{
|
||||||
const wxDataViewColumn *c =
|
const wxDataViewColumn *c =
|
||||||
const_cast<wxDataViewCtrl*>(GetOwner())->GetColumn( i );
|
const_cast<wxDataViewCtrl*>(GetOwner())->GetColumnAt( i );
|
||||||
|
|
||||||
if (!c->IsHidden())
|
if (!c->IsHidden())
|
||||||
width += c->GetWidth();
|
width += c->GetWidth();
|
||||||
@@ -2549,7 +2558,7 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item
|
|||||||
m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
|
m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
|
||||||
for (unsigned x_start = 0; colnum < cols; colnum++)
|
for (unsigned x_start = 0; colnum < cols; colnum++)
|
||||||
{
|
{
|
||||||
col = GetOwner()->GetColumn(colnum);
|
col = GetOwner()->GetColumnAt(colnum);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -2573,9 +2582,9 @@ wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxD
|
|||||||
wxDataViewColumn *col = NULL;
|
wxDataViewColumn *col = NULL;
|
||||||
for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
|
for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
|
||||||
{
|
{
|
||||||
col = GetOwner()->GetColumn( i );
|
col = GetOwner()->GetColumnAt( i );
|
||||||
x += col->GetWidth();
|
x += col->GetWidth();
|
||||||
if( GetOwner()->GetColumn(i+1) == column )
|
if( GetOwner()->GetColumnAt(i+1) == column )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int w = col->GetWidth();
|
int w = col->GetWidth();
|
||||||
@@ -2864,7 +2873,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < cols; i++)
|
for (i = 0; i < cols; i++)
|
||||||
{
|
{
|
||||||
wxDataViewColumn *c = GetOwner()->GetColumn( i );
|
wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
|
||||||
if (c->IsHidden())
|
if (c->IsHidden())
|
||||||
continue; // skip it!
|
continue; // skip it!
|
||||||
|
|
||||||
@@ -3399,16 +3408,34 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
|
|||||||
return m_cols[idx];
|
return m_cols[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
|
wxDataViewColumn *wxDataViewCtrl::GetColumnAt(unsigned int pos) const
|
||||||
{
|
{
|
||||||
if (new_pos > m_cols.GetCount()) return;
|
// columns can't be reordered if there is no header window which allows
|
||||||
|
// to do this
|
||||||
|
const unsigned idx = m_headerArea ? m_headerArea->GetColumnsOrder()[pos]
|
||||||
|
: pos;
|
||||||
|
|
||||||
// Exchange position
|
return GetColumn(idx);
|
||||||
m_cols.DeleteContents(false);
|
}
|
||||||
m_cols.DeleteObject( col );
|
|
||||||
m_cols.Insert( new_pos, col );
|
|
||||||
m_cols.DeleteContents(true);
|
|
||||||
|
|
||||||
|
int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const
|
||||||
|
{
|
||||||
|
const unsigned count = m_cols.size();
|
||||||
|
for ( unsigned n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
if ( m_cols[n] == column )
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDataViewCtrl::ColumnMoved(wxDataViewColumn * WXUNUSED(col),
|
||||||
|
unsigned int WXUNUSED(new_pos))
|
||||||
|
{
|
||||||
|
// do _not_ reorder m_cols elements here, they should always be in the
|
||||||
|
// order in which columns were added, we only display the columns in
|
||||||
|
// different order
|
||||||
m_clientArea->UpdateDisplay();
|
m_clientArea->UpdateDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3433,17 +3460,18 @@ bool wxDataViewCtrl::ClearColumns()
|
|||||||
|
|
||||||
int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
|
int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
|
||||||
{
|
{
|
||||||
int ret = 0, dead = 0;
|
int ret = 0,
|
||||||
int len = GetColumnCount();
|
dummy = 0;
|
||||||
for (int i=0; i<len; i++)
|
unsigned int len = GetColumnCount();
|
||||||
|
for ( unsigned int i = 0; i < len; i++ )
|
||||||
{
|
{
|
||||||
wxDataViewColumn * col = GetColumn(i);
|
wxDataViewColumn * col = GetColumnAt(i);
|
||||||
if (col->IsHidden())
|
if (col->IsHidden())
|
||||||
continue;
|
continue;
|
||||||
ret += col->GetWidth();
|
ret += col->GetWidth();
|
||||||
if (column==col)
|
if (column==col)
|
||||||
{
|
{
|
||||||
CalcScrolledPosition( ret, dead, &ret, &dead );
|
CalcScrolledPosition( ret, dummy, &ret, &dummy );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3619,17 +3647,7 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie
|
|||||||
if( column == NULL )
|
if( column == NULL )
|
||||||
EnsureVisible(row, -1);
|
EnsureVisible(row, -1);
|
||||||
else
|
else
|
||||||
{
|
EnsureVisible( row, GetColumnIndex(column) );
|
||||||
int col = 0;
|
|
||||||
int len = GetColumnCount();
|
|
||||||
for( int i = 0; i < len; i ++ )
|
|
||||||
if( GetColumn(i) == column )
|
|
||||||
{
|
|
||||||
col = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
EnsureVisible( row, col );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -151,7 +151,7 @@ void wxHeaderCtrl::DoSetCount(unsigned int count)
|
|||||||
// and add the new ones
|
// and add the new ones
|
||||||
for ( n = 0; n < count; n++ )
|
for ( n = 0; n < count; n++ )
|
||||||
{
|
{
|
||||||
DoInsertItem(n);
|
DoInsertItem(n, -1 /* default order, i.e. append */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +162,15 @@ void wxHeaderCtrl::DoUpdate(unsigned int idx)
|
|||||||
// arrange not to block setting the width from there and the logic would be
|
// arrange not to block setting the width from there and the logic would be
|
||||||
// more complicated as we'd have to reset the old values as well as setting
|
// more complicated as we'd have to reset the old values as well as setting
|
||||||
// the new ones -- so instead just recreate the column
|
// the new ones -- so instead just recreate the column
|
||||||
|
|
||||||
|
// we need to preserve the old position ourselves as the column doesn't
|
||||||
|
// store it (TODO: should it?)
|
||||||
|
const unsigned int pos = GetColumnPos(idx);
|
||||||
Header_DeleteItem(GetHwnd(), idx);
|
Header_DeleteItem(GetHwnd(), idx);
|
||||||
DoInsertItem(idx);
|
DoInsertItem(idx, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxHeaderCtrl::DoInsertItem(unsigned int idx)
|
void wxHeaderCtrl::DoInsertItem(unsigned int idx, int order)
|
||||||
{
|
{
|
||||||
const wxHeaderColumnBase& col = GetColumn(idx);
|
const wxHeaderColumnBase& col = GetColumn(idx);
|
||||||
|
|
||||||
@@ -249,12 +253,38 @@ void wxHeaderCtrl::DoInsertItem(unsigned int idx)
|
|||||||
hdi.cxy = col.IsHidden() ? 0 : col.GetWidth();
|
hdi.cxy = col.IsHidden() ? 0 : col.GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( order != -1 )
|
||||||
|
{
|
||||||
|
hdi.mask |= HDI_ORDER;
|
||||||
|
hdi.iOrder = order;
|
||||||
|
}
|
||||||
|
|
||||||
if ( ::SendMessage(GetHwnd(), HDM_INSERTITEM, idx, (LPARAM)&hdi) == -1 )
|
if ( ::SendMessage(GetHwnd(), HDM_INSERTITEM, idx, (LPARAM)&hdi) == -1 )
|
||||||
{
|
{
|
||||||
wxLogLastError(_T("Header_InsertItem()"));
|
wxLogLastError(_T("Header_InsertItem()"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxHeaderCtrl::DoSetColumnsOrder(const wxArrayInt& order)
|
||||||
|
{
|
||||||
|
if ( !Header_SetOrderArray(GetHwnd(), order.size(), &order[0]) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("Header_GetOrderArray"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxArrayInt wxHeaderCtrl::DoGetColumnsOrder() const
|
||||||
|
{
|
||||||
|
const unsigned count = GetColumnCount();
|
||||||
|
wxArrayInt order(count);
|
||||||
|
if ( !Header_GetOrderArray(GetHwnd(), count, &order[0]) )
|
||||||
|
{
|
||||||
|
wxLogLastError(_T("Header_GetOrderArray"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxHeaderCtrl events
|
// wxHeaderCtrl events
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -294,7 +324,9 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
wxEventType evtType = wxEVT_NULL;
|
wxEventType evtType = wxEVT_NULL;
|
||||||
int idx = nmhdr->iItem;
|
int idx = nmhdr->iItem;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
int order = -1;
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
|
bool veto = false;
|
||||||
const UINT code = nmhdr->hdr.code;
|
const UINT code = nmhdr->hdr.code;
|
||||||
switch ( code )
|
switch ( code )
|
||||||
{
|
{
|
||||||
@@ -336,9 +368,8 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
// even generate any events for them
|
// even generate any events for them
|
||||||
if ( !GetColumn(idx).IsResizeable() )
|
if ( !GetColumn(idx).IsResizeable() )
|
||||||
{
|
{
|
||||||
*result = TRUE;
|
veto = true;
|
||||||
|
break;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
evtType = wxEVT_COMMAND_HEADER_BEGIN_RESIZE;
|
evtType = wxEVT_COMMAND_HEADER_BEGIN_RESIZE;
|
||||||
@@ -370,12 +401,34 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
{
|
{
|
||||||
// prevent the column from being shrunk beneath its min width
|
// prevent the column from being shrunk beneath its min width
|
||||||
if ( nmhdr->pitem->cxy < GetColumn(idx).GetMinWidth() )
|
if ( nmhdr->pitem->cxy < GetColumn(idx).GetMinWidth() )
|
||||||
{
|
veto = true;
|
||||||
*result = TRUE;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
// column reordering events
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
case HDN_BEGINDRAG:
|
||||||
|
// Windows sometimes sends us events with invalid column indices
|
||||||
|
if ( idx == -1 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// column must have the appropriate flag to be draggable
|
||||||
|
if ( !GetColumn(idx).IsReorderable() )
|
||||||
|
{
|
||||||
|
veto = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evtType = wxEVT_COMMAND_HEADER_BEGIN_REORDER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HDN_ENDDRAG:
|
||||||
|
evtType = wxEVT_COMMAND_HEADER_END_REORDER;
|
||||||
|
|
||||||
|
wxASSERT_MSG( nmhdr->pitem->mask & HDI_ORDER, "should have order" );
|
||||||
|
order = nmhdr->pitem->iOrder;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NM_RELEASEDCAPTURE:
|
case NM_RELEASEDCAPTURE:
|
||||||
@@ -391,22 +444,31 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
event.SetEventObject(this);
|
event.SetEventObject(this);
|
||||||
event.SetColumn(idx);
|
event.SetColumn(idx);
|
||||||
event.SetWidth(width);
|
event.SetWidth(width);
|
||||||
|
if ( order != -1 )
|
||||||
|
event.SetNewOrder(order);
|
||||||
if ( cancelled )
|
if ( cancelled )
|
||||||
event.SetCancelled();
|
event.SetCancelled();
|
||||||
|
|
||||||
if ( GetEventHandler()->ProcessEvent(event) )
|
if ( GetEventHandler()->ProcessEvent(event) )
|
||||||
{
|
{
|
||||||
if ( !event.IsAllowed() )
|
if ( event.IsAllowed() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// we need to veto the default handling of this message, don't
|
||||||
|
// return to execute the code in the "if veto" branch below
|
||||||
|
veto = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( veto )
|
||||||
{
|
{
|
||||||
// all of HDN_BEGIN{DRAG,TRACK}, HDN_TRACK and HDN_ITEMCHANGING
|
// all of HDN_BEGIN{DRAG,TRACK}, HDN_TRACK and HDN_ITEMCHANGING
|
||||||
// interpret TRUE return value as meaning to stop the control
|
// interpret TRUE return value as meaning to stop the control
|
||||||
// default handling of the message
|
// default handling of the message
|
||||||
*result = TRUE;
|
*result = TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
|
return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user