add a possibility to disable individual grid rows/columns resizing

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60408 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2009-04-26 17:02:53 +00:00
parent fa531da023
commit 82edfbe7d9
7 changed files with 189 additions and 91 deletions

View File

@ -329,6 +329,7 @@ All:
All (GUI):
- wxGrid: add possibility to prevent resizing of individual rows/columns.
- wxHTML: add support for table borders width (Laurent Humbertclaude).
i18n:

View File

@ -143,12 +143,15 @@ to fit its contents with wxGrid::AutoSizeRow() or do it for all rows at once
with wxGrid::AutoSizeRows().
Additionally, by default the user can also drag the row separator lines to
resize the rows interactively. This can be forbidden by calling
wxGrid::DisableDragRowSize(). If you do allow the user to resize the grid rows,
it may be a good idea to save their heights and restore it when the grid is
recreated the next time (possibly during a next program execution): the
functions wxGrid::GetRowSizes() and wxGrid::SetRowSizes() can help with this,
you will just need to serialize wxGridSizesInfo structure returned by the
former in some way and deserialize it back before calling the latter.
resize the rows interactively. This can be forbidden completely by calling
wxGrid::DisableDragRowSize() or just for the individual rows using
wxGrid::DisableRowResize().
If you do allow the user to resize the grid rows, it may be a good idea to save
their heights and restore it when the grid is recreated the next time (possibly
during a next program execution): the functions wxGrid::GetRowSizes() and
wxGrid::SetRowSizes() can help with this, you will just need to serialize
wxGridSizesInfo structure returned by the former in some way and deserialize it
back before calling the latter.
*/

View File

@ -16,6 +16,8 @@
#if wxUSE_GRID
#include "wx/hashmap.h"
#include "wx/scrolwin.h"
// ----------------------------------------------------------------------------
@ -85,6 +87,8 @@ class WXDLLIMPEXP_FWD_CORE wxTextCtrl;
class WXDLLIMPEXP_FWD_CORE wxSpinCtrl;
#endif
class wxGridFixedIndicesSet;
class wxGridOperations;
class wxGridRowOperations;
class wxGridColumnOperations;
@ -771,7 +775,7 @@ private:
// their non default size for those which don't have the default size.
// ----------------------------------------------------------------------------
// Hashmap to store postions as the keys and sizes as the values
// hash map to store positions as the keys and sizes as the values
WX_DECLARE_HASH_MAP_WITH_DECL( unsigned, int, wxIntegerHash, wxIntegerEqual,
wxUnsignedToIntHashMap, class WXDLLIMPEXP_ADV );
@ -1101,19 +1105,42 @@ public:
void SetCellHighlightPenWidth(int width);
void SetCellHighlightROPenWidth(int width);
// interactive grid mouse operations control
// -----------------------------------------
// functions globally enabling row/column interactive resizing (enabled by
// default)
void EnableDragRowSize( bool enable = true );
void DisableDragRowSize() { EnableDragRowSize( false ); }
bool CanDragRowSize() const { return m_canDragRowSize; }
void EnableDragColSize( bool enable = true );
void DisableDragColSize() { EnableDragColSize( false ); }
bool CanDragColSize() const { return m_canDragColSize; }
// if interactive resizing is enabled, some rows/columns can still have
// fixed size
void DisableRowResize(int row) { DoDisableLineResize(row, m_setFixedRows); }
void DisableColResize(int col) { DoDisableLineResize(col, m_setFixedCols); }
// these functions return whether the given row/column can be
// effectively resized: for this interactive resizing must be enabled
// and this index must not have been passed to DisableRow/ColResize()
bool CanDragRowSize(int row) const
{ return m_canDragRowSize && DoCanResizeLine(row, m_setFixedRows); }
bool CanDragColSize(int col) const
{ return m_canDragColSize && DoCanResizeLine(col, m_setFixedCols); }
// interactive column reordering (disabled by default)
void EnableDragColMove( bool enable = true );
void DisableDragColMove() { EnableDragColMove( false ); }
bool CanDragColMove() const { return m_canDragColMove; }
// interactive resizing of grid cells (enabled by default)
void EnableDragGridSize(bool enable = true);
void DisableDragGridSize() { EnableDragGridSize(false); }
bool CanDragGridSize() const { return m_canDragGridSize; }
// interactive dragging of cells (disabled by default)
void EnableDragCell( bool enable = true );
void DisableDragCell() { EnableDragCell( false ); }
bool CanDragCell() const { return m_canDragCell; }
@ -1659,6 +1686,9 @@ public:
wxGRID_CHECKBOX,
wxGRID_CHOICE,
wxGRID_COMBOBOX };
wxDEPRECATED_INLINE(bool CanDragRowSize() const, return m_canDragRowSize; )
wxDEPRECATED_INLINE(bool CanDragColSize() const, return m_canDragColSize; )
#endif // WXWIN_COMPATIBILITY_2_8
@ -2083,10 +2113,22 @@ private:
bool DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
int num, bool updateLabels);
// Common part of Set{Col,Row}Sizes
// common part of Set{Col,Row}Sizes
void DoSetSizes(const wxGridSizesInfo& sizeInfo,
const wxGridOperations& oper);
// common part of Disable{Row,Col}Resize and CanDrag{Row,Col}Size
void DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed);
bool DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const;
// these sets contain the indices of fixed, i.e. non-resizable
// interactively, grid rows or columns and are NULL if there are no fixed
// elements (which is the default)
wxGridFixedIndicesSet *m_setFixedRows,
*m_setFixedCols;
DECLARE_DYNAMIC_CLASS( wxGrid )
DECLARE_EVENT_TABLE()
wxDECLARE_NO_COPY_CLASS(wxGrid);

