Add wxGridFitMode and functions working with it

Replace "bool overflow" flag with a class allowing to specify the same
overflow/clipping behaviour currently, but also allowing to extend it,
notable to add ellipsization support, in the future.

Preserve the existing API by reimplementing it in terms of the new one.

Also update the same to demonstrate a cell which always overflows,
independently of the default cell behaviour.
This commit is contained in:
Vadim Zeitlin
2020-01-11 18:02:12 +01:00
parent 325408f062
commit f13085441c
4 changed files with 259 additions and 28 deletions

View File

@@ -408,6 +408,42 @@ public:
wxRect& rect) const wxOVERRIDE;
};
// ----------------------------------------------------------------------------
// Helper class used to define What should happen if the cell contents doesn't
// fit into its allotted space.
// ----------------------------------------------------------------------------
class wxGridFitMode
{
public:
// Default ctor creates an object not specifying any particular behaviour.
wxGridFitMode() : m_mode(Mode_Unset) {}
// Static methods allowing to create objects actually specifying behaviour.
static wxGridFitMode Clip() { return wxGridFitMode(Mode_Clip); }
static wxGridFitMode Overflow() { return wxGridFitMode(Mode_Overflow); }
// Accessors.
bool IsSpecified() const { return m_mode != Mode_Unset; }
bool IsClip() const { return m_mode == Mode_Clip; }
bool IsOverflow() const { return m_mode == Mode_Overflow; }
// This one is used in the implementation only.
static wxGridFitMode FromOverflowFlag(bool allow)
{ return allow ? Overflow() : Clip(); }
private:
enum Mode
{
Mode_Unset = -1,
Mode_Overflow,
Mode_Clip
};
explicit wxGridFitMode(Mode mode) : m_mode(mode) {}
Mode m_mode;
};
// ----------------------------------------------------------------------------
// wxGridCellAttr: this class can be used to alter the cells appearance in
@@ -462,8 +498,9 @@ public:
m_vAlign = vAlign;
}
void SetSize(int num_rows, int num_cols);
void SetFitMode(wxGridFitMode fitMode) { m_fitMode = fitMode; }
void SetOverflow(bool allow = true)
{ m_overflow = allow ? Overflow : SingleCell; }
{ SetFitMode(wxGridFitMode::FromOverflowFlag(allow)); }
void SetReadOnly(bool isReadOnly = true)
{ m_isReadOnly = isReadOnly ? ReadOnly : ReadWrite; }
@@ -486,7 +523,7 @@ public:
bool HasRenderer() const { return m_renderer != NULL; }
bool HasEditor() const { return m_editor != NULL; }
bool HasReadWriteMode() const { return m_isReadOnly != Unset; }
bool HasOverflowMode() const { return m_overflow != UnsetOverflow; }
bool HasOverflowMode() const { return m_fitMode.IsSpecified(); }
bool HasSize() const { return m_sizeRows != 1 || m_sizeCols != 1; }
const wxColour& GetTextColour() const;
@@ -503,8 +540,8 @@ public:
void GetNonDefaultAlignment(int *hAlign, int *vAlign) const;
void GetSize(int *num_rows, int *num_cols) const;
bool GetOverflow() const
{ return m_overflow != SingleCell; }
wxGridFitMode GetFitMode() const;
bool GetOverflow() const { return GetFitMode().IsOverflow(); }
wxGridCellRenderer *GetRenderer(const wxGrid* grid, int row, int col) const;
wxGridCellEditor *GetEditor(const wxGrid* grid, int row, int col) const;
@@ -530,13 +567,6 @@ private:
ReadOnly
};
enum wxAttrOverflowMode
{
UnsetOverflow = -1,
Overflow,
SingleCell
};
// the common part of all ctors
void Init(wxGridCellAttr *attrDefault = NULL);
@@ -549,7 +579,7 @@ private:
int m_sizeRows,
m_sizeCols;
wxAttrOverflowMode m_overflow;
wxGridFitMode m_fitMode;
wxGridCellRenderer* m_renderer;
wxGridCellEditor* m_editor;
@@ -1436,8 +1466,14 @@ public:
wxFont GetCellFont( int row, int col ) const;
void GetDefaultCellAlignment( int *horiz, int *vert ) const;
void GetCellAlignment( int row, int col, int *horiz, int *vert ) const;
bool GetDefaultCellOverflow() const;
bool GetCellOverflow( int row, int col ) const;
wxGridFitMode GetDefaultCellFitMode() const;
wxGridFitMode GetCellFitMode(int row, int col) const;
bool GetDefaultCellOverflow() const
{ return GetDefaultCellFitMode().IsOverflow(); }
bool GetCellOverflow( int row, int col ) const
{ return GetCellFitMode(row, col).IsOverflow(); }
// this function returns 1 in num_rows and num_cols for normal cells,
// positive numbers for a cell spanning multiple columns/rows (as set with
@@ -1589,8 +1625,14 @@ public:
void SetCellFont( int row, int col, const wxFont& );
void SetDefaultCellAlignment( int horiz, int vert );
void SetCellAlignment( int row, int col, int horiz, int vert );
void SetDefaultCellOverflow( bool allow );
void SetCellOverflow( int row, int col, bool allow );
void SetDefaultCellFitMode(wxGridFitMode fitMode);
void SetCellFitMode(int row, int col, wxGridFitMode fitMode);
void SetDefaultCellOverflow( bool allow )
{ SetDefaultCellFitMode(wxGridFitMode::FromOverflowFlag(allow)); }
void SetCellOverflow( int row, int col, bool allow )
{ SetCellFitMode(row, col, wxGridFitMode::FromOverflowFlag(allow)); }
void SetCellSize( int row, int col, int num_rows, int num_cols );
// takes ownership of the pointer

