implement column resizing events in wxHeaderCtrl
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57190 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -359,11 +359,6 @@ private:
|
|||||||
m_sortAscending = true;
|
m_sortAscending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// like SetWidth() but does not ask the header window of the
|
|
||||||
// wxDataViewCtrl to reflect the width-change.
|
|
||||||
void SetInternalWidth(int width);
|
|
||||||
|
|
||||||
|
|
||||||
wxString m_title;
|
wxString m_title;
|
||||||
int m_width,
|
int m_width,
|
||||||
m_minWidth;
|
m_minWidth;
|
||||||
@@ -482,8 +477,11 @@ public: // utility functions not part of the API
|
|||||||
// called by header window after reorder
|
// called by header window after reorder
|
||||||
void ColumnMoved( wxDataViewColumn* col, unsigned int new_pos );
|
void ColumnMoved( wxDataViewColumn* col, unsigned int new_pos );
|
||||||
|
|
||||||
// updates the header window after a change in a column setting
|
// update the display after a change to an individual column
|
||||||
void OnColumnChange();
|
void OnColumnChange(unsigned int idx);
|
||||||
|
|
||||||
|
// update after a change to the number of columns
|
||||||
|
void OnColumnsCountChanged();
|
||||||
|
|
||||||
wxWindow *GetMainWindow() { return (wxWindow*) m_clientArea; }
|
wxWindow *GetMainWindow() { return (wxWindow*) m_clientArea; }
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "wx/event.h"
|
#include "wx/event.h"
|
||||||
#include "wx/vector.h"
|
#include "wx/vector.h"
|
||||||
|
#include "wx/overlay.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxHeaderCtrl
|
// wxHeaderCtrl
|
||||||
@@ -64,6 +65,7 @@ private:
|
|||||||
// event handlers
|
// event handlers
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
void OnMouse(wxMouseEvent& event);
|
void OnMouse(wxMouseEvent& event);
|
||||||
|
void OnCaptureLost(wxMouseCaptureLostEvent& event);
|
||||||
|
|
||||||
// return the horizontal start position of the given column
|
// return the horizontal start position of the given column
|
||||||
int GetColStart(unsigned int idx) const;
|
int GetColStart(unsigned int idx) const;
|
||||||
@@ -84,6 +86,17 @@ private:
|
|||||||
// column 1 but close enough to the divider separating it from column 0)
|
// column 1 but close enough to the divider separating it from column 0)
|
||||||
int FindColumnAtPos(int x, bool& onSeparator) const;
|
int FindColumnAtPos(int x, bool& onSeparator) const;
|
||||||
|
|
||||||
|
// end any drag operation currently in progress (resizing or reordering)
|
||||||
|
void EndDragging();
|
||||||
|
|
||||||
|
// and the resizing operation currently in progress and generate an event
|
||||||
|
// about it with its cancelled flag set if width is -1
|
||||||
|
void EndResizing(int width);
|
||||||
|
|
||||||
|
// update the current position of the resizing marker if xPhysical is a
|
||||||
|
// valid physical coordinate value or remove it entirely if it is -1
|
||||||
|
void UpdateResizingMarker(int xPhysical);
|
||||||
|
|
||||||
|
|
||||||
// number of columns in the control currently
|
// number of columns in the control currently
|
||||||
unsigned int m_numColumns;
|
unsigned int m_numColumns;
|
||||||
@@ -91,9 +104,16 @@ private:
|
|||||||
// index of the column under mouse or -1 if none
|
// index of the column under mouse or -1 if none
|
||||||
unsigned int m_hover;
|
unsigned int m_hover;
|
||||||
|
|
||||||
|
// the column being resized or -1 if there is no resizing operation in
|
||||||
|
// progress
|
||||||
|
unsigned int m_colBeingResized;
|
||||||
|
|
||||||
// the horizontal scroll offset
|
// the horizontal scroll offset
|
||||||
int m_scrollOffset;
|
int m_scrollOffset;
|
||||||
|
|
||||||
|
// the overlay display used during the dragging operations
|
||||||
|
wxOverlay m_overlay;
|
||||||
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_NO_COPY_CLASS(wxHeaderCtrl)
|
DECLARE_NO_COPY_CLASS(wxHeaderCtrl)
|
||||||
|
@@ -269,25 +269,45 @@ class WXDLLIMPEXP_CORE wxHeaderCtrlEvent : public wxNotifyEvent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxHeaderCtrlEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
|
wxHeaderCtrlEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
|
||||||
: wxNotifyEvent(commandType, winid)
|
: wxNotifyEvent(commandType, winid),
|
||||||
|
m_col(-1),
|
||||||
|
m_width(0),
|
||||||
|
m_cancelled(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
wxHeaderCtrlEvent(const wxHeaderCtrlEvent& event)
|
wxHeaderCtrlEvent(const wxHeaderCtrlEvent& event)
|
||||||
: wxNotifyEvent(event),
|
: wxNotifyEvent(event),
|
||||||
m_col(event.m_col)
|
m_col(event.m_col),
|
||||||
|
m_width(event.m_width),
|
||||||
|
m_cancelled(event.m_cancelled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the column which this event pertains to: valid for all header events
|
||||||
int GetColumn() const { return m_col; }
|
int GetColumn() const { return m_col; }
|
||||||
void SetColumn(int col) { m_col = col; }
|
void SetColumn(int col) { m_col = col; }
|
||||||
|
|
||||||
|
// the width of the column: valid for column resizing/dragging events only
|
||||||
|
int GetWidth() const { return m_width; }
|
||||||
|
void SetWidth(int width) { m_width = width; }
|
||||||
|
|
||||||
|
// was the drag operation cancelled or did it complete successfully?
|
||||||
|
bool IsCancelled() const { return m_cancelled; }
|
||||||
|
void SetCancelled() { m_cancelled = true; }
|
||||||
|
|
||||||
virtual wxEvent *Clone() const { return new wxHeaderCtrlEvent(*this); }
|
virtual wxEvent *Clone() const { return new wxHeaderCtrlEvent(*this); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// the column affected by the event
|
// the column affected by the event
|
||||||
int m_col;
|
int m_col;
|
||||||
|
|
||||||
|
// the current width for the dragging events
|
||||||
|
int m_width;
|
||||||
|
|
||||||
|
// was the drag operation cancelled?
|
||||||
|
bool m_cancelled;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxHeaderCtrlEvent)
|
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxHeaderCtrlEvent)
|
||||||
};
|
};
|
||||||
@@ -303,6 +323,10 @@ extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_MIDDLE_DCLICK;
|
|||||||
|
|
||||||
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK;
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK;
|
||||||
|
|
||||||
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_BEGIN_DRAG;
|
||||||
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_DRAGGING;
|
||||||
|
extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_HEADER_END_DRAG;
|
||||||
|
|
||||||
typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
||||||
|
|
||||||
#define wxHeaderCtrlEventHandler(func) \
|
#define wxHeaderCtrlEventHandler(func) \
|
||||||
@@ -322,4 +346,8 @@ typedef void (wxEvtHandler::*wxHeaderCtrlEventFunction)(wxHeaderCtrlEvent&);
|
|||||||
|
|
||||||
#define EVT_HEADER_SEPARATOR_DCLICK(id, fn) wx__DECLARE_HEADER_EVT(SEPARATOR_DCLICK, id, fn)
|
#define EVT_HEADER_SEPARATOR_DCLICK(id, fn) wx__DECLARE_HEADER_EVT(SEPARATOR_DCLICK, id, fn)
|
||||||
|
|
||||||
|
#define EVT_HEADER_BEGIN_DRAG(id, fn) wx__DECLARE_HEADER_EVT(BEGIN_DRAG, id, fn)
|
||||||
|
#define EVT_HEADER_DRAGGING(id, fn) wx__DECLARE_HEADER_EVT(DRAGGING, id, fn)
|
||||||
|
#define EVT_HEADER_END_DRAG(id, fn) wx__DECLARE_HEADER_EVT(END_DRAG, id, fn)
|
||||||
|
|
||||||
#endif // _WX_HEADERCTRL_H_
|
#endif // _WX_HEADERCTRL_H_
|
||||||
|
@@ -71,13 +71,10 @@ private:
|
|||||||
enum Operation { Set, Insert };
|
enum Operation { Set, Insert };
|
||||||
void DoSetOrInsertItem(Operation oper, unsigned int idx);
|
void DoSetOrInsertItem(Operation oper, unsigned int idx);
|
||||||
|
|
||||||
// send an event of the given type for the given column, return true if it
|
// get the event type corresponding to a click or double click event
|
||||||
// was processed
|
// (depending on dblclk value) with the specified (using MSW convention)
|
||||||
bool SendEvent(wxEventType evtType, unsigned int idx);
|
// mouse button
|
||||||
|
wxEventType GetClickEventType(bool dblclk, int button);
|
||||||
// send a click or double click event (depending on dblclk value) for the
|
|
||||||
// click with the given button on the given item
|
|
||||||
bool SendClickEvent(bool dblclk, int button, unsigned int idx);
|
|
||||||
|
|
||||||
|
|
||||||
// the image list: initially NULL, created on demand
|
// the image list: initially NULL, created on demand
|
||||||
|
@@ -69,6 +69,22 @@
|
|||||||
(this action is commonly used to resize the column to fit its
|
(this action is commonly used to resize the column to fit its
|
||||||
contents width and the control provides UpdateColumnWidthToFit() method
|
contents width and the control provides UpdateColumnWidthToFit() method
|
||||||
to make implementing this easier).
|
to make implementing this easier).
|
||||||
|
|
||||||
|
@event{EVT_HEADER_BEGIN_DRAG(id, func)}
|
||||||
|
The user started to drag the column with the specified index (this
|
||||||
|
can only happen if wxHeaderColumn::IsResizeable() returned true for
|
||||||
|
this column). The event can be vetoed to prevent the control from
|
||||||
|
being resized, if it isn't, the dragging and end drag events will
|
||||||
|
be generated later.
|
||||||
|
@event{EVT_HEADER_DRAGGING(id, func)}
|
||||||
|
The user is dragging the column with the specified index and its
|
||||||
|
current width is wxHeaderCtrlEvent::GetWidth(). The event can be
|
||||||
|
vetoed to stop the dragging operation completely at any time.
|
||||||
|
@event{EVT_HEADER_END_DRAG(id, func)}
|
||||||
|
The user stopped dragging the column. If
|
||||||
|
wxHeaderCtrlEvent::IsCancelled() returns @true, nothing should
|
||||||
|
be done, otherwise the column should normally be resized to the
|
||||||
|
value of wxHeaderCtrlEvent::GetWidth().
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@library{wxcore}
|
@library{wxcore}
|
||||||
@@ -389,6 +405,22 @@ class wxHeaderCtrlEvent : public wxNotifyEvent
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Return the index of the column affected by this event.
|
Return the index of the column affected by this event.
|
||||||
|
|
||||||
|
This method can be called for all header control events.
|
||||||
*/
|
*/
|
||||||
int GetColumn() const;
|
int GetColumn() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the current width of the column.
|
||||||
|
|
||||||
|
This method can only be called for the dragging events.
|
||||||
|
*/
|
||||||
|
int GetWidth() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return @true if the drag operation was cancelled.
|
||||||
|
|
||||||
|
This method can only be called for the end drag event.
|
||||||
|
*/
|
||||||
|
bool IsCancelled() const;
|
||||||
};
|
};
|
||||||
|
@@ -177,3 +177,7 @@ const wxEventType wxEVT_COMMAND_HEADER_RIGHT_DCLICK = wxNewEventType();
|
|||||||
const wxEventType wxEVT_COMMAND_HEADER_MIDDLE_DCLICK = wxNewEventType();
|
const wxEventType wxEVT_COMMAND_HEADER_MIDDLE_DCLICK = wxNewEventType();
|
||||||
|
|
||||||
const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK = wxNewEventType();
|
const wxEventType wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK = wxNewEventType();
|
||||||
|
|
||||||
|
const wxEventType wxEVT_COMMAND_HEADER_BEGIN_DRAG = wxNewEventType();
|
||||||
|
const wxEventType wxEVT_COMMAND_HEADER_DRAGGING = wxNewEventType();
|
||||||
|
const wxEventType wxEVT_COMMAND_HEADER_END_DRAG = wxNewEventType();
|
||||||
|
@@ -102,6 +102,7 @@ protected:
|
|||||||
|
|
||||||
int widthContents = owner->GetBestColumnWidth(idx);
|
int widthContents = owner->GetBestColumnWidth(idx);
|
||||||
owner->GetColumn(idx)->SetWidth(wxMax(widthTitle, widthContents));
|
owner->GetColumn(idx)->SetWidth(wxMax(widthTitle, widthContents));
|
||||||
|
owner->OnColumnChange(idx);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -136,6 +137,28 @@ private:
|
|||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnBeginDrag(wxHeaderCtrlEvent& event)
|
||||||
|
{
|
||||||
|
if ( !GetColumn(event.GetColumn()).IsResizeable() )
|
||||||
|
event.Veto();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDragging(wxHeaderCtrlEvent& event)
|
||||||
|
{
|
||||||
|
const wxHeaderColumnBase& col = GetColumn(event.GetColumn());
|
||||||
|
|
||||||
|
const int minWidth = col.GetMinWidth();
|
||||||
|
if ( event.GetWidth() < minWidth )
|
||||||
|
event.Veto();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnEndDrag(wxHeaderCtrlEvent& event)
|
||||||
|
{
|
||||||
|
const unsigned col = event.GetColumn();
|
||||||
|
GetColumn(col).SetWidth(event.GetWidth());
|
||||||
|
GetOwner()->OnColumnChange(col);
|
||||||
|
}
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
|
DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
|
||||||
};
|
};
|
||||||
@@ -143,6 +166,10 @@ private:
|
|||||||
BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
|
BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
|
||||||
EVT_HEADER_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnClick)
|
EVT_HEADER_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnClick)
|
||||||
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
|
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
|
||||||
|
|
||||||
|
EVT_HEADER_BEGIN_DRAG(wxID_ANY, wxDataViewHeaderWindow::OnBeginDrag)
|
||||||
|
EVT_HEADER_DRAGGING(wxID_ANY, wxDataViewHeaderWindow::OnDragging)
|
||||||
|
EVT_HEADER_END_DRAG(wxID_ANY, wxDataViewHeaderWindow::OnEndDrag)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -3288,7 +3315,7 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_cols.Append( col );
|
m_cols.Append( col );
|
||||||
OnColumnChange();
|
OnColumnsCountChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3298,7 +3325,7 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_cols.Insert( col );
|
m_cols.Insert( col );
|
||||||
OnColumnChange();
|
OnColumnsCountChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3308,11 +3335,19 @@ bool wxDataViewCtrl::InsertColumn( unsigned int pos, wxDataViewColumn *col )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_cols.Insert( pos, col );
|
m_cols.Insert( pos, col );
|
||||||
OnColumnChange();
|
OnColumnsCountChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataViewCtrl::OnColumnChange()
|
void wxDataViewCtrl::OnColumnChange(unsigned int idx)
|
||||||
|
{
|
||||||
|
if ( m_headerArea )
|
||||||
|
m_headerArea->UpdateColumn(idx);
|
||||||
|
|
||||||
|
m_clientArea->UpdateDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDataViewCtrl::OnColumnsCountChanged()
|
||||||
{
|
{
|
||||||
if (m_headerArea)
|
if (m_headerArea)
|
||||||
m_headerArea->SetColumnCount(GetColumnCount());
|
m_headerArea->SetColumnCount(GetColumnCount());
|
||||||
@@ -3335,20 +3370,9 @@ unsigned int wxDataViewCtrl::GetColumnCount() const
|
|||||||
return m_cols.GetCount();
|
return m_cols.GetCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const
|
wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
|
||||||
{
|
{
|
||||||
wxDataViewColumnList::const_iterator iter;
|
return m_cols[idx];
|
||||||
unsigned int i = 0;
|
|
||||||
for (iter = m_cols.begin(); iter!=m_cols.end(); iter++)
|
|
||||||
{
|
|
||||||
if (i == pos)
|
|
||||||
return *iter;
|
|
||||||
|
|
||||||
if ((*iter)->IsHidden())
|
|
||||||
continue;
|
|
||||||
i ++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
|
void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
|
||||||
@@ -3371,7 +3395,7 @@ bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_cols.Erase(ret);
|
m_cols.Erase(ret);
|
||||||
OnColumnChange();
|
OnColumnsCountChanged();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3379,7 +3403,7 @@ bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column )
|
|||||||
bool wxDataViewCtrl::ClearColumns()
|
bool wxDataViewCtrl::ClearColumns()
|
||||||
{
|
{
|
||||||
m_cols.Clear();
|
m_cols.Clear();
|
||||||
OnColumnChange();
|
OnColumnsCountChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -57,7 +57,8 @@ const unsigned COL_NONE = (unsigned)-1;
|
|||||||
void wxHeaderCtrl::Init()
|
void wxHeaderCtrl::Init()
|
||||||
{
|
{
|
||||||
m_numColumns = 0;
|
m_numColumns = 0;
|
||||||
m_hover = COL_NONE;
|
m_hover =
|
||||||
|
m_colBeingResized = COL_NONE;
|
||||||
m_scrollOffset = 0;
|
m_scrollOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,6 +210,55 @@ void wxHeaderCtrl::RefreshColsAfter(unsigned int idx)
|
|||||||
RefreshRect(rect);
|
RefreshRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxHeaderCtrl dragging
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxHeaderCtrl::UpdateResizingMarker(int xPhysical)
|
||||||
|
{
|
||||||
|
// unfortunately drawing the marker over the parent window doesn't work as
|
||||||
|
// it's usually covered by another window (the main control view) so just
|
||||||
|
// draw the marker over the header itself, even if it makes it not very
|
||||||
|
// useful
|
||||||
|
wxClientDC dc(this);
|
||||||
|
|
||||||
|
wxDCOverlay dcover(m_overlay, &dc);
|
||||||
|
dcover.Clear();
|
||||||
|
|
||||||
|
if ( xPhysical != -1 )
|
||||||
|
{
|
||||||
|
dc.SetPen(*wxLIGHT_GREY_PEN);
|
||||||
|
dc.DrawLine(xPhysical, 0, xPhysical, GetClientSize().y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxHeaderCtrl::EndDragging()
|
||||||
|
{
|
||||||
|
UpdateResizingMarker(-1);
|
||||||
|
|
||||||
|
m_overlay.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxHeaderCtrl::EndResizing(int width)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( m_colBeingResized != COL_NONE,
|
||||||
|
"shouldn't be called if we're not resizing" );
|
||||||
|
|
||||||
|
EndDragging();
|
||||||
|
|
||||||
|
wxHeaderCtrlEvent event(wxEVT_COMMAND_HEADER_END_DRAG, GetId());
|
||||||
|
event.SetEventObject(this);
|
||||||
|
event.SetColumn(m_colBeingResized);
|
||||||
|
if ( width == -1 )
|
||||||
|
event.SetCancelled();
|
||||||
|
else
|
||||||
|
event.SetWidth(width);
|
||||||
|
|
||||||
|
GetEventHandler()->ProcessEvent(event);
|
||||||
|
|
||||||
|
m_colBeingResized = COL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxHeaderCtrl event handlers
|
// wxHeaderCtrl event handlers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -217,6 +267,8 @@ BEGIN_EVENT_TABLE(wxHeaderCtrl, wxHeaderCtrlBase)
|
|||||||
EVT_PAINT(wxHeaderCtrl::OnPaint)
|
EVT_PAINT(wxHeaderCtrl::OnPaint)
|
||||||
|
|
||||||
EVT_MOUSE_EVENTS(wxHeaderCtrl::OnMouse)
|
EVT_MOUSE_EVENTS(wxHeaderCtrl::OnMouse)
|
||||||
|
|
||||||
|
EVT_MOUSE_CAPTURE_LOST(wxHeaderCtrl::OnCaptureLost)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||||
@@ -283,18 +335,42 @@ void wxHeaderCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxHeaderCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
if ( m_colBeingResized != COL_NONE )
|
||||||
|
EndResizing(-1);
|
||||||
|
}
|
||||||
|
|
||||||
void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent)
|
void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent)
|
||||||
{
|
{
|
||||||
|
// do this in advance to allow simply returning if we're not interested,
|
||||||
|
// we'll undo it if we do handle the event below
|
||||||
mevent.Skip();
|
mevent.Skip();
|
||||||
|
|
||||||
|
|
||||||
// account for the control displacement
|
// account for the control displacement
|
||||||
const int x = mevent.GetX() - m_scrollOffset;
|
const int xPhysical = mevent.GetX();
|
||||||
|
const int xLogical = xPhysical - m_scrollOffset;
|
||||||
|
|
||||||
|
// first deal with the [continuation of any] dragging operations in
|
||||||
|
// progress
|
||||||
|
if ( m_colBeingResized != COL_NONE )
|
||||||
|
{
|
||||||
|
if ( mevent.LeftUp() )
|
||||||
|
EndResizing(xLogical - GetColStart(m_colBeingResized));
|
||||||
|
else // update the live separator position
|
||||||
|
UpdateResizingMarker(xPhysical);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// find if the event is over a column at all
|
// find if the event is over a column at all
|
||||||
bool onSeparator;
|
bool onSeparator;
|
||||||
const unsigned col = mevent.Leaving()
|
const unsigned col = mevent.Leaving()
|
||||||
? (onSeparator = false, COL_NONE)
|
? (onSeparator = false, COL_NONE)
|
||||||
: FindColumnAtPos(x, onSeparator);
|
: FindColumnAtPos(xLogical, onSeparator);
|
||||||
|
|
||||||
|
|
||||||
// update the highlighted column if it changed
|
// update the highlighted column if it changed
|
||||||
if ( col != m_hover )
|
if ( col != m_hover )
|
||||||
@@ -306,9 +382,6 @@ void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent)
|
|||||||
RefreshColIfNotNone(m_hover);
|
RefreshColIfNotNone(m_hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( col == COL_NONE )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// update mouse cursor as it moves around
|
// update mouse cursor as it moves around
|
||||||
if ( mevent.Moving() )
|
if ( mevent.Moving() )
|
||||||
{
|
{
|
||||||
@@ -316,20 +389,30 @@ void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all the other events only make sense when they happen over a column
|
||||||
|
if ( col == COL_NONE )
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
// enter various dragging modes on left mouse press
|
||||||
if ( mevent.LeftDown() )
|
if ( mevent.LeftDown() )
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
if ( onSeparator )
|
if ( onSeparator )
|
||||||
// resize column
|
{
|
||||||
;
|
// start resizing the column
|
||||||
else
|
m_colBeingResized = col;
|
||||||
// drag column
|
UpdateResizingMarker(xPhysical);
|
||||||
|
}
|
||||||
|
else // on column itself
|
||||||
|
{
|
||||||
|
// TODO: drag column
|
||||||
;
|
;
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// determine the type of header event corresponding to this mouse event
|
// determine the type of header event corresponding to click events
|
||||||
wxEventType evtType = wxEVT_NULL;
|
wxEventType evtType = wxEVT_NULL;
|
||||||
const bool click = mevent.ButtonUp(),
|
const bool click = mevent.ButtonUp(),
|
||||||
dblclk = mevent.ButtonDClick();
|
dblclk = mevent.ButtonDClick();
|
||||||
|
@@ -260,16 +260,7 @@ void wxHeaderCtrl::DoSetOrInsertItem(Operation oper, unsigned int idx)
|
|||||||
// wxHeaderCtrl events
|
// wxHeaderCtrl events
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool wxHeaderCtrl::SendEvent(wxEventType evtType, unsigned int idx)
|
wxEventType wxHeaderCtrl::GetClickEventType(bool dblclk, int button)
|
||||||
{
|
|
||||||
wxHeaderCtrlEvent event(evtType, GetId());
|
|
||||||
event.SetEventObject(this);
|
|
||||||
event.SetColumn(idx);
|
|
||||||
|
|
||||||
return GetEventHandler()->ProcessEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxHeaderCtrl::SendClickEvent(bool dblclk, int button, unsigned int idx)
|
|
||||||
{
|
{
|
||||||
wxEventType evtType;
|
wxEventType evtType;
|
||||||
switch ( button )
|
switch ( button )
|
||||||
@@ -291,23 +282,27 @@ bool wxHeaderCtrl::SendClickEvent(bool dblclk, int button, unsigned int idx)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( wxS("unexpected event type") );
|
wxFAIL_MSG( wxS("unexpected event type") );
|
||||||
return false;
|
evtType = wxEVT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SendEvent(evtType, idx);
|
return evtType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||||
{
|
{
|
||||||
NMHEADER * const nmhdr = (NMHEADER *)lParam;
|
NMHEADER * const nmhdr = (NMHEADER *)lParam;
|
||||||
|
|
||||||
const int idx = nmhdr->iItem;
|
wxEventType evtType = wxEVT_NULL;
|
||||||
|
int idx = nmhdr->iItem;
|
||||||
|
int width = 0;
|
||||||
switch ( const UINT code = nmhdr->hdr.code )
|
switch ( const UINT code = nmhdr->hdr.code )
|
||||||
{
|
{
|
||||||
|
// click events
|
||||||
|
// ------------
|
||||||
|
|
||||||
case HDN_ITEMCLICK:
|
case HDN_ITEMCLICK:
|
||||||
case HDN_ITEMDBLCLICK:
|
case HDN_ITEMDBLCLICK:
|
||||||
if ( SendClickEvent(code == HDN_ITEMDBLCLICK, nmhdr->iButton, idx) )
|
evtType = GetClickEventType(code == HDN_ITEMDBLCLICK, nmhdr->iButton);
|
||||||
return true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// although we should get the notifications about the right clicks
|
// although we should get the notifications about the right clicks
|
||||||
@@ -317,20 +312,64 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
|||||||
case NM_RDBLCLK:
|
case NM_RDBLCLK:
|
||||||
{
|
{
|
||||||
POINT pt;
|
POINT pt;
|
||||||
const int col = wxMSWGetColumnClicked(&nmhdr->hdr, &pt);
|
idx = wxMSWGetColumnClicked(&nmhdr->hdr, &pt);
|
||||||
if ( col != wxNOT_FOUND )
|
if ( idx != wxNOT_FOUND )
|
||||||
{
|
evtType = GetClickEventType(code == NM_RDBLCLK, 1);
|
||||||
if ( SendClickEvent(code == NM_RDBLCLK, 1, col) )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//else: ignore clicks outside any column
|
//else: ignore clicks outside any column
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HDN_DIVIDERDBLCLICK:
|
case HDN_DIVIDERDBLCLICK:
|
||||||
if ( SendEvent(wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK, idx) )
|
evtType = wxEVT_COMMAND_HEADER_SEPARATOR_DCLICK;
|
||||||
return true;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// column resizing events
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
// see comments in wxListCtrl::MSWOnNotify() for why we catch both
|
||||||
|
// ASCII and Unicode versions of this message
|
||||||
|
case HDN_BEGINTRACKA:
|
||||||
|
case HDN_BEGINTRACKW:
|
||||||
|
evtType = wxEVT_COMMAND_HEADER_BEGIN_DRAG;
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case HDN_TRACKA:
|
||||||
|
case HDN_TRACKW:
|
||||||
|
if ( evtType == wxEVT_NULL )
|
||||||
|
evtType = wxEVT_COMMAND_HEADER_DRAGGING;
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case HDN_ENDTRACKA:
|
||||||
|
case HDN_ENDTRACKW:
|
||||||
|
if ( evtType == wxEVT_NULL )
|
||||||
|
evtType = wxEVT_COMMAND_HEADER_END_DRAG;
|
||||||
|
|
||||||
|
width = nmhdr->pitem->cxy;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// do generate the corresponding wx event
|
||||||
|
if ( evtType != wxEVT_NULL )
|
||||||
|
{
|
||||||
|
wxHeaderCtrlEvent event(evtType, GetId());
|
||||||
|
event.SetEventObject(this);
|
||||||
|
event.SetColumn(idx);
|
||||||
|
event.SetWidth(width);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
|
return wxHeaderCtrlBase::MSWOnNotify(idCtrl, lParam, result);
|
||||||
|
Reference in New Issue
Block a user