View File

@ -107,7 +107,7 @@ public:
// we can't know in advance whether we can sort by this column or not
// with wxGrid API so suppose we can by default
int flags = wxCOL_SORTABLE;
if ( m_grid->CanDragColSize() )
if ( m_grid->CanDragColSize(m_col) )
flags |= wxCOL_RESIZABLE;
if ( m_grid->CanDragColMove() )
flags |= wxCOL_REORDERABLE;
@ -500,9 +500,6 @@ public:
// Set the row default height or column default width
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const = 0;
// True if rows/columns can be resized by user
virtual bool CanResizeLines(const wxGrid *grid) const = 0;
// Return the index of the line at the given position
//
@ -572,10 +569,8 @@ public:
{ return grid->GetRowMinimalHeight(line); }
virtual void SetLineSize(wxGrid *grid, int line, int size) const
{ grid->SetRowSize(line, size); }
virtual bool CanResizeLines(const wxGrid *grid) const
{ return grid->CanDragRowSize(); }
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
{ grid->SetDefaultRowSize(size, resizeExisting); }
{ grid->SetDefaultRowSize(size, resizeExisting); }
virtual int GetLineAt(const wxGrid * WXUNUSED(grid), int line) const
{ return line; } // TODO: implement row reordering
@ -635,10 +630,8 @@ public:
{ return grid->GetColMinimalWidth(line); }
virtual void SetLineSize(wxGrid *grid, int line, int size) const
{ grid->SetColSize(line, size); }
virtual bool CanResizeLines(const wxGrid *grid) const
{ return grid->CanDragColSize(); }
virtual void SetDefaultLineSize(wxGrid *grid, int size, bool resizeExisting) const
{ grid->SetDefaultColSize(size, resizeExisting); }
{ grid->SetDefaultColSize(size, resizeExisting); }
virtual int GetLineAt(const wxGrid *grid, int line) const
{ return grid->GetColAt(line); }

View File

