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
This commit is contained in:
Vadim Zeitlin
2008-12-15 22:42:37 +00:00
parent c2ee27612a
commit 613de0e89e
6 changed files with 116 additions and 53 deletions

View File

@@ -30,10 +30,14 @@ class WXDLLIMPEXP_FWD_CORE wxHeaderCtrlEvent;
enum enum
{ {
// allow column drag and drop // 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 // 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[]; 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 // show the popup menu containing all columns with check marks for the ones
// which are currently shown -- this is meant to be called from // which are currently shown and return true if something was done using it
// EVT_HEADER_RIGHT_CLICK handler and should toggle the visibility of the // (in this case UpdateColumnVisibility() will have been called) or false
// n-th column if the function returns valid column index and not wxID_NONE // if the menu was cancelled
// which is returned if the user cancels the menu //
int ShowColumnsMenu(const wxString& title = wxString()); // 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 // implementation only from now on
@@ -150,6 +165,15 @@ protected:
return false; 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 // this method can be overridden in the derived classes to do something
// (e.g. update/resize some internal data structures) before the number of // (e.g. update/resize some internal data structures) before the number of
// columns in the control changes // columns in the control changes
@@ -177,6 +201,7 @@ private:
// event handlers // event handlers
void OnSeparatorDClick(wxHeaderCtrlEvent& event); void OnSeparatorDClick(wxHeaderCtrlEvent& event);
void OnRClick(wxHeaderCtrlEvent& event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View File

@@ -53,12 +53,12 @@
@beginStyleTable @beginStyleTable
@style{wxHD_DRAGDROP} @style{wxHD_ALLOW_REORDER}
If this style is specified (it is by default), the user can reorder If this style is specified (it is by default), the user can reorder
the control columns by dragging them. the control columns by dragging them.
@style{wxHD_DEFAULT_STYLE} @style{wxHD_DEFAULT_STYLE}
Symbolic name for the default control style, currently equal to Symbolic name for the default control style, currently equal to
@c wxHD_DRAGDROP. @c wxHD_ALLOW_REORDER.
@endStyleTable @endStyleTable
@beginEventTable{wxHeaderCtrlEvent} @beginEventTable{wxHeaderCtrlEvent}
@@ -97,7 +97,7 @@
wxHeaderCtrlEvent::GetWidth(). wxHeaderCtrlEvent::GetWidth().
@event{EVT_HEADER_BEGIN_REORDER(id, func)} @event{EVT_HEADER_BEGIN_REORDER(id, func)}
The user started to drag the column with the specified index (this 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, This event can be vetoed to prevent the column from being reordered,
otherwise the end reorder message will be generated later. otherwise the end reorder message will be generated later.
@event{EVT_HEADER_END_REORDER(id, func)} @event{EVT_HEADER_END_REORDER(id, func)}
@@ -161,8 +161,8 @@ public:
The control style, @c wxHD_DEFAULT_STYLE by default. Notice that The control style, @c wxHD_DEFAULT_STYLE by default. Notice that
the default style allows the user to reorder the columns by the default style allows the user to reorder the columns by
dragging them and you need to explicitly turn this feature off by dragging them and you need to explicitly turn this feature off by
using @code wxHD_DEFAULT_STYLE & ~wxHD_DRAGDROP @endcode if this is using @code wxHD_DEFAULT_STYLE & ~wxHD_ALLOW_REORDER @endcode if
undesirable. this is undesirable.
@param name @param name
The name of the control. The name of the control.
*/ */
@@ -236,11 +236,11 @@ public:
/** /**
Return the array describing the columns display order. Return the array describing the columns display order.
For the controls without wxHD_DRAGDROP style the returned array will be For the controls without wxHD_ALLOW_REORDER style the returned array
the same as was passed to SetColumnsOrder() previously or define the will be the same as was passed to SetColumnsOrder() previously or
default order (with n-th element being n) if it hadn't been called. But define the default order (with n-th element being n) if it hadn't been
for the controls with wxHD_DRAGDROP style, the columns can be also called. But for the controls with wxHD_ALLOW_REORDER style, the columns
reordered by user. can be also reordered by user.
*/ */
wxArrayInt GetColumnsOrder() const; wxArrayInt GetColumnsOrder() const;

View File

@@ -1746,7 +1746,8 @@ private:
int col = m_txtColShowHide->GetCol(); int col = m_txtColShowHide->GetCol();
if ( col != -1 ) 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(); UpdateOrderAndVisibility();
} }
@@ -1787,6 +1788,16 @@ private:
event.Skip(); 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) void OnIdle(wxIdleEvent& event)
{ {
if ( m_shouldUpdateOrder ) if ( m_shouldUpdateOrder )
@@ -1798,20 +1809,6 @@ private:
event.Skip(); 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() void UpdateOrderAndVisibility()
{ {
wxString s; wxString s;
@@ -1873,6 +1870,7 @@ BEGIN_EVENT_TABLE(TabularGridFrame, wxFrame)
EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort) EVT_GRID_COL_SORT(TabularGridFrame::OnGridColSort)
EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove) EVT_GRID_COL_MOVE(TabularGridFrame::OnGridColMove)
EVT_GRID_COL_SIZE(TabularGridFrame::OnGridColSize)
EVT_IDLE(TabularGridFrame::OnIdle) EVT_IDLE(TabularGridFrame::OnIdle)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -1895,14 +1893,6 @@ TabularGridFrame::TabularGridFrame()
m_grid->UseNativeColHeader(); m_grid->UseNativeColHeader();
m_grid->HideRowLabels(); 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 // add it and the other controls to the frame
wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
sizerTop->Add(m_grid, wxSizerFlags(1).Expand().Border()); sizerTop->Add(m_grid, wxSizerFlags(1).Expand().Border());

View File

@@ -48,6 +48,7 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxHeaderCtrlNameStr[] = "wxHeaderCtrl";
BEGIN_EVENT_TABLE(wxHeaderCtrlBase, wxControl) BEGIN_EVENT_TABLE(wxHeaderCtrlBase, wxControl)
EVT_HEADER_SEPARATOR_DCLICK(wxID_ANY, wxHeaderCtrlBase::OnSeparatorDClick) EVT_HEADER_SEPARATOR_DCLICK(wxID_ANY, wxHeaderCtrlBase::OnSeparatorDClick)
EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxHeaderCtrlBase::OnRClick)
END_EVENT_TABLE() END_EVENT_TABLE()
void wxHeaderCtrlBase::ScrollWindow(int dx, void wxHeaderCtrlBase::ScrollWindow(int dx,
@@ -67,11 +68,11 @@ void wxHeaderCtrlBase::ScrollWindow(int dx,
void wxHeaderCtrlBase::SetColumnCount(unsigned int count) void wxHeaderCtrlBase::SetColumnCount(unsigned int count)
{ {
if ( count == GetColumnCount() ) if ( count != GetColumnCount() )
return;
OnColumnCountChanging(count); OnColumnCountChanging(count);
// still call DoSetCount() even if the count didn't really change in order
// to update all the columns
DoSetCount(count); DoSetCount(count);
} }
@@ -92,6 +93,17 @@ void wxHeaderCtrlBase::OnSeparatorDClick(wxHeaderCtrlEvent& event)
UpdateColumn(col); UpdateColumn(col);
} }
void wxHeaderCtrlBase::OnRClick(wxHeaderCtrlEvent& event)
{
if ( !HasFlag(wxHD_ALLOW_HIDE) )
{
event.Skip();
return;
}
ShowColumnsMenu(ScreenToClient(wxGetMousePosition()));
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxHeaderCtrlBase column reordering // wxHeaderCtrlBase column reordering
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -219,10 +231,7 @@ wxHeaderCtrlBase::DoResizeColumnIndices(wxArrayInt& colIndices, unsigned int cou
colIndices.swap(colIndicesNew); colIndices.swap(colIndicesNew);
} }
else // count didn't really change, we shouldn't even be called //else: count didn't really change, nothing to do
{
wxFAIL_MSG( "useless call to DoResizeColumnIndices()" );
}
wxASSERT_MSG( colIndices.size() == count, "logic error" ); wxASSERT_MSG( colIndices.size() == count, "logic error" );
} }
@@ -231,8 +240,9 @@ wxHeaderCtrlBase::DoResizeColumnIndices(wxArrayInt& colIndices, unsigned int cou
// wxHeaderCtrl extra UI // 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; wxMenu menu;
if ( !title.empty() ) if ( !title.empty() )
menu.SetTitle(title); menu.SetTitle(title);
@@ -246,8 +256,35 @@ int wxHeaderCtrlBase::ShowColumnsMenu(const wxString& title)
menu.Check(n, true); menu.Check(n, true);
} }
return GetPopupMenuSelectionFromUser(menu, // ... and an extra one to show the customization dialog if the user is
ScreenToClient(wxGetMousePosition())); // 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<unsigned>(rc) == count )
{
return ShowCustomizeDialog();
}
else // a column selected from the menu
{
UpdateColumnVisibility(rc, !GetColumn(rc).IsShown());
}
return true;
}
bool wxHeaderCtrlBase::ShowCustomizeDialog()
{
// TODO
return false;
} }
// ============================================================================ // ============================================================================

View File

@@ -224,7 +224,8 @@ public:
wxID_ANY, wxID_ANY,
wxDefaultPosition, wxDefaultPosition,
wxDefaultSize, wxDefaultSize,
owner->CanDragColMove() ? wxHD_DRAGDROP : 0) wxHD_ALLOW_HIDE |
(owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
{ {
} }
@@ -267,6 +268,16 @@ private:
return true; 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 // event handlers forwarding wxHeaderCtrl events to wxGrid
void OnClick(wxHeaderCtrlEvent& event) void OnClick(wxHeaderCtrlEvent& event)

View File

@@ -78,7 +78,7 @@ WXDWORD wxHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
{ {
WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle); WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
if ( style & wxHD_DRAGDROP ) if ( style & wxHD_ALLOW_REORDER )
msStyle |= HDS_DRAGDROP; msStyle |= HDS_DRAGDROP;
// the control looks nicer with these styles and there doesn't seem to be // the control looks nicer with these styles and there doesn't seem to be