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; }
|
||||
|
||||
// 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:
|
||||
wxDataViewColumnList m_cols;
|
||||
wxDataViewModelNotifier *m_notifier;
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "wx/control.h"
|
||||
|
||||
#include "wx/dynarray.h"
|
||||
#include "wx/vector.h"
|
||||
|
||||
#include "wx/headercol.h"
|
||||
@@ -85,6 +86,18 @@ public:
|
||||
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
|
||||
// -------------------------------
|
||||
@@ -120,6 +133,9 @@ private:
|
||||
|
||||
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
|
||||
virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
|
||||
|
||||
@@ -272,6 +288,7 @@ public:
|
||||
: wxNotifyEvent(commandType, winid),
|
||||
m_col(-1),
|
||||
m_width(0),
|
||||
m_order(static_cast<unsigned int>(-1)),
|
||||
m_cancelled(false)
|
||||
{
|
||||
}
|
||||
@@ -280,6 +297,7 @@ public:
|
||||
: wxNotifyEvent(event),
|
||||
m_col(event.m_col),
|
||||
m_width(event.m_width),
|
||||
m_order(event.m_order),
|
||||
m_cancelled(event.m_cancelled)
|
||||
{
|
||||
}
|
||||
@@ -292,6 +310,10 @@ public:
|
||||
int GetWidth() const { return m_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?
|
||||
bool IsCancelled() const { return m_cancelled; }
|
||||
void SetCancelled() { m_cancelled = true; }
|
||||
@@ -305,6 +327,9 @@ protected:
|
||||
// the current width for the dragging events
|
||||
int m_width;
|
||||
|
||||
// the new column position for end reorder event
|
||||
unsigned int m_order;
|
||||
|
||||
// was the drag operation 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_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&);
|
||||
|
||||
#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_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_
|
||||
|
@@ -55,6 +55,9 @@ private:
|
||||
|
||||
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
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
|
||||
@@ -66,8 +69,8 @@ private:
|
||||
void Init();
|
||||
|
||||
// wrapper around Header_InsertItem(): insert the item by using information
|
||||
// from GetColumn(idx)
|
||||
void DoInsertItem(unsigned int idx);
|
||||
// from GetColumn(idx) and at the given display position if order != -1
|
||||
void DoInsertItem(unsigned int idx, int order);
|
||||
|
||||
// get the event type corresponding to a click or double click event
|
||||
// (depending on dblclk value) with the specified (using MSW convention)
|
||||
|
@@ -86,6 +86,20 @@
|
||||
or the resizing was cancelled. If wxHeaderCtrlEvent::IsCancelled()
|
||||
returns @true, nothing should be done, otherwise the column should
|
||||
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
|
||||
|
||||
@library{wxcore}
|
||||
@@ -195,6 +209,62 @@ public:
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
Method to be implemented by the derived classes to return the
|
||||
@@ -430,6 +500,16 @@ public:
|
||||
*/
|
||||
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.
|
||||
|
||||
|
@@ -64,6 +64,10 @@ void wxHeaderCtrlBase::ScrollWindow(int dx,
|
||||
DoScrollHorz(dx);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxHeaderCtrlBase event handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
|
||||
{
|
||||
const unsigned col = event.GetColumn();
|
||||
@@ -77,6 +81,65 @@ void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
|
||||
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
|
||||
// ============================================================================
|
||||
@@ -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_RESIZING = 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_NO_COPY_CLASS(wxDataViewHeaderWindow)
|
||||
};
|
||||
@@ -193,6 +200,8 @@ BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
|
||||
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
|
||||
|
||||
EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
|
||||
|
||||
EVT_HEADER_END_REORDER(wxID_ANY, wxDataViewHeaderWindow::OnEndReorder)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1227,7 +1236,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
||||
unsigned int x_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())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -1242,7 +1251,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
||||
unsigned int x_last = x_start;
|
||||
for (; col_last < cols; col_last++)
|
||||
{
|
||||
wxDataViewColumn *col = GetOwner()->GetColumn(col_last);
|
||||
wxDataViewColumn *col = GetOwner()->GetColumnAt(col_last);
|
||||
if (col->IsHidden())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -1274,7 +1283,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
||||
int x = x_start;
|
||||
for (unsigned int i = col_start; i < col_last; i++)
|
||||
{
|
||||
wxDataViewColumn *col = GetOwner()->GetColumn(i);
|
||||
wxDataViewColumn *col = GetOwner()->GetColumnAt(i);
|
||||
if (col->IsHidden())
|
||||
continue; // skip it
|
||||
|
||||
@@ -1315,8 +1324,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
||||
wxDataViewColumn *expander = GetOwner()->GetExpanderColumn();
|
||||
if (!expander)
|
||||
{
|
||||
// TODO: last column for RTL support
|
||||
expander = GetOwner()->GetColumn( 0 );
|
||||
// TODO-RTL: last column for RTL support
|
||||
expander = GetOwner()->GetColumnAt( 0 );
|
||||
GetOwner()->SetExpanderColumn(expander);
|
||||
}
|
||||
|
||||
@@ -1326,7 +1335,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
|
||||
for (unsigned int i = col_start; i < col_last; i++)
|
||||
{
|
||||
|
||||
wxDataViewColumn *col = GetOwner()->GetColumn( i );
|
||||
wxDataViewColumn *col = GetOwner()->GetColumnAt( i );
|
||||
wxDataViewRenderer *cell = col->GetRenderer();
|
||||
cell_rect.width = col->GetWidth();
|
||||
|
||||
@@ -1476,7 +1485,7 @@ void wxDataViewMainWindow::OnRenameTimer()
|
||||
unsigned int i;
|
||||
for (i = 0; i < cols; i++)
|
||||
{
|
||||
wxDataViewColumn *c = GetOwner()->GetColumn( i );
|
||||
wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
|
||||
if (c->IsHidden())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -1787,7 +1796,7 @@ void wxDataViewMainWindow::ScrollTo( int rows, int column )
|
||||
m_owner->CalcUnscrolledPosition( rect.x, rect.y, &xx, &yy );
|
||||
for (x_start = 0; colnum < column; colnum++)
|
||||
{
|
||||
wxDataViewColumn *col = GetOwner()->GetColumn(colnum);
|
||||
wxDataViewColumn *col = GetOwner()->GetColumnAt(colnum);
|
||||
if (col->IsHidden())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -1822,7 +1831,7 @@ int wxDataViewMainWindow::GetEndOfLastCol() const
|
||||
for (i = 0; i < GetOwner()->GetColumnCount(); i++)
|
||||
{
|
||||
const wxDataViewColumn *c =
|
||||
const_cast<wxDataViewCtrl*>(GetOwner())->GetColumn( i );
|
||||
const_cast<wxDataViewCtrl*>(GetOwner())->GetColumnAt( i );
|
||||
|
||||
if (!c->IsHidden())
|
||||
width += c->GetWidth();
|
||||
@@ -2549,7 +2558,7 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item
|
||||
m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
|
||||
for (unsigned x_start = 0; colnum < cols; colnum++)
|
||||
{
|
||||
col = GetOwner()->GetColumn(colnum);
|
||||
col = GetOwner()->GetColumnAt(colnum);
|
||||
if (col->IsHidden())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -2573,9 +2582,9 @@ wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxD
|
||||
wxDataViewColumn *col = NULL;
|
||||
for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
|
||||
{
|
||||
col = GetOwner()->GetColumn( i );
|
||||
col = GetOwner()->GetColumnAt( i );
|
||||
x += col->GetWidth();
|
||||
if( GetOwner()->GetColumn(i+1) == column )
|
||||
if( GetOwner()->GetColumnAt(i+1) == column )
|
||||
break;
|
||||
}
|
||||
int w = col->GetWidth();
|
||||
@@ -2864,7 +2873,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
|
||||
unsigned int i;
|
||||
for (i = 0; i < cols; i++)
|
||||
{
|
||||
wxDataViewColumn *c = GetOwner()->GetColumn( i );
|
||||
wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
|
||||
if (c->IsHidden())
|
||||
continue; // skip it!
|
||||
|
||||
@@ -3399,16 +3408,34 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
|
||||
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
|
||||
m_cols.DeleteContents(false);
|
||||
m_cols.DeleteObject( col );
|
||||
m_cols.Insert( new_pos, col );
|
||||
m_cols.DeleteContents(true);
|
||||
return GetColumn(idx);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -3433,17 +3460,18 @@ bool wxDataViewCtrl::ClearColumns()
|
||||
|
||||
int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
|
||||
{
|
||||
int ret = 0, dead = 0;
|
||||
int len = GetColumnCount();
|
||||
for (int i=0; i<len; i++)
|
||||
int ret = 0,
|
||||
dummy = 0;
|
||||
unsigned int len = GetColumnCount();
|
||||
for ( unsigned int i = 0; i < len; i++ )
|
||||
{
|
||||
wxDataViewColumn * col = GetColumn(i);
|
||||
wxDataViewColumn * col = GetColumnAt(i);
|
||||
if (col->IsHidden())
|
||||
continue;
|
||||
ret += col->GetWidth();
|
||||
if (column==col)
|
||||
{
|
||||
CalcScrolledPosition( ret, dead, &ret, &dead );
|
||||
CalcScrolledPosition( ret, dummy, &ret, &dummy );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3619,17 +3647,7 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie
|
||||
if( column == NULL )
|
||||
EnsureVisible(row, -1);
|
||||
else
|
||||
{
|
||||
int col = 0;
|
||||
int len = GetColumnCount();
|
||||
for( int i = 0; i < len; i ++ )
|
||||
if( GetColumn(i) == column )
|
||||
{
|
||||
col = i;
|
||||
break;
|
||||
}
|
||||
EnsureVisible( row, col );
|
||||
}
|
||||
EnsureVisible( row, GetColumnIndex(column) );
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -151,7 +151,7 @@ void wxHeaderCtrl::DoSetCount(unsigned int count)
|
||||
// and add the new ones
|
||||
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
|
||||
// more complicated as we'd have to reset the old values as well as setting
|
||||
// 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);
|
||||
DoInsertItem(idx);
|
||||
DoInsertItem(idx, pos);
|
||||
}
|
||||
|
||||
void wxHeaderCtrl::DoInsertItem(unsigned int idx)
|
||||
void wxHeaderCtrl::DoInsertItem(unsigned int idx, int order)
|
||||
{
|
||||
const wxHeaderColumnBase& col = GetColumn(idx);
|
||||
|
||||
@@ -249,12 +253,38 @@ void wxHeaderCtrl::DoInsertItem(unsigned int idx)
|
||||
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 )
|
||||
{
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -294,7 +324,9 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
wxEventType evtType = wxEVT_NULL;
|
||||
int idx = nmhdr->iItem;
|
||||
int width = 0;
|
||||
int order = -1;
|
||||
bool cancelled = false;
|
||||
bool veto = false;
|
||||
const UINT code = nmhdr->hdr.code;
|
||||
switch ( code )
|
||||
{
|
||||
@@ -336,9 +368,8 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
// even generate any events for them
|
||||
if ( !GetColumn(idx).IsResizeable() )
|
||||
{
|
||||
*result = TRUE;
|
||||
|
||||
return true;
|
||||
veto = true;
|
||||
break;
|
||||
}
|
||||
|
||||
evtType = wxEVT_COMMAND_HEADER_BEGIN_RESIZE;
|
||||
@@ -370,14 +401,36 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
{
|
||||
// prevent the column from being shrunk beneath its min width
|
||||
if ( nmhdr->pitem->cxy < GetColumn(idx).GetMinWidth() )
|
||||
{
|
||||
*result = TRUE;
|
||||
|
||||
return true;
|
||||
}
|
||||
veto = true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
case NM_RELEASEDCAPTURE:
|
||||
cancelled = true;
|
||||
break;
|
||||
@@ -391,23 +444,32 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
event.SetEventObject(this);
|
||||
event.SetColumn(idx);
|
||||
event.SetWidth(width);
|
||||
if ( order != -1 )
|
||||
event.SetNewOrder(order);
|
||||
if ( cancelled )
|
||||
event.SetCancelled();
|
||||
|
||||
if ( GetEventHandler()->ProcessEvent(event) )
|
||||
{
|
||||
if ( !event.IsAllowed() )
|
||||
{
|
||||
// all of HDN_BEGIN{DRAG,TRACK}, HDN_TRACK and HDN_ITEMCHANGING
|
||||
// interpret TRUE return value as meaning to stop the control
|
||||
// default handling of the message
|
||||
*result = TRUE;
|
||||
}
|
||||
if ( event.IsAllowed() )
|
||||
return true;
|
||||
|
||||
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
|
||||
// interpret TRUE return value as meaning to stop the control
|
||||
// default handling of the message
|
||||
*result = TRUE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user