View File

@@ -873,6 +873,81 @@ public:
/**
@class wxGridFitMode
Allows to specify the behaviour when the cell contents doesn't fit into its
allotted space.
Objects of this class are used with wxGridCellAttr::SetFitMode() and
wxGrid::SetDefaultCellFitMode() and wxGrid::SetCellFitMode() functions and
allow to specify what should happen if the cell contents doesn't fit into
the available space. The possibilities are:
- Overflow into the cell to the right if it is empty, or possibly several
cells, if the cell contents still doesn't fit after overflowing into the
immediately neighbouring cell.
- Clip the cell contents, discarding the part which doesn't fit.
The default behaviour is to overflow, use wxGrid::SetDefaultCellFitMode()
to change this, for example:
@code
grid->SetDefaultCellFitMode(wxGridFitMode::Clip());
@endcode
Objects of this class are created using static functions instead of
constructors for better readability and can't be changed after creating
them except by using the assignment operator.
@library{wxcore}
@category{grid}
@since 3.1.4
*/
class wxGridFitMode
{
public:
/**
Default constructor creates an object not specifying any behaviour.
This constructor is not very useful, use static methods Clip() and
Overflow() below to create objects of this class instead.
*/
wxGridFitMode();
/**
Pseudo-constructor for object specifying clipping behaviour.
*/
static wxGridFitMode Clip();
/**
Pseudo-constructor for object specifying overflow behaviour.
*/
static wxGridFitMode Overflow();
/**
Return true if the object specifies some particular behaviour.
This method returns @false for default-constructed objects of this
type only.
*/
bool IsSpecified() const;
/**
Return true if the object specifies clipping behaviour.
This method returns @true only for the objects returned by Clip().
*/
bool IsClip() const;
/**
Return true if the object specifies overflow behaviour.
This method returns @true only for the objects returned by Overflow().
*/
bool IsOverflow() const;
};
/**
@class wxGridCellAttr
@@ -1088,7 +1163,29 @@ public:
void MergeWith(wxGridCellAttr *mergefrom);
void SetSize(int num_rows, int num_cols);
/**
Specifies the behaviour of the cell contents if it doesn't fit into the
available space.
@see wxGridFitMode
@since 3.1.4
*/
void SetFitMode(wxGridFitMode fitMode);
/**
Specifies if cells using this attribute should overflow or clip their
contents.
This is the same as calling SetFitMode() with either
wxGridFitMode::Overflow() or wxGridFitMode::Clip() argument depending
on whether @a allow is @true or @false.
Prefer using SetFitMode() directly instead in the new code.
*/
void SetOverflow(bool allow = true);
void SetKind(wxAttrKind kind);
bool HasReadWriteMode() const;
@@ -1096,7 +1193,26 @@ public:
bool HasSize() const;
void GetSize(int *num_rows, int *num_cols) const;
/**
Returns the fitting mode for the cells using this attribute.
The returned wxGridFitMode is always specified, i.e.
wxGridFitMode::IsSpecified() always returns @true. The default value,
if SetFitMode() hadn't been called before, is "overflow".
@since 3.1.4
*/
wxGridFitMode GetFitMode() const;
/**
Returns true if the cells using this attribute overflow into the
neighbouring cells.
Prefer using GetFitMode() in the new code.
*/
bool GetOverflow() const;
wxAttrKind GetKind();
@@ -3318,10 +3434,22 @@ public:
*/
void AutoSizeRows(bool setAsMin = true);
/**
Returns the cell fitting mode.
@see wxGridFitMode
@since 3.1.4
*/
wxGridFitMode GetCellFitMode(int row, int col) const;
/**
Returns @true if the cell value can overflow.
A cell can overflow if the next cell in the row is empty.
This is identical to calling GetCellFitMode() and using
wxGridFitMode::IsOverflow() on the returned value.
Prefer using GetCellFitMode() directly in the new code.
*/
bool GetCellOverflow(int row, int col) const;
@@ -3350,8 +3478,25 @@ public:
*/
bool IsColShown(int col) const;
/**
Returns the default cell fitting mode.
The default mode is "overflow", but can be modified using
SetDefaultCellFitMode().
@see wxGridFitMode
@since 3.1.4
*/
wxGridFitMode GetDefaultCellFitMode() const;
/**
Returns @true if the cells can overflow by default.
This is identical to calling GetDefaultCellFitMode() and using
wxGridFitMode::IsOverflow() on the returned value.
Prefer using GetDefaultCellFitMode() directly in the new code.
*/
bool GetDefaultCellOverflow() const;
@@ -3400,8 +3545,20 @@ public:
*/
bool IsRowShown(int row) const;
/**
Specifies the behaviour of the cell contents if it doesn't fit into the
available space.
@see wxGridFitMode
@since 3.1.4
*/
void SetCellFitMode(int row, int col, wxGridFitMode fitMode);
/**
Sets the overflow permission of the cell.
Prefer using SetCellFitMode() in the new code.
*/
void SetCellOverflow(int row, int col, bool allow);
@@ -3470,8 +3627,20 @@ public:
void ShowCol(int col);
/**
Specifies the default behaviour of the cell contents if it doesn't fit
into the available space.
@see wxGridFitMode
@since 3.1.4
*/
void SetDefaultCellFitMode(wxGridFitMode fitMode);
/**
Sets the default overflow permission of the cells.
Prefer using SetDefaultCellFitMode() in the new code.
*/
void SetDefaultCellOverflow( bool allow );