@ -2037,6 +2037,8 @@ public:
/**
@name Column and Row Sizes
@see overview_grid_resizing
*/
//@{
@ -2322,6 +2324,17 @@ public:
/**
@name User-Resizing and Dragging
Functions controlling various interactive mouse operations.
By default, columns and rows can be resized by dragging the edges of
their labels (this can be disabled using DisableDragColSize() and
DisableDragRowSize() methods). And if grid line dragging is enabled with
EnableDragGridSize() they can also be resized by dragging the right or
bottom edge of the grid cells.
Columns can also be moved to interactively change their order but this
needs to be explicitly enabled with EnableDragColMove().
*/
//@{
@ -2338,13 +2351,15 @@ public:
bool CanDragColMove() const;
/**
Returns @true if columns can be resized by dragging with the mouse.
Returns @true if the given column can be resized by dragging with the
mouse.
Columns can be resized by dragging the edges of their labels. If grid
line dragging is enabled they can also be resized by dragging the right
edge of the column in the grid cell area (see EnableDragGridSize()).
This function returns @true if resizing the columns interactively is
globally enabled, i.e. if DisableDragColSize() hadn't been called, and
if this column wasn't explicitly marked as non-resizable with
DisableColResize().
*/
bool CanDragColSize() const;
bool CanDragColSize(int col) const;
/**
Return @true if the dragging of grid lines to resize rows and columns
@ -2353,13 +2368,42 @@ public:
bool CanDragGridSize() const;
/**
Returns @true if rows can be resized by dragging with the mouse.
Returns @true if the given row can be resized by dragging with the
mouse.
Rows can be resized by dragging the edges of their labels. If grid line
dragging is enabled they can also be resized by dragging the lower edge
of the row in the grid cell area (see EnableDragGridSize()).
This is the same as CanDragColSize() but for rows.
*/
bool CanDragRowSize() const;
bool CanDragRowSize(int row) const;
/**
Disable interactive resizing of the specified column.
This method allows to disable resizing of an individual column in a
grid where the columns are otherwise resizable (which is the case by
default).
Notice that currently there is no way to make some columns resizable in
a grid where columns can't be resized by default as there doesn't seem
to be any need for this in practice. There is also no way to make the
column marked as fixed using this method resizeable again because it is
supposed that fixed columns are used for static parts of the grid and
so should remain fixed during the entire grid lifetime.
Also notice that disabling interactive column resizing will not prevent
the program from changing the column size.
@see EnableDragColSize()
*/
void DisableColResize(int col);
/**
Disable interactive resizing of the specified row.
This is the same as DisableColResize() but for rows.
@see EnableDragRowSize()
*/
void DisableRowResize(int row);
/**
Disables column moving by dragging with the mouse.
@ -2401,6 +2445,8 @@ public:
/**
Enables or disables column sizing by dragging with the mouse.
@see DisableColResize()
*/
void EnableDragColSize(bool enable = true);
@ -2412,6 +2458,8 @@ public:
/**
Enables or disables row sizing by dragging with the mouse.
@see DisableRowResize()
*/
void EnableDragRowSize(bool enable = true);

View File

@ -377,6 +377,14 @@ GridFrame::GridFrame()
grid->SetCellAlignment(7, 1, wxALIGN_CENTRE, wxALIGN_CENTRE);
grid->SetCellValue(7, 1, _T("Big box!"));
// create a separator-like row: it's grey and it's non-resizeable
grid->DisableRowResize(10);
grid->SetRowSize(10, 30);
attr = new wxGridCellAttr;
attr->SetBackgroundColour(*wxLIGHT_GREY);
grid->SetRowAttr(10, attr);
grid->SetCellValue(10, 0, "You can't resize this row interactively -- try it");
// this does exactly nothing except testing that SetAttr() handles NULL
// attributes and does reference counting correctly
grid->SetAttr(11, 11, NULL);

View File

