First ButtonHandler refactor
This commit is contained in:
@@ -25,18 +25,14 @@ namespace {
|
||||
const int SEPARATION = 6;
|
||||
}
|
||||
|
||||
ButtonHandler::ButtonHandler(const QVector<CaptureButton*> &v, QObject *parent) :
|
||||
QObject(parent), m_isPartiallyHidden(false), m_buttonsAreInside(false)
|
||||
ButtonHandler::ButtonHandler(const QVector<CaptureButton*> &v, const QRect &limits, QObject *parent) :
|
||||
QObject(parent), m_limits(limits)
|
||||
{
|
||||
if (!v.isEmpty()) {
|
||||
m_buttonBaseSize = v[0]->buttonBaseSize();
|
||||
m_distance = m_buttonBaseSize + SEPARATION;
|
||||
m_vectorButtons = v;
|
||||
}
|
||||
setButtons(v);
|
||||
}
|
||||
|
||||
ButtonHandler::ButtonHandler(QObject *parent) :
|
||||
QObject(parent), m_isPartiallyHidden(false), m_buttonsAreInside(false)
|
||||
ButtonHandler::ButtonHandler(const QRect &limits, QObject *parent) :
|
||||
QObject(parent), m_limits(limits)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -45,42 +41,12 @@ void ButtonHandler::hide() {
|
||||
b->hide();
|
||||
}
|
||||
|
||||
void ButtonHandler::hideSectionUnderMouse(const QPoint &p) {
|
||||
if (m_topRegion.contains(p)) {
|
||||
m_isPartiallyHidden = true;
|
||||
for (CaptureButton *b: m_topButtons)
|
||||
b->hide();
|
||||
} else if (m_bottonRegion.contains(p)) {
|
||||
m_isPartiallyHidden = true;
|
||||
for (CaptureButton *b: m_bottonButtons)
|
||||
b->hide();
|
||||
} else if (m_rightRegion.contains(p)) {
|
||||
m_isPartiallyHidden = true;
|
||||
for (CaptureButton *b: m_rightButtons)
|
||||
b->hide();
|
||||
} else if (m_leftRegion.contains(p)) {
|
||||
m_isPartiallyHidden = true;
|
||||
for (CaptureButton *b: m_leftButtons)
|
||||
b->hide();
|
||||
} else if (m_insideRegion.contains(p)) {
|
||||
m_isPartiallyHidden = true;
|
||||
for (CaptureButton *b: m_insideButtons)
|
||||
b->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonHandler::show() {
|
||||
if (m_isPartiallyHidden) {
|
||||
m_isPartiallyHidden = false;
|
||||
for (CaptureButton *b: m_vectorButtons) {
|
||||
if (b->isHidden()) {
|
||||
b->animatedShow();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (CaptureButton *b: m_vectorButtons)
|
||||
b->animatedShow();
|
||||
if (m_vectorButtons.isEmpty() || m_vectorButtons.first()->isVisible()) {
|
||||
return;
|
||||
}
|
||||
for (CaptureButton *b: m_vectorButtons)
|
||||
b->animatedShow();
|
||||
}
|
||||
|
||||
bool ButtonHandler::isVisible() const {
|
||||
@@ -94,10 +60,6 @@ bool ButtonHandler::isVisible() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ButtonHandler::isPartiallyHidden() const {
|
||||
return m_isPartiallyHidden;
|
||||
}
|
||||
|
||||
bool ButtonHandler::buttonsAreInside() const {
|
||||
return m_buttonsAreInside;
|
||||
}
|
||||
@@ -105,214 +67,151 @@ bool ButtonHandler::buttonsAreInside() const {
|
||||
size_t ButtonHandler::size() const {
|
||||
return m_vectorButtons.size();
|
||||
}
|
||||
|
||||
// updatePosition updates the position of the buttons arround the
|
||||
// selection area. Ignores the sides blocked by the end of the screen.
|
||||
// When the selection is too small it works on a virtual selection with
|
||||
// the original in the center.
|
||||
void ButtonHandler::updatePosition(const QRect &selection,
|
||||
const QRect &limits)
|
||||
{
|
||||
void ButtonHandler::updatePosition(const QRect &selection) {
|
||||
resetRegionTrack();
|
||||
const int vecLength = m_vectorButtons.size();
|
||||
if (vecLength == 0) {
|
||||
return;
|
||||
}
|
||||
// button dimmensions
|
||||
const int baseHeight = m_buttonBaseSize;
|
||||
const int baseWidth = m_buttonBaseSize;
|
||||
// copy of the selection area for internal modifications
|
||||
QRect baseArea = selection;
|
||||
|
||||
// calculates the blocked sides (no more space for buttons)
|
||||
bool blockedRight =
|
||||
(limits.right() - baseArea.right() < SEPARATION*2 + baseWidth);
|
||||
bool blockedLeft =
|
||||
(baseArea.x() < baseWidth + SEPARATION*2);
|
||||
bool blockedBotton =
|
||||
(limits.bottom() - baseArea.bottom() < SEPARATION*2 + baseHeight);
|
||||
bool blockedTop =
|
||||
(baseArea.y() < baseHeight + SEPARATION*2);
|
||||
// copy of the selection area for internal modifications
|
||||
m_selection = selection;
|
||||
|
||||
// detect if a side is smaller than a button in order to prevent collision
|
||||
// and redimension the base area the the base size of a single button per side
|
||||
if (baseArea.width() < baseWidth) {
|
||||
if (blockedRight && !blockedLeft) {
|
||||
baseArea.setX(baseArea.x() - (baseWidth-baseArea.width()));
|
||||
} else if (!blockedLeft && !blockedRight) {
|
||||
if (m_selection.width() < m_buttonBaseSize) {
|
||||
if (m_blockedRight && !m_blockedLeft) {
|
||||
m_selection.setX(m_selection.x() - (m_buttonBaseSize-m_selection.width()));
|
||||
} else if (!m_blockedLeft && !m_blockedRight) {
|
||||
// when not close to the left side (because the rect grows to the right)
|
||||
baseArea.setX(baseArea.x() - (baseWidth-baseArea.width()) / 2);
|
||||
m_selection.setX(m_selection.x() - (m_buttonBaseSize-m_selection.width()) / 2);
|
||||
}
|
||||
baseArea.setWidth(baseWidth);
|
||||
m_selection.setWidth(m_buttonBaseSize);
|
||||
}
|
||||
if (baseArea.height() < baseHeight) {
|
||||
if (blockedBotton && !blockedTop) {
|
||||
baseArea.setY(baseArea.y() - (baseHeight-baseArea.height()));
|
||||
} else if (!blockedTop && !blockedBotton) {
|
||||
if (m_selection.height() < m_buttonBaseSize) {
|
||||
if (m_blockedBotton && !m_blockedTop) {
|
||||
m_selection.setY(m_selection.y() - (m_buttonBaseSize-m_selection.height()));
|
||||
} else if (!m_blockedTop && !m_blockedBotton) {
|
||||
// when not close to the top (because the rect grows to the bottom)
|
||||
baseArea.setY(baseArea.y() - (baseHeight-baseArea.height()) / 2);
|
||||
m_selection.setY(m_selection.y() - (m_buttonBaseSize-m_selection.height()) / 2);
|
||||
}
|
||||
baseArea.setHeight(baseHeight);
|
||||
m_selection.setHeight(m_buttonBaseSize);
|
||||
}
|
||||
// indicates the actual button to be moved
|
||||
int elemIndicator = 0;
|
||||
|
||||
while (elemIndicator < vecLength) {
|
||||
// update of blocked sides
|
||||
blockedRight = (limits.right() - baseArea.right() < SEPARATION * 2 + baseWidth);
|
||||
blockedLeft = (baseArea.x() < baseWidth + SEPARATION * 2);
|
||||
blockedBotton = (limits.bottom() - baseArea.bottom() < SEPARATION * 2 + baseHeight);
|
||||
blockedTop = (baseArea.y() < baseHeight + SEPARATION * 2);
|
||||
// helper booleans
|
||||
bool oneHorizontalBlocked = (!blockedRight && blockedLeft) ||
|
||||
(blockedRight && !blockedLeft);
|
||||
bool horizontalBlocked = (blockedRight && blockedLeft);
|
||||
bool allSidesBlocked = (blockedBotton && horizontalBlocked && blockedTop);
|
||||
updateBlockedSides();
|
||||
|
||||
// add them inside the area when there is no more space
|
||||
if (allSidesBlocked) {
|
||||
QVector<QPoint> positions;
|
||||
int buttonsPerRow = (baseArea.width() - SEPARATION) / (baseWidth + SEPARATION);
|
||||
int xPos = baseArea.left() + SEPARATION;
|
||||
int yPos = baseArea.bottom() - SEPARATION - baseHeight;
|
||||
positions << QPoint(xPos, yPos);
|
||||
for (; elemIndicator < vecLength; ++elemIndicator) {
|
||||
if (elemIndicator % buttonsPerRow == 0 && elemIndicator != 0) {
|
||||
xPos = baseArea.left() + SEPARATION;
|
||||
yPos -= (SEPARATION + baseHeight);
|
||||
}
|
||||
auto button = m_vectorButtons[elemIndicator];
|
||||
m_insideButtons << button;
|
||||
button->move(xPos, yPos);
|
||||
xPos += (SEPARATION + baseWidth);
|
||||
positions << QPoint(xPos, yPos);
|
||||
}
|
||||
addToRegion(positions, INSIDE);
|
||||
m_buttonsAreInside = true;
|
||||
if (m_allSidesBlocked) {
|
||||
positionButtonsInside(elemIndicator);
|
||||
break; // the while
|
||||
}
|
||||
// number of buttons per row column
|
||||
int buttonsPerRow = (baseArea.width() + SEPARATION) / (baseWidth + SEPARATION);
|
||||
int buttonsPerCol = (baseArea.height() + SEPARATION) / (baseHeight + SEPARATION);
|
||||
int buttonsPerRow = (m_selection.width() + SEPARATION) / (m_buttonExtendedSize);
|
||||
int buttonsPerCol = (m_selection.height() + SEPARATION) / (m_buttonExtendedSize);
|
||||
// buttons to be placed in the corners
|
||||
int extraButtons = vecLength - buttonsPerRow*2 - buttonsPerCol*2;
|
||||
int elemsAtCorners = extraButtons > 4 ? 4 : extraButtons;
|
||||
// add buttons at the botton of the seletion
|
||||
if (!blockedBotton) {
|
||||
if (!m_blockedBotton) {
|
||||
int addCounter =
|
||||
(vecLength - elemIndicator < buttonsPerRow) ?
|
||||
vecLength - elemIndicator : buttonsPerRow;
|
||||
if (elemsAtCorners > 2) {
|
||||
int temp = elemsAtCorners - 2;
|
||||
if (oneHorizontalBlocked && temp > 1) {
|
||||
if (m_oneHorizontalBlocked && temp > 1) {
|
||||
temp -= 1;
|
||||
}
|
||||
addCounter += temp;
|
||||
}
|
||||
QPoint center = QPoint(baseArea.center().x(),
|
||||
baseArea.bottom() + SEPARATION);
|
||||
QPoint center = QPoint(m_selection.center().x(),
|
||||
m_selection.bottom() + SEPARATION);
|
||||
if (addCounter > buttonsPerRow) {
|
||||
if (blockedLeft) {
|
||||
center.setX(center.x() + (baseWidth+SEPARATION)/2);
|
||||
} else if (blockedRight) {
|
||||
center.setX(center.x() - (baseWidth+SEPARATION)/2);
|
||||
if (m_blockedLeft) {
|
||||
center.setX(center.x() + m_buttonExtendedSize/2);
|
||||
} else if (m_blockedRight) {
|
||||
center.setX(center.x() - m_buttonExtendedSize/2);
|
||||
}
|
||||
}
|
||||
// elemIndicator, elemsAtCorners
|
||||
QVector<QPoint> positions = horizontalPoints(center, addCounter, true);
|
||||
for (const QPoint &p: positions) {
|
||||
auto button = m_vectorButtons[elemIndicator];
|
||||
m_bottonButtons << button;
|
||||
button->move(p);
|
||||
++elemIndicator;
|
||||
}
|
||||
addToRegion(positions, BOTTON);
|
||||
}
|
||||
// add buttons at the right side of the seletion
|
||||
if (!blockedRight && elemIndicator < vecLength) {
|
||||
if (!m_blockedRight && elemIndicator < vecLength) {
|
||||
int addCounter =
|
||||
(vecLength - elemIndicator < buttonsPerCol) ?
|
||||
vecLength - elemIndicator : buttonsPerCol;
|
||||
|
||||
QPoint center = QPoint(baseArea.right() + SEPARATION,
|
||||
baseArea.center().y());
|
||||
QPoint center = QPoint(m_selection.right() + SEPARATION,
|
||||
m_selection.center().y());
|
||||
QVector<QPoint> positions = verticalPoints(center, addCounter, false);
|
||||
for (const QPoint &p: positions) {
|
||||
auto button = m_vectorButtons[elemIndicator];
|
||||
m_rightButtons << button;
|
||||
button->move(p);
|
||||
++elemIndicator;
|
||||
}
|
||||
addToRegion(positions, RIGHT);
|
||||
}
|
||||
// add buttons at the top of the seletion
|
||||
if (!blockedTop && elemIndicator < vecLength) {
|
||||
if (!m_blockedTop && elemIndicator < vecLength) {
|
||||
int addCounter =
|
||||
(vecLength - elemIndicator < buttonsPerRow) ?
|
||||
vecLength - elemIndicator : buttonsPerRow;
|
||||
|
||||
if (elemsAtCorners > 1 && !horizontalBlocked && !oneHorizontalBlocked) {
|
||||
if (elemsAtCorners > 1 && !m_horizontalyBlocked && !m_oneHorizontalBlocked) {
|
||||
addCounter += 2;
|
||||
} else if ((elemsAtCorners >= 1 &&
|
||||
(!horizontalBlocked || oneHorizontalBlocked))){
|
||||
(!m_horizontalyBlocked || m_oneHorizontalBlocked))){
|
||||
addCounter += 1;
|
||||
}
|
||||
QPoint center = QPoint(baseArea.center().x(),
|
||||
baseArea.top() - (SEPARATION+baseHeight));
|
||||
QPoint center = QPoint(m_selection.center().x(),
|
||||
m_selection.top() - m_buttonExtendedSize);
|
||||
addCounter = qBound(0, addCounter, vecLength - elemIndicator);
|
||||
if (addCounter == 1 + buttonsPerRow) {
|
||||
if (blockedLeft) {
|
||||
center.setX(center.x() + (baseWidth+SEPARATION)/2);
|
||||
} else if (blockedRight) {
|
||||
center.setX(center.x() - (baseWidth+SEPARATION)/2);
|
||||
if (m_blockedLeft) {
|
||||
center.setX(center.x() + m_buttonExtendedSize/2);
|
||||
} else if (m_blockedRight) {
|
||||
center.setX(center.x() - m_buttonExtendedSize/2);
|
||||
}
|
||||
}
|
||||
QVector<QPoint> positions = horizontalPoints(center, addCounter, false);
|
||||
for (const QPoint &p: positions) {
|
||||
auto button = m_vectorButtons[elemIndicator];
|
||||
m_topButtons << button;
|
||||
button->move(p);
|
||||
++elemIndicator;
|
||||
}
|
||||
addToRegion(positions, TOP);
|
||||
}
|
||||
// add buttons at the left side of the seletion
|
||||
if (!blockedLeft && elemIndicator < vecLength) {
|
||||
if (!m_blockedLeft && elemIndicator < vecLength) {
|
||||
int addCounter =
|
||||
(vecLength - elemIndicator < buttonsPerCol) ?
|
||||
vecLength - elemIndicator : buttonsPerCol;
|
||||
|
||||
QPoint center = QPoint(baseArea.left() - (SEPARATION + baseWidth),
|
||||
baseArea.center().y());
|
||||
QPoint center = QPoint(m_selection.left() - m_buttonExtendedSize,
|
||||
m_selection.center().y());
|
||||
QVector<QPoint> positions = verticalPoints(center, addCounter, true);
|
||||
for (const QPoint &p: positions) {
|
||||
auto button = m_vectorButtons[elemIndicator];
|
||||
m_leftButtons << button;
|
||||
button->move(p);
|
||||
++elemIndicator;
|
||||
}
|
||||
addToRegion(positions, LEFT);
|
||||
}
|
||||
// if there are elements for the next cycle, increase the size of the base area
|
||||
if (elemIndicator < vecLength &&
|
||||
!(allSidesBlocked))
|
||||
!(m_allSidesBlocked))
|
||||
{
|
||||
if (blockedRight && !blockedLeft) {
|
||||
baseArea.setX(baseArea.x() - (baseWidth + SEPARATION));
|
||||
} else if (!blockedRight && !blockedLeft) {
|
||||
baseArea.setX(baseArea.x() - (baseWidth + SEPARATION));
|
||||
baseArea.setWidth(baseArea.width() + (baseWidth + SEPARATION));
|
||||
} else {
|
||||
baseArea.setWidth(baseArea.width() + (baseWidth + SEPARATION));
|
||||
}
|
||||
|
||||
if (blockedBotton && !blockedTop) {
|
||||
baseArea.setY(baseArea.y() - (baseHeight + SEPARATION));
|
||||
} else if (!blockedTop && !blockedBotton) {
|
||||
baseArea.setY(baseArea.y() - (baseHeight + SEPARATION));
|
||||
baseArea.setHeight(baseArea.height() + (baseHeight + SEPARATION));
|
||||
} else {
|
||||
baseArea.setHeight(baseArea.height() + (baseHeight + SEPARATION));
|
||||
}
|
||||
expandSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,9 +226,9 @@ QVector<QPoint> ButtonHandler::horizontalPoints(
|
||||
// distance from the center to start adding buttons
|
||||
int shift = 0;
|
||||
if (elements % 2 == 0) {
|
||||
shift = m_distance * (elements / 2) - (SEPARATION / 2);
|
||||
shift = m_buttonExtendedSize * (elements / 2) - (SEPARATION / 2);
|
||||
} else {
|
||||
shift = m_distance * ((elements-1) / 2) + m_buttonBaseSize / 2;
|
||||
shift = m_buttonExtendedSize * ((elements-1) / 2) + m_buttonBaseSize / 2;
|
||||
}
|
||||
if (!leftToRight) { shift -= m_buttonBaseSize; }
|
||||
int x = leftToRight ? center.x() - shift :
|
||||
@@ -337,8 +236,8 @@ QVector<QPoint> ButtonHandler::horizontalPoints(
|
||||
QPoint i(x, center.y());
|
||||
while (elements > res.length()) {
|
||||
res.append(i);
|
||||
leftToRight ? i.setX(i.x() + m_distance) :
|
||||
i.setX(i.x() - m_distance);
|
||||
leftToRight ? i.setX(i.x() + m_buttonExtendedSize) :
|
||||
i.setX(i.x() - m_buttonExtendedSize);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -347,15 +246,15 @@ QVector<QPoint> ButtonHandler::horizontalPoints(
|
||||
// starts from a known center and keeps adding elements vertically
|
||||
// and returns the computed positions.
|
||||
QVector<QPoint> ButtonHandler::verticalPoints(
|
||||
const QPoint ¢er, const int elements,const bool upToDown) const
|
||||
const QPoint ¢er, const int elements, const bool upToDown) const
|
||||
{
|
||||
QVector<QPoint> res;
|
||||
// distance from the center to start adding buttons
|
||||
int shift = 0;
|
||||
if (elements % 2 == 0) {
|
||||
shift = m_distance * (elements / 2) - (SEPARATION / 2);
|
||||
shift = m_buttonExtendedSize * (elements / 2) - (SEPARATION / 2);
|
||||
} else {
|
||||
shift = m_distance * ((elements-1) / 2) + m_buttonBaseSize / 2;
|
||||
shift = m_buttonExtendedSize * ((elements-1) / 2) + m_buttonBaseSize / 2;
|
||||
}
|
||||
if (!upToDown) { shift -= m_buttonBaseSize; }
|
||||
int y = upToDown ? center.y() - shift :
|
||||
@@ -363,70 +262,87 @@ QVector<QPoint> ButtonHandler::verticalPoints(
|
||||
QPoint i(center.x(), y);
|
||||
while (elements > res.length()) {
|
||||
res.append(i);
|
||||
upToDown ? i.setY(i.y() + m_distance) :
|
||||
i.setY(i.y() - m_distance);
|
||||
upToDown ? i.setY(i.y() + m_buttonExtendedSize) :
|
||||
i.setY(i.y() - m_buttonExtendedSize);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void ButtonHandler::addToRegion(const QVector<QPoint> &points, const side side) {
|
||||
if (points.isEmpty())
|
||||
void ButtonHandler::resetRegionTrack() {
|
||||
m_buttonsAreInside = false;
|
||||
}
|
||||
|
||||
void ButtonHandler::updateBlockedSides() {
|
||||
m_blockedRight =
|
||||
(m_limits.right() - m_selection.right() < SEPARATION*2 + m_buttonBaseSize);
|
||||
m_blockedLeft =
|
||||
(m_selection.x() < m_buttonBaseSize + SEPARATION*2);
|
||||
m_blockedBotton =
|
||||
(m_limits.bottom() - m_selection.bottom() < SEPARATION*2 + m_buttonBaseSize);
|
||||
m_blockedTop =
|
||||
(m_selection.y() < m_buttonBaseSize + SEPARATION*2);
|
||||
m_oneHorizontalBlocked = (!m_blockedRight && m_blockedLeft) ||
|
||||
(m_blockedRight && !m_blockedLeft);
|
||||
m_horizontalyBlocked = (m_blockedRight && m_blockedLeft);
|
||||
m_allSidesBlocked = (m_blockedBotton && m_horizontalyBlocked && m_blockedTop);
|
||||
}
|
||||
|
||||
void ButtonHandler::expandSelection() {
|
||||
if (m_blockedRight && !m_blockedLeft) {
|
||||
m_selection.setX(m_selection.x() - m_buttonExtendedSize);
|
||||
} else if (!m_blockedRight && !m_blockedLeft) {
|
||||
m_selection.setX(m_selection.x() - m_buttonExtendedSize);
|
||||
m_selection.setWidth(m_selection.width() + m_buttonExtendedSize);
|
||||
} else {
|
||||
m_selection.setWidth(m_selection.width() + m_buttonExtendedSize);
|
||||
}
|
||||
|
||||
if (m_blockedBotton && !m_blockedTop) {
|
||||
m_selection.setY(m_selection.y() - m_buttonExtendedSize);
|
||||
} else if (!m_blockedTop && !m_blockedBotton) {
|
||||
m_selection.setY(m_selection.y() - m_buttonExtendedSize);
|
||||
m_selection.setHeight(m_selection.height() + m_buttonExtendedSize);
|
||||
} else {
|
||||
m_selection.setHeight(m_selection.height() + m_buttonExtendedSize);
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonHandler::positionButtonsInside(int index) {
|
||||
int xPos = m_selection.left() + SEPARATION;
|
||||
int yPos = m_selection.bottom() - m_buttonExtendedSize;
|
||||
CaptureButton *button = nullptr;
|
||||
for (; index < m_vectorButtons.size(); ++index) {
|
||||
button = m_vectorButtons[index];
|
||||
button->move(xPos, yPos);
|
||||
if (button->pos().x() + m_buttonExtendedSize) {
|
||||
xPos = m_selection.left() + SEPARATION;
|
||||
yPos -= (m_buttonExtendedSize);
|
||||
}
|
||||
xPos += (m_buttonExtendedSize);
|
||||
}
|
||||
m_buttonsAreInside = true;
|
||||
}
|
||||
|
||||
// setButtons redefines the buttons of the button handler
|
||||
void ButtonHandler::setButtons(const QVector<CaptureButton *> v) {
|
||||
if (v.isEmpty())
|
||||
return;
|
||||
|
||||
QPoint first(points.first());
|
||||
QPoint last(points.last());
|
||||
for (CaptureButton *b: m_vectorButtons)
|
||||
delete(b);
|
||||
m_vectorButtons = v;
|
||||
m_buttonBaseSize = v[0]->buttonBaseSize();
|
||||
m_buttonExtendedSize = m_buttonBaseSize + SEPARATION;
|
||||
}
|
||||
|
||||
bool ButtonHandler::contains(const QPoint &p) const {
|
||||
QPoint first(m_vectorButtons.first()->pos());
|
||||
QPoint last(m_vectorButtons.last()->pos());
|
||||
bool firstIsTopLeft = (first.x() <= last.x() && first.y() <= last.y());
|
||||
QPoint topLeft = firstIsTopLeft ? first : last;
|
||||
QPoint bottonRight = firstIsTopLeft ? last : first;
|
||||
topLeft += QPoint(-SEPARATION, -SEPARATION);
|
||||
bottonRight += QPoint(m_distance, m_distance);
|
||||
switch (side) {
|
||||
case LEFT:
|
||||
m_leftRegion += QRegion(QRect(topLeft, bottonRight).normalized());
|
||||
break;
|
||||
case RIGHT:
|
||||
m_rightRegion += QRegion(QRect(topLeft, bottonRight).normalized());
|
||||
break;
|
||||
case TOP:
|
||||
m_topRegion += QRegion(QRect(topLeft, bottonRight).normalized());
|
||||
break;
|
||||
case BOTTON:
|
||||
m_bottonRegion += QRegion(QRect(topLeft, bottonRight).normalized());
|
||||
break;
|
||||
case INSIDE:
|
||||
m_insideRegion += QRegion(QRect(topLeft, bottonRight).normalized());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ButtonHandler::resetRegionTrack() {
|
||||
m_buttonsAreInside = false;
|
||||
m_topButtons.clear();
|
||||
m_bottonButtons.clear();
|
||||
m_leftButtons.clear();
|
||||
m_rightButtons.clear();
|
||||
|
||||
m_topRegion = QRegion();
|
||||
m_bottonRegion = QRegion();
|
||||
m_leftRegion = QRegion();
|
||||
m_rightRegion = QRegion();
|
||||
m_insideRegion = QRegion();
|
||||
}
|
||||
// setButtons redefines the buttons of the button handler
|
||||
void ButtonHandler::setButtons(const QVector<CaptureButton *> v) {
|
||||
for (CaptureButton *b: m_vectorButtons)
|
||||
delete(b);
|
||||
m_vectorButtons = v;
|
||||
if (!v.isEmpty()) {
|
||||
m_buttonBaseSize = v[0]->buttonBaseSize();
|
||||
m_distance = m_buttonBaseSize + SEPARATION;
|
||||
}
|
||||
}
|
||||
|
||||
bool ButtonHandler::contains(const QPoint &p) const {
|
||||
return m_leftRegion.contains(p) || m_rightRegion.contains(p)
|
||||
|| m_topRegion.contains(p) || m_bottonRegion.contains(p)
|
||||
|| m_insideRegion.contains(p);
|
||||
bottonRight += QPoint(m_buttonExtendedSize, m_buttonExtendedSize);
|
||||
QRegion r(QRect(topLeft, bottonRight).normalized());
|
||||
return r.contains(p);
|
||||
}
|
||||
|
||||
@@ -29,17 +29,16 @@ class QPoint;
|
||||
class ButtonHandler : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ButtonHandler(const QVector<CaptureButton*>&, QObject *parent = nullptr);
|
||||
ButtonHandler(QObject *parent = nullptr);
|
||||
ButtonHandler(const QVector<CaptureButton*>&, const QRect &limits, QObject *parent = nullptr);
|
||||
ButtonHandler(const QRect &limits, QObject *parent = nullptr);
|
||||
|
||||
void hideSectionUnderMouse(const QPoint &p);
|
||||
|
||||
bool isVisible() const;
|
||||
bool isPartiallyHidden() const;
|
||||
bool buttonsAreInside() const;
|
||||
size_t size() const;
|
||||
|
||||
void updatePosition(const QRect &selection, const QRect &limits);
|
||||
void updatePosition(const QRect &selection);
|
||||
void setButtons(const QVector<CaptureButton*>);
|
||||
bool contains(const QPoint &p) const;
|
||||
|
||||
@@ -55,32 +54,26 @@ private:
|
||||
|
||||
QVector<CaptureButton*> m_vectorButtons;
|
||||
|
||||
QVector<CaptureButton*> m_topButtons;
|
||||
QVector<CaptureButton*> m_bottonButtons;
|
||||
QVector<CaptureButton*> m_leftButtons;
|
||||
QVector<CaptureButton*> m_rightButtons;
|
||||
QVector<CaptureButton*> m_insideButtons;
|
||||
QVector<CaptureButton*> * m_hiddenButtonVector;
|
||||
|
||||
QRegion m_topRegion;
|
||||
QRegion m_bottonRegion;
|
||||
QRegion m_leftRegion;
|
||||
QRegion m_rightRegion;
|
||||
QRegion m_insideRegion;
|
||||
|
||||
bool m_isPartiallyHidden;
|
||||
|
||||
enum side {
|
||||
TOP, LEFT, BOTTON, RIGHT, INSIDE, NONE
|
||||
};
|
||||
|
||||
int m_distance;
|
||||
int m_buttonExtendedSize;
|
||||
int m_buttonBaseSize;
|
||||
|
||||
bool m_buttonsAreInside;
|
||||
bool m_blockedRight;
|
||||
bool m_blockedLeft;
|
||||
bool m_blockedBotton;
|
||||
bool m_blockedTop;
|
||||
bool m_oneHorizontalBlocked;
|
||||
bool m_horizontalyBlocked;
|
||||
bool m_allSidesBlocked;
|
||||
|
||||
QRect m_limits;
|
||||
QRect m_selection;
|
||||
|
||||
// aux methods
|
||||
void addToRegion(const QVector<QPoint> &points, const side s);
|
||||
void resetRegionTrack();
|
||||
void updateBlockedSides();
|
||||
void expandSelection();
|
||||
void positionButtonsInside(int index);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ CaptureWidget::CaptureWidget(const uint id, const QString &forcedSavePath,
|
||||
setGeometry(0 ,0 , size.width()+1, size.height()+1);
|
||||
|
||||
// create buttons
|
||||
m_buttonHandler = new ButtonHandler(this);
|
||||
m_buttonHandler = new ButtonHandler(rect(), this);
|
||||
updateButtons();
|
||||
m_buttonHandler->hide();
|
||||
// init interface color
|
||||
@@ -344,12 +344,12 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||
// drawing with a tool
|
||||
m_modifications.last()->addPoint(e->pos());
|
||||
update();
|
||||
// hides the group of buttons under the mouse, if you leave
|
||||
// Hides the buttons under the mouse. If the mouse leaves, it shows them.
|
||||
if (m_buttonHandler->buttonsAreInside()) {
|
||||
bool containsMouse = m_buttonHandler->contains(m_mousePos);
|
||||
const bool containsMouse = m_buttonHandler->contains(m_mousePos);
|
||||
if (containsMouse) {
|
||||
m_buttonHandler->hideSectionUnderMouse(e->pos());
|
||||
} else if (m_buttonHandler->isPartiallyHidden()) {
|
||||
m_buttonHandler->hide();
|
||||
} else {
|
||||
m_buttonHandler->show();
|
||||
}
|
||||
}
|
||||
@@ -387,7 +387,7 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
|
||||
if (!m_buttonHandler->isVisible() && !m_selection.isNull()) {
|
||||
updateSizeIndicator();
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
m_buttonHandler->show();
|
||||
}
|
||||
m_mouseIsClicked = false;
|
||||
@@ -403,25 +403,25 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) {
|
||||
} else if (e->key() == Qt::Key_Up
|
||||
&& m_selection.top() > rect().top()) {
|
||||
m_selection.moveTop(m_selection.top()-1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateHandles();
|
||||
update();
|
||||
} else if (e->key() == Qt::Key_Down
|
||||
&& m_selection.bottom() < rect().bottom()) {
|
||||
m_selection.moveBottom(m_selection.bottom()+1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateHandles();
|
||||
update();
|
||||
} else if (e->key() == Qt::Key_Left
|
||||
&& m_selection.left() > rect().left()) {
|
||||
m_selection.moveLeft(m_selection.left()-1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateHandles();
|
||||
update();
|
||||
} else if (e->key() == Qt::Key_Right
|
||||
&& m_selection.right() < rect().right()) {
|
||||
m_selection.moveRight(m_selection.right()+1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateHandles();
|
||||
update();
|
||||
}
|
||||
@@ -518,7 +518,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) {
|
||||
void CaptureWidget::leftResize() {
|
||||
if (!m_selection.isNull() && m_selection.right() > m_selection.left()) {
|
||||
m_selection.setRight(m_selection.right()-1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateSizeIndicator();
|
||||
updateHandles();
|
||||
update();
|
||||
@@ -528,7 +528,7 @@ void CaptureWidget::leftResize() {
|
||||
void CaptureWidget::rightResize() {
|
||||
if (!m_selection.isNull() && m_selection.right() < rect().right()) {
|
||||
m_selection.setRight(m_selection.right()+1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateSizeIndicator();
|
||||
updateHandles();
|
||||
update();
|
||||
@@ -538,7 +538,7 @@ void CaptureWidget::rightResize() {
|
||||
void CaptureWidget::upResize() {
|
||||
if (!m_selection.isNull() && m_selection.bottom() > m_selection.top()) {
|
||||
m_selection.setBottom(m_selection.bottom()-1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateSizeIndicator();
|
||||
updateHandles();
|
||||
update();
|
||||
@@ -548,7 +548,7 @@ void CaptureWidget::upResize() {
|
||||
void CaptureWidget::downResize() {
|
||||
if (!m_selection.isNull() && m_selection.bottom() < rect().bottom()) {
|
||||
m_selection.setBottom(m_selection.bottom()+1);
|
||||
m_buttonHandler->updatePosition(m_selection, rect());
|
||||
m_buttonHandler->updatePosition(m_selection);
|
||||
updateSizeIndicator();
|
||||
updateHandles();
|
||||
update();
|
||||
|
||||
Reference in New Issue
Block a user