Skip to content

Commit

Permalink
better multi-monitor support for capture selection
Browse files Browse the repository at this point in the history
  • Loading branch information
olav-st committed Mar 18, 2014
1 parent 87d487e commit fa02d5c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 53 deletions.
93 changes: 70 additions & 23 deletions screencloud/src/gui-elements/selectionoverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,24 @@ SelectionOverlay::SelectionOverlay(QWidget *parent) :
rbDistX = 0;
rbDistY = 0;
drawingRubberBand = resizingRubberBand = movingRubberBand = false;
currentScreenNumber = QApplication::desktop()->screenNumber(QCursor::pos());
moveToScreen(currentScreenNumber);
setMouseTracking(true);
//Set mau5 cursor
setCursor(crossShape);
}
SelectionOverlay::~SelectionOverlay()
{

}


void SelectionOverlay::setScreenshot(QPixmap& screenshot)
{
this->screenshot = screenshot;
selection = QRect(0,0,0,0);
drawingRubberBand = resizingRubberBand = movingRubberBand = false;
startedDrawingRubberBand = false;
releaseMouse();
releaseKeyboard();
}

void SelectionOverlay::mousePressEvent(QMouseEvent *event)
{
this->activateWindow();
//Stop the overlay from drawing help text
startedDrawingRubberBand = true;
QPoint mousePos = event->pos();
//Check if the mau5 is over the rubber band
//Check if the mouse is over the rubber band
if(checkMouseOverRubberBand(mousePos) == MOUSE_OVER_INSIDE)
{
movingRubberBand = true;
Expand Down Expand Up @@ -85,34 +79,37 @@ void SelectionOverlay::mouseReleaseEvent(QMouseEvent *event)
}
void SelectionOverlay::mouseMoveEvent(QMouseEvent *event)
{
//Check if the mau5 is over the rubber band
//Check if the mouse is over the rubber band
QPoint mousePos = event->pos();
if(checkMouseOverRubberBand(mousePos) == MOUSE_OVER_INSIDE)
{
//Mouse is over rubber band
if(!drawingRubberBand && !movingRubberBand && !resizingRubberBand)
{
setCursor(openHandShape);
}else if(movingRubberBand)
{
setCursor(closedHandShape);
}
}
//If the mau5 is on the left side of the rubberband
else if(!movingRubberBand && !drawingRubberBand && !resizingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_LEFT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_RIGHT))
//If the mouse is on the left side of the rubberband
else if(!movingRubberBand && !drawingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_LEFT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_RIGHT))
{
setCursor(horizontalShape);
}
else if(!movingRubberBand && !drawingRubberBand && !resizingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOP || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOM))
else if(!movingRubberBand && !drawingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOP || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOM))
{
setCursor(verticalShape);
}
else if(!movingRubberBand && !drawingRubberBand && !resizingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOPLEFT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOMRIGHT))
else if(!movingRubberBand && !drawingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOPLEFT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOMRIGHT))
{
setCursor(leftDiagonalShape);
}
else if(!movingRubberBand && !drawingRubberBand && !resizingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOPRIGHT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOMLEFT))
else if(!movingRubberBand && !drawingRubberBand && (checkMouseOverRubberBand(mousePos) == MOUSE_OVER_TOPRIGHT || checkMouseOverRubberBand(mousePos) == MOUSE_OVER_BOTTOMLEFT))
{
setCursor(rightDiagonalShape);
}
else if(!drawingRubberBand && !resizingRubberBand)
else if(!movingRubberBand && !resizingRubberBand)
{
setCursor(crossShape);
}
Expand All @@ -125,6 +122,7 @@ void SelectionOverlay::mouseMoveEvent(QMouseEvent *event)
{
selRectEnd = event->pos();
selection = QRect(selRectStart, selRectEnd).normalized();
selection = selection.intersected(this->rect());
}
if(event->buttons() == Qt::LeftButton && resizingRubberBand)
{
Expand Down Expand Up @@ -227,6 +225,7 @@ void SelectionOverlay::mouseMoveEvent(QMouseEvent *event)
{
this->repaint();
}
selection = selection.intersected(this->rect());
}

void SelectionOverlay::keyReleaseEvent(QKeyEvent *event)
Expand All @@ -237,8 +236,16 @@ void SelectionOverlay::keyReleaseEvent(QKeyEvent *event)
emit selectionDone(selection, screenshot);
}else if(event->matches(QKeySequence::Quit) || event->key() == Qt::Key_Escape)
{
emit selectionCanceled();
this->close();
}else if(event->key() == Qt::Key_Left || event->key() == Qt::Key_A)
{
this->moveToScreen(currentScreenNumber + 1);
}else if(event->key() == Qt::Key_Right || event->key() == Qt::Key_D)
{
this->moveToScreen(currentScreenNumber - 1);
}
QWidget::keyReleaseEvent(event);
}

