517 lines
22 KiB
Text
517 lines
22 KiB
Text
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Name: block.h
|
||
|
// Purpose: Rectangular selection storage classes for ints and doubles
|
||
|
// Author: John Labenski
|
||
|
// Created: 07/01/02
|
||
|
// Copyright: (c) John Labenski, 2004
|
||
|
// License: wxWidgets
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#ifndef __wxBLOCK_H__
|
||
|
#define __wxBLOCK_H__
|
||
|
|
||
|
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||
|
#pragma interface "block.h"
|
||
|
#endif
|
||
|
|
||
|
#include "wx/geometry.h"
|
||
|
#include "wx/things/thingdef.h"
|
||
|
|
||
|
//#define USE_wxRANGE
|
||
|
|
||
|
#ifdef USE_wxRANGE
|
||
|
#include "wx/things/range.h"
|
||
|
#endif
|
||
|
|
||
|
// Note: Why are these not just wxRect2DXXX with m_x and m_width?
|
||
|
// because the double blocks need to match up at the edges and x+width
|
||
|
// does not always exactly equal the edge of an adjoining block
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockInt;
|
||
|
class WXDLLIMPEXP_THINGS wxBlockDouble;
|
||
|
class WXDLLIMPEXP_THINGS wxBlockIntSelection;
|
||
|
class WXDLLIMPEXP_THINGS wxBlockDoubleSelection;
|
||
|
|
||
|
#include "wx/dynarray.h"
|
||
|
WX_DECLARE_OBJARRAY_WITH_DECL(wxBlockInt, wxArrayBlockInt, class WXDLLIMPEXP_THINGS);
|
||
|
WX_DECLARE_OBJARRAY_WITH_DECL(wxBlockDouble, wxArrayBlockDouble, class WXDLLIMPEXP_THINGS);
|
||
|
WX_DECLARE_OBJARRAY_WITH_DECL(wxBlockIntSelection, wxArrayBlockIntSelection, class WXDLLIMPEXP_THINGS);
|
||
|
WX_DECLARE_OBJARRAY_WITH_DECL(wxBlockDoubleSelection, wxArrayBlockDoubleSelection, class WXDLLIMPEXP_THINGS);
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockXXX constants
|
||
|
//=============================================================================
|
||
|
|
||
|
// wxEmptyBlockXXX = (0,0,-1,-1)
|
||
|
WXDLLIMPEXP_DATA_THINGS(extern const wxBlockInt) wxEmptyBlockInt;
|
||
|
WXDLLIMPEXP_DATA_THINGS(extern const wxBlockDouble) wxEmptyBlockDouble;
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockXXX sorting functions
|
||
|
//=============================================================================
|
||
|
|
||
|
enum wxBlockSort_Type
|
||
|
{
|
||
|
wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT,
|
||
|
wxBLOCKSORT_TOPRIGHT_BOTTOMLEFT,
|
||
|
wxBLOCKSORT_BOTTOMLEFT_TOPRIGHT,
|
||
|
wxBLOCKSORT_BOTTOMRIGHT_TOPLEFT,
|
||
|
wxBLOCKSORT_SMALLEST_TO_LARGEST,
|
||
|
wxBLOCKSORT_LARGEST_TO_SMALLEST
|
||
|
};
|
||
|
|
||
|
// functions to sort an array of blocks from any corner
|
||
|
extern void wxArrayBlockIntSort(wxArrayBlockInt &blocks,
|
||
|
wxBlockSort_Type type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT);
|
||
|
|
||
|
extern void wxArrayBlockDoubleSort(wxArrayBlockDouble &blocks,
|
||
|
wxBlockSort_Type type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT);
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockInt - a rectangle bounded by the corner points that can combine with
|
||
|
// other wxBlockInts
|
||
|
//=============================================================================
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockInt
|
||
|
{
|
||
|
public:
|
||
|
inline wxBlockInt(wxInt32 x1=0, wxInt32 y1=0, wxInt32 x2=0, wxInt32 y2=0) : m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {}
|
||
|
inline wxBlockInt(const wxRect2DInt &rect) : m_x1(rect.m_x), m_y1(rect.m_y), m_x2(rect.GetRight()), m_y2(rect.GetBottom()) {}
|
||
|
|
||
|
inline wxInt32 GetLeft() const { return m_x1; }
|
||
|
inline wxInt32 GetRight() const { return m_x2; }
|
||
|
inline wxInt32 GetTop() const { return m_y1; }
|
||
|
inline wxInt32 GetBottom() const { return m_y2; }
|
||
|
|
||
|
inline wxInt32 GetWidth() const { return m_x2 - m_x1 + 1; }
|
||
|
inline wxInt32 GetHeight() const { return m_y2 - m_y1 + 1; }
|
||
|
|
||
|
inline wxPoint2DInt GetLeftTop() const { return wxPoint2DInt(m_x1, m_y1); }
|
||
|
inline wxPoint2DInt GetLeftBottom() const { return wxPoint2DInt(m_x1, m_y2); }
|
||
|
inline wxPoint2DInt GetRightTop() const { return wxPoint2DInt(m_x2, m_y1); }
|
||
|
inline wxPoint2DInt GetRightBottom() const { return wxPoint2DInt(m_x2, m_y2); }
|
||
|
|
||
|
inline wxRect2DInt GetRect2DInt() const { return wxRect2DInt(m_x1, m_y1, m_x2-m_x1+1, m_y2-m_y1+1); }
|
||
|
inline void SetRect2DInt(const wxRect2DInt &r) { m_x1=r.m_x; m_y1=r.m_y, m_x2=r.GetRight(); m_y2=r.GetBottom(); }
|
||
|
|
||
|
inline bool Contains( wxInt32 x, wxInt32 y ) const
|
||
|
{ return ((x >= m_x1) && (x <= m_x2) && (y >= m_y1) && (y <= m_y2)); }
|
||
|
inline bool Contains( const wxPoint2DInt &pt ) const { return Contains(pt.m_x, pt.m_y); }
|
||
|
inline bool Contains( const wxBlockInt &b ) const
|
||
|
{ return ((m_x1 <= b.m_x1) && (b.m_x2 <= m_x2) && (m_y1 <= b.m_y1) && (b.m_y2 <= m_y2)); }
|
||
|
|
||
|
inline bool Intersects( const wxBlockInt &b ) const
|
||
|
{ return (wxMax(m_x1, b.m_x1)<=wxMin(m_x2, b.m_x2)) && (wxMax(m_y1, b.m_y1)<=wxMin(m_y2, b.m_y2)); }
|
||
|
inline void Intersect( const wxBlockInt &otherBlock ) { Intersect( *this, otherBlock, this ); }
|
||
|
inline void Intersect( const wxBlockInt &src1 , const wxBlockInt &src2 , wxBlockInt *dest ) const
|
||
|
{
|
||
|
dest->m_x1 = wxMax(src1.m_x1, src2.m_x1);
|
||
|
dest->m_x2 = wxMin(src1.m_x2, src2.m_x2);
|
||
|
dest->m_y1 = wxMax(src1.m_y1, src2.m_y1);
|
||
|
dest->m_y2 = wxMin(src1.m_y2, src2.m_y2);
|
||
|
}
|
||
|
|
||
|
inline void Union( const wxBlockInt &otherBlock ) { Union(*this, otherBlock, this); }
|
||
|
inline void Union( const wxBlockInt &src1, const wxBlockInt &src2, wxBlockInt *dest ) const
|
||
|
{
|
||
|
dest->m_x1 = wxMin(src1.m_x1, src2.m_x1);
|
||
|
dest->m_x2 = wxMax(src1.m_x2, src2.m_x2);
|
||
|
dest->m_y1 = wxMin(src1.m_y1, src2.m_y1);
|
||
|
dest->m_y2 = wxMax(src1.m_y2, src2.m_y2);
|
||
|
}
|
||
|
|
||
|
// is this block larger than input block, return 1 = larger, 0 = equal, -1 = smaller
|
||
|
int IsLarger(const wxBlockInt &b) const
|
||
|
{
|
||
|
wxInt32 width = m_x2 - m_x1 + 1,
|
||
|
height = m_y2 - m_y1 + 1,
|
||
|
b_width = b.m_x2 - b.m_x1 + 1,
|
||
|
b_height = b.m_y2 - b.m_y1 + 1;
|
||
|
|
||
|
if ((width <= 0) || (height <= 0))
|
||
|
return (b_width > 0) && (b_height > 0) ? -1 : 0;
|
||
|
if ((b_width <= 0) || (b_height <= 0))
|
||
|
return (width > 0) && (height > 0) ? 1 : 0;
|
||
|
|
||
|
wxDouble w_bw = wxDouble(width)/b_width,
|
||
|
bh_h = wxDouble(b_height)/height;
|
||
|
return (w_bw == bh_h) ? 0 : ((w_bw > bh_h) ? 1 : -1);
|
||
|
}
|
||
|
|
||
|
bool IsEmpty() const { return (m_x1 > m_x2) || (m_y1 > m_y2); }
|
||
|
|
||
|
// Unlike Intersects this also includes just touching the other block
|
||
|
bool Touches(const wxBlockInt &block) const;
|
||
|
|
||
|
// Try to combine these blocks, they must touch and fit to make a single larger block
|
||
|
// this block is expanded if possible
|
||
|
bool Combine(const wxBlockInt &block);
|
||
|
|
||
|
// test combining the input block with this one, returning the
|
||
|
// remainder of block in top, bottom, left, right - each may be IsEmpty()
|
||
|
// returns false if blocks don't touch or this block already contains block
|
||
|
// |---------------------------|
|
||
|
// | top |
|
||
|
// |---------------------------|
|
||
|
// | left |block| right |
|
||
|
// |---------------------------|
|
||
|
// | bottom |
|
||
|
// |---------------------------|
|
||
|
bool Combine( const wxBlockInt &block,
|
||
|
wxBlockInt &top, wxBlockInt &bottom,
|
||
|
wxBlockInt &left, wxBlockInt &right) const;
|
||
|
|
||
|
// test removal of a portion or all of this contained in block returning the
|
||
|
// remainder in top, bottom, left, right - each may be IsEmpty()
|
||
|
// returns false if nothing to delete, this cell is not changed
|
||
|
bool Delete(const wxBlockInt &block, wxBlockInt &top, wxBlockInt &bottom,
|
||
|
wxBlockInt &left, wxBlockInt &right) const;
|
||
|
|
||
|
// operators
|
||
|
inline bool operator == (const wxBlockInt& b)
|
||
|
{ return (m_x1==b.m_x1) && (m_y1==b.m_y1) && (m_x2==b.m_x2) && (m_y2==b.m_y2); }
|
||
|
inline bool operator != (const wxBlockInt& b)
|
||
|
{ return !(*this == b); }
|
||
|
|
||
|
wxInt32 m_x1, m_y1, m_x2, m_y2;
|
||
|
};
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockDouble
|
||
|
//=============================================================================
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockDouble
|
||
|
{
|
||
|
public:
|
||
|
inline wxBlockDouble(wxDouble x1=0, wxDouble y1=0, wxDouble x2=0, wxDouble y2=0)
|
||
|
: m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {}
|
||
|
inline wxBlockDouble(const wxRect2DDouble &rect)
|
||
|
{ m_x1=rect.m_x; m_y1=rect.m_y; m_x2=rect.GetRight(); m_y2=rect.GetBottom(); }
|
||
|
|
||
|
inline wxDouble GetLeft() const { return m_x1; }
|
||
|
inline wxDouble GetRight() const { return m_x2; }
|
||
|
inline wxDouble GetTop() const { return m_y1; }
|
||
|
inline wxDouble GetBottom() const { return m_y2; }
|
||
|
|
||
|
inline wxDouble GetWidth() const { return m_x2 - m_x1; }
|
||
|
inline wxDouble GetHeight() const { return m_y2 - m_y1; }
|
||
|
|
||
|
inline wxPoint2DDouble GetLeftTop() const { return wxPoint2DDouble(m_x1, m_y1); }
|
||
|
inline wxPoint2DDouble GetLeftBottom() const { return wxPoint2DDouble(m_x1, m_y2); }
|
||
|
inline wxPoint2DDouble GetRightTop() const { return wxPoint2DDouble(m_x2, m_y1); }
|
||
|
inline wxPoint2DDouble GetRightBottom() const { return wxPoint2DDouble(m_x2, m_y2); }
|
||
|
|
||
|
inline wxRect2DDouble GetRect2DDouble() const { return wxRect2DDouble(m_x1, m_y1, m_x2-m_x1, m_y2-m_y1); }
|
||
|
inline void SetRect2DDouble(const wxRect2DDouble &r) { m_x1=r.m_x; m_y1=r.m_y, m_x2=r.GetRight(); m_y2=r.GetBottom(); }
|
||
|
|
||
|
inline bool Contains( wxDouble x, wxDouble y ) const
|
||
|
{ return ((x >= m_x1) && (x <= m_x2) && (y >= m_y1) && (y <= m_y2)); }
|
||
|
inline bool Contains( const wxPoint2DDouble &pt ) const { return Contains(pt.m_x, pt.m_y); }
|
||
|
inline bool Contains( const wxBlockDouble &b ) const
|
||
|
{ return ((m_x1 <= b.m_x1) && (b.m_x2 <= m_x2) && (m_y1 <= b.m_y1) && (b.m_y2 <= m_y2)); }
|
||
|
|
||
|
inline bool Intersects( const wxBlockDouble &b ) const
|
||
|
{ return (wxMax(m_x1, b.m_x1)<wxMin(m_x2, b.m_x2)) && (wxMax(m_y1, b.m_y1)<wxMin(m_y2, b.m_y2)); }
|
||
|
inline void Intersect( const wxBlockDouble &otherBlock ) { Intersect( *this, otherBlock, this ); }
|
||
|
inline void Intersect( const wxBlockDouble &src1 , const wxBlockDouble &src2 , wxBlockDouble *dest ) const
|
||
|
{
|
||
|
dest->m_x1 = wxMax(src1.m_x1, src2.m_x1);
|
||
|
dest->m_x2 = wxMin(src1.m_x2, src2.m_x2);
|
||
|
dest->m_y1 = wxMax(src1.m_y1, src2.m_y1);
|
||
|
dest->m_y2 = wxMin(src1.m_y2, src2.m_y2);
|
||
|
}
|
||
|
|
||
|
inline void Union( const wxBlockDouble &otherBlock ) { Union( *this, otherBlock, this ); }
|
||
|
inline void Union( const wxBlockDouble &src1, const wxBlockDouble &src2, wxBlockDouble *dest ) const
|
||
|
{
|
||
|
dest->m_x1 = wxMin(src1.m_x1, src2.m_x1);
|
||
|
dest->m_x2 = wxMax(src1.m_x2, src2.m_x2);
|
||
|
dest->m_y1 = wxMin(src1.m_y1, src2.m_y1);
|
||
|
dest->m_y2 = wxMax(src1.m_y2, src2.m_y2);
|
||
|
}
|
||
|
|
||
|
// is this block larger than input block, return 1 - larger, 0 = equal, -1 smaller
|
||
|
int IsLarger(const wxBlockDouble &b) const
|
||
|
{
|
||
|
wxDouble width = m_x2 - m_x1,
|
||
|
height = m_y2 - m_y1,
|
||
|
b_width = b.m_x2 - b.m_x1,
|
||
|
b_height = b.m_y2 - b.m_y1;
|
||
|
|
||
|
if ((width <= 0) || (height <= 0))
|
||
|
return (b_width > 0) && (b_height > 0) ? -1 : 0;
|
||
|
if ((b_width <= 0) || (b_height <= 0))
|
||
|
return (width > 0) && (height > 0) ? 1 : 0;
|
||
|
|
||
|
wxDouble w_bw = width/b_width,
|
||
|
bh_h = b_height/height;
|
||
|
return (w_bw == bh_h) ? 0 : ((w_bw > bh_h) ? 1 : -1);
|
||
|
}
|
||
|
inline bool IsEmpty() const { return (m_x1 > m_x2) || (m_y1 > m_y2); }
|
||
|
|
||
|
// Unlike Intersects this also includes just touching the other block
|
||
|
bool Touches(const wxBlockDouble &block) const;
|
||
|
|
||
|
// Try to combine these blocks, they must touch and fit to make a single larger block
|
||
|
// this block is expanded if possible
|
||
|
bool Combine(const wxBlockDouble &block);
|
||
|
|
||
|
// test combining the input block with this one, returning the
|
||
|
// remainder of block in top, bottom, left, right - each may be IsEmpty()
|
||
|
// returns false if blocks don't touch or this block already contains block
|
||
|
// |---------------------------|
|
||
|
// | top |
|
||
|
// |---------------------------|
|
||
|
// | left |block| right |
|
||
|
// |---------------------------|
|
||
|
// | bottom |
|
||
|
// |---------------------------|
|
||
|
bool Combine( const wxBlockDouble &block,
|
||
|
wxBlockDouble &top, wxBlockDouble &bottom,
|
||
|
wxBlockDouble &left, wxBlockDouble &right) const;
|
||
|
|
||
|
// test removal of a portion or all of this contained in block returning the
|
||
|
// remainder in top, bottom, left, right - each may be IsEmpty()
|
||
|
// returns false if nothing to delete, this cell is not changed
|
||
|
bool Delete( const wxBlockDouble &block,
|
||
|
wxBlockDouble &top, wxBlockDouble &bottom,
|
||
|
wxBlockDouble &left, wxBlockDouble &right) const;
|
||
|
|
||
|
// operators
|
||
|
inline bool operator == (const wxBlockDouble& b)
|
||
|
{ return (m_x1==b.m_x1) && (m_y1==b.m_y1) && (m_x2==b.m_x2) && (m_y2==b.m_y2); }
|
||
|
inline bool operator != (const wxBlockDouble& b)
|
||
|
{ return !(*this == b); }
|
||
|
|
||
|
wxDouble m_x1, m_y1, m_x2, m_y2;
|
||
|
};
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockIntSelection - ordered 2D array of wxBlockInts, combines to minimize size
|
||
|
// blocks never overlap each other
|
||
|
//=============================================================================
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockIntSelection
|
||
|
{
|
||
|
public :
|
||
|
wxBlockIntSelection(wxBlockSort_Type sort_type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT)
|
||
|
: m_sort(sort_type) {}
|
||
|
wxBlockIntSelection(const wxBlockIntSelection &blocks,
|
||
|
wxBlockSort_Type sort_type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT)
|
||
|
: m_sort(sort_type) { Copy(blocks); }
|
||
|
|
||
|
// Make a full copy of the source
|
||
|
void Copy(const wxBlockIntSelection &source)
|
||
|
{
|
||
|
m_blocks.Clear();
|
||
|
WX_APPEND_ARRAY(m_blocks, source.GetBlockArray());
|
||
|
m_sort = source.GetSortType();
|
||
|
}
|
||
|
|
||
|
inline int GetCount() const { return m_blocks.GetCount(); }
|
||
|
|
||
|
inline void Clear() { m_blocks.Clear(); }
|
||
|
|
||
|
wxArrayBlockInt GetBlockArray() const { return m_blocks; }
|
||
|
|
||
|
#ifdef USE_wxRANGE
|
||
|
// Get an array of ranges cutting though these blocks
|
||
|
wxArrayRangeInt GetBlockCol(int col) const;
|
||
|
wxArrayRangeInt GetBlockRow(int row) const;
|
||
|
#endif
|
||
|
|
||
|
wxBlockInt GetBlock( int index ) const;
|
||
|
inline wxBlockInt Item( int index ) const { return GetBlock(index); }
|
||
|
|
||
|
// Get a block that bounds the selection
|
||
|
wxBlockInt GetBoundingBlock() const;
|
||
|
|
||
|
// do any of the blocks contains elements
|
||
|
inline bool Contains( int x, int y ) const { return Index(x,y) != wxNOT_FOUND; }
|
||
|
inline bool Contains( const wxPoint2DInt &pt ) const { return Index(pt) != wxNOT_FOUND; }
|
||
|
inline bool Contains( const wxBlockInt &b ) const { return Index(b) != wxNOT_FOUND; }
|
||
|
|
||
|
// what is the index of a block that contains element
|
||
|
int Index( int x, int y ) const;
|
||
|
inline int Index( const wxPoint2DInt &pt ) const { return Index(pt.m_x, pt.m_y); }
|
||
|
int Index( const wxBlockInt &b ) const;
|
||
|
|
||
|
// Sorts the blocks according to the wxBlockIntSort_Type
|
||
|
void Sort(wxBlockSort_Type type = wxBLOCKSORT_TOPRIGHT_BOTTOMLEFT);
|
||
|
wxBlockSort_Type GetSortType() const { return m_sort; }
|
||
|
|
||
|
// Add the block to the selection, returns false if nothing was done
|
||
|
// use combineNow=false to make quick additions, when done call Minimize()
|
||
|
// addedBlocks (if !NULL) will be filled with the actual changed selections
|
||
|
// by removing the previous selections from the input block
|
||
|
bool SelectBlock( const wxBlockInt &block, bool combineNow=true, wxArrayBlockInt *addedBlocks=NULL);
|
||
|
|
||
|
// Remove the block to the selection, return false if nothing was done
|
||
|
// use combineNow=false to make quick additions, when done call Minimize()
|
||
|
bool DeselectBlock( const wxBlockInt &block, bool combineNow=true);
|
||
|
|
||
|
// Try to combine the blocks if possible, returns if anything was done
|
||
|
// only need to call this if you've called (De)SelectBlock(..., false)
|
||
|
bool Minimize();
|
||
|
|
||
|
// Operators
|
||
|
inline wxBlockInt operator[](int index) const { return GetBlock(index); }
|
||
|
|
||
|
//wxBlockIntSelection& operator = (const wxBlockIntSelection& other) { Copy(other); return *this; }
|
||
|
|
||
|
// generic routine using if (b1.Combine(b2)) remove b2 to cleanup array
|
||
|
// sort top_left_bottom_right first (internal use)
|
||
|
static bool DoMinimize( wxArrayBlockInt &blocks );
|
||
|
// DoMinimize calls this internally
|
||
|
static bool DoDoMinimize( wxArrayBlockInt &blocks );
|
||
|
|
||
|
protected :
|
||
|
wxArrayBlockInt m_blocks;
|
||
|
wxBlockSort_Type m_sort;
|
||
|
};
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockDoubleSelection - ordered 2D array of wxBlockDoubles, combines to minimze size
|
||
|
// blocks never overlap each other
|
||
|
//=============================================================================
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockDoubleSelection
|
||
|
{
|
||
|
public :
|
||
|
wxBlockDoubleSelection(wxBlockSort_Type sort_type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT)
|
||
|
: m_sort(sort_type) {}
|
||
|
wxBlockDoubleSelection(const wxBlockDoubleSelection &blocks,
|
||
|
wxBlockSort_Type sort_type = wxBLOCKSORT_TOPLEFT_BOTTOMRIGHT)
|
||
|
: m_sort(sort_type) { Copy(blocks); }
|
||
|
|
||
|
// Make a full copy of the source
|
||
|
void Copy(const wxBlockDoubleSelection &source)
|
||
|
{
|
||
|
m_blocks.Clear();
|
||
|
WX_APPEND_ARRAY(m_blocks, source.GetBlockArray());
|
||
|
m_sort = source.GetSortType();
|
||
|
}
|
||
|
|
||
|
inline int GetCount() const { return m_blocks.GetCount(); }
|
||
|
|
||
|
inline void Clear() { m_blocks.Clear(); }
|
||
|
|
||
|
wxArrayBlockDouble GetBlockArray() const { return m_blocks; }
|
||
|
|
||
|
#ifdef USE_wxRANGE
|
||
|
// Get an array of ranges cutting though these blocks
|
||
|
wxArrayRangeDouble GetBlockCol(wxDouble col) const;
|
||
|
wxArrayRangeDouble GetBlockRow(wxDouble row) const;
|
||
|
#endif
|
||
|
|
||
|
wxBlockDouble GetBlock( int index ) const;
|
||
|
inline wxBlockDouble Item( int index ) const { return GetBlock(index); }
|
||
|
|
||
|
// Get a block that bounds the selection
|
||
|
wxBlockDouble GetBoundingBlock() const;
|
||
|
|
||
|
// do any of the blocks contains elements
|
||
|
inline bool Contains( wxDouble x, wxDouble y ) const { return Index(wxPoint2DDouble(x,y)) != wxNOT_FOUND; }
|
||
|
inline bool Contains( const wxPoint2DInt &pt ) const { return Index(pt) != wxNOT_FOUND; }
|
||
|
inline bool Contains( const wxBlockDouble &b ) const { return Index(b) != wxNOT_FOUND; }
|
||
|
|
||
|
// what is the index of a block that contains element
|
||
|
int Index( wxDouble x, wxDouble y ) const;
|
||
|
inline int Index( const wxPoint2DDouble &pt ) const { return Index(pt.m_x, pt.m_y); }
|
||
|
int Index( const wxBlockDouble &b ) const;
|
||
|
|
||
|
// Sorts the blocks according to the wxBlockIntSort_Type
|
||
|
void Sort(wxBlockSort_Type type = wxBLOCKSORT_TOPRIGHT_BOTTOMLEFT);
|
||
|
wxBlockSort_Type GetSortType() const { return m_sort; }
|
||
|
|
||
|
// Add the block to the selection, returns false if nothing was done
|
||
|
// use combineNow=false to make quick additions, when done call Minimize()
|
||
|
bool SelectBlock( const wxBlockDouble &block, bool combineNow=true);
|
||
|
|
||
|
// Remove the block to the selection, return false if nothing was done
|
||
|
// use combineNow=false to make quick additions, when done call Minimize()
|
||
|
bool DeselectBlock( const wxBlockDouble &block, bool combineNow=true);
|
||
|
|
||
|
// Try to combine the blocks if possible, returns if anything was done
|
||
|
// only need to call this if you've called (De)SelectBlock(..., false)
|
||
|
bool Minimize();
|
||
|
|
||
|
// Operators
|
||
|
inline wxBlockDouble operator[](int index) const { return GetBlock(index); }
|
||
|
|
||
|
//wxBlockIntSelection& operator = (const wxBlockIntSelection& other) { Copy(other); return *this; }
|
||
|
|
||
|
// generic routine using if (b1.Combine(b2)) remove b2 to cleanup array
|
||
|
// sort top_left_bottom_right first (internal use)
|
||
|
static bool DoMinimize( wxArrayBlockDouble &blocks );
|
||
|
// DoMinimize calls this internally
|
||
|
static bool DoDoMinimize( wxArrayBlockDouble &blocks );
|
||
|
|
||
|
protected :
|
||
|
wxArrayBlockDouble m_blocks;
|
||
|
wxBlockSort_Type m_sort;
|
||
|
};
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockIntSelectionIterator - iterates through a wxBlockIntSelection
|
||
|
//=============================================================================
|
||
|
enum wxBISI_Type
|
||
|
{
|
||
|
wxBISI_POINT, // wxBlockIntSelectionIterator::SetType go point by point
|
||
|
wxBISI_BLOCK // go block by block
|
||
|
};
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockIntSelectionIterator
|
||
|
{
|
||
|
public :
|
||
|
wxBlockIntSelectionIterator( const wxBlockIntSelection &sel, wxBISI_Type type = wxBISI_POINT );
|
||
|
wxBlockIntSelectionIterator( const wxArrayBlockInt &blocks, wxBISI_Type type = wxBISI_POINT );
|
||
|
|
||
|
// resets the iterating to start at the beginning
|
||
|
void Reset();
|
||
|
// Set the method to get the blocks, either point by point or each whole block
|
||
|
// also resets the iteration to the beginning
|
||
|
void SetType( wxBISI_Type type ) { m_type = type; Reset(); }
|
||
|
wxBISI_Type GetType() const { return m_type; }
|
||
|
|
||
|
// Get next selection, returns false if at end (only valid for wxBISI_point)
|
||
|
bool GetNext(wxPoint2DInt &pt);
|
||
|
// Get next selection, returns false if at end (only valid for wxBISI_block)
|
||
|
bool GetNext(wxBlockInt &block);
|
||
|
|
||
|
// checks if this row and col are in this selection
|
||
|
bool IsInSelection(const wxPoint2DInt &pt) const;
|
||
|
inline bool IsInSelection( int x, int y ) const { return IsInSelection(wxPoint2DInt(x,y)); }
|
||
|
|
||
|
protected :
|
||
|
wxBISI_Type m_type;
|
||
|
int m_block_index;
|
||
|
wxPoint2DInt m_pt;
|
||
|
wxArrayBlockInt m_blocks;
|
||
|
};
|
||
|
|
||
|
//=============================================================================
|
||
|
// wxBlockDoubleSelectionIterator - iterates through a wxBlockDoubleSelection
|
||
|
//=============================================================================
|
||
|
|
||
|
class WXDLLIMPEXP_THINGS wxBlockDoubleSelectionIterator
|
||
|
{
|
||
|
public :
|
||
|
wxBlockDoubleSelectionIterator( const wxBlockDoubleSelection &sel );
|
||
|
wxBlockDoubleSelectionIterator( const wxArrayBlockDouble &blocks );
|
||
|
|
||
|
// resets the iterating to start at the beginning
|
||
|
void Reset();
|
||
|
// Get next selection, returns false if at the end
|
||
|
bool GetNext(wxBlockDouble &block);
|
||
|
// checks if this row and col are in this selection
|
||
|
bool IsInSelection(const wxPoint2DDouble &pt) const;
|
||
|
inline bool IsInSelection( int x, int y ) const { return IsInSelection(wxPoint2DDouble(x,y)); }
|
||
|
|
||
|
protected :
|
||
|
size_t m_block_index;
|
||
|
wxArrayBlockDouble m_blocks;
|
||
|
};
|
||
|
|
||
|
#endif // __wxBLOCK_H__
|