aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/experimental/lumina-terminal/TermWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/experimental/lumina-terminal/TermWindow.cpp')
-rw-r--r--src-qt5/experimental/lumina-terminal/TermWindow.cpp316
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());
+}
bgstack15