1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/*
VeroRoute - Qt based Veroboard/Perfboard/PCB layout & routing application.
Copyright (C) 2017 Alex Lawrow ( dralx@users.sourceforge.net )
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "Rect.h"
class RectManager : public Persist
{
public:
RectManager() {}
virtual ~RectManager() {}
void Clear() { m_startRow = m_startCol = 0; m_current.SetInvalid(); m_bounding.SetInvalid(); m_list.clear(); }
RectManager(const RectManager& o) { *this = o; }
RectManager& operator=(const RectManager& o)
{
m_startRow = o.m_startRow;
m_startCol = o.m_startCol;
m_current = o.m_current;
m_bounding = o.m_bounding;
m_list.clear();
for (const auto& oo : o.m_list) m_list.push_back( oo );
return *this;
}
bool operator==(const RectManager& o) const // Compare persisted info
{
bool bOK = m_startRow == o.m_startRow
&& m_startCol == o.m_startCol
&& m_current == o.m_current
&& m_bounding == o.m_bounding
&& GetSize() == o.GetSize();
auto iter1 = m_list.begin();
auto iter2 = o.m_list.begin();
while( iter1 != m_list.end() && bOK )
{
bOK = ( *iter1 == *iter2 );
++iter1; ++iter2;
}
return bOK;
}
bool operator!=(const RectManager& o) const
{
return !(*this == o);
}
void StartNewRect(int row, int col)
{
m_current.m_rowMin = m_current.m_rowMax = m_startRow = row;
m_current.m_colMin = m_current.m_colMax = m_startCol = col;
}
void UpdateNewRect(int row, int col)
{
m_current.m_rowMin = std::min(m_startRow, row);
m_current.m_rowMax = std::max(m_startRow, row);
m_current.m_colMin = std::min(m_startCol, col);
m_current.m_colMax = std::max(m_startCol, col);
}
void EndNewRect() { Add(m_current); m_current.SetInvalid(); } // Update list
size_t GetSize() const { return m_list.size(); }
Rect& GetCurrent() const { return m_current; }
Rect& GetBounding() const { return m_bounding; }
// Rect& GetAt(size_t i) { return m_list[i]; }
bool ContainsPoint(int row, int col) const
{
if ( m_current.ContainsPoint(row, col) ) return true; // Check current before the list
if ( !m_bounding.ContainsPoint(row, col) ) return false; // Check bounding rect of the list first
for (const auto& o : m_list) if ( o.ContainsPoint(row,col) ) return true;
return false;
}
bool Overlaps(const Rect& r) const
{
if ( m_current.Overlaps(r) ) return true; // Check current before the list
if ( !m_bounding.Overlaps(r) ) return false; // Check bounding rect of the list first
for (const auto& o : m_list) if ( o.Overlaps(r) ) return true;
return false;
}
void MoveAll(int iDown, int iRight)
{
m_startRow += iDown;
m_startCol += iRight;
m_current.Move(iDown, iRight);
m_bounding.Move(iDown,iRight);
for (auto& rect : m_list)
rect.Move(iDown, iRight);
}
// Persist interface functions
virtual void Load(DataStream& inStream) override
{
Clear();
inStream.Load(m_startRow);
inStream.Load(m_startCol);
m_current.Load(inStream);
if ( inStream.GetVersion() >= VRT_VERSION_11 )
m_bounding.Load(inStream);
unsigned int iSize(0);
inStream.Load(iSize);
Rect entry;
for (unsigned int i = 0; i < iSize; i++)
{
entry.Load(inStream);
m_list.push_back(entry);
}
}
virtual void Save(DataStream& outStream) override
{
outStream.Save(m_startRow);
outStream.Save(m_startCol);
m_current.Save(outStream);
m_bounding.Save(outStream); // Added in VRT_VERSION_11
const unsigned int iSize = static_cast<unsigned int>( GetSize() );
outStream.Save(iSize);
for (auto& rect : m_list)
rect.Save(outStream);
}
private:
void Add(const Rect& rect)
{
if ( !rect.GetIsValid() ) return;
m_list.push_back(rect); std::sort(m_list.begin(), m_list.end());
m_bounding |= rect; // Update bounding rectangle
}
private:
int m_startRow = 0;
int m_startCol = 0;
mutable Rect m_current; // The rectangle currently being defined by the user
mutable Rect m_bounding; // The bounding rectangle of m_list
std::vector<Rect> m_list; // The list of completed rectangles
};
|