This is an automated email from the git hooks/post-receive script. x2go pushed a change to branch master in repository x2gokdriveclient. from 2e34dfd debian/rules: let qmake add general Qt {C{,XX},L}FLAGS instead of overriding them. new 44e288f Add floating tool bar. The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Summary of changes: client.cpp | 112 ++++--- client.h | 10 +- debian/changelog | 3 + displayarea.cpp | 20 +- menuframe.cpp | 515 +++++++++++++++++++++++++++++ menuframe.h | 92 ++++++ res/{application-menu.svg => minimize.svg} | 6 +- res/pin.svg | 13 + res/view.svg | 13 + resources.qrc | 3 + x2gokdriveclient.pro | 4 +- 11 files changed, 730 insertions(+), 61 deletions(-) create mode 100644 menuframe.cpp create mode 100644 menuframe.h copy res/{application-menu.svg => minimize.svg} (54%) create mode 100644 res/pin.svg create mode 100644 res/view.svg -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdriveclient.git
This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gokdriveclient. commit 44e288fea482d84f3c5063fde4a4c978f405bf94 Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Wed Jan 22 13:18:16 2020 +0100 Add floating tool bar. --- client.cpp | 112 +++++++---- client.h | 10 +- debian/changelog | 3 + displayarea.cpp | 20 +- menuframe.cpp | 515 +++++++++++++++++++++++++++++++++++++++++++++++++++ menuframe.h | 92 +++++++++ res/minimize.svg | 13 ++ res/pin.svg | 13 ++ res/view.svg | 13 ++ resources.qrc | 3 + x2gokdriveclient.pro | 4 +- 11 files changed, 740 insertions(+), 58 deletions(-) diff --git a/client.cpp b/client.cpp index 73b6994..44977aa 100644 --- a/client.cpp +++ b/client.cpp @@ -32,6 +32,14 @@ #include <QDesktopWidget> #include <QMimeData> #include <QBuffer> +#include <QMenuBar> +#include <QToolBar> +#include "menuframe.h" + +#include <QHBoxLayout> + +#include <QLabel> +#include <QInputDialog> #include <QResizeEvent> @@ -40,12 +48,13 @@ #include <QGuiApplication> #include <QScreen> #include <QPushButton> +#include <QToolButton> #include <QMenu> - #include <QClipboard> + X2GoCursor::X2GoCursor(uint16_t width, uint16_t height, uint16_t xhot, uint16_t yhot, uint32_t serialNumber, uint32_t dataSize) { this->width=width; @@ -101,14 +110,13 @@ Frame::~Frame() Client::Client() { - resize(799,600); - move(-0,0); + displayArea=new DisplayArea(this); + + displayArea->setObjectName("DisplayArea"); + displayArea->setStyleSheet("QFrame#DisplayArea{background-color:black;border-image:url(:res/x2gobg.svg) 0 0 0 0 stretch stretch;}"); - displayArea=new DisplayArea(this); - displayArea->setStyleSheet("background-color:black;"); - displayArea->setStyleSheet("border-image:url(:res/x2gobg.svg) 0 0 0 0 stretch stretch;"); displayArea->show(); setCentralWidget(displayArea); setWindowIcon(QIcon(":res/x2goclient.png")); @@ -123,7 +131,6 @@ Client::Client() connect(QGuiApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), this, SLOT(slotSelectionChanged(QClipboard::Mode))); - QTimer::singleShot(10,this,SLOT(connectToServer())); geometryDelay=new QTimer(this); geometryDelay->setSingleShot(true); @@ -143,28 +150,39 @@ Client::Client() slotScreenAdded(screen); } - menuButton=new QPushButton("",this); - menuButton->resize(24,24); - menuButton->move(0,0); - menuButton->setStyleSheet("border-image:none;"); - menuButton->setFocusPolicy(Qt::NoFocus); - menu=new QMenu(menuButton); + QMenu* menuCon=menuBar()->addMenu(tr("&Connection")); + menu=menuBar()->addMenu(tr("&View")); + FSMenuBar=new MenuFrame(this, menu); +// FSMenuBar->hide(); + menuBar()->hide(); + + connect(FSMenuBar, SIGNAL(editCaption()), this, SLOT(editWindowTitle())); + connect(this, SIGNAL(windowTitleChanged(const QString &)), FSMenuBar, SLOT(setCaption(const QString &))); + - actRandr=menu->addAction(QIcon(":res/randr.svg"), tr("Enable RandR extension"),this, SLOT(slotEnableRandr())); + actRandr=menu->addAction(QIcon(":res/randr.svg"), tr("Multiple monitors"),this, SLOT(slotEnableRandr())); + actRandr->setCheckable(true); + menu->addSeparator(); for(int i=0;i<4;++i) - actDisp[i]=menu->addAction(QIcon(":res/view-fullscreen.svg"), tr("Display ")+QString::number(i+1) ,this, SLOT(slotDisplayFS())); - actFS=menu->addAction(QIcon(":res/view-fullscreen.svg"), tr("All displays"),this, SLOT(slotFS())); - actRestore=menu->addAction(QIcon(":res/view-restore.svg"), tr("Restore") ,this, SLOT(slotRestore())); + actDisp[i]=menu->addAction(QIcon(":res/view-fullscreen.svg"), tr("Monitor ")+QString::number(i+1) ,this, SLOT(slotDisplayFS())); + + actFS=menu->addAction(QIcon(":res/view-fullscreen.svg"), tr("All monitors"),this, SLOT(slotFS())); menu->addSeparator(); - actDisconnect=menu->addAction(QIcon(":res/network-disconnect.svg"), tr("Disconnect"),this, SLOT(slotDisconnect())); + actRestore=menu->addAction(QIcon(":res/view-restore.svg"), tr("Restore") ,this, SLOT(slotRestore())); + menuBar()->addSeparator(); + + + actDisconnect=menuCon->addAction( tr("Disconnect"),this, SLOT(slotDisconnect())); + actDisconnect->setIcon(QIcon(":res/network-disconnect.svg")); + actDisconnect->setToolTip(tr("Disconnect")); + + QTimer::singleShot(10,this,SLOT(connectToServer())); + - menuButton->setMenu(menu); - menuButton->hide(); - menuButton->setCursor(Qt::ArrowCursor); - connect(menu,SIGNAL(aboutToHide()), menuButton, SLOT(hide())); connect(menu,SIGNAL(aboutToShow()), this, SLOT(slotSetupMenu())); + setWindowTitle(tr("X2GoKDrive Client")); } @@ -180,6 +198,23 @@ Client::~Client() delete currentCursor; } + +void Client::editWindowTitle() +{ + bool ok; + QString title=QInputDialog::getText(this,tr("Enter new window title"),tr("New window title:"),QLineEdit::Normal, windowTitle(),&ok); + if(ok) + { + if(title.length()==0) + { + setWindowTitle(tr("X2GoKDrive Client")); + return; + } + setWindowTitle(title); + } +} + + void Client::slotEnableRandr() { setUseRandr(!useRandr); @@ -289,7 +324,6 @@ void Client::slotRealFs() #endif } - void Client::setFS(int screenNumber) { if(!isFs) @@ -331,16 +365,16 @@ void Client::slotSetupMenu() menu->setEnabled(clientSocket->isOpen()); if(useRandr) { - actRandr->setText(tr("Disable RandR extension")); + actRandr->setChecked(true); } else { - actRandr->setText(tr("Enable RandR extension")); + actRandr->setChecked(false); } actRestore->setVisible(isFs); actFS->setVisible((!isFs)); - actDisp[0]->setText(tr("Display 1")); + actDisp[0]->setText(tr("Monitor 1")); if(((QGuiApplication*)QGuiApplication::instance())->screens().count()==1) { @@ -366,22 +400,22 @@ void Client::slotSetupMenu() displayArea->slotGrabDisplay(); } - -void Client::hideMenuButton() -{ - menuButton->hide(); -} - -void Client::showMenuButton() +bool Client::isDisplayPointer(QMouseEvent* event) { - if(!menuButton->isVisible()) + if(event->x() > FSMenuBar->x() && event->x() < FSMenuBar->x() + FSMenuBar->width() && + event->y() > FSMenuBar->y() && event->y() < FSMenuBar->y() + FSMenuBar->height() && + event->button()== Qt::NoButton && event->buttons() == 0) { - displayArea->slotGrabDisplay(); + FSMenuBar->setHasPointer(true); + return false; + } + else + { + FSMenuBar->setHasPointer(false); + return true; } - menuButton->show(); } - void Client::freeMessageBuffer() { if(messageBuffer) @@ -556,7 +590,7 @@ void Client::renderFrame() } else { - qDebug()<<"got Screen update:"<<currentFrame->width<< currentFrame->height<<currentFrame->regions[0]->pix.size(); +// qDebug()<<"got Screen update:"<<currentFrame->width<< currentFrame->height<<currentFrame->regions[0]->pix.size(); displayArea->setDisplayPix(currentFrame->regions[0]->pix, currentFrame->x, currentFrame->y); } } @@ -1009,6 +1043,7 @@ void Client::dataArrived() void Client::socketConnected() { + displayArea->setStyleSheet("QFrame#DisplayArea{background-color:black;}"); fprintf(stderr,"Connected to server\n"); fprintf(stderr,"Established X server connection\n"); @@ -1099,6 +1134,7 @@ void Client::resizeEvent(QResizeEvent* ) if(geometryDelay->isActive()) geometryDelay->stop(); geometryDelay->start(); + FSMenuBar->adjustPosition(); } void Client::resizeToOldSize() diff --git a/client.h b/client.h index 4163e37..04a1b3b 100644 --- a/client.h +++ b/client.h @@ -108,7 +108,7 @@ public: class QTcpSocket; class DisplayArea; class QTimer; -class QPushButton; +class MenuFrame; class QMenu; class QAction; @@ -120,13 +120,12 @@ public: Client(); ~Client(); void sendEvent(char *event); - void showMenuButton(); - void hideMenuButton(); Frame* getCurrentFrame(){return currentFrame;} bool needUpdate(){return wantRepaint;} void setUptodate(); QPixmap getPixmapFromCache(uint32_t crc); QPixmap addPixmapToCache(); + bool isDisplayPointer(QMouseEvent* event); private slots: @@ -152,6 +151,8 @@ private slots: void slotEnableRandr(); void slotResizeFSFinal(); void slotSelectionChanged(QClipboard::Mode mode); +public slots: + void editWindowTitle(); private: @@ -192,8 +193,9 @@ private: int dispNumber=1; QString cookie; - QPushButton *menuButton; + MenuFrame *FSMenuBar; QMenu* menu; + QAction* actRandr; QAction* actFS; QAction* actDisp[4]; diff --git a/debian/changelog b/debian/changelog index 6e5fed2..a3b1ab2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,4 +13,7 @@ x2gokdriveclient (0.0.0.1-0x2go1) UNRELEASED; urgency=medium * Let qmake add general Qt {C{,XX},L}FLAGS instead of overriding them. Especially needed for C++11 support. + [ Oleksandr Shneyder ] + * Add floating tool bar. + -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Tue, 04 Jun 2019 11:10:43 +0200 diff --git a/displayarea.cpp b/displayarea.cpp index ad14953..855922a 100644 --- a/displayarea.cpp +++ b/displayarea.cpp @@ -182,10 +182,10 @@ void DisplayArea::paintEvent(QPaintEvent* ev) int32_t etype, x, y, width, height; etype=UPDATE; - width=ev->rect().width(); - height=ev->rect().height(); - x=ev->rect().x(); - y=ev->rect().y(); + width=ev->rect().width()+ev->rect().x(); + height=ev->rect().height()+ev->rect().y(); + x=0; + y=0; memcpy(evmsg,(char*)&etype,4); @@ -238,6 +238,8 @@ uint32_t DisplayArea::X11MouseButton(Qt::MouseButton qtMouseButton) void DisplayArea::mouseMoveEvent(QMouseEvent* event) { + if(!parent->isDisplayPointer(event)) + return; char evmsg[EVLENGTH]={}; uint32_t etype, x, y; etype=MOUSEMOTION; @@ -247,16 +249,6 @@ void DisplayArea::mouseMoveEvent(QMouseEvent* event) x=event->x(); y=event->y(); - if(x<25 && y<25 &&event->button()== Qt::NoButton && event->buttons() == 0) - { - parent->showMenuButton(); - return; - } - else - { - parent->hideMenuButton(); - } - memcpy(evmsg,(char*)&etype,4); memcpy(evmsg+4,(char*)&x,4); memcpy(evmsg+8,(char*)&y,4); diff --git a/menuframe.cpp b/menuframe.cpp new file mode 100644 index 0000000..7605d96 --- /dev/null +++ b/menuframe.cpp @@ -0,0 +1,515 @@ +/* + * QT Client for X2GoKDrive + * Copyright (C) 2018 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> + * Copyright (C) 2018 phoca-GmbH + * + * 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/>. + * + */ + +#include <menuframe.h> +#include <QDebug> +#include <QMouseEvent> +#include <QCursor> +#include <QToolButton> +#include <QLabel> +#include <QMenu> +#include <QHBoxLayout> +#include <QSettings> +#include <QTimer> + +#include "client.h" + + + + + +#include <QPainter> + +RotatedLabel::RotatedLabel(QWidget *parent): QLabel(parent) +{ +} + +RotatedLabel::RotatedLabel(const QString &text, QWidget *parent): QLabel(text, parent) +{ +} + +void RotatedLabel::setOrientation(RotatedLabel::orient ort) +{ + orientation=ort; +} + +void RotatedLabel::mouseDoubleClickEvent(QMouseEvent*) +{ + emit doubleClick(); +} + + +void RotatedLabel::paintEvent(QPaintEvent* ev) +{ + switch (orientation) + { + case NORMAL: + QLabel::paintEvent(ev); + return; + case LEFT: + { + QPainter painter(this); + painter.translate(8,2); + painter.rotate(90); + painter.drawText(0,0,text()); + break; + } + case RIGHT: + { + QPainter painter(this); + painter.translate( sizeHint().height()-4,sizeHint().width()+1); + painter.rotate(270); + painter.drawText(0,0,text()); + break; + } + } +} + +MenuFrame::MenuFrame(QWidget* parent, QMenu* menu):QFrame(parent) +{ + setMouseTracking(true); + setObjectName("FSMenuBar"); + + bPin=new QToolButton(this); + bPin->setIcon(QIcon(":res/pin.svg")); + bPin->setCheckable(true); + bPin->setToolTip(tr("Pin menu bar")); + + + connect(bPin, SIGNAL(toggled(bool)), this, SLOT(setPinned(bool))); + + + QHBoxLayout* ml=new QHBoxLayout(this); + + hLayout=new QHBoxLayout(); + vLayout=new QVBoxLayout(); + + ml->addLayout(hLayout); + ml->addLayout(vLayout); + + defaultMargin=ml->margin(); + defaultSpacing=ml->spacing(); + + ml->setSpacing(0); + ml->setMargin(0); + + + viewMenu=new QToolButton(this); + + viewMenu->setMenu(menu); + viewMenu->setPopupMode(QToolButton::InstantPopup); + viewMenu->setToolTip(tr("View")); + viewMenu->setIcon(QIcon(":res/view.svg")); + + capt=new RotatedLabel("", this); + capt->setToolTip(tr("Double click to change window title\nDrag to change position")); + + connect(capt, SIGNAL(doubleClick()), this,SIGNAL(editCaption())); + + bDisc=new QToolButton(this); + bDisc->setToolTip(tr("Disconnect")); + bDisc->setIcon(QIcon(":res/network-disconnect.svg")); + Client* client=(Client*)parent; + connect(bDisc, SIGNAL(clicked(bool)),client, SLOT(slotDisconnect())); + + bMin=new QToolButton(this); + bMin->setToolTip(tr("Minimize")); + bMin->setIcon(QIcon(":res/minimize.svg")); + connect(bMin, SIGNAL(clicked(bool)),client, SLOT(showMinimized())); + + QSettings s( "Obviously Nice","x2gokdriveclient"); + isPinned=s.value("pinned",false).toBool(); + + position=s.value("position",0.5).toDouble(); + + QString orstr=s.value("orientation", "top").toString(); + + if(orstr=="bottom") + orientation=BOTTOM; + if(orstr=="left") + orientation=LEFT; + if(orstr=="right") + orientation=RIGHT; + + + setupFrame(); + adjustPosition(); + bPin->setChecked(isPinned); + hovered=true; + setHasPointer(false); + applyStyle(); + +} + +void MenuFrame::setupFrame() +{ + if(hLayout->count()) + { + hLayout->removeWidget(bPin); + hLayout->removeWidget(viewMenu); + hLayout->removeWidget(capt); + hLayout->removeWidget(bMin); + hLayout->removeWidget(bDisc); + } + if(vLayout->count()) + { + vLayout->removeWidget(bPin); + vLayout->removeWidget(viewMenu); + vLayout->removeWidget(capt); + vLayout->removeWidget(bMin); + vLayout->removeWidget(bDisc); + } + + switch(orientation) + { + case TOP: + case BOTTOM: + vLayout->setSpacing(0); + vLayout->setMargin(0); + hLayout->setSpacing(defaultSpacing); + hLayout->setMargin(defaultMargin); + hLayout->addWidget(bPin); + hLayout->addWidget(viewMenu); + hLayout->addWidget(capt); + hLayout->addWidget(bMin); + hLayout->addWidget(bDisc); + capt->setOrientation(RotatedLabel::NORMAL); + setMinimumHeight(bDisc->sizeHint().height()+defaultMargin*2); + setMaximumHeight(bDisc->sizeHint().height()+defaultMargin*2); + setMinimumWidth(defaultSpacing*4+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + setMaximumWidth(defaultSpacing*4+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + break; + case LEFT: + capt->setOrientation(RotatedLabel::LEFT); + // fall through + case RIGHT: + if(orientation!=LEFT) + capt->setOrientation(RotatedLabel::RIGHT); + hLayout->setSpacing(0); + hLayout->setMargin(0); + vLayout->setSpacing(defaultSpacing); + vLayout->setMargin(defaultMargin); + vLayout->addWidget(bPin); + vLayout->addWidget(viewMenu); + vLayout->addWidget(capt); + vLayout->addWidget(bMin); + vLayout->addWidget(bDisc); + setMinimumWidth(bDisc->sizeHint().height()+defaultMargin*2); + setMaximumWidth(bDisc->sizeHint().height()+defaultMargin*2); + setMinimumHeight(defaultSpacing*5+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + setMaximumHeight(defaultSpacing*5+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + break; + } + +} + + +void MenuFrame::adjustPosition() +{ + int y=0; + int x=0; + + qDebug()<<"Widget width"<<width(); + switch(orientation) + { + case BOTTOM: + y=parentWidget()->height()-height(); + // fall through + case TOP: + { + if(position==0) + { + x=0; + } + else if(position==1) + { + x=parentWidget()->width()-width()-1; + } + else + { + x=parentWidget()->width()*position-width()/2; + if(x<11) + { + x=11; + } + if(x+11>parentWidget()->width()-width()) + { + x=parentWidget()->width()-width()-11; + } + } + break; + } + case RIGHT: + x=parentWidget()->width()-width(); + // fall through + case LEFT: + { + if(position==0) + { + y=0; + } + else if(position==1) + { + y=parentWidget()->height()-height()-1; + } + else + { + y=parentWidget()->height()*position-height()/2; + if(y<11) + { + y=11; + } + if(y+11>parentWidget()->height()-height()) + { + y=parentWidget()->height()-height()-11; + } + } + break; + } + } + move(x,y); + + hovered=true; + setHasPointer(false); +} + + +void MenuFrame::setCaption(const QString& text) +{ + capt->setText(text); + switch(orientation) + { + case TOP: + case BOTTOM: + setMinimumWidth(defaultSpacing*4+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + setMaximumWidth(defaultSpacing*4+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + break; + case LEFT: + case RIGHT: + setMinimumHeight(defaultSpacing*5+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + setMaximumHeight(defaultSpacing*5+defaultMargin*2+capt->sizeHint().width()+bPin->sizeHint().width()*4); + break; + } + + QTimer::singleShot(20,this, SLOT(adjustPosition())); +} + +void MenuFrame::applyStyle() +{ + QPalette pal=bPin->palette(); + QString bgCol; + QColor col=pal.color(QPalette::Window); + + bgCol.sprintf("rgba(%d,%d,%d,%d)",col.red(), col.green(), col.blue() ,col.alpha()) ; + + switch(orientation) + { + case TOP: + setStyleSheet("QFrame#FSMenuBar{background-color:"+bgCol+";border-bottom-right-radius:5px;border-bottom-left-radius:5px;border-left-style:solid;border-right-style:solid;border-bottom-style:solid;border-width:1px;border-color:grey;}"); + break; + case BOTTOM: + setStyleSheet("QFrame#FSMenuBar{background-color:"+bgCol+";border-top-right-radius:5px;border-top-left-radius:5px;border-left-style:solid;border-right-style:solid;border-top-style:solid;border-width:1px;border-color:grey;}"); + break; + case LEFT: + setStyleSheet("QFrame#FSMenuBar{background-color:"+bgCol+";border-top-right-radius:5px;border-bottom-right-radius:5px;border-right-style:solid;border-bottom-style:solid;border-top-style:solid;border-width:1px;border-color:grey;}"); + break; + case RIGHT: + setStyleSheet("QFrame#FSMenuBar{background-color:"+bgCol+";border-top-left-radius:5px;border-bottom-left-radius:5px;border-left-style:solid;border-bottom-style:solid;border-top-style:solid;border-width:1px;border-color:grey;}"); + break; + } +} + + +void MenuFrame::mouseMoveEvent(QMouseEvent* event) +{ + setHasPointer(true); + if(!drag) + return; + int deltaX=event->screenPos().x()-startPosX; + startPosX=event->screenPos().x(); + + int deltaY=event->screenPos().y()-startPosY; + startPosY=event->screenPos().y(); + + + int localY=event->screenPos().y() - parentWidget()->geometry().y(); + int localX=event->screenPos().x() - parentWidget()->geometry().x(); + + int rDist=parentWidget()->width()-localX; + int bDist=parentWidget()->height()-localY; + + if(rDist<localX && rDist<localY && rDist<bDist) + { + if(orientation!=RIGHT) + { + orientation=RIGHT; + applyStyle(); + setupFrame(); + } + }else if(localY<rDist && localY<localX && localY<bDist) + { + if(orientation!=TOP) + { + orientation=TOP; + applyStyle(); + setupFrame(); + } + } + else if(bDist<localY && bDist<localX && bDist<rDist) + { + if(orientation!=BOTTOM) + { + orientation=BOTTOM; + applyStyle(); + setupFrame(); + } + } + else + { + if(orientation!=LEFT) + { + orientation=LEFT; + applyStyle(); + setupFrame(); + } + } + + int newX=0; + int newY=0; + + switch(orientation) + { + case BOTTOM: + newY=parentWidget()->height()-height(); + // fall through + case TOP: + { + newX=x()+deltaX; + if(newX<0) + newX=0; + if(newX+width() > parentWidget()->width()) + newX=parentWidget()->width() - width(); + + move(newX,newY); + position=(newX+width()/2.)/parentWidget()->width(); + if(newX<=10) + position=0; + if(newX+width()>=parentWidget()->width()-10) + position=1; + } + break; + case RIGHT: + newX=parentWidget()->width()-width(); + // fall through + case LEFT: + { + newY=y()+deltaY; + if(newY<0) + newY=0; + if(newY+height() > parentWidget()->height()) + newY=parentWidget()->height()-height(); + move(newX, newY); + position=(newY+height()/2.)/parentWidget()->height(); + if(newY<=10) + position=0; + if(newY+height()>=parentWidget()->height()-10) + position=1; + } + break; + } + + QSettings s( "Obviously Nice","x2gokdriveclient"); + s.setValue("position",position); + switch(orientation) + { + case TOP: + s.setValue("orientation","top"); + break; + case BOTTOM: + s.setValue("orientation","bottom"); + break; + case LEFT: + s.setValue("orientation","left"); + break; + case RIGHT: + s.setValue("orientation","right"); + break; + + } + +} + + +void MenuFrame::setHasPointer(bool hasPointer) +{ + if(hasPointer==hovered) + return; + hovered=hasPointer; +// qDebug()<<"hovered:"<<hovered; + int newY=y(); + int newX=x(); + + if(hovered || isPinned) + { + switch(orientation) + { + case TOP: newY=0; break; + case BOTTOM: newY=parentWidget()->height()-height(); break; + case LEFT: newX=0;break; + case RIGHT:newX=parentWidget()->width()-width();break; + } + } + else + { + switch(orientation) + { + case TOP: newY=0-height()+5; break; + case BOTTOM: newY=parentWidget()->height()-5; break; + case LEFT: newX=0-width()+5;break; + case RIGHT: newX=parentWidget()->width()-5; break; + } + } + move(newX, newY); +} + + +void MenuFrame::mousePressEvent(QMouseEvent* event) +{ + drag=true; + startPosX=event->screenPos().x(); + startPosY=event->screenPos().y(); + setCursor(Qt::SizeAllCursor); +} + +void MenuFrame::mouseReleaseEvent(QMouseEvent* ) +{ + drag=false; + setCursor(Qt::ArrowCursor); +} + +void MenuFrame::setPinned(bool toggled) +{ + qDebug()<<"pinned: "<<toggled; + isPinned=toggled; + QSettings s( "Obviously Nice","x2gokdriveclient"); + s.setValue("pinned",isPinned); +} + + diff --git a/menuframe.h b/menuframe.h new file mode 100644 index 0000000..a15c991 --- /dev/null +++ b/menuframe.h @@ -0,0 +1,92 @@ +/* + * QT Client for X2GoKDrive + * Copyright (C) 2018 Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> + * Copyright (C) 2018 phoca-GmbH + * + * 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/>. + * + */ + +#ifndef MENUFRAME_H +#define MENUFRAME_H +#include <QFrame> +#include <QLabel> + +class RotatedLabel: public QLabel +{ + Q_OBJECT +public: + typedef enum{NORMAL,LEFT, RIGHT} orient; + explicit RotatedLabel(QWidget *parent=0); + explicit RotatedLabel(const QString &text, QWidget *parent=0); + void setOrientation(orient ort); + +private: + orient orientation=NORMAL; + +protected: + void paintEvent(QPaintEvent* ev); + void mouseDoubleClickEvent(QMouseEvent*); +signals: + void doubleClick(); +}; + +class QMenu; +class QLabel; +class QHBoxLayout; +class QVBoxLayout; +class QToolButton; +class MenuFrame : public QFrame +{ + Q_OBJECT +public: + MenuFrame(QWidget* parent, QMenu* menu); + void setHasPointer(bool hasPointer); + +private: + void applyStyle(); + void setupFrame(); + bool isPinned=false; + int startPosX=0; + int startPosY=0; + double position; + bool drag=false; + bool hovered=false; + int defaultMargin=0; + int defaultSpacing=0; + RotatedLabel *capt; + QHBoxLayout* hLayout; + QVBoxLayout* vLayout; + QToolButton* bPin; + QToolButton* viewMenu; + QToolButton* bDisc; + QToolButton* bMin; + + enum{TOP,BOTTOM, LEFT, RIGHT} orientation=TOP; + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +public slots: + void setPinned(bool toggled); + void setCaption(const QString& text); + void adjustPosition(); + +signals: + void editCaption(); +}; + +#endif // MENUFRAME_H diff --git a/res/minimize.svg b/res/minimize.svg new file mode 100644 index 0000000..937de0f --- /dev/null +++ b/res/minimize.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> + .ColorScheme-Text { + color:#232629; + } + </style> + </defs> + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="m8 11.5l-6-6.251.719-.749 4.125 4.298 1.156 1.237 1.156-1.237 4.125-4.298.719.749-4.125 4.298z" + class="ColorScheme-Text" + /> +</svg> diff --git a/res/pin.svg b/res/pin.svg new file mode 100644 index 0000000..0275514 --- /dev/null +++ b/res/pin.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> + .ColorScheme-Text { + color:#232629; + } + </style> + </defs> + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 8.5 2 C 7.119294 2 6.0000083 3.1192857 6 4.5 L 6 10.535156 L 6.0019531 10.535156 C 6.0210368 11.349063 6.6858693 11.999164 7.5 12 C 8.3284271 12 9 11.328427 9 10.5 L 9 5 L 8 5 L 8 10.5 C 8 10.776142 7.7761424 11 7.5 11 C 7.2238576 11 7 10.776142 7 10.5 L 7 4.5 C 7 3.6715729 7.6715729 3 8.5 3 C 9.3284271 3 10 3.6715729 10 4.5 L 10 10.5 C 10 11.880712 8.8807119 13 7.5 13 C 6.1192881 13 5 11.880712 5 10.5 L 5 4 L 4 4 L 4 10.5 C 4 12.433 5.567 14.000008 7.5 14 C 9.433 14.000008 11. [...] + class="ColorScheme-Text" + /> +</svg> diff --git a/res/view.svg b/res/view.svg new file mode 100644 index 0000000..ce99a6a --- /dev/null +++ b/res/view.svg @@ -0,0 +1,13 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"> + <defs id="defs3051"> + <style type="text/css" id="current-color-scheme"> + .ColorScheme-Text { + color:#232629; + } + </style> + </defs> + <path style="fill:currentColor;fill-opacity:1;stroke:none" + d="M 2 2 L 2 11 L 6 11 L 6 13 L 5 13 L 5 14 L 11 14 L 11 13 L 10 13 L 10 11 L 14 11 L 14 2 L 2 2 z M 3 3 L 13 3 L 13 10 L 3 10 L 3 3 z M 7 4 L 7 9 L 10 6.5 L 7 4 z M 7 11 L 9 11 L 9 13 L 7 13 L 7 11 z " + class="ColorScheme-Text" + /> +</svg> diff --git a/resources.qrc b/resources.qrc index 4b3e91b..8bcf0d1 100644 --- a/resources.qrc +++ b/resources.qrc @@ -5,6 +5,9 @@ <file>res/application-menu.svg</file> <file>res/network-disconnect.svg</file> <file>res/randr.svg</file> + <file>res/minimize.svg</file> + <file>res/view.svg</file> + <file>res/pin.svg</file> <file>res/view-fullscreen.svg</file> <file>res/view-restore.svg</file> </qresource> diff --git a/x2gokdriveclient.pro b/x2gokdriveclient.pro index f3df708..fab1ed2 100644 --- a/x2gokdriveclient.pro +++ b/x2gokdriveclient.pro @@ -20,5 +20,5 @@ RESOURCES += resources.qrc # Input -SOURCES += main.cpp client.cpp displayarea.cpp -HEADERS += client.h displayarea.h +SOURCES += main.cpp client.cpp displayarea.cpp menuframe.cpp +HEADERS += client.h displayarea.h menuframe.h -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdriveclient.git