View File

@@ -501,6 +501,9 @@ GridFrame::GridFrame()
grid->SetCellValue( 99, 99, "Ctrl+End\nwill go to\nthis cell" );
grid->SetCellValue( 1, 0, "This default cell will overflow into neighboring cells, but not if you turn overflow off.");
grid->SetCellValue(2, 0, "This one always overflows");
grid->SetCellFitMode(2, 0, wxGridFitMode::Overflow());
grid->SetCellTextColour(1, 2, *wxRED);
grid->SetCellBackgroundColour(1, 2, *wxGREEN);

View File

@@ -409,7 +409,6 @@ void wxGridCellAttr::Init(wxGridCellAttr *attrDefault)
m_attrkind = wxGridCellAttr::Cell;
m_sizeRows = m_sizeCols = 1;
m_overflow = UnsetOverflow;
SetDefAttr(attrDefault);
}
@@ -443,7 +442,7 @@ wxGridCellAttr *wxGridCellAttr::Clone() const
if ( IsReadOnly() )
attr->SetReadOnly();
attr->SetOverflow( m_overflow == Overflow );
attr->m_fitMode = m_fitMode;
attr->SetKind( m_attrkind );
return attr;
@@ -626,6 +625,23 @@ void wxGridCellAttr::GetSize( int *num_rows, int *num_cols ) const
*num_cols = m_sizeCols;
}
wxGridFitMode wxGridCellAttr::GetFitMode() const
{
if ( m_fitMode.IsSpecified() )
{
return m_fitMode;
}
else if (m_defGridAttr && m_defGridAttr != this)
{
return m_defGridAttr->GetFitMode();
}
else
{
wxFAIL_MSG(wxT("Missing default cell attribute"));
return wxGridFitMode();
}
}
// GetRenderer and GetEditor use a slightly different decision path about
// which attribute to use. If a non-default attr object has one then it is
// used, otherwise the default editor or renderer is fetched from the grid and
@@ -2383,6 +2399,7 @@ void wxGrid::Create()
m_defaultCellAttr->SetAlignment(wxALIGN_LEFT, wxALIGN_TOP);
m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer);
m_defaultCellAttr->SetEditor(new wxGridCellTextEditor);
m_defaultCellAttr->SetFitMode(wxGridFitMode::Overflow());
#if _USE_VISATTR
wxVisualAttributes gva = wxListBox::GetClassDefaultAttributes();
@@ -8441,9 +8458,9 @@ void wxGrid::SetDefaultCellAlignment( int horiz, int vert )
m_defaultCellAttr->SetAlignment(horiz, vert);
}
void wxGrid::SetDefaultCellOverflow( bool allow )
void wxGrid::SetDefaultCellFitMode(wxGridFitMode fitMode)
{
m_defaultCellAttr->SetOverflow(allow);
m_defaultCellAttr->SetFitMode(fitMode);
}
void wxGrid::SetDefaultCellFont( const wxFont& font )
@@ -8494,9 +8511,9 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert ) const
m_defaultCellAttr->GetAlignment(horiz, vert);
}
bool wxGrid::GetDefaultCellOverflow() const
wxGridFitMode wxGrid::GetDefaultCellFitMode() const
{
return m_defaultCellAttr->GetOverflow();
return m_defaultCellAttr->GetFitMode();
}
wxGridCellRenderer *wxGrid::GetDefaultRenderer() const
@@ -8547,13 +8564,13 @@ void wxGrid::GetCellAlignment( int row, int col, int *horiz, int *vert ) const
attr->DecRef();
}
bool wxGrid::GetCellOverflow( int row, int col ) const
wxGridFitMode wxGrid::GetCellFitMode( int row, int col ) const
{
wxGridCellAttr *attr = GetCellAttr(row, col);
bool allow = attr->GetOverflow();
wxGridFitMode fitMode = attr->GetFitMode();
attr->DecRef();
return allow;
return fitMode;
}
wxGrid::CellSpan
@@ -8854,12 +8871,12 @@ void wxGrid::SetCellAlignment( int row, int col, int horiz, int vert )
}
}
void wxGrid::SetCellOverflow( int row, int col, bool allow )
void wxGrid::SetCellFitMode( int row, int col, wxGridFitMode fitMode )
{
if ( CanHaveAttributes() )
{
wxGridCellAttr *attr = GetOrCreateCellAttr(row, col);
attr->SetOverflow(allow);
attr->SetFitMode(fitMode);
attr->DecRef();
}
}