diff options
Diffstat (limited to 'src-qt5/experimental/lumina-terminal/TermWindow.cpp')
-rw-r--r-- | src-qt5/experimental/lumina-terminal/TermWindow.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/src-qt5/experimental/lumina-terminal/TermWindow.cpp b/src-qt5/experimental/lumina-terminal/TermWindow.cpp new file mode 100644 index 00000000..812d3679 --- /dev/null +++ b/src-qt5/experimental/lumina-terminal/TermWindow.cpp @@ -0,0 +1,316 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "TermWindow.h" +//#include "ui_TermWindow.h" + +#include <QDesktopWidget> +#include <QDebug> +#include <QTimer> +#include <QApplication> +#include <QVBoxLayout> +#include "TerminalWidget.h" + +// =============== +// PUBLIC +// =============== +TermWindow::TermWindow(QSettings *set) : QWidget(0, Qt::Window | Qt::BypassWindowManagerHint){//, ui(new Ui::TermWindow){ + this->setWindowOpacity(0.85); + CLOSING = false; //internal flag + settings = set; + //Create the Window + this->setLayout(new QVBoxLayout()); + this->setCursor(Qt::SplitVCursor); + tabWidget = new QTabWidget(this); + tabWidget->clear(); //just in case + tabWidget->setCursor(Qt::ArrowCursor); + tabWidget->setTabBarAutoHide(true); + tabWidget->setTabsClosable(true); + tabWidget->setMovable(true); + tabWidget->setUsesScrollButtons(true); + tabWidget->setFocusPolicy(Qt::ClickFocus); + this->layout()->addWidget(tabWidget); + //Setup the animation + ANIM = new QPropertyAnimation(this, "geometry", this); + ANIM->setDuration(300); //1/3 second animation + connect(ANIM, SIGNAL(finished()), this, SLOT(AnimFinished()) ); + activeTimer = new QTimer(this); + activeTimer->setInterval(50); + activeTimer->setSingleShot(true); + connect(activeTimer, SIGNAL(timeout()), this, SLOT(activeStatusChanged()) ); + connect(QApplication::instance(), SIGNAL(applicationStateChanged(Qt::ApplicationState)), activeTimer, SLOT(start()) ); + //Create the keyboard shortcuts + //hideS = new QShortcut(QKeySequence(Qt::Key_Escape),this); + closeS = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q),this); + newTabS = new QShortcut(QKeySequence::AddTab,this); + closeTabS = new QShortcut(QKeySequence::Close,this); + prevTabS = new QShortcut(QKeySequence::PreviousChild,this); + nextTabS = new QShortcut(QKeySequence::NextChild,this); + //Print out all the keyboard shortcuts onto the screen + qDebug() << "New Tab Shortcut:" << QKeySequence::keyBindings(QKeySequence::AddTab); + qDebug() << "Close Tab Shortcut:" << QKeySequence::keyBindings(QKeySequence::Close); + qDebug() << "Next Tab Shortcut:" << QKeySequence::keyBindings(QKeySequence::NextChild); + qDebug() << "Previous Tab Shortcut:" << QKeySequence::keyBindings(QKeySequence::PreviousChild); + //Connect the signals/slots + connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(Close_Tab(int)) ); + connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(focusOnWidget()) ); + connect(closeTabS, SIGNAL(activated()), this, SLOT(Close_Tab()) ); + connect(newTabS, SIGNAL(activated()), this, SLOT(New_Tab()) ); + //connect(hideS, SIGNAL(activated()), this, SLOT(HideWindow()) ); + connect(closeS, SIGNAL(activated()), this, SLOT(CloseWindow()) ); + connect(prevTabS, SIGNAL(activated()), this, SLOT(Prev_Tab()) ); + connect(nextTabS, SIGNAL(activated()), this, SLOT(Next_Tab()) ); + //Now set the defaults + screennum = 0; //default value + setTopOfScreen(true); //default value + if(settings->contains("lastSize")){ + //qDebug() << "Re-use last size:" << settings->value("lastSize").toSize(); + this->resize( settings->value("lastSize").toSize() ); + CalculateGeom(); + //qDebug() << "After size:" << this->size(); + } + + //this->resize(this->width(),300); + //this->setMinimumSize(20, 300); + +} + + +TermWindow::~TermWindow(){ + +} + +void TermWindow::cleanup(){ + //called right before the window is closed + //Make sure to close any open tabs/processes + CLOSING = true; + for(int i=0; i<tabWidget->count(); i++){ + static_cast<TerminalWidget*>(tabWidget->widget(i))->aboutToClose(); + } +} + +void TermWindow::OpenDirs(QStringList dirs){ + for(int i=0; i<dirs.length(); i++){ + //Open a new tab for each directory + TerminalWidget *page = new TerminalWidget(tabWidget, dirs[i]); + QString ID = GenerateTabID(); + page->setWhatsThis(ID); + tabWidget->addTab(page, ID); + tabWidget->setCurrentWidget(page); + QTimer::singleShot(500, this, SLOT(focusOnWidget()));//page->setFocus(); + qDebug() << "New Tab:" << ID << dirs[i]; + connect(page, SIGNAL(ProcessClosed(QString)), this, SLOT(Close_Tab(QString)) ); + } +} + +void TermWindow::setCurrentScreen(int num){ + screennum = num; + QTimer::singleShot(0,this, SLOT(ReShowWindow())); +} + +void TermWindow::setTopOfScreen(bool ontop){ + onTop = ontop; + this->layout()->setContentsMargins(0, (onTop ? 0 : 3), 0, (onTop ? 3 : 0)); + tabWidget->setTabPosition(onTop ? QTabWidget::South : QTabWidget::North); + QTimer::singleShot(0,this, SLOT(ReShowWindow())); +} + +// ======================= +// PUBLIC SLOTS +// ======================= +void TermWindow::ShowWindow(){ + if(animRunning>=0){ return; } //something running + animRunning = 1; + this->hide(); + QApplication::processEvents(); + CalculateGeom(); + //Now setup the animation + ANIM->setEndValue(this->geometry()); + if(onTop){ //use top edge + ANIM->setStartValue( QRect(this->x(), this->y(), this->width(), 0) ); //same location - no height + }else{ + ANIM->setStartValue( QRect(this->x(), this->geometry().bottom(), this->width(), 0) ); //same location - no height + } + this->show(); + //qDebug() << "Start Animation" << ANIM->startValue() << ANIM->endValue(); + ANIM->start(); +} + +void TermWindow::HideWindow(){ + if(animRunning>=0){ return; } //something running + //Now setup the animation + //Note: Do *not* use the private settings/variables because it may be changing right now - use the current geometry *ONLY* + animRunning = 0; + ANIM->setStartValue(this->geometry()); + QDesktopWidget *desk = QApplication::desktop(); + int screen = desk->screenNumber(this); //which screen it is currently on + if(desk->availableGeometry(screen).top() == this->geometry().top()){ //use top edge + ANIM->setEndValue( QRect(this->x(), this->y(), this->width(), 0) ); //same location - no height + }else{ + ANIM->setEndValue( QRect(this->x(), this->y()+this->height(), this->width(), 0) ); //same location - no height + } + this->show(); + ANIM->start(); +} + +void TermWindow::CloseWindow(){ + if(animRunning>=0){ return; } //something running + //Now setup the animation + animRunning = 2; + ANIM->setStartValue(this->geometry()); + if(onTop){ //use top edge + ANIM->setEndValue( QRect(this->x(), this->y(), this->width(), 0) ); //same location - no height + }else{ + ANIM->setEndValue( QRect(this->x(), this->geometry().bottom(), this->width(), 0) ); //same location - no height + } + this->show(); + ANIM->start(); +} + +void TermWindow::ReShowWindow(){ + if(this->isVisible()){ + HideWindow(); //start with same animation as hide + animRunning = 3; //flag as a re-show (hide, then show); + }else{ + //Already hidden, just show it + ShowWindow(); + } +} +// ======================= +// PRIVATE +// ======================= +void TermWindow::CalculateGeom(){ + //qDebug() << "Calculating Geom:" << this->size(); + QDesktopWidget *desk = QApplication::desktop(); + if(desk->screenCount() <= screennum){ screennum = desk->primaryScreen(); } //invalid screen detected + //Now align the window with the proper screen edge + QRect workarea = desk->availableGeometry(screennum); //this respects the WORKAREA property + if(onTop){ + this->setGeometry( workarea.x(), workarea.y(), workarea.width(), this->height()); //maintain current hight of window + + }else{ + this->setGeometry( workarea.x(), workarea.y() + workarea.height() - this->height(), workarea.width(), this->height()); //maintain current hight of window + } + this->setFixedWidth(this->width()); //Make sure the window is not re-sizeable in the width dimension + this->setMinimumHeight(0); +} + +QString TermWindow::GenerateTabID(){ + //generate a unique ID for this new tab + int num = 1; + for(int i=0; i<tabWidget->count(); i++){ + if(tabWidget->widget(i)->whatsThis().toInt() >= num){ num = tabWidget->widget(i)->whatsThis().toInt()+1; } + } + return QString::number(num); +} + +// ======================= +// PRIVATE SLOTS +// ======================= + +//Tab Interactions +void TermWindow::New_Tab(){ + OpenDirs(QStringList() << QDir::homePath()); +} + +void TermWindow::Close_Tab(int tab){ + qDebug() << "Close Tab:" << tab; + if(tab<0){ tab = tabWidget->currentIndex(); } + static_cast<TerminalWidget*>(tabWidget->widget(tab))->aboutToClose(); + tabWidget->widget(tab)->deleteLater(); //delete the page within the tag + tabWidget->removeTab(tab); // remove the tab itself + //Let the tray know when the last terminal is closed + if(tabWidget->count() < 1){ + emit TerminalFinished(); + } +} + +void TermWindow::Close_Tab(QString ID){ + //Close a tab based on it's ID instead of it's tab number + qDebug() << "Close Tab by ID:" << ID; + for(int i=0; i<tabWidget->count(); i++){ + if(tabWidget->widget(i)->whatsThis()==ID){ + qDebug() << " - Start close by number:" << i; + Close_Tab(i); + return; //all done + } + } +} + +void TermWindow::Next_Tab(){ + qDebug() << "Next Tab"; + int next = tabWidget->currentIndex()+1; + if(next>=tabWidget->count()){ next = 0; } + tabWidget->setCurrentIndex(next); +} + +void TermWindow::Prev_Tab(){ + qDebug() << "Previous Tab"; + int next = tabWidget->currentIndex()-1; + if(next<0){ next = tabWidget->count()-1; } + tabWidget->setCurrentIndex(next); +} + +void TermWindow::focusOnWidget(){ + if(tabWidget->currentWidget()!=0){ + //qDebug() << "Focus on Widget"; + tabWidget->currentWidget()->setFocus(); + } +} + +//Animation finishing +void TermWindow::AnimFinished(){ + if(animRunning <0){ return; } //nothing running + if(animRunning==0){ + //Hide Event + this->hide(); //need to hide the whole thing now + this->setGeometry( ANIM->startValue().toRect() ); //reset back to initial size after hidden + emit TerminalHidden(); + }else if(animRunning==1){ + //Show Event + this->activateWindow(); + tabWidget->currentWidget()->setFocus(); + emit TerminalVisible(); + }else if(animRunning==2){ + //Close Event + this->hide(); //need to hide the whole thing now + emit TerminalClosed(); + }else if(animRunning>2){ + //Re-Show event + this->hide(); + this->setGeometry( ANIM->startValue().toRect() ); //reset back to initial size after hidden + //Now re-show it + QTimer::singleShot(0,this, SLOT(ShowWindow())); + } + animRunning = -1; //done +} + +void TermWindow::activeStatusChanged(){ + if(animRunning>=0){ return; } //ignore this event - already changing + QWidget *active = QApplication::activeWindow(); + if(active==0 && this->isVisible()){ HideWindow(); } +} + +// =================== +// PROTECTED +// =================== +void TermWindow::mouseMoveEvent(QMouseEvent *ev){ + //Note: With mouse tracking turned off, this event only happens when the user is holding down the mouse button + if(onTop){ + //Move the bottom edge to the current point + if( (ev->globalPos().y() - this->y()) < 50){ return; } //quick check that the window is not smaller than 20 pixels + QRect geom = this->geometry(); + geom.setBottom(ev->globalPos().y()); + this->setGeometry(geom); + }else{ + //Move the top edge to the current point + if( (this->y() + this->height() -ev->globalPos().y()) < 50){ return; } //quick check that the window is not smaller than 20 pixels + QRect geom = this->geometry(); + geom.setTop(ev->globalPos().y()); + this->setGeometry(geom); + } + settings->setValue("lastSize",this->geometry().size()); +} |