NewMainWindow resizing

.. frameless window so we need to do it all ourselves.
   Works ok, so time to move onto titlebar with Mac.
This commit is contained in:
Mark Liversedge
2020-03-31 19:54:30 +01:00
parent b3f35597d3
commit 18922e1316
2 changed files with 186 additions and 12 deletions

View File

@@ -9,12 +9,13 @@
constexpr double gl_minwidth = 1024;
constexpr double gl_minheight = 768;
constexpr double gl_toolbarheight = 50;
constexpr double gl_searchwidth = 350;
constexpr double gl_searchwidth = 500;
constexpr double gl_searchheight = 38;
constexpr double gl_quitheight = 38;
constexpr double gl_quitwidth = 38;
constexpr double gl_hoverzone = 10; // how many px to be hovering on an edge?
NewMainWindow::NewMainWindow(QApplication *app) : QMainWindow(NULL), app(app), state(None)
NewMainWindow::NewMainWindow(QApplication *app) : QMainWindow(NULL), state(Inactive), resize(None), app(app)
{
// setup
main = new QWidget(this);
@@ -28,10 +29,13 @@ NewMainWindow::NewMainWindow(QApplication *app) : QMainWindow(NULL), app(app), s
// toolbar
setupToolbar();
// more to come...
// set geometry etc
initialPosition();
// mouse tracking
setMouseTracking(true);
qApp->installEventFilter(this);
}
void
@@ -51,9 +55,9 @@ NewMainWindow::setupToolbar()
searchbox->setFixedWidth(gl_searchwidth * dpiXFactor);
searchbox->setFixedHeight(gl_searchheight * dpiXFactor);
searchbox->setFrame(QFrame::NoFrame);
searchbox->setStyleSheet("QLineEdit { background: #eeeeee; border-radius: 7px; }"
searchbox->setStyleSheet("QLineEdit { background: #eeeeee; border-radius: 7px; padding-left: 10px;}" //XXX hidpi constants
"QLineEdit:focus { background: white; }");
searchbox->setPlaceholderText(tr(" Search or type a command "));
searchbox->setPlaceholderText(tr(" Search or type a command "));
// spacer to balance the minimize and close buttons
QWidget *balanceSpacer = new QWidget(this);
@@ -139,32 +143,194 @@ NewMainWindow::initialPosition()
// start with drag, but will need resize at some
// point too.
bool
NewMainWindow::isHotSpot(QPoint pos)
NewMainWindow::isDragHotSpot(QPoint pos)
{
if (pos.y() < gl_toolbarheight * dpiYFactor) return true;
if (pos.y() > gl_hoverzone && pos.y() < gl_toolbarheight * dpiYFactor) return true;
return false;
}
int
NewMainWindow::isResizeHotSpot(QPoint pos)
{
int returning = None;
if (pos.y() < gl_hoverzone) {
returning = Top;
if (pos.x() < gl_hoverzone) returning = TL;
if (pos.x() > width()-gl_hoverzone) returning = TR;
} else if (pos.y() > height() -gl_hoverzone) {
returning = Bottom;
if (pos.x() < gl_hoverzone) returning = BL;
if (pos.x() > width()-gl_hoverzone) returning = BR;
} else if (pos.x() <gl_hoverzone) {
returning = Left;
} else if (pos.x() > width()-gl_hoverzone) {
returning = Right;
}
return returning;
}
void
NewMainWindow::mousePressEvent(QMouseEvent *event) {
if (isHotSpot(event->pos())) {
// always grab focus, user is 'clicking away' from a widget
setFocus();
if (state == EdgeHover) {
clickPos.setX(event->x());
clickPos.setY(event->y());
clickGeom=geometry();
state = Resize;
resize = static_cast<ResizeType>(isResizeHotSpot(event->pos()));
} else if (isDragHotSpot(event->pos())) {
clickPos.setX(event->x());
clickPos.setY(event->y());
clickGeom=geometry();
state = Drag;
}
}
void
NewMainWindow::mouseReleaseEvent(QMouseEvent *) {
state = None;
state = Inactive;
setCursor(Qt::ArrowCursor);
}
bool
NewMainWindow::eventFilter(QObject *, QEvent *e)
{
if (e->type() == QEvent::MouseMove) this->mouseMoveEvent(static_cast<QMouseEvent*>(e));
// we must NEVER steal events, this is on the entire app
return false;
}
void
NewMainWindow::mouseMoveEvent(QMouseEvent *event) {
if (state == Drag) move(event->globalX()-clickPos.x(),event->globalY()-clickPos.y());
int hotspot=None;
if (state == Drag) {
move(event->globalX()-clickPos.x(),event->globalY()-clickPos.y());
} else if (state == Resize) {
this->setUpdatesEnabled(false);
QRect geom = geometry();
switch(resize) {
case None:
// should never get here !
state = Inactive;
break;
case BR:
QMainWindow::resize(event->globalX()-geom.x(),event->globalY()-geom.y());
break;
case Right:
QMainWindow::resize(event->globalX()-geom.x(),geom.height());
break;
case Bottom:
QMainWindow::resize(geom.width(),event->globalY()-geom.y());
break;
case TR:
{
int newwidth = event->globalX()-geom.x();
newwidth = newwidth > minimumWidth() ? newwidth : minimumWidth();
int newheight = clickGeom.height() + (clickGeom.y() - event->globalY());
newheight = newheight > minimumHeight() ? newheight : minimumHeight();
QMainWindow::resize(newwidth, newheight);
move(clickGeom.bottomLeft().x(),clickGeom.bottomLeft().y()-newheight);
}
break;
case TL:
{
int newwidth = clickGeom.width() + (clickGeom.x() - event->globalX());
newwidth = newwidth > minimumWidth() ? newwidth : minimumWidth();
int newheight = clickGeom.height() + (clickGeom.y() - event->globalY());
newheight = newheight > minimumHeight() ? newheight : minimumHeight();
QMainWindow::resize(newwidth, newheight);
move(clickGeom.bottomRight().x()-newwidth,clickGeom.bottomRight().y()-newheight);
}
break;
case BL:
{
int newwidth = clickGeom.width() + (clickGeom.x() - event->globalX());
newwidth = newwidth > minimumWidth() ? newwidth : minimumWidth();
int newheight = event->globalY()-geom.y();
newheight = newheight > minimumHeight() ? newheight : minimumHeight();
QMainWindow::resize(newwidth, newheight);
move(clickGeom.bottomRight().x()-newwidth,clickGeom.y());
}
break;
case Left:
{
int newwidth = clickGeom.width() + (clickGeom.x() - event->globalX());
newwidth = newwidth > minimumWidth() ? newwidth : minimumWidth();
QMainWindow::resize(newwidth, clickGeom.height());
move(clickGeom.bottomRight().x()-newwidth,clickGeom.y());
}
break;
case Top:
{
int newheight = clickGeom.height() + (clickGeom.y() - event->globalY());
newheight = newheight > minimumHeight() ? newheight : minimumHeight();
QMainWindow::resize(clickGeom.width(), newheight);
move(clickGeom.x(),clickGeom.bottomRight().y()-newheight);
}
break;
default:
break;
}
this->setUpdatesEnabled(true);
} else if (state != Resize && state != Drag) {
hotspot=isResizeHotSpot(event->pos());
switch (hotspot) {
case None:
// unhover
setCursor(Qt::ArrowCursor);
break;
case Top:
case Bottom:
setCursor(Qt::SizeVerCursor);
break;
case Left:
case Right:
setCursor(Qt::SizeHorCursor);
break;
case TL:
case BR:
setCursor(Qt::SizeFDiagCursor);
break;
case TR:
case BL:
setCursor(Qt::SizeBDiagCursor);
break;
}
// state transition
if (state != EdgeHover && hotspot != None) state = EdgeHover;
if (state == EdgeHover && hotspot == None) state = Inactive;
}
}
void

View File

@@ -11,6 +11,12 @@ class NewMainWindow : public QMainWindow
public:
NewMainWindow(QApplication *app);
// we are frameless, so we handle functions that
// would normally be performed by the window manager
// in exchange we get to handle all the aesthetics
enum { Inactive, Drag, EdgeHover, Resize } state;
enum ResizeType { None, Top, Left, Right, Bottom, TL, TR, BL, BR } resize;
// initially lets just do this, the code will
// get more complex over time, but lets start
// with the simplest methods for dragging a
@@ -19,7 +25,9 @@ class NewMainWindow : public QMainWindow
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
bool isHotSpot(QPoint);
bool eventFilter(QObject *oj, QEvent *e);
bool isDragHotSpot(QPoint);
int isResizeHotSpot(QPoint);
protected:
@@ -43,5 +51,5 @@ class NewMainWindow : public QMainWindow
QPushButton *quitbutton, *minimisebutton;
QPoint clickPos;
enum { None, Drag, Resize } state;
QRect clickGeom;
};