@ -48,6 +48,7 @@
#include "wx/tokenzr.h"
#include "wx/renderer.h"
#include "wx/headerctrl.h"
#include "wx/hashset.h"
#include "wx/generic/gridsel.h"
#include "wx/generic/gridctrl.h"
@ -71,6 +72,9 @@ const char wxGridNameStr[] = "grid";
// Required for wxIs... functions
#include <ctype.h>
WX_DECLARE_HASH_SET_WITH_DECL(int, wxIntegerHash, wxIntegerEqual,
wxGridFixedIndicesSet, class WXDLLIMPEXP_ADV);
// ----------------------------------------------------------------------------
// globals
@ -1822,6 +1826,9 @@ wxGrid::~wxGrid()
delete m_typeRegistry;
delete m_selection;
delete m_setFixedRows;
delete m_setFixedCols;
}
//
@ -2047,6 +2054,9 @@ void wxGrid::Init()
m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH;
m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT;
m_setFixedRows =
m_setFixedCols = NULL;
// init attr cache
m_attrCache.row = -1;
m_attrCache.col = -1;
@ -2916,11 +2926,12 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
//
else if ( event.LeftDown() )
{
// don't send a label click event for a hit on the
// edge of the row label - this is probably the user
// wanting to resize the row
//
if ( YToEdgeOfRow(y) < 0 )
row = YToEdgeOfRow(y);
if ( row != wxNOT_FOUND && CanDragRowSize(row) )
{
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin);
}
else // not a request to start resizing
{
row = YToRow(y);
if ( row >= 0 &&
@ -2948,12 +2959,6 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin);
}
}
else
{
// starting to drag-resize a row
if ( CanDragRowSize() )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin);
}
}
// ------------ Left double click
@ -2961,7 +2966,15 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
else if (event.LeftDClick() )
{
row = YToEdgeOfRow(y);
if ( row < 0 )
if ( row != wxNOT_FOUND && CanDragRowSize(row) )
{
// adjust row height depending on label text
AutoSizeRowLabelSize( row );
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
m_dragLastPos = -1;
}
else // not on row separator or it's not resizeable
{
row = YToRow(y);
if ( row >=0 &&
@ -2970,14 +2983,6 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
// no default action at the moment
}
}
else
{
// adjust row height depending on label text
AutoSizeRowLabelSize( row );
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow());
m_dragLastPos = -1;
}
}
// ------------ Left button released
@ -3027,12 +3032,11 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
else if ( event.Moving() )
{
m_dragRowOrCol = YToEdgeOfRow( y );
if ( m_dragRowOrCol >= 0 )
if ( m_dragRowOrCol != wxNOT_FOUND )
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
// don't capture the mouse yet
if ( CanDragRowSize() )
if ( CanDragRowSize(m_dragRowOrCol) )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin, false);
}
}
@ -3248,12 +3252,14 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
//
else if ( event.LeftDown() )
{
// don't send a label click event for a hit on the
// edge of the col label - this is probably the user
// wanting to resize the col
//
if ( XToEdgeOfCol(x) < 0 )
int col = XToEdgeOfCol(x);
if ( col != wxNOT_FOUND && CanDragColSize(col) )
{
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow());
}
else // not a request to start resizing
{
col = XToCol(x);
if ( col >= 0 &&
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
{
@ -3294,13 +3300,6 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
}
}
}
else
{
// starting to drag-resize a col
//
if ( CanDragColSize() )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow());
}
}
// ------------ Left double click
@ -3394,8 +3393,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
{
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
// don't capture the cursor yet
if ( CanDragColSize() )
if ( CanDragColSize(m_dragRowOrCol) )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow(), false);
}
}
@ -3796,27 +3794,24 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
return;
}
if ( dragRow >= 0 )
if ( dragRow >= 0 && CanDragGridSize() && CanDragRowSize(dragRow) )
{
m_dragRowOrCol = dragRow;
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if ( CanDragRowSize() && CanDragGridSize() )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, NULL, false);
m_dragRowOrCol = dragRow;
ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, NULL, false);
}
}
// When using the native header window we can only resize the columns by
// dragging the dividers in it because we can't make it enter into the
// column resizing mode programmatically
else if ( dragCol >= 0 && !m_useNativeHeader )
else if ( dragCol >= 0 && !m_useNativeHeader &&
CanDragGridSize() && CanDragColSize(dragCol) )
{
m_dragRowOrCol = dragCol;
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if ( CanDragColSize() && CanDragGridSize() )
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, NULL, false);
m_dragRowOrCol = dragCol;
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, NULL, false);
}
}
else // Neither on a row or col edge
@ -6124,23 +6119,15 @@ int wxGrid::XToPos(int x) const
return PosToLinePos(x, true /* clip */, wxGridColumnOperations());
}
// return the row number that that the y coord is near the edge of, or -1 if
// return the row number such that the y coord is near the edge of, or -1 if
// not near an edge.
//
// coords can only possibly be near an edge if
// (a) the row/column is large enough to still allow for an "inner" area
// that is _not_ near the edge (i.e., if the height/width is smaller
// than WXGRID_LABEL_EDGE_ZONE, coords are _never_ considered to be
// near the edge).
// and
// (b) resizing rows/columns (the thing for which edge detection is
// relevant at all) is enabled.
//
// notice that position can only possibly be near an edge if the row/column is
// large enough to still allow for an "inner" area that is _not_ near the edge
// (i.e., if the height/width is smaller than WXGRID_LABEL_EDGE_ZONE, pos will
// _never_ be considered to be near the edge).
int wxGrid::PosToEdgeOfLine(int pos, const wxGridOperations& oper) const
{
if ( !oper.CanResizeLines(this) )
return -1;
const int line = oper.PosToLine(this, pos, true);
if ( oper.GetLineSize(this, line) > WXGRID_LABEL_EDGE_ZONE )
@ -7481,6 +7468,22 @@ wxGridCellRenderer * wxGrid::GetDefaultRendererForType(const wxString& typeName)
// row/col size
// ----------------------------------------------------------------------------
void wxGrid::DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed)
{
if ( !setFixed )
{
setFixed = new wxGridFixedIndicesSet;
}
setFixed->insert(line);
}
bool
wxGrid::DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const
{
return !setFixed || !setFixed->count(line);
}
void wxGrid::EnableDragRowSize( bool enable )
{
m_canDragRowSize = enable;