void SelectionOverlay::checkIfRubberBandOutOfBounds()
Expand Down Expand Up @@ -404,19 +411,55 @@ void SelectionOverlay::drawHelpText(QPainter *painter,const QColor &bgColor, con
QFont d;
QFont f(d.defaultFamily(), 22, QFont::Normal);
painter->setFont(f);
QRect helpTextRect = QRect(0, 0, 620, 100);
QRect primaryScreenRect = QApplication::desktop()->screenGeometry(QApplication::desktop()->primaryScreen());
helpTextRect.moveCenter(this->mapFromGlobal(primaryScreenRect.center()));
QRect helpTextRect = QRect( 0, 0, 620, 100);
QString helpText = tr("Draw a a rectangular area using the mouse.\nPress Enter to take a screenshot or Esc to exit.");
if(QApplication::desktop()->screenCount() > 1)
{
helpText.append(tr("\nUse the arrow keys to switch between screens."));
helpTextRect.setWidth(helpTextRect.width() + 30);
helpTextRect.setHeight(helpTextRect.height() + 30);
}
helpTextRect.moveCenter(this->mapFromGlobal(QApplication::desktop()->screenGeometry(currentScreenNumber).center()));
painter->setBrush(roundedRectBrush);
painter->setPen(roundedRectPen);
painter->drawRoundedRect(helpTextRect, 10.0, 10.0);
painter->setBrush(textBrush);
painter->setPen(QPen(textBrush, 1.0));
painter->drawText(helpTextRect, Qt::AlignCenter, tr("Draw a a rectangular area using the mouse.\nPress enter to take a screenshot or esc to exit."));
painter->drawText(helpTextRect, Qt::AlignCenter, helpText);
painter->restore();
}
}

void SelectionOverlay::moveToScreen(int screenNumber)
{
if(screenNumber < 0)
{
screenNumber = QApplication::desktop()->screenCount() -1;
}else if(screenNumber >= QApplication::desktop()->screenCount())
{
screenNumber = 0;
}
currentScreenNumber = screenNumber;
QRect screenGeom = QApplication::desktop()->screenGeometry(currentScreenNumber);
screenshot = QPixmap::grabWindow(QApplication::desktop()->winId(), screenGeom.x(), screenGeom.y(), screenGeom.width(), screenGeom.height());
setGeometry(screenGeom);
selection = QRect(0,0,0,0);
drawingRubberBand = resizingRubberBand = movingRubberBand = false;
startedDrawingRubberBand = false;
this->resetRubberBand();
if(this->isVisible())
{
this->hide();
this->showFullScreen();
}
}

void SelectionOverlay::showEvent(QShowEvent *e)
{
grabKeyboard();
grabMouse();
}

