Implement wxGridBlockCoords class
wxGridBlockCoords represents a location of a block of cells in the grid.
This commit is contained in:
committed by
Vadim Zeitlin
parent
673ed29d7b
commit
acd72efbf1
@@ -747,9 +747,132 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxGridBlockCoords: location of a block of cells in the grid
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct wxGridBlockDiffResult;
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_CORE wxGridBlockCoords
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxGridBlockCoords() :
|
||||||
|
m_topRow(-1),
|
||||||
|
m_leftCol(-1),
|
||||||
|
m_bottomRow(-1),
|
||||||
|
m_rightCol(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGridBlockCoords(int topRow, int leftCol, int bottomRow, int rightCol) :
|
||||||
|
m_topRow(topRow),
|
||||||
|
m_leftCol(leftCol),
|
||||||
|
m_bottomRow(bottomRow),
|
||||||
|
m_rightCol(rightCol)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// default copy ctor is ok
|
||||||
|
|
||||||
|
int GetTopRow() const { return m_topRow; }
|
||||||
|
void SetTopRow(int row) { m_topRow = row; }
|
||||||
|
int GetLeftCol() const { return m_leftCol; }
|
||||||
|
void SetLeftCol(int col) { m_leftCol = col; }
|
||||||
|
int GetBottomRow() const { return m_bottomRow; }
|
||||||
|
void SetBottomRow(int row) { m_bottomRow = row; }
|
||||||
|
int GetRightCol() const { return m_rightCol; }
|
||||||
|
void SetRightCol(int col) { m_rightCol = col; }
|
||||||
|
|
||||||
|
wxGridCellCoords GetTopLeft() const
|
||||||
|
{
|
||||||
|
return wxGridCellCoords(m_topRow, m_leftCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGridCellCoords GetBottomRight() const
|
||||||
|
{
|
||||||
|
return wxGridCellCoords(m_bottomRow, m_rightCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGridBlockCoords Canonicalize() const
|
||||||
|
{
|
||||||
|
wxGridBlockCoords result = *this;
|
||||||
|
|
||||||
|
if ( result.m_topRow > result.m_bottomRow )
|
||||||
|
wxSwap(result.m_topRow, result.m_bottomRow);
|
||||||
|
|
||||||
|
if ( result.m_leftCol > result.m_rightCol )
|
||||||
|
wxSwap(result.m_leftCol, result.m_rightCol);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Intersects(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
return m_topRow <= other.m_bottomRow && m_bottomRow >= other.m_topRow &&
|
||||||
|
m_leftCol <= other.m_rightCol && m_rightCol >= other.m_leftCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether the block contains the cell.
|
||||||
|
// returns @true, if the block contains the cell,
|
||||||
|
// @false, otherwise
|
||||||
|
bool ContainCell(const wxGridCellCoords& cell) const;
|
||||||
|
|
||||||
|
// Whether the blocks contain each other.
|
||||||
|
// returns 1, if this block contains the other,
|
||||||
|
// -1, if the other block contains this one,
|
||||||
|
// 0, otherwise
|
||||||
|
int ContainBlock(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
// Calculates the result blocks by subtracting the other block from this
|
||||||
|
// block. splitOrientation can be wxVERTICAL or wxHORIZONTAL.
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
Difference(const wxGridBlockCoords& other, int splitOrientation) const;
|
||||||
|
|
||||||
|
// Calculates the symmetric difference of the blocks.
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
SymDifference(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
bool operator==(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
return m_topRow == other.m_topRow && m_leftCol == other.m_leftCol &&
|
||||||
|
m_bottomRow == other.m_bottomRow && m_rightCol == other.m_rightCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!() const
|
||||||
|
{
|
||||||
|
return m_topRow == -1 && m_leftCol == -1 &&
|
||||||
|
m_bottomRow == -1 && m_rightCol == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_topRow;
|
||||||
|
int m_leftCol;
|
||||||
|
int m_bottomRow;
|
||||||
|
int m_rightCol;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxGridBlockDiffResult: The helper struct uses as a result type for difference
|
||||||
|
// functions of wxGridBlockCoords class.
|
||||||
|
// Parts can be uninitialized (equals to wxGridNoBlockCoords), that means
|
||||||
|
// that the corresponding part doesn't exists in the result.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct wxGridBlockDiffResult
|
||||||
|
{
|
||||||
|
wxGridBlockCoords m_parts[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// For comparisons...
|
// For comparisons...
|
||||||
//
|
//
|
||||||
extern WXDLLIMPEXP_CORE wxGridCellCoords wxGridNoCellCoords;
|
extern WXDLLIMPEXP_CORE wxGridCellCoords wxGridNoCellCoords;
|
||||||
|
extern WXDLLIMPEXP_CORE wxGridBlockCoords wxGridNoBlockCoords;
|
||||||
extern WXDLLIMPEXP_CORE wxRect wxGridNoCellRect;
|
extern WXDLLIMPEXP_CORE wxRect wxGridNoCellRect;
|
||||||
|
|
||||||
// An array of cell coords...
|
// An array of cell coords...
|
||||||
|
@@ -1816,6 +1816,195 @@ public:
|
|||||||
bool operator!() const;
|
bool operator!() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Represents coordinates of a block of cells in the grid.
|
||||||
|
|
||||||
|
An object of this class contains coordinates of the left top and the bottom right
|
||||||
|
corners of a block.
|
||||||
|
|
||||||
|
@since 3.1.4
|
||||||
|
*/
|
||||||
|
class wxGridBlockCoords
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Default constructor initializes the object to invalid state.
|
||||||
|
|
||||||
|
Initially the coordinates are invalid (-1) and so operator!() for an
|
||||||
|
uninitialized wxGridBlockCoords returns @true.
|
||||||
|
*/
|
||||||
|
wxGridBlockCoords();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructor taking a coordinates of the left top and the bottom right
|
||||||
|
corners.
|
||||||
|
*/
|
||||||
|
wxGridBlockCoords(int topRow, int leftCol, int bottomRow, int rightCol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the row of the left top corner.
|
||||||
|
*/
|
||||||
|
int GetTopRow() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the row of the left top corner.
|
||||||
|
*/
|
||||||
|
void SetTopRow(int row);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the column of the left top corner.
|
||||||
|
*/
|
||||||
|
int GetLeftCol() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the column of the left top corner.
|
||||||
|
*/
|
||||||
|
void SetLeftCol(int col);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the row of the bottom right corner.
|
||||||
|
*/
|
||||||
|
int GetBottomRow() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the row of the bottom right corner.
|
||||||
|
*/
|
||||||
|
void SetBottomRow(int row);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the column of the bottom right corner.
|
||||||
|
*/
|
||||||
|
int GetRightCol() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the column of the bottom right corner.
|
||||||
|
*/
|
||||||
|
void SetRightCol(int col);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the coordinates of the top left corner.
|
||||||
|
*/
|
||||||
|
wxGridCellCoords GetTopLeft() const
|
||||||
|
{
|
||||||
|
return wxGridCellCoords(m_topRow, m_leftCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the coordinates of the bottom right corner.
|
||||||
|
*/
|
||||||
|
wxGridCellCoords GetBottomRight() const
|
||||||
|
{
|
||||||
|
return wxGridCellCoords(m_bottomRow, m_rightCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return the canonicalized block where top left coordinates is less
|
||||||
|
then bottom right coordinates.
|
||||||
|
*/
|
||||||
|
wxGridBlockCoords Canonicalize() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Whether the blocks intersects.
|
||||||
|
|
||||||
|
@return
|
||||||
|
@true, if the block intersects with the other, @false, otherwise.
|
||||||
|
*/
|
||||||
|
bool Intersects(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
return m_topRow <= other.m_bottomRow && m_bottomRow >= other.m_topRow &&
|
||||||
|
m_leftCol <= other.m_rightCol && m_rightCol >= other.m_leftCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Whether the block contains the cell.
|
||||||
|
|
||||||
|
@return
|
||||||
|
@true, if the block contains the cell, @false, otherwise.
|
||||||
|
*/
|
||||||
|
bool ContainCell(const wxGridCellCoords& cell) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Whether the blocks contain each other.
|
||||||
|
|
||||||
|
@return
|
||||||
|
1, if this block contains the other,
|
||||||
|
-1, if the other block contains this one,
|
||||||
|
0, otherwise.
|
||||||
|
*/
|
||||||
|
int ContainBlock(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculates the result blocks by subtracting the other block from this
|
||||||
|
block.
|
||||||
|
|
||||||
|
@param other
|
||||||
|
The block to subtract from this block.
|
||||||
|
@param splitOrientation
|
||||||
|
The block splitting orientation (either @c wxHORIZONTAL or
|
||||||
|
@c wxVERTICAL).
|
||||||
|
@return
|
||||||
|
Up to 4 blocks. If block doesn't exist in the result, it has value
|
||||||
|
of @c wxGridNoBlockCoords.
|
||||||
|
*/
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
Difference(const wxGridBlockCoords& other, int splitOrientation) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculates the symmetric difference of the blocks.
|
||||||
|
|
||||||
|
@param other
|
||||||
|
The block to subtract from this block.
|
||||||
|
@return
|
||||||
|
Up to 4 blocks. If block doesn't exist in the result, it has value
|
||||||
|
of @c wxGridNoBlockCoords.
|
||||||
|
*/
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
SymDifference(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Equality operator.
|
||||||
|
*/
|
||||||
|
bool operator==(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inequality operator.
|
||||||
|
*/
|
||||||
|
bool operator!=(const wxGridBlockCoords& other) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Checks whether the cells block is invalid.
|
||||||
|
|
||||||
|
Returns @true only if all components are -1. Notice that if one
|
||||||
|
of the components (but not all) is -1, this method returns @false even
|
||||||
|
if the object is invalid. This is done because objects in such state
|
||||||
|
should actually never exist, i.e. either all components should be -1
|
||||||
|
or none of them should be -1.
|
||||||
|
*/
|
||||||
|
bool operator!() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_topRow;
|
||||||
|
int m_leftCol;
|
||||||
|
int m_bottomRow;
|
||||||
|
int m_rightCol;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@class wxGridBlockDiffResult
|
||||||
|
|
||||||
|
The helper struct uses as a result type for difference functions of
|
||||||
|
@c wxGridBlockCoords class.
|
||||||
|
|
||||||
|
Parts can be uninitialized (equals to @c wxGridNoBlockCoords), that means
|
||||||
|
that the corresponding part doesn't exists in the result.
|
||||||
|
|
||||||
|
@since 3.1.4
|
||||||
|
*/
|
||||||
|
struct wxGridBlockDiffResult
|
||||||
|
{
|
||||||
|
wxGridBlockCoords m_parts[4];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class wxGridTableBase
|
@class wxGridTableBase
|
||||||
|
|
||||||
|
@@ -94,6 +94,7 @@ struct DefaultHeaderRenderers
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
|
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
|
||||||
|
wxGridBlockCoords wxGridNoBlockCoords( -1, -1, -1, -1 );
|
||||||
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
|
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -1152,6 +1153,226 @@ const wxGridCornerHeaderRenderer& wxGridCellAttrProvider::GetCornerRenderer()
|
|||||||
return gs_defaultHeaderRenderers.cornerRenderer;
|
return gs_defaultHeaderRenderers.cornerRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxGridBlockCoords
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxGridBlockCoords::ContainCell(const wxGridCellCoords& cell) const
|
||||||
|
{
|
||||||
|
return m_topRow <= cell.GetRow() && cell.GetRow() <= m_bottomRow &&
|
||||||
|
m_leftCol <= cell.GetCol() && cell.GetCol() <= m_rightCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxGridBlockCoords::ContainBlock(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
// returns 1, if this block contains the other,
|
||||||
|
// -1, if the other block contains this one,
|
||||||
|
// 0, otherwise
|
||||||
|
if ( m_topRow <= other.m_topRow && other.m_bottomRow <= m_bottomRow &&
|
||||||
|
m_leftCol <= other.m_leftCol && other.m_rightCol <= m_rightCol )
|
||||||
|
return 1;
|
||||||
|
else if ( other.m_topRow <= m_topRow && m_bottomRow <= other.m_bottomRow &&
|
||||||
|
other.m_leftCol <= m_leftCol && m_rightCol <= other.m_rightCol )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
wxGridBlockCoords::Difference(const wxGridBlockCoords& other,
|
||||||
|
int splitOrientation) const
|
||||||
|
{
|
||||||
|
wxGridBlockDiffResult result;
|
||||||
|
|
||||||
|
// Check whether the blocks intersect.
|
||||||
|
if (!Intersects(other))
|
||||||
|
{
|
||||||
|
result.m_parts[0] = *this;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the block in up to 4 new parts, that don't contain the other
|
||||||
|
// block, like this (for wxHORIZONTAL):
|
||||||
|
// |-----------------------------|
|
||||||
|
// | |
|
||||||
|
// | part[0] |
|
||||||
|
// | |
|
||||||
|
// |-----------------------------|
|
||||||
|
// | part[2] | other | part[3] |
|
||||||
|
// |-----------------------------|
|
||||||
|
// | |
|
||||||
|
// | part[1] |
|
||||||
|
// | |
|
||||||
|
// |-----------------------------|
|
||||||
|
// And for wxVERTICAL:
|
||||||
|
// |-----------------------------|
|
||||||
|
// | | | |
|
||||||
|
// | | part[2] | |
|
||||||
|
// | | | |
|
||||||
|
// | |---------| |
|
||||||
|
// | part[0] | other | part[1] |
|
||||||
|
// | |---------| |
|
||||||
|
// | | | |
|
||||||
|
// | | part[3] | |
|
||||||
|
// | | | |
|
||||||
|
// |-----------------------------|
|
||||||
|
|
||||||
|
if ( splitOrientation == wxHORIZONTAL )
|
||||||
|
{
|
||||||
|
// Part[0].
|
||||||
|
if ( m_topRow < other.m_topRow )
|
||||||
|
result.m_parts[0] =
|
||||||
|
wxGridBlockCoords(m_topRow, m_leftCol,
|
||||||
|
other.m_topRow - 1, m_rightCol);
|
||||||
|
|
||||||
|
// Part[1].
|
||||||
|
if ( m_bottomRow > other.m_bottomRow )
|
||||||
|
result.m_parts[1] =
|
||||||
|
wxGridBlockCoords(other.m_bottomRow + 1, m_leftCol,
|
||||||
|
m_bottomRow, m_rightCol);
|
||||||
|
|
||||||
|
const int maxTopRow = wxMax(m_topRow, other.m_topRow);
|
||||||
|
const int minBottomRow = wxMin(m_bottomRow, other.m_bottomRow);
|
||||||
|
|
||||||
|
// Part[2].
|
||||||
|
if ( m_leftCol < other.m_leftCol )
|
||||||
|
result.m_parts[2] =
|
||||||
|
wxGridBlockCoords(maxTopRow, m_leftCol,
|
||||||
|
minBottomRow, other.m_leftCol - 1);
|
||||||
|
|
||||||
|
// Part[3].
|
||||||
|
if ( m_rightCol > other.m_rightCol )
|
||||||
|
result.m_parts[3] =
|
||||||
|
wxGridBlockCoords(maxTopRow, other.m_rightCol + 1,
|
||||||
|
minBottomRow, m_rightCol);
|
||||||
|
}
|
||||||
|
else // wxVERTICAL
|
||||||
|
{
|
||||||
|
// Part[0].
|
||||||
|
if ( m_leftCol < other.m_leftCol )
|
||||||
|
result.m_parts[0] =
|
||||||
|
wxGridBlockCoords(m_topRow, m_leftCol,
|
||||||
|
m_bottomRow, other.m_leftCol - 1);
|
||||||
|
|
||||||
|
// Part[1].
|
||||||
|
if ( m_rightCol > other.m_rightCol )
|
||||||
|
result.m_parts[1] =
|
||||||
|
wxGridBlockCoords(m_topRow, other.m_rightCol + 1,
|
||||||
|
m_bottomRow, m_rightCol);
|
||||||
|
|
||||||
|
const int maxLeftCol = wxMax(m_leftCol, other.m_leftCol);
|
||||||
|
const int minRightCol = wxMin(m_rightCol, other.m_rightCol);
|
||||||
|
|
||||||
|
// Part[2].
|
||||||
|
if ( m_topRow < other.m_topRow )
|
||||||
|
result.m_parts[2] =
|
||||||
|
wxGridBlockCoords(m_topRow, maxLeftCol,
|
||||||
|
other.m_topRow - 1, minRightCol);
|
||||||
|
|
||||||
|
// Part[3].
|
||||||
|
if ( m_bottomRow > other.m_bottomRow )
|
||||||
|
result.m_parts[3] =
|
||||||
|
wxGridBlockCoords(other.m_bottomRow + 1, maxLeftCol,
|
||||||
|
m_bottomRow, minRightCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxGridBlockDiffResult
|
||||||
|
wxGridBlockCoords::SymDifference(const wxGridBlockCoords& other) const
|
||||||
|
{
|
||||||
|
wxGridBlockDiffResult result;
|
||||||
|
|
||||||
|
// Check whether the blocks intersect.
|
||||||
|
if ( !Intersects(other) )
|
||||||
|
{
|
||||||
|
result.m_parts[0] = *this;
|
||||||
|
result.m_parts[1] = other;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Possible result blocks:
|
||||||
|
// |------------------|
|
||||||
|
// | | minUpper->m_topRow
|
||||||
|
// | part[0] |
|
||||||
|
// | | maxUpper->m_topRow - 1
|
||||||
|
// |-----------------------------|
|
||||||
|
// | | | | maxUpper->m_topRow
|
||||||
|
// | part[2] | x | part[3] |
|
||||||
|
// | | | | minLower->m_bottomRow
|
||||||
|
// |-----------------------------|
|
||||||
|
// | | minLower->m_bottomRow + 1
|
||||||
|
// | part[1] |
|
||||||
|
// | | maxLower->m_bottomRow
|
||||||
|
// |-------------------|
|
||||||
|
//
|
||||||
|
// The x marks the intersection of the blocks, which is not a part
|
||||||
|
// of the result.
|
||||||
|
|
||||||
|
// Part[0].
|
||||||
|
int maxUpperRow;
|
||||||
|
if ( m_topRow != other.m_topRow )
|
||||||
|
{
|
||||||
|
const bool block1Min = m_topRow < other.m_topRow;
|
||||||
|
const wxGridBlockCoords& minUpper = block1Min ? *this : other;
|
||||||
|
const wxGridBlockCoords& maxUpper = block1Min ? other : *this;
|
||||||
|
maxUpperRow = maxUpper.m_topRow;
|
||||||
|
|
||||||
|
result.m_parts[0] = wxGridBlockCoords(minUpper.m_topRow,
|
||||||
|
minUpper.m_leftCol,
|
||||||
|
maxUpper.m_topRow - 1,
|
||||||
|
minUpper.m_rightCol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxUpperRow = m_topRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Part[1].
|
||||||
|
int minLowerRow;
|
||||||
|
if ( m_bottomRow != other.m_bottomRow )
|
||||||
|
{
|
||||||
|
const bool block1Min = m_bottomRow < other.m_bottomRow;
|
||||||
|
const wxGridBlockCoords& minLower = block1Min ? *this : other;
|
||||||
|
const wxGridBlockCoords& maxLower = block1Min ? other : *this;
|
||||||
|
minLowerRow = minLower.m_bottomRow;
|
||||||
|
|
||||||
|
result.m_parts[1] = wxGridBlockCoords(minLower.m_bottomRow + 1,
|
||||||
|
maxLower.m_leftCol,
|
||||||
|
maxLower.m_bottomRow,
|
||||||
|
maxLower.m_rightCol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minLowerRow = m_bottomRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Part[2].
|
||||||
|
if ( m_leftCol != other.m_leftCol )
|
||||||
|
{
|
||||||
|
result.m_parts[2] = wxGridBlockCoords(maxUpperRow,
|
||||||
|
wxMin(m_leftCol,
|
||||||
|
other.m_leftCol),
|
||||||
|
minLowerRow,
|
||||||
|
wxMax(m_leftCol,
|
||||||
|
other.m_leftCol) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Part[3].
|
||||||
|
if ( m_rightCol != other.m_rightCol )
|
||||||
|
{
|
||||||
|
result.m_parts[3] = wxGridBlockCoords(maxUpperRow,
|
||||||
|
wxMin(m_rightCol,
|
||||||
|
other.m_rightCol) + 1,
|
||||||
|
minLowerRow,
|
||||||
|
wxMax(m_rightCol,
|
||||||
|
other.m_rightCol));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxGridTableBase
|
// wxGridTableBase
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -1259,4 +1259,191 @@ TEST_CASE_METHOD(GridTestCase, "Grid::AutoSizeColumn", "[grid]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test wxGridBlockCoords here because it'a a part of grid sources.
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const wxGridBlockCoords& block) {
|
||||||
|
os << "wxGridBlockCoords(" <<
|
||||||
|
block.GetTopRow() << ", " << block.GetLeftCol() << ", " <<
|
||||||
|
block.GetBottomRow() << ", " << block.GetRightCol() << ")";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::Canonicalize", "[grid]")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block =
|
||||||
|
wxGridBlockCoords(4, 3, 2, 1).Canonicalize();
|
||||||
|
|
||||||
|
CHECK(block.GetTopRow() == 2);
|
||||||
|
CHECK(block.GetLeftCol() == 1);
|
||||||
|
CHECK(block.GetBottomRow() == 4);
|
||||||
|
CHECK(block.GetRightCol() == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::Intersects", "[grid]")
|
||||||
|
{
|
||||||
|
// Inside.
|
||||||
|
CHECK(wxGridBlockCoords(1, 1, 3, 3).Intersects(wxGridBlockCoords(1, 2, 2, 3)));
|
||||||
|
|
||||||
|
// Intersects.
|
||||||
|
CHECK(wxGridBlockCoords(1, 1, 3, 3).Intersects(wxGridBlockCoords(2, 2, 4, 4)));
|
||||||
|
|
||||||
|
// Doesn't intersects.
|
||||||
|
CHECK(!wxGridBlockCoords(1, 1, 3, 3).Intersects(wxGridBlockCoords(4, 4, 6, 6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::ContainCell", "[grid]")
|
||||||
|
{
|
||||||
|
// Inside.
|
||||||
|
CHECK(wxGridBlockCoords(1, 1, 3, 3).ContainCell(wxGridCellCoords(2, 2)));
|
||||||
|
|
||||||
|
// Outside.
|
||||||
|
CHECK(!wxGridBlockCoords(1, 1, 3, 3).ContainCell(wxGridCellCoords(5, 5)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::ContainBlock", "[grid]")
|
||||||
|
{
|
||||||
|
wxGridBlockCoords block1(1, 1, 5, 5);
|
||||||
|
wxGridBlockCoords block2(1, 1, 3, 3);
|
||||||
|
wxGridBlockCoords block3(2, 2, 7, 7);
|
||||||
|
wxGridBlockCoords block4(10, 10, 12, 12);
|
||||||
|
|
||||||
|
CHECK(block1.ContainBlock(block2) == 1);
|
||||||
|
CHECK(block2.ContainBlock(block1) == -1);
|
||||||
|
CHECK(block1.ContainBlock(block3) == 0);
|
||||||
|
CHECK(block1.ContainBlock(block4) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::Difference", "[grid]")
|
||||||
|
{
|
||||||
|
SECTION("Subtract contained block (splitted horizontally)")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 7, 7);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 5, 5);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxHORIZONTAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 2, 7));
|
||||||
|
CHECK(result.m_parts[1] == wxGridBlockCoords(6, 1, 7, 7));
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(3, 1, 5, 2));
|
||||||
|
CHECK(result.m_parts[3] == wxGridBlockCoords(3, 6, 5, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Subtract contained block (splitted vertically)")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 7, 7);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 5, 5);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxVERTICAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 7, 2));
|
||||||
|
CHECK(result.m_parts[1] == wxGridBlockCoords(1, 6, 7, 7));
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(1, 3, 2, 5));
|
||||||
|
CHECK(result.m_parts[3] == wxGridBlockCoords(6, 3, 7, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks intersect by the corner (splitted horizontally)")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 5, 5);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 7, 7);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxHORIZONTAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 2, 5));
|
||||||
|
CHECK(result.m_parts[1] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(3, 1, 5, 2));
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks intersect by the corner (splitted vertically)")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 5, 5);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 7, 7);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxVERTICAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 5, 2));
|
||||||
|
CHECK(result.m_parts[1] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(1, 3, 2, 5));
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks are the same")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 3, 3);
|
||||||
|
const wxGridBlockCoords block2(1, 1, 3, 3);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxHORIZONTAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[1] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[2] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks doesn't intersects")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 3, 3);
|
||||||
|
const wxGridBlockCoords block2(5, 5, 7, 7);
|
||||||
|
const wxGridBlockDiffResult result =
|
||||||
|
block1.Difference(block2, wxHORIZONTAL);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 3, 3));
|
||||||
|
CHECK(result.m_parts[1] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[2] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("GridBlockCoords::SymDifference", "[grid]")
|
||||||
|
{
|
||||||
|
SECTION("With contained block")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 7, 7);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 5, 5);
|
||||||
|
const wxGridBlockDiffResult result = block1.SymDifference(block2);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 2, 7));
|
||||||
|
CHECK(result.m_parts[1] == wxGridBlockCoords(6, 1, 7, 7));
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(3, 1, 5, 2));
|
||||||
|
CHECK(result.m_parts[3] == wxGridBlockCoords(3, 6, 5, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks intersect by the corner")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 5, 5);
|
||||||
|
const wxGridBlockCoords block2(3, 3, 7, 7);
|
||||||
|
const wxGridBlockDiffResult result = block1.SymDifference(block2);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 2, 5));
|
||||||
|
CHECK(result.m_parts[1] == wxGridBlockCoords(6, 3, 7, 7));
|
||||||
|
CHECK(result.m_parts[2] == wxGridBlockCoords(3, 1, 5, 2));
|
||||||
|
CHECK(result.m_parts[3] == wxGridBlockCoords(3, 6, 5, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks are the same")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 3, 3);
|
||||||
|
const wxGridBlockCoords block2(1, 1, 3, 3);
|
||||||
|
const wxGridBlockDiffResult result = block1.SymDifference(block2);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[1] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[2] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Blocks doesn't intersects")
|
||||||
|
{
|
||||||
|
const wxGridBlockCoords block1(1, 1, 3, 3);
|
||||||
|
const wxGridBlockCoords block2(5, 5, 7, 7);
|
||||||
|
const wxGridBlockDiffResult result = block1.SymDifference(block2);
|
||||||
|
|
||||||
|
CHECK(result.m_parts[0] == wxGridBlockCoords(1, 1, 3, 3));
|
||||||
|
CHECK(result.m_parts[1] == wxGridBlockCoords(5, 5, 7, 7));
|
||||||
|
CHECK(result.m_parts[2] == wxGridNoBlockCoords);
|
||||||
|
CHECK(result.m_parts[3] == wxGridNoBlockCoords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif //wxUSE_GRID
|
#endif //wxUSE_GRID
|
||||||
|
Reference in New Issue
Block a user