From: Vadim Zeitlin Date: Mon, 8 Dec 2008 17:33:03 +0000 (+0000) Subject: honour column min width when resizing in wxHeaderCtrl, no need to do it in wxDataViewCtrl X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a45caa71bf39f7b01f586a2378927a1a76659263 honour column min width when resizing in wxHeaderCtrl, no need to do it in wxDataViewCtrl git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57201 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/generic/headerctrlg.h b/include/wx/generic/headerctrlg.h index 42fe827ea8..127f798c40 100644 --- a/include/wx/generic/headerctrlg.h +++ b/include/wx/generic/headerctrlg.h @@ -94,9 +94,19 @@ private: // 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); + // start (if m_colBeingResized is -1) or continue resizing the column + // + // this generates wxEVT_COMMAND_HEADER_BEGIN_RESIZE/RESIZING events and can + // cancel the operation if the user handler decides so + void StartOrContinueResizing(unsigned int col, int xPhysical); + + // end the resizing operation currently in progress and generate an event + // about it with its cancelled flag set if xPhysical is -1 + void EndResizing(int xPhysical); + + // constrain the given position to be larger than the start position of the + // given column plus its minimal width and return the effective width + int ConstrainByMinWidth(unsigned int col, int& xPhysical); // update the current position of the resizing marker if xPhysical is a // valid physical coordinate value or remove it entirely if it is -1 diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 7112252982..edf9429ba4 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -143,15 +143,6 @@ private: event.Veto(); } - void OnResizing(wxHeaderCtrlEvent& event) - { - const wxHeaderColumnBase& col = GetColumn(event.GetColumn()); - - const int minWidth = col.GetMinWidth(); - if ( event.GetWidth() < minWidth ) - event.Veto(); - } - void OnEndResize(wxHeaderCtrlEvent& event) { if ( !event.IsCancelled() ) @@ -171,7 +162,6 @@ BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl) EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick) EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnBeginResize) - EVT_HEADER_RESIZING(wxID_ANY, wxDataViewHeaderWindow::OnResizing) EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize) END_EVENT_TABLE() diff --git a/src/generic/headerctrlg.cpp b/src/generic/headerctrlg.cpp index 37cc6039a9..0887b94cfc 100644 --- a/src/generic/headerctrlg.cpp +++ b/src/generic/headerctrlg.cpp @@ -247,7 +247,54 @@ void wxHeaderCtrl::EndDragging() SetCursor(wxNullCursor); } -void wxHeaderCtrl::EndResizing(int width) +int wxHeaderCtrl::ConstrainByMinWidth(unsigned int col, int& xPhysical) +{ + const int xStart = GetColStart(col); + + // notice that GetMinWidth() returns 0 if there is no minimal width so it + // still makes sense to use it even in this case + const int xMinEnd = xStart + GetColumn(col).GetMinWidth(); + + if ( xPhysical < xMinEnd ) + xPhysical = xMinEnd; + + return xPhysical - xStart; +} + +void wxHeaderCtrl::StartOrContinueResizing(unsigned int col, int xPhysical) +{ + wxHeaderCtrlEvent event(IsResizing() ? wxEVT_COMMAND_HEADER_RESIZING + : wxEVT_COMMAND_HEADER_BEGIN_RESIZE, + GetId()); + event.SetEventObject(this); + event.SetColumn(col); + + event.SetWidth(ConstrainByMinWidth(col, xPhysical)); + + if ( GetEventHandler()->ProcessEvent(event) && !event.IsAllowed() ) + { + if ( IsResizing() ) + { + ReleaseMouse(); + EndResizing(-1); + } + //else: nothing to do -- we just don't start to resize + } + else // go ahead with resizing + { + if ( !IsResizing() ) + { + m_colBeingResized = col; + SetCursor(wxCursor(wxCURSOR_SIZEWE)); + CaptureMouse(); + } + //else: we had already done the above when we started + + UpdateResizingMarker(xPhysical); + } +} + +void wxHeaderCtrl::EndResizing(int xPhysical) { wxASSERT_MSG( IsResizing(), "shouldn't be called if we're not resizing" ); @@ -255,16 +302,16 @@ void wxHeaderCtrl::EndResizing(int width) // if dragging was cancelled we must have already lost the mouse capture so // don't try to release it - if ( width != -1 ) + if ( xPhysical != -1 ) ReleaseMouse(); wxHeaderCtrlEvent event(wxEVT_COMMAND_HEADER_END_RESIZE, GetId()); event.SetEventObject(this); event.SetColumn(m_colBeingResized); - if ( width == -1 ) + if ( xPhysical == -1 ) event.SetCancelled(); else - event.SetWidth(width); + event.SetWidth(ConstrainByMinWidth(m_colBeingResized, xPhysical)); GetEventHandler()->ProcessEvent(event); @@ -384,9 +431,9 @@ void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent) if ( IsResizing() ) { if ( mevent.LeftUp() ) - EndResizing(xPhysical - GetColStart(m_colBeingResized)); + EndResizing(xPhysical); else // update the live separator position - UpdateResizingMarker(xPhysical); + StartOrContinueResizing(m_colBeingResized, xPhysical); return; } @@ -427,10 +474,8 @@ void wxHeaderCtrl::OnMouse(wxMouseEvent& mevent) if ( onSeparator ) { // start resizing the column - m_colBeingResized = col; - SetCursor(wxCursor(wxCURSOR_SIZEWE)); - CaptureMouse(); - UpdateResizingMarker(xPhysical); + wxASSERT_MSG( !IsResizing(), "reentering resize mode?" ); + StartOrContinueResizing(col, xPhysical); } else // on column itself { diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 39a0beaa01..463ef53132 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -295,6 +295,7 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxEventType evtType = wxEVT_NULL; int idx = nmhdr->iItem; int width = 0; + bool cancelled = false; const UINT code = nmhdr->hdr.code; switch ( code ) { @@ -343,10 +344,34 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case HDN_ENDTRACKA: case HDN_ENDTRACKW: + width = nmhdr->pitem->cxy; + if ( evtType == wxEVT_NULL ) + { evtType = wxEVT_COMMAND_HEADER_END_RESIZE; - width = nmhdr->pitem->cxy; + // don't generate events with invalid width + const int minWidth = GetColumn(idx).GetMinWidth(); + if ( width < minWidth ) + width = minWidth; + } + break; + + case HDN_ITEMCHANGING: + if ( nmhdr->pitem && (nmhdr->pitem->mask & HDI_WIDTH) ) + { + // prevent the column from being shrunk beneath its min width + if ( nmhdr->pitem->cxy < GetColumn(idx).GetMinWidth() ) + { + *result = TRUE; + + return true; + } + } + break; + + case NM_RELEASEDCAPTURE: + cancelled = true; break; } @@ -358,6 +383,8 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) event.SetEventObject(this); event.SetColumn(idx); event.SetWidth(width); + if ( cancelled ) + event.SetCancelled(); if ( GetEventHandler()->ProcessEvent(event) ) {