From: Vadim Zeitlin Date: Mon, 15 Dec 2008 22:42:37 +0000 (+0000) Subject: handle actions of the columns popup menu in wxHeaderCtrl itself (but the derived... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/613de0e89efab1cbf8463ea06e0cf0b2914fbce9?ds=sidebyside handle actions of the columns popup menu in wxHeaderCtrl itself (but the derived class must implement UpdateColumnVisibility()); also renamed wxHD_DRAGDROP to wxHD_ALLOW_REORDER as it will be possible to reorder columns interactively using a customization dialog and not just by dragging them soon git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57363 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/headerctrl.h b/include/wx/headerctrl.h index 6b3ec3e059..e404f166db 100644 --- a/include/wx/headerctrl.h +++ b/include/wx/headerctrl.h @@ -30,10 +30,14 @@ class WXDLLIMPEXP_FWD_CORE wxHeaderCtrlEvent; enum { // allow column drag and drop - wxHD_DRAGDROP = 0x0001, + wxHD_ALLOW_REORDER = 0x0001, + + // allow hiding (and showing back) the columns using the menu shown by + // right clicking the header + wxHD_ALLOW_HIDE = 0x0002, // style used by default when creating the control - wxHD_DEFAULT_STYLE = wxHD_DRAGDROP + wxHD_DEFAULT_STYLE = wxHD_ALLOW_REORDER }; extern WXDLLIMPEXP_DATA_CORE(const char) wxHeaderCtrlNameStr[]; @@ -118,11 +122,22 @@ public: // ---------- // show the popup menu containing all columns with check marks for the ones - // which are currently shown -- this is meant to be called from - // EVT_HEADER_RIGHT_CLICK handler and should toggle the visibility of the - // n-th column if the function returns valid column index and not wxID_NONE - // which is returned if the user cancels the menu - int ShowColumnsMenu(const wxString& title = wxString()); + // which are currently shown and return true if something was done using it + // (in this case UpdateColumnVisibility() will have been called) or false + // if the menu was cancelled + // + // this is called from the default right click handler for the controls + // with wxHD_ALLOW_HIDE style + bool ShowColumnsMenu(const wxPoint& pt, const wxString& title = wxString()); + + // show the columns customization dialog and return true if something was + // changed using it (in which case UpdateColumnVisibility() and/or + // UpdateColumnWidth() will have been called) + // + // this is called by the control itself from ShowColumnsMenu() (which in + // turn is only called by the control if wxHD_ALLOW_HIDE style was + // specified) and if the control has wxHD_ALLOW_REORDER style as well + bool ShowCustomizeDialog(); // implementation only from now on @@ -150,6 +165,15 @@ protected: return false; } + // this method is called from ShowColumnsMenu() and must be overridden to + // update the internal column visibility (there is no need to call + // UpdateColumn() from here, this will be done internally) + virtual void UpdateColumnVisibility(unsigned int WXUNUSED(idx), + bool WXUNUSED(show)) + { + wxFAIL_MSG( "must be overridden if called" ); + } + // this method can be overridden in the derived classes to do something // (e.g. update/resize some internal data structures) before the number of // columns in the control changes @@ -177,6 +201,7 @@ private: // event handlers void OnSeparatorDClick(wxHeaderCtrlEvent& event); + void OnRClick(wxHeaderCtrlEvent& event); DECLARE_EVENT_TABLE() }; diff --git a/interface/wx/headerctrl.h b/interface/wx/headerctrl.h index f4a1306b66..5908cc0a38 100644 --- a/interface/wx/headerctrl.h +++ b/interface/wx/headerctrl.h @@ -53,12 +53,12 @@ @beginStyleTable - @style{wxHD_DRAGDROP} + @style{wxHD_ALLOW_REORDER} If this style is specified (it is by default), the user can reorder the control columns by dragging them. @style{wxHD_DEFAULT_STYLE} Symbolic name for the default control style, currently equal to - @c wxHD_DRAGDROP. + @c wxHD_ALLOW_REORDER. @endStyleTable @beginEventTable{wxHeaderCtrlEvent} @@ -97,7 +97,7 @@ 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). + can only happen for the controls with wxHD_ALLOW_REORDER 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)} @@ -161,8 +161,8 @@ public: The control style, @c wxHD_DEFAULT_STYLE by default. Notice that the default style allows the user to reorder the columns by dragging them and you need to explicitly turn this feature off by - using @code wxHD_DEFAULT_STYLE & ~wxHD_DRAGDROP @endcode if this is - undesirable. + using @code wxHD_DEFAULT_STYLE & ~wxHD_ALLOW_REORDER @endcode if + this is undesirable. @param name The name of the control. */ @@ -236,11 +236,11 @@ public: /** 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. + For the controls without wxHD_ALLOW_REORDER 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_ALLOW_REORDER style, the columns + can be also reordered by user. */ wxArrayInt GetColumnsOrder() const; diff --git a/samples/grid/griddemo.cpp b/samples/grid/griddemo.cpp index 8ea628b1c5..d21b8a0761 100644 --- a/samples/grid/griddemo.cpp +++ b/samples/grid/griddemo.cpp @@ -1746,7 +1746,8 @@ private: int col = m_txtColShowHide->GetCol(); if ( col != -1 ) { - m_grid->SetColSize(col, event.GetId() == wxID_ADD ? -1 : 0); + m_grid->SetColSize(col, + event.GetId() == wxID_ADD ? wxGRID_AUTOSIZE : 0); UpdateOrderAndVisibility(); } @@ -1787,6 +1788,16 @@ private: event.Skip(); } + void OnGridColSize(wxGridSizeEvent& event) + { + // we only catch this event to react to the user showing or hiding this + // column using the header control menu and not because we're + // interested in column resizing + UpdateOrderAndVisibility(); + + event.Skip(); + } + void OnIdle(wxIdleEvent& event) { if ( m_shouldUpdateOrder ) @@ -1798,20 +1809,6 @@ private: event.Skip(); } - void OnColRightClick(wxHeaderCtrlEvent&) - { - int col = m_grid->GetGridColHeader()->ShowColumnsMenu("Columns:"); - if ( col == wxID_NONE ) - return; - - if ( m_grid->IsColShown(col) ) - m_grid->HideCol(col); - else - m_grid->ShowCol(col); - - UpdateOrderAndVisibility(); - } - void UpdateOrderAndVisibility() { wxString s; @@ -1873,6 +1870,7 @@ BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame) EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort) EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove) + EVT_GRID_COL_SIZE(TabularGridFrame::OnGridColSize) EVT_IDLE(TabularGridFrame::OnIdle) END_EVENT_TABLE() @@ -1895,14 +1893,6 @@ TabularGridFrame::TabularGridFrame() m_grid->UseNativeColHeader(); m_grid->HideRowLabels(); - m_grid->GetGridColHeader()->Connect - ( - wxEVT_COMMAND_HEADER_RIGHT_CLICK, - wxHeaderCtrlEventHandler(TabularGridFrame::OnColRightClick), - NULL, - this - ); - // add it and the other controls to the frame wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); sizerTop->Add(m_grid, wxSizerFlags(1).Expand().Border()); diff --git a/src/common/headerctrlcmn.cpp b/src/common/headerctrlcmn.cpp index 1d8f2670d3..fe43fe19cd 100644 --- a/src/common/headerctrlcmn.cpp +++ b/src/common/headerctrlcmn.cpp @@ -48,6 +48,7 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxHeaderCtrlNameStr[] = "wxHeaderCtrl"; BEGIN_EVENT_TABLE(wxHeaderCtrlBase, wxControl) EVT_HEADER_SEPARATOR_DCLICK(wxID_ANY, wxHeaderCtrlBase::OnSeparatorDClick) + EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxHeaderCtrlBase::OnRClick) END_EVENT_TABLE() void wxHeaderCtrlBase::ScrollWindow(int dx, @@ -67,11 +68,11 @@ void wxHeaderCtrlBase::ScrollWindow(int dx, void wxHeaderCtrlBase::SetColumnCount(unsigned int count) { - if ( count == GetColumnCount() ) - return; - - OnColumnCountChanging(count); + if ( count != GetColumnCount() ) + OnColumnCountChanging(count); + // still call DoSetCount() even if the count didn't really change in order + // to update all the columns DoSetCount(count); } @@ -92,6 +93,17 @@ void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event) UpdateColumn(col); } +void wxHeaderCtrlBase::OnRClick(wxHeaderCtrlEvent& event) +{ + if ( !HasFlag(wxHD_ALLOW_HIDE) ) + { + event.Skip(); + return; + } + + ShowColumnsMenu(ScreenToClient(wxGetMousePosition())); +} + // ---------------------------------------------------------------------------- // wxHeaderCtrlBase column reordering // ---------------------------------------------------------------------------- @@ -219,10 +231,7 @@ wxHeaderCtrlBase::DoResizeColumnIndices(wxArrayInt& colIndices, unsigned int cou colIndices.swap(colIndicesNew); } - else // count didn't really change, we shouldn't even be called - { - wxFAIL_MSG( "useless call to DoResizeColumnIndices()" ); - } + //else: count didn't really change, nothing to do wxASSERT_MSG( colIndices.size() == count, "logic error" ); } @@ -231,8 +240,9 @@ wxHeaderCtrlBase::DoResizeColumnIndices(wxArrayInt& colIndices, unsigned int cou // wxHeaderCtrl extra UI // ---------------------------------------------------------------------------- -int wxHeaderCtrlBase::ShowColumnsMenu(const wxString& title) +bool wxHeaderCtrlBase::ShowColumnsMenu(const wxPoint& pt, const wxString& title) { + // construct the menu with the entries for all columns wxMenu menu; if ( !title.empty() ) menu.SetTitle(title); @@ -246,8 +256,35 @@ int wxHeaderCtrlBase::ShowColumnsMenu(const wxString& title) menu.Check(n, true); } - return GetPopupMenuSelectionFromUser(menu, - ScreenToClient(wxGetMousePosition())); + // ... and an extra one to show the customization dialog if the user is + // allowed to reorder the columns too + if ( HasFlag(wxHD_ALLOW_REORDER) ) + { + menu.AppendSeparator(); + menu.Append(count, _("&Customize...")); + } + + // do show the menu and get the user selection + const int rc = GetPopupMenuSelectionFromUser(menu, pt); + if ( rc == wxID_NONE ) + return false; + + if ( static_cast(rc) == count ) + { + return ShowCustomizeDialog(); + } + else // a column selected from the menu + { + UpdateColumnVisibility(rc, !GetColumn(rc).IsShown()); + } + + return true; +} + +bool wxHeaderCtrlBase::ShowCustomizeDialog() +{ + // TODO + return false; } // ============================================================================ diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 7257f41aa0..316bd1d2c3 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -224,7 +224,8 @@ public: wxID_ANY, wxDefaultPosition, wxDefaultSize, - owner->CanDragColMove() ? wxHD_DRAGDROP : 0) + wxHD_ALLOW_HIDE | + (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0)) { } @@ -267,6 +268,16 @@ private: return true; } + // overridden to react to the actions using the columns popup menu + virtual void UpdateColumnVisibility(unsigned int idx, bool show) + { + GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0); + + // as this is done by the user we should notify the main program about + // it + GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx); + } + // event handlers forwarding wxHeaderCtrl events to wxGrid void OnClick(wxHeaderCtrlEvent& event) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 2fb4dea8c1..7ab562e2ba 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -78,7 +78,7 @@ WXDWORD wxHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const { WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle); - if ( style & wxHD_DRAGDROP ) + if ( style & wxHD_ALLOW_REORDER ) msStyle |= HDS_DRAGDROP; // the control looks nicer with these styles and there doesn't seem to be