From 25b2e77aa2395ba9143683a5ce1a27b99ee7a211 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 4 Jan 2017 16:44:55 -0500 Subject: Create a new "lumina-desktop-unified" core subproject (DO NOT USE) This is just a staging area for the merging of the desktop, window manager, etc.. into a single unified application. It is highly fragmented right now and will not build *AT ALL* for a while. --- .../src-DE/LDesktopPluginSpace.h | 303 +++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.h (limited to 'src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.h') diff --git a/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.h b/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.h new file mode 100644 index 00000000..abc34878 --- /dev/null +++ b/src-qt5/core/lumina-desktop-unified/src-DE/LDesktopPluginSpace.h @@ -0,0 +1,303 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_DESKTOP_LDESKTOP_PLUGIN_SPACE_H +#define _LUMINA_DESKTOP_LDESKTOP_PLUGIN_SPACE_H + +#include +#include +#include //includes all the QDrag*Event classes +#include +#include +#include +#include +#include +#include +#include +#include + +#include "desktop-plugins/LDPlugin.h" + +#define MIMETYPE QString("x-special/lumina-desktop-plugin") + +class LDesktopPluginSpace : public QWidget{ + Q_OBJECT + +signals: + void PluginRemovedByUser(QString ID); + void IncreaseIcons(); //increase default icon sizes + void DecreaseIcons(); //decrease default icon sizes + void HideDesktopMenu(); + +public: + LDesktopPluginSpace(); + ~LDesktopPluginSpace(); + + void LoadItems(QStringList plugs, QStringList files); + //void setShowGrid(bool show); This is already implemented in QTableView (inherited) + void SetIconSize(int size); + void ArrangeTopToBottom(bool ttb); //if false, will arrange left->right + void cleanup(); + + void setBackground(QPixmap pix); //should already be sized appropriately for this widget + void setDesktopArea(QRect area); + +public slots: + void UpdateGeom(int oldgrid = -1); + +private: + QSettings *plugsettings; + QStringList plugins, deskitems; + QList ITEMS; + QPixmap wallpaper; + QRect desktopRect; + bool TopToBottom; + float GRIDSIZE; + + int RoundUp(double num){ + int out = num; //This will truncate the number + if(out < num){ out++; } //need to increase by 1 + return out; + } + + void addDesktopItem(QString filepath); //This will convert it into a valid Plugin ID automatically + void addDesktopPlugin(QString plugID); + + + QRect findOpenSpot(int gridwidth = 1, int gridheight = 1, int startRow = 0, int startCol = 0, bool reversed = false, QString plugID = ""); + QRect findOpenSpot(QRect grid, QString plugID, bool recursive = false); + + QPoint posToGrid(QPoint pos){ + //This assumes a point in widget-relative coordinates + pos.setX( RoundUp(pos.x()/GRIDSIZE)); + pos.setY( RoundUp(pos.y()/GRIDSIZE)); + return pos; + } + + QRect geomToGrid(QRect geom, int grid = -1){ + if(grid<0){ + //use the current grid size + return QRect( RoundUp(geom.x()/GRIDSIZE), RoundUp(geom.y()/GRIDSIZE), \ + RoundUp(geom.width()/GRIDSIZE), RoundUp(geom.height()/GRIDSIZE) ); + }else{ + //use the input grid size + return QRect( RoundUp(geom.x()/((double) grid)), RoundUp(geom.y()/((double) grid)), \ + RoundUp(geom.width()/((double) grid)), RoundUp(geom.height()/((double) grid)) ); + } + } + + QRect gridToGeom(QRect grid){ + //This function incorporates the bottom/right edge matchins procedures (for incomplete last grid) + QRect geom(grid.x()*GRIDSIZE, grid.y()*GRIDSIZE, grid.width()*GRIDSIZE, grid.height()*GRIDSIZE); + //Now check the edge conditions (last right/bottom grid points might be smaller than GRIDSIZE) + QSize areaSize = desktopRect.size(); //use the size of the area instead of the geometry - because we need this in child coordinates like "geom" above + //qDebug() << "GridToGeom:" << grid << geom << "Area size:" << areaSize; + if(geom.right() > areaSize.width() && (geom.right()-areaSize.width()) areaSize.height() && (geom.bottom() -areaSize.height())setData(MIMETYPE, QString(type+"::::"+id).toLocal8Bit() ); + //If this is a desktop file - also add it to the generic URI list mimetype + if(id.startsWith("applauncher::")){ + QList urilist; + urilist << QUrl::fromLocalFile( id.section("---",0,0).section("::",1,50) ); + mime->setUrls(urilist); + } + //Create the drag structure + QDrag *drag = new QDrag(this); + drag->setMimeData(mime); + drag->exec(Qt::CopyAction); + } + + bool ValidGrid(QRect grid){ + //qDebug() << "Check Valid Grid:" << grid << RoundUp(this->width()/GRIDSIZE) << RoundUp(this->height()/GRIDSIZE); + //This just checks that the grid coordinates are not out of bounds - should still run ValidGeometry() below with the actual pixel geom + if(grid.x()<0 || grid.y()<0 || grid.width()<0 || grid.height()<0){ return false; } + else if( (grid.x()+grid.width()) > RoundUp(desktopRect.width()/GRIDSIZE) ){ return false; } + else if( (grid.y()+grid.height()) > RoundUp(desktopRect.height()/GRIDSIZE) ){ return false; } + return true; + } + + bool ValidGeometry(QString id, QRect geom){ + //First check that it is within the desktop area completely + // Note that "this->geometry()" is not in the same coordinate space as the geometry inputs + if(!QRect(0,0,desktopRect.width(), desktopRect.height()).contains(geom)){ return false; } + //Now check that it does not collide with any other items + for(int i=0; iwhatsThis()==id){ continue; } + else if(geom.intersects(ITEMS[i]->geometry())){ return false; } + } + return true; + } + + LDPlugin* ItemFromID(QString ID){ + for(int i=0; iwhatsThis()==ID){ return ITEMS[i]; } + } + return 0; + } + + void MovePlugin(LDPlugin* plug, QRect geom){ + plug->setGeometry( geom ); + plug->setFixedSize(geom.size()); //needed for some plugins + plug->savePluginGeometry(geom); + } + +private slots: + void reloadPlugins(bool ForceIconUpdate = false); + + void StartItemMove(QString ID){ + setupDrag(ID, "move"); + } + void StartItemResize(QString ID){ + setupDrag(ID, "resize"); + } + void RemoveItem(QString ID){ + //Special case - desktop file/dir link using the "applauncher" plugin + if(ID.startsWith("applauncher::")){ + QFileInfo info(ID.section("---",0,0).section("::",1,50) ); + if(info.exists() && info.absolutePath()==QDir::homePath()+"/Desktop"){ + qDebug() << "Deleting Desktop Item:" << info.absoluteFilePath(); + if(!info.isSymLink() && info.isDir()){ QProcess::startDetached("rm -r \""+info.absoluteFilePath()+"\""); } + else{ QFile::remove(info.absoluteFilePath()); } //just remove the file/symlink directly + emit PluginRemovedByUser(ID); + return; + } + } + //Any other type of plugin + for(int i=0; iwhatsThis()==ID){ + ITEMS[i]->Cleanup(); + ITEMS.takeAt(i)->deleteLater(); + break; + } + } + emit PluginRemovedByUser(ID); + } + +protected: + void focusInEvent(QFocusEvent *ev){ + this->lower(); //make sure we stay on the bottom of the window stack + QWidget::focusInEvent(ev); //do normal handling + } + void paintEvent(QPaintEvent*ev); + + //Need Drag and Drop functionality (internal movement) + void dragEnterEvent(QDragEnterEvent *ev){ + if(ev->mimeData()->hasFormat(MIMETYPE) ){ + ev->acceptProposedAction(); //allow this to be dropped here + }else if(ev->mimeData()->hasUrls()){ + ev->acceptProposedAction(); //allow this to be dropped here + }else{ + ev->ignore(); + } + } + + void dragMoveEvent(QDragMoveEvent *ev){ + if(ev->mimeData()->hasFormat(MIMETYPE) ){ + //Internal move/resize - Check for validity + QString act = QString( ev->mimeData()->data(MIMETYPE) ); + LDPlugin *item = ItemFromID(act.section("::::",1,50)); + //qDebug() << "Internal Move Event:" << act << ev->pos(); + if(item!=0){ + QRect geom = item->geometry(); + QPoint grid = posToGrid(ev->pos()); + if(act.section("::::",0,0)=="move"){ + QPoint diff = grid - posToGrid(geom.center()); //difference in grid coords + //qDebug() << "Move Event:" << "Diff:" << diff << "Geom:" << geom << grid << ev->pos(); + geom = geomToGrid(geom); //convert to grid coords + //qDebug() << "Move Event:" << "Old geom (grid):" << geom; + geom.moveTo( (geom.topLeft()+diff) ); + //qDebug() << " - After Move:" << geom; + bool valid = ValidGrid(geom); + if(valid){ + //Convert to pixel coordinates and check validity again + geom = gridToGeom(geom); //convert back to px coords with edge matching + valid = ValidGeometry(act.section("::::",1,50), geom); + } + if(valid){ + MovePlugin(item, geom); + //item->setGeometry(geom); + //item->setFixedSize(geom.size()); //needed due to resizing limitations and such for some plugins + ev->acceptProposedAction(); + //item->savePluginGeometry(geom); //save in pixel coords + }else{ ev->ignore(); } //invalid location + + }else{ + //Resize operation + QPoint diff = ev->pos() - (geom.center()-QPoint(1,1)); //need difference from center (pixels) + //Note: Use the 1x1 pixel offset to ensure that the center point is not exactly on a grid point intersection (2x2, 4x4, etc) + //qDebug() << "Resize Plugin:" << geom << grid << posToGrid(geom.center()) << diff; + geom = geomToGrid(geom); //convert to grid coordinates now + //qDebug() << " - Grid Geom:" << geom; + if(diff.x()<0){ geom.setLeft(ev->pos().x()/GRIDSIZE); } //expanding to the left (round down) + else if(diff.x()>0){ geom.setRight( ev->pos().x()/GRIDSIZE); } //expanding to the right (round down) + if(diff.y()<0){ geom.setTop( ev->pos().y()/GRIDSIZE); } //expanding above (round down) + else if(diff.y()>0){ geom.setBottom( ev->pos().y()/GRIDSIZE); } //expanding below (round down) + //qDebug() << " - Adjusted:" << geom; + bool valid = ValidGrid(geom); + if(valid){ + //Convert to pixel coordinates and check validity again + geom = gridToGeom(geom); //convert back to px coords with edge matching + valid = ValidGeometry(act.section("::::",1,50), geom); + } + if(valid){ + MovePlugin(item, geom); + //item->setGeometry(geom); + //item->setFixedSize(geom.size()); //needed due to resizing limitations and such for some plugins + ev->acceptProposedAction(); + //item->savePluginGeometry(geom); //save in pixel coords + }else{ ev->ignore(); } //invalid location + } + } + }else if(ev->mimeData()->hasUrls()){ + ev->acceptProposedAction(); //allow this to be dropped here + }else{ + ev->ignore(); + } + } + + void dropEvent(QDropEvent *ev){ + //QPoint grid = posToGrid(ev->pos()); + if(ev->mimeData()->hasFormat(MIMETYPE)){ + //Desktop Items getting moved around - already performed in the dragMoveEvent + ev->accept(); + }else if(ev->mimeData()->hasUrls()){ + ev->accept(); + //Files getting dropped here + QList urls = ev->mimeData()->urls(); + qDebug() << "Desktop Drop Event:" << urls; + for(int i=0; iignore(); + } + } + +}; + +#endif -- cgit