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[];
// ----------
// 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
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
// event handlers
void OnSeparatorDClick(wxHeaderCtrlEvent& event);
+ void OnRClick(wxHeaderCtrlEvent& event);
DECLARE_EVENT_TABLE()
};
@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}
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)}
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.
*/
/**
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;
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();
}
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 )
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;
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()
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());
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,
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);
}
UpdateColumn(col);
}
+void wxHeaderCtrlBase::OnRClick(wxHeaderCtrlEvent& event)
+{
+ if ( !HasFlag(wxHD_ALLOW_HIDE) )
+ {
+ event.Skip();
+ return;
+ }
+
+ ShowColumnsMenu(ScreenToClient(wxGetMousePosition()));
+}
+
// ----------------------------------------------------------------------------
// wxHeaderCtrlBase column reordering
// ----------------------------------------------------------------------------
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" );
}
// 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);
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<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;
}
// ============================================================================
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
- owner->CanDragColMove() ? wxHD_DRAGDROP : 0)
+ wxHD_ALLOW_HIDE |
+ (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
{
}
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)
{
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