void SelectionOverlay::hideEvent(QHideEvent *e)
{
releaseMouse();
Expand All @@ -438,20 +481,24 @@ void SelectionOverlay::resizeLeft(QPoint &mousePos, QRect &rbGeometryBeforeResiz
{
selection.moveTo(mousePos.x(), selection.y());
selection.setSize(QSize(rbGeometryBeforeResize.width() - (mousePos.x()- rbGeometryBeforeResize.x()), selection.height()));
selection = selection.intersected(this->rect());
}

void SelectionOverlay::resizeTop(QPoint &mousePos, QRect &rbGeometryBeforeResize)
{
selection.moveTo(selection.x(), mousePos.y());
selection.setSize(QSize(selection.width(), rbGeometryBeforeResize.height() - (mousePos.y()- rbGeometryBeforeResize.y())));
selection = selection.intersected(this->rect());
}

void SelectionOverlay::resizeRight(QPoint &mousePos, QRect &rbGeometryBeforeResize)
{
selection.setSize(QSize(mousePos.x() - rbGeometryBeforeResize.x() , selection.height()));
selection = selection.intersected(this->rect());
}

void SelectionOverlay::resizeBottom(QPoint &mousePos, QRect &rbGeometryBeforeResize)
{
selection.setSize(QSize(selection.width(), mousePos.y() - rbGeometryBeforeResize.y()));
selection = selection.intersected(this->rect());
}
7 changes: 6 additions & 1 deletion screencloud/src/gui-elements/selectionoverlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@ class SelectionOverlay : public QWidget
public:
explicit SelectionOverlay(QWidget *parent = 0);
virtual ~SelectionOverlay();
void setScreenshot(QPixmap &screenshot);
void checkIfRubberBandOutOfBounds();
int checkMouseOverRubberBand(QPoint& mousePos);
void resetRubberBand();
void drawOverlay(QPainter *painter, const QColor &color);
void drawRubberband(QPainter* painter, const QRect& rect, const QColor& color, int lineSize);
void drawHandles(QPainter* painter, const QRect& rect, const QColor& color, int lineSize, int handleSize);
void drawHelpText(QPainter *painter, const QColor &bgColor, const QColor &textColor);
void moveToScreen(int screenNumber);

protected:
void showEvent(QShowEvent *e);
void hideEvent(QHideEvent *e);
void paintEvent(QPaintEvent* pe);
void mousePressEvent(QMouseEvent* event);
Expand All @@ -69,6 +71,8 @@ class SelectionOverlay : public QWidget

signals:
void selectionDone(QRect& area, QPixmap& screenshot);
void selectionCanceled();
void currentScreenChanged(int newScreenNumber);

private:
//Cursors
Expand All @@ -85,6 +89,7 @@ class SelectionOverlay : public QWidget
bool drawingRubberBand, movingRubberBand, resizingRubberBand, startedDrawingRubberBand;
int resizingFrom;
int rbDistX, rbDistY;
int currentScreenNumber;

public slots:

Expand Down
38 changes: 12 additions & 26 deletions screencloud/src/systemtrayicon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
SystemTrayIcon::SystemTrayIcon(QObject *parent, QString color) :
QSystemTrayIcon(parent)
{
overlay = NULL;
setToolTip("ScreenCloud - Idle");
connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
// load icon
Expand Down Expand Up @@ -80,7 +79,6 @@ SystemTrayIcon::~SystemTrayIcon()
delete preferencesAct;
delete quitAct;
delete askMeAct;
delete overlay;
delete prefDialog;
}

Expand Down Expand Up @@ -349,6 +347,12 @@ void SystemTrayIcon::captureSelection(QRect &rect, QPixmap &fullScreenShot)
{
saveScreenshot();
}
capturing = false;
}

void SystemTrayIcon::selectionCanceled()
{
capturing = false;
}

void SystemTrayIcon::captureWindow()
Expand Down Expand Up @@ -405,37 +409,19 @@ void SystemTrayIcon::quitApplication()

void SystemTrayIcon::openSelectionOverlay()
{
if(overlay == NULL)
{
overlay = new SelectionOverlay();
}
if(!overlay->isVisible())
SelectionOverlay* overlay = new SelectionOverlay();
overlay->setAttribute(Qt::WA_DeleteOnClose);
if(!capturing)
{
overlay->resetRubberBand();
//Set attributes for fullscreen
overlay->setFocusPolicy( Qt::StrongFocus );
overlay->setWindowFlags( overlay->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
if(QApplication::desktop()->screenCount() > 1)
{
overlay->setWindowFlags(overlay->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
}
overlay->setWindowFlags( overlay->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool);
overlay->setWindowState(Qt::WindowFullScreen | Qt::WindowActive);
//Figure out which screen we want to use
QRect screenGeom = QApplication::desktop()->geometry();
//Grab a full screenshot to work with
fullScreenshot = QPixmap::grabWindow(QApplication::desktop()->winId(), screenGeom.x(), screenGeom.y(), screenGeom.width(), screenGeom.height());
//Show the fullScreenshot in fullscreen with an overlay
overlay->setScreenshot(fullScreenshot);
//Move the widget to the screen where the mouse is and resize it
overlay->showFullScreen();
overlay->setGeometry(screenGeom);
overlay->resize(screenGeom.width(), screenGeom.height());
connect(overlay, SIGNAL(selectionDone(QRect&, QPixmap&)), this, SLOT(captureSelection(QRect&, QPixmap&)));
if(QApplication::desktop()->screenCount() > 1)
{
overlay->grabKeyboard();
overlay->grabMouse();
}
connect(overlay, SIGNAL(selectionCanceled()), this, SLOT(selectionCanceled()));
capturing = true;
}
}

Expand Down
5 changes: 2 additions & 3 deletions screencloud/src/systemtrayicon.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ class SystemTrayIcon : public QSystemTrayIcon
QIcon systrayIconSelected;
#endif
QMap<QString, QAction*> submenuActions; //Key is uploaders shortname
QPixmap fullScreenshot;
SelectionOverlay* overlay;
int screenshotDelay;
//systray menu actions
QAction* openDashboardAct;
Expand All @@ -89,7 +87,7 @@ class SystemTrayIcon : public QSystemTrayIcon
QxtGlobalShortcut* hotkeySelection;
QxtGlobalShortcut* hotkeyWindow;
bool showSaveDialog;
bool uploading;
bool uploading, capturing;
bool showNotifications;
Updater updater;
bool autoCheckUpdates;
Expand All @@ -104,6 +102,7 @@ private slots:
void captureWindowAction();
void captureFullScreen();
void captureSelection(QRect& rect, QPixmap& fullScreenshot);
void selectionCanceled();
void captureWindow();
void saveScreenshot(QString name = "", QString uploaderShortname = "");
void openPreferencesWindow();
Expand Down

0 comments on commit fa02d5c

Please sign in to comment.