aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-qt5/core/libLumina/RootSubWindow.cpp102
-rw-r--r--src-qt5/core/libLumina/RootSubWindow.h6
2 files changed, 85 insertions, 23 deletions
diff --git a/src-qt5/core/libLumina/RootSubWindow.cpp b/src-qt5/core/libLumina/RootSubWindow.cpp
index 9769c922..7ec25a71 100644
--- a/src-qt5/core/libLumina/RootSubWindow.cpp
+++ b/src-qt5/core/libLumina/RootSubWindow.cpp
@@ -10,6 +10,8 @@
#include <QVBoxLayout>
#include <QVBoxLayout>
+#define WIN_BORDER 3
+
// === PUBLIC ===
RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){
this->setAttribute(Qt::WA_DeleteOnClose);
@@ -22,7 +24,6 @@ RootSubWindow::RootSubWindow(QWidget *root, NativeWindow *win) : QFrame(root){
LoadProperties( QList< NativeWindow::Property>() << NativeWindow::Title << NativeWindow::Icon \
<< NativeWindow::MinSize << NativeWindow::MaxSize << NativeWindow::Size );
//Hookup the signals/slots
- connect(this, SIGNAL(aboutToActivate()), this, SLOT(aboutToActivate()) );
connect(WIN, SIGNAL(PropertyChanged(NativeWindow::Property, QVariant)), this, SLOT(propertyChanged(NativeWindow::Property, QVariant)));
//Make sure the visibily property only gets loaded after it is added to the root area
propertyChanged(NativeWindow::Visible, WIN->property(NativeWindow::Visible));
@@ -39,26 +40,26 @@ WId RootSubWindow::id(){
// === PRIVATE ===
RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset){
//Note: pt should be in widget-relative coordinates, not global
- if(!WinWidget->geometry().contains(pt)){
+ if(!WinWidget->geometry().contains(pt) && !titleBar->geometry().contains(pt)){
//above the frame itself - need to figure out which quadrant it is in (8-directions)
- if(pt.y() < 3){
+ if(pt.y() < WIN_BORDER){
//One of the top options
- if(pt.x() < 3){
+ if(pt.x() < WIN_BORDER){
if(setoffset){ offset.setX(pt.x()); offset.setY(pt.y()); } //difference from top-left corner
return ResizeTopLeft;
- }else if(pt.x() > (this->width()-3)){
+ }else if(pt.x() > (this->width()-WIN_BORDER)){
if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(pt.y()); } //difference from top-right corner
return ResizeTopRight;
}else{
if(setoffset){ offset.setX(0); offset.setY(pt.y()); } //difference from top edge (X does not matter)
return ResizeTop;
}
- }else if(pt.y() > (this->height()-3) ){
+ }else if(pt.y() > (this->height()-WIN_BORDER) ){
//One of the bottom options
- if(pt.x() < 3){
+ if(pt.x() < WIN_BORDER){
if(setoffset){ offset.setX(pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-left corner
return ResizeBottomLeft;
- }else if(pt.x() > (this->width()-3)){
+ }else if(pt.x() > (this->width()-WIN_BORDER)){
if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(this->height()-pt.y()); } //difference from bottom-right corner
return ResizeBottomRight;
}else{
@@ -67,10 +68,10 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset
}
}else{
//One of the side options
- if(pt.x() < 3){
+ if(pt.x() < WIN_BORDER){
if(setoffset){ offset.setX(pt.x()); offset.setY(0); } //difference from left edge (Y does not matter)
return ResizeLeft;
- }else if(pt.x() > (this->width()-3) ){
+ }else if(pt.x() > (this->width()-WIN_BORDER) ){
if(setoffset){ offset.setX(this->width()-pt.x()); offset.setY(0); } //difference from right edge (Y does not matter)
return ResizeRight;
}else{
@@ -82,6 +83,7 @@ RootSubWindow::ModState RootSubWindow::getStateAtPoint(QPoint pt, bool setoffset
}
void RootSubWindow::setMouseCursor(ModState state, bool override){
+ if(currentCursor==state && !override){ return; } //nothing to change
Qt::CursorShape shape;
switch(state){
case Normal:
@@ -118,6 +120,7 @@ void RootSubWindow::setMouseCursor(ModState state, bool override){
if(override){
QApplication::setOverrideCursor(QCursor(shape));
}else{
+ currentCursor = state;
this->setCursor(shape);
}
}
@@ -128,14 +131,19 @@ void RootSubWindow::initWindowFrame(){
closeB = new QToolButton(this);
maxB = new QToolButton(this);
minB = new QToolButton(this);
+ otherB = new QToolButton(this);
titleLabel = new QLabel(this);
titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
otherM = new QMenu(this); //menu of other actions
+ otherB->setMenu(otherM);
+ otherB->setPopupMode(QToolButton::InstantPopup);
+ otherB->setAutoRaise(true);
connect(closeB, SIGNAL(clicked()), this, SLOT(triggerClose()) );
connect(maxB, SIGNAL(clicked()), this, SLOT(toggleMaximize()) );
connect(minB, SIGNAL(clicked()), this, SLOT(toggleMinimize()) );
//Now assemble the frame layout based on the current settings
this->setLayout(mainLayout);
+ titleBar->addWidget(otherB);
titleBar->addWidget(titleLabel);
titleBar->addWidget(minB);
titleBar->addWidget(maxB);
@@ -150,9 +158,9 @@ void RootSubWindow::initWindowFrame(){
maxB->setObjectName("Button_Maximize");
otherM->setObjectName("Menu_Actions");
titleLabel->setObjectName("Label_Title");
- this->setStyleSheet("QWidget#WindowFrame{background-color: black;} QWidget#Label_Title{background-color: darkgrey; color: white; }");
+ this->setStyleSheet("QWidget#WindowFrame{background-color: darkblue;} QWidget#Label_Title{background-color: transparent; color: white; }");
//And adjust the margins
- mainLayout->setContentsMargins(4,4,4,4);
+ mainLayout->setContentsMargins(WIN_BORDER,WIN_BORDER,WIN_BORDER,WIN_BORDER);
mainLayout->setSpacing(0);
titleBar->setSpacing(1);
titleBar->setContentsMargins(0,0,0,0);
@@ -194,7 +202,18 @@ void RootSubWindow::activate(){
//Mouse Interactivity
void RootSubWindow::startMoving(){
-
+ //If the cursor is not over this window, move it to the center of the titlebar
+ QPoint curpt = QCursor::pos(); //global coords
+ if(!this->geometry().contains(curpt)){
+ curpt = this->mapToGlobal(titleBar->geometry().center());
+ QCursor::setPos(curpt);
+ }
+ //Calculate the offset
+ activeState = Move;
+ offset = this->mapFromGlobal(curpt);
+ setMouseCursor(activeState, true); //this one is an override cursor
+ //Also need to capture the mouse
+ this->grabMouse();
}
void RootSubWindow::startResizing(){
@@ -204,10 +223,6 @@ void RootSubWindow::startResizing(){
// === PRIVATE SLOTS ===
-void RootSubWindow::aboutToActivate(){
-
-}
-
void RootSubWindow::propertyChanged(NativeWindow::Property prop, QVariant val){
if(val.isNull()){ return; } //not the same as a default/empty value - the property has just not been set yet
qDebug() << "Set Window Property:" << prop << val;
@@ -220,7 +235,7 @@ void RootSubWindow::propertyChanged(NativeWindow::Property prop, QVariant val){
titleLabel->setText(val.toString());
break;
case NativeWindow::Icon:
- //this->setWindowIcon(val.value< QIcon>());
+ otherB->setIcon(val.value< QIcon>());
break;
case NativeWindow::Size:
WinWidget->resize(val.toSize());
@@ -244,7 +259,7 @@ void RootSubWindow::propertyChanged(NativeWindow::Property prop, QVariant val){
// === PROTECTED ===
void RootSubWindow::mousePressEvent(QMouseEvent *ev){
- qDebug() << "Frame Mouse Press Event";
+ //qDebug() << "Frame Mouse Press Event";
offset.setX(0); offset.setY(0);
if(activeState != Normal){ return; } // do nothing - already in a state of grabbed mouse
this->activate();
@@ -265,41 +280,78 @@ void RootSubWindow::mouseMoveEvent(QMouseEvent *ev){
ev->accept();
if(activeState == Normal){
setMouseCursor( getStateAtPoint(ev->pos()) ); //just update the mouse cursor
-
}else{
//Currently in a modification state
QRect geom = this->geometry();
+ QSize minsize(WinWidget->minimumSize().width() + (2*WIN_BORDER), WinWidget->minimumSize().height()+(2*WIN_BORDER)+titleBar->geometry().size().height());
switch(activeState){
case Move:
geom.moveTopLeft(ev->globalPos()-offset); //will not change size
break;
case ResizeTop:
geom.setTop(ev->globalPos().y()-offset.y());
+ if(geom.size().height() < minsize.height()){
+ geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height
+ }
break;
case ResizeTopRight:
geom.setTopRight(ev->globalPos()-offset);
+ if(geom.size().height() < minsize.height()){
+ geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height
+ }
+ if(geom.size().width() < minsize.width()){
+ geom.setRight(geom.x() + minsize.width()); //reset back to min width
+ }
break;
case ResizeRight:
geom.setRight(ev->globalPos().x()-offset.x());
+ if(geom.size().width() < minsize.width()){
+ geom.setRight(geom.x() + minsize.width()); //reset back to min width
+ }
break;
case ResizeBottomRight:
geom.setBottomRight(ev->globalPos()-offset);
+ if(geom.size().height() < minsize.height()){
+ geom.setBottom(geom.y() + minsize.height()); //reset back to min height
+ }
+ if(geom.size().width() < minsize.width()){
+ geom.setRight(geom.x() + minsize.width()); //reset back to min width
+ }
break;
case ResizeBottom:
geom.setBottom(ev->globalPos().y()-offset.y());
+ if(geom.size().height() < minsize.height()){
+ geom.setBottom(geom.y() + minsize.height()); //reset back to min height
+ }
break;
case ResizeBottomLeft:
geom.setBottomLeft(ev->globalPos()-offset);
+ if(geom.size().height() < minsize.height()){
+ geom.setBottom(geom.y() + minsize.height()); //reset back to min height
+ }
+ if(geom.size().width() < minsize.width()){
+ geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width
+ }
break;
case ResizeLeft:
geom.setLeft(ev->globalPos().x()-offset.x());
+ if(geom.size().width() < minsize.width()){
+ geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width
+ }
break;
case ResizeTopLeft:
geom.setTopLeft(ev->globalPos()-offset);
- break;
+ if(geom.size().height() < minsize.height()){
+ geom.setTop(geom.y() - (minsize.height()-geom.size().height())); //reset back to min height
+ }
+ if(geom.size().width() < minsize.width()){
+ geom.setLeft(geom.x() - (minsize.width()-geom.size().width())); //reset back to min width
+ }
+ break;
default:
break;
}
+
this->setGeometry(geom);
}
}
@@ -315,4 +367,12 @@ void RootSubWindow::mouseReleaseEvent(QMouseEvent *ev){
activeState = Normal;
QApplication::restoreOverrideCursor();
setMouseCursor( getStateAtPoint(ev->pos()) );
+ if(QWidget::mouseGrabber() == this){ this->releaseMouse(); }
+}
+
+void RootSubWindow::leaveEvent(QEvent *ev){
+ QFrame::leaveEvent(ev);
+ if(activeState == Normal){
+ setMouseCursor(Normal);
+ }
}
diff --git a/src-qt5/core/libLumina/RootSubWindow.h b/src-qt5/core/libLumina/RootSubWindow.h
index fcf0fdae..12feaea6 100644
--- a/src-qt5/core/libLumina/RootSubWindow.h
+++ b/src-qt5/core/libLumina/RootSubWindow.h
@@ -20,6 +20,7 @@
#include <QMenu>
#include <NativeWindow.h>
+
class RootSubWindow : public QFrame{
Q_OBJECT
public:
@@ -32,6 +33,7 @@ private:
//Window status
enum ModState{Normal, Move, ResizeTop, ResizeTopRight, ResizeRight, ResizeBottomRight, ResizeBottom, ResizeBottomLeft, ResizeLeft, ResizeTopLeft};
ModState activeState;
+ ModState currentCursor;
QPoint offset; //needed for movement calculations (offset from mouse click to movement point)
//Functions for getting/setting state
ModState getStateAtPoint(QPoint pt, bool setoffset = false); //generally used for mouse location detection
@@ -42,7 +44,7 @@ private:
bool closing;
//Title bar objects
QBoxLayout *titleBar, *mainLayout;
- QToolButton *closeB, *maxB, *minB;
+ QToolButton *closeB, *maxB, *minB, *otherB;
QLabel *titleLabel;
QMenu *otherM; //menu of other actions
void initWindowFrame();
@@ -64,13 +66,13 @@ public slots:
void startResizing();
private slots:
- void aboutToActivate();
void propertyChanged(NativeWindow::Property, QVariant);
protected:
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
+ void leaveEvent(QEvent *ev);
};
bgstack15