diff options
Diffstat (limited to 'src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.cpp')
-rw-r--r-- | src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.cpp | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.cpp b/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.cpp new file mode 100644 index 00000000..18126dfa --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.cpp @@ -0,0 +1,333 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "LDesktopPluginSpace.h" +#include "LSession.h" +#include "desktop-plugins/NewDP.h" + +#include <LuminaXDG.h> +#include <QDesktopWidget> + +#define DEBUG 0 + +// =================== +// PUBLIC +// =================== +LDesktopPluginSpace::LDesktopPluginSpace() : QWidget(){ + this->setObjectName("LuminaDesktopPluginSpace"); + this->setAttribute(Qt::WA_TranslucentBackground); + //this->setAttribute(Qt::WA_NoSystemBackground); + this->setAutoFillBackground(false); + this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }"); + this->setWindowFlags(Qt::WindowStaysOnBottomHint | Qt::CustomizeWindowHint | Qt::FramelessWindowHint); + this->setAcceptDrops(true); + this->setContextMenuPolicy(Qt::NoContextMenu); + this->setMouseTracking(true); + TopToBottom = true; + GRIDSIZE = 100.0; //default value if not set + plugsettings = LSession::handle()->DesktopPluginSettings(); + LSession::handle()->XCB->SetAsDesktop(this->winId()); + //this->setWindowOpacity(0.0); +} + +LDesktopPluginSpace::~LDesktopPluginSpace(){ + +} + +void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){ + if(DEBUG){ qDebug() << "Loading Desktop Items:" << plugs << files << "Area:" << this->size() << GRIDSIZE; } + bool changes = false; + if(plugs != plugins){ plugins = plugs; changes = true; } + if(files != deskitems){ deskitems = files; changes = true; } + if(changes){ QTimer::singleShot(0,this, SLOT(reloadPlugins())); } + this->show(); +} + +void LDesktopPluginSpace::SetIconSize(int size){ + if(DEBUG){ qDebug() << "Set Desktop Icon Size:" << size; } + //QSize newsize = calculateItemSize(size); + int oldsize = GRIDSIZE; + GRIDSIZE = size; //turn the int into a float; + //itemSize = QSize(1,1); //save this for all the later icons which are generated (grid size) + UpdateGeom(oldsize); + //Now re-set the item icon size + //reloadPlugins(true); +} + +void LDesktopPluginSpace::cleanup(){ + //Perform any final cleanup actions here + for(int i=0; i<ITEMS.length(); i++){ + ITEMS.takeAt(i)->deleteLater(); + i--; + } + plugins.clear(); + deskitems.clear(); + this->hide(); +} + +void LDesktopPluginSpace::setBackground(QPixmap pix){ + wallpaper = pix; + this->repaint(); +} + +void LDesktopPluginSpace::setDesktopArea(QRect area){ + desktopRect = area; +} + +// =================== +// PUBLIC SLOTS +// =================== +void LDesktopPluginSpace::UpdateGeom(int oldgrid){ + if(DEBUG){ qDebug() << "Updated Desktop Geom:" << desktopRect.size() << GRIDSIZE << desktopRect.size()/GRIDSIZE; } + //Go through and check the locations/sizes of all items (particularly the ones on the bottom/right edges) + //bool reload = false; + for(int i=0; i<ITEMS.length(); i++){ + QRect grid = geomToGrid(ITEMS[i]->geometry(), oldgrid); + if(DEBUG){ qDebug() << " - Check Plugin:" << ITEMS[i]->whatsThis() << grid; } + if( !ValidGrid(grid) ){ + //This plugin is too far out of the screen - find new location for it + if(DEBUG){ qDebug() << " -- Out of bounds - Find a new spot"; } + grid = findOpenSpot(grid, ITEMS[i]->whatsThis(), true); //Reverse lookup spot + } + if(!ValidGrid(grid)){ + qDebug() << "No Place for plugin:" << ITEMS[i]->whatsThis(); + qDebug() << " - Removing it for now..."; + ITEMS.takeAt(i)->deleteLater(); + i--; + }else{ + //NOTE: We are not doing the ValidGeometry() checks because we are only resizing existing plugin with pre-set & valid grid positions + grid = gridToGeom(grid); //convert to pixels before saving/sizing + MovePlugin(ITEMS[i], grid); + /*ITEMS[i]->setGeometry( grid ); + ITEMS[i]->setFixedSize(grid.size()); + ITEMS[i]->savePluginGeometry(grid);*/ + } + } + //if(reload){ QTimer::singleShot(0,this, SLOT(reloadPlugins())); } +} + +// =================== +// PRIVATE +// =================== +void LDesktopPluginSpace::addDesktopItem(QString filepath){ + addDesktopPlugin("applauncher::"+filepath+"---dlink"+QString::number(LSession::handle()->desktop()->screenNumber(this)) ); +} + +void LDesktopPluginSpace::addDesktopPlugin(QString plugID){ + //This is used for generic plugins (QWidget-based) + if(DEBUG){ qDebug() << "Adding Desktop Plugin:" << plugID; } + LDPlugin *plug = NewDP::createPlugin(plugID, this); + if(plug==0){ return; } //invalid plugin + //plug->setAttribute(Qt::WA_TranslucentBackground); + plug->setWhatsThis(plugID); + //Now get the geometry for the plugin + QRect geom = plug->loadPluginGeometry(); //in pixel coords + if(!geom.isNull()){ geom = geomToGrid(geom); } //convert to grid coordinates + if(geom.isNull()){ + //No previous location - need to calculate initial geom + QSize sz = plug->defaultPluginSize(); //in grid coordinates + geom.setSize(sz); + //if an applauncher - add from top-left, otherwise add in from bottom-right + if(plugID.startsWith("applauncher")){ geom = findOpenSpot(geom.width(), geom.height() ); } + else{ geom = findOpenSpot(geom.width(), geom.height(), RoundUp(this->height()/GRIDSIZE), RoundUp(this->width()/GRIDSIZE), true); } + }else if(!ValidGeometry(plugID, gridToGeom(geom)) ){ + //Find a new location for the plugin (saved location is invalid) + geom = findOpenSpot(geom.width(), geom.height(), geom.y(), geom.x(), false); //try to get it within the same general area first + } + if(geom.x() < 0 || geom.y() < 0){ + qDebug() << "No available space for desktop plugin:" << plugID << " - IGNORING"; + delete plug; + }else{ + if(DEBUG){ qDebug() << " - New Plugin Geometry (grid):" << geom; } + //Now place the item in the proper spot/size + MovePlugin(plug, gridToGeom(geom)); + //plug->setGeometry( gridToGeom(geom) ); + plug->show(); + if(DEBUG){ qDebug() << " - New Plugin Geometry (px):" << plug->geometry(); } + ITEMS << plug; + connect(plug, SIGNAL(StartMoving(QString)), this, SLOT(StartItemMove(QString)) ); + connect(plug, SIGNAL(StartResizing(QString)), this, SLOT(StartItemResize(QString)) ); + connect(plug, SIGNAL(RemovePlugin(QString)), this, SLOT(RemoveItem(QString)) ); + connect(plug, SIGNAL(IncreaseIconSize()), this, SIGNAL(IncreaseIcons()) ); + connect(plug, SIGNAL(DecreaseIconSize()), this, SIGNAL(DecreaseIcons()) ); + connect(plug, SIGNAL(CloseDesktopMenu()), this, SIGNAL(HideDesktopMenu()) ); + } +} + +QRect LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int startRow, int startCol, bool reversed, QString plugID){ + //Note about the return QPoint: x() is the column number, y() is the row number + QPoint pt(0,0); + //qDebug() << "FIND OPEN SPOT:" << gridwidth << gridheight << startRow << startCol << reversed; + int row = startRow; int col = startCol; + if(row<0){ row = 0; } //just in case - since this can be recursively called + if(col<0){ col = 0; } //just in case - since this can be recursively called + bool found = false; + int rowCount, colCount; + rowCount = RoundUp(desktopRect.height()/GRIDSIZE); + colCount = RoundUp(desktopRect.width()/GRIDSIZE); + if( (row+gridheight)>rowCount){ row = rowCount-gridheight; startRow = row; } + if( (col+gridwidth)>colCount){ col = colCount-gridwidth; startCol = col; } + QRect geom(0, 0, gridwidth*GRIDSIZE, gridheight*GRIDSIZE); //origin point will be adjusted in a moment + if(DEBUG){ qDebug() << "Search for plugin space:" << rowCount << colCount << gridheight << gridwidth << this->size(); } + if(TopToBottom && reversed && (startRow>0 || startCol>0) ){ + //Arrange Top->Bottom (work backwards) + //qDebug() << "Search backwards for space:" << rowCount << colCount << startRow << startCol << gridheight << gridwidth; + while(col>=0 && !found){ + while(row>=0 && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //qDebug() << " - Check Geom:" << geom << col << row; + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(ITEMS[i]->whatsThis()==plugID){ continue; } //same plugin - this is not a conflict + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + //qDebug() << "Collision:" << col << row; + row = ((ITEMS[i]->geometry().y()-GRIDSIZE/2)/GRIDSIZE) -gridheight; //use top edge for next search (minus item height) + //qDebug() << " - new row:" << row; + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + } + if(!found){ col--; row=rowCount-gridheight; } //go to the previous column + } + }else if(TopToBottom){ + //Arrange Top->Bottom + while(col<(colCount-gridwidth) && !found){ + while(row<(rowCount-gridheight) && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //qDebug() << " - Check Geom:" << geom << col << row; + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(ITEMS[i]->whatsThis()==plugID){ continue; } //same plugin - this is not a conflict + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + row = posToGrid(ITEMS[i]->geometry().bottomLeft()).y(); //use bottom edge for next search + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + //else{ row++; } + } + if(!found){ col++; row=0; } //go to the next column + } + }else if(reversed && (startRow>0 || startCol>0) ){ + //Arrange Left->Right (work backwards) + while(row>=0 && !found){ + while(col>=0 && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(ITEMS[i]->whatsThis()==plugID){ continue; } //same plugin - this is not a conflict + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + col = (ITEMS[i]->geometry().x()-GRIDSIZE/2)/GRIDSIZE - gridwidth; // Fill according to row/column + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + //else{ col++; } + } + if(!found){ row--; col=colCount-gridwidth;} //go to the previous row + } + }else{ + //Arrange Left->Right + while(row<(rowCount-gridheight) && !found){ + while(col<(colCount-gridwidth) && !found){ + bool ok = true; + geom.moveTo(col*GRIDSIZE, row*GRIDSIZE); + //Check all the existing items to ensure no overlap + for(int i=0; i<ITEMS.length() && ok; i++){ + if(ITEMS[i]->whatsThis()==plugID){ continue; } //same plugin - this is not a conflict + if(geom.intersects(ITEMS[i]->geometry())){ + //Collision - move the next searchable row/column index + ok = false; + col = posToGrid(ITEMS[i]->geometry().topRight()).x(); // Fill according to row/column + } + } + if(ok){ pt = QPoint(col,row); found = true; } //found an open spot + //else{ col++; } + } + if(!found){ row++; col=0;} //go to the next row + } + } + if(!found){ + //qDebug() << "Could not find a spot:" << startRow << startCol << gridheight << gridwidth; + if( (startRow!=0 || startCol!=0) && !reversed){ + //Did not check the entire screen yet - gradually work it's way back to the top/left corner + //qDebug() << " - Start backwards search"; + return findOpenSpot(gridwidth, gridheight,startRow,startCol, true); //reverse the scan + }else if(gridwidth>1 && gridheight>1){ + //Decrease the size of the item by 1x1 grid points and try again + //qDebug() << " - Out of space: Decrease item size and try again..."; + return findOpenSpot(gridwidth-1, gridheight-1, 0, 0); + }else{ + //qDebug() << " - Could not find an open spot for a desktop plugin:" << gridwidth << gridheight << startRow << startCol; + return QRect(-1,-1,-1,-1); + } + }else{ + return QRect(pt,QSize(gridwidth,gridheight)); + } +} + +QRect LDesktopPluginSpace::findOpenSpot(QRect grid, QString plugID, bool recursive){ //Reverse lookup spotc{ + //This is just an overloaded simplification for checking currently existing plugins + return findOpenSpot(grid.width(), grid.height(), grid.y(), grid.x(), recursive, plugID); +} + +// =================== +// PRIVATE SLOTS +// =================== +void LDesktopPluginSpace::reloadPlugins(bool ForceIconUpdate ){ + //Remove any plugins as necessary + QStringList plugs = plugins; + QStringList items = deskitems; + for(int i=0; i<ITEMS.length(); i++){ + + if( ITEMS[i]->whatsThis().startsWith("applauncher") && ForceIconUpdate){ + //Change the size of the existing plugin - preserving the location if possible + /*QRect geom = ITEMS[i]->loadPluginGeometry(); //pixel coords + if(!geom.isNull()){ + geom = geomToGrid(geom); //convert to grid coords + geom.setSize(itemSize); //Reset back to default size (does not change location) + ITEMS[i]->savePluginGeometry( gridToGeom(geom)); //save it back in pixel coords + }*/ + //Now remove the plugin for the moment - run it through the re-creation routine below + ITEMS.takeAt(i)->deleteLater(); + i--; + } + else if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); } + else if(items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50))){ items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)); } + else{ ITEMS[i]->removeSettings(true); ITEMS.takeAt(i)->deleteLater(); i--; } //this is considered a permanent removal (cleans settings) + } + + //Now create any new items + //First load the plugins (almost always have fixed locations) + for(int i=0; i<plugs.length(); i++){ + addDesktopPlugin(plugs[i]); + } + //Now load the desktop shortcuts (fill in the gaps as needed) + for(int i=0; i<items.length(); i++){ + addDesktopItem(items[i]); + } +} + + +//================= +// PROTECTED +//================= +void LDesktopPluginSpace::paintEvent(QPaintEvent*ev){ + if(!wallpaper.isNull()){ + QPainter painter(this); + painter.setBrush(wallpaper); + painter.drawRect(ev->rect().adjusted(-1,-1,2,2)); + }else{ + QWidget::paintEvent(ev); + } +} |