diff options
Diffstat (limited to 'lumina-desktop/LDesktopPluginSpace.h')
-rw-r--r-- | lumina-desktop/LDesktopPluginSpace.h | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/lumina-desktop/LDesktopPluginSpace.h b/lumina-desktop/LDesktopPluginSpace.h new file mode 100644 index 00000000..353543d9 --- /dev/null +++ b/lumina-desktop/LDesktopPluginSpace.h @@ -0,0 +1,231 @@ +//=========================================== +// 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 <QListWidget> +#include <QDropEvent> +#include <QDrag> //includes all the QDrag*Event classes +#include <QUrl> +#include <QMimeData> +#include <QSettings> +#include <QDebug> + +#include "desktop-plugins/LDPlugin.h" + +#define MIMETYPE QString("x-special/lumina-desktop-plugin") +//#define MIMEPOS QString("x-special/lumina-desktop-plugin-pos") +#define GRIDSIZE 16.0 //Need this to be a double/float - usually used for divisions + +class LDesktopPluginSpace : public QWidget{ + Q_OBJECT + +signals: + void PluginRemovedByUser(QString ID); + +public: + LDesktopPluginSpace(QWidget *parent = 0); + ~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(); + +public slots: + void UpdateGeom(); + +private: + QSettings *plugsettings; + QSize itemSize; + QStringList plugins, deskitems; + QList<LDPlugin*> ITEMS; + bool TopToBottom; + + int RoundUp(double num){ + int out = num; //This will truncate the number + if(out < num){ out++; } //need to increase by 1 + return out; + } + + QSize calculateItemSize(int icosize); + void addDesktopItem(QString filepath); //This will convert it into a valid Plugin ID + void addDesktopPlugin(QString plugID); + + + QPoint findOpenSpot(int gridwidth = 1, int gridheight = 1, int startRow = 0, int startCol = 0); + + 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){ + return QRect( RoundUp(geom.x()/GRIDSIZE), RoundUp(geom.y()/GRIDSIZE), \ + RoundUp(geom.width()/GRIDSIZE), RoundUp(geom.height()/GRIDSIZE) ); + + } + 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) + //qDebug() << "GridToGeom:" << grid << geom; + if(geom.right() > this->geometry().right() && (geom.right() -this->geometry().right())<GRIDSIZE ){ + geom.setRight(this->geometry().right()); //match up with the edge + } + if(geom.bottom() > this->geometry().bottom() && (geom.bottom() -this->geometry().bottom())<GRIDSIZE ){ + geom.setBottom(this->geometry().bottom()); //match up with the edge + } + //qDebug() << " - Adjusted:" << geom; + return geom; + } + + //Internal simplification for setting up a drag event + void setupDrag(QString id, QString type){ + QMimeData *mime = new QMimeData; + mime->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<QUrl> 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 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,this->width(), this->height()).contains(geom)){ return false; } + //Now check that it does not collide with any other items + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==id){ continue; } + else if(geom.intersects(ITEMS[i]->geometry())){ return false; } + } + return true; + } + + LDPlugin* ItemFromID(QString ID){ + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==ID){ return ITEMS[i]; } + } + return 0; + } + +private slots: + void reloadPlugins(); + + void StartItemMove(QString ID){ + setupDrag(ID, "move"); + } + void StartItemResize(QString ID){ + setupDrag(ID, "resize"); + } + void RemoveItem(QString ID){ + for(int i=0; i<ITEMS.length(); i++){ + if(ITEMS[i]->whatsThis()==ID){ + ITEMS[i]->Cleanup(); + delete ITEMS.takeAt(i); + emit PluginRemovedByUser(ID); + return; + } + } + } + +protected: + //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 + geom.moveTo( (geom.topLeft()+diff) ); + geom = gridToGeom(geom); //convert back to px coords with edge matching + //qDebug() << " - Setting Geometry:" << geom; + if(ValidGeometry(act.section("::::",1,50), geom)){ + item->setGeometry(geom); + ev->acceptProposedAction(); + item->savePluginGeometry(geomToGrid(geom)); + }else{ ev->ignore(); } //invalid location + + }else{ + //Resize operation + QPoint diff = grid - posToGrid(geom.center());; //need difference from center (grid) + geom = geomToGrid(geom); //convert to grid coordinates now + if(diff.x()==0 && diff.y()==0){ + ev->acceptProposedAction(); //nothing to do - but keep the drag active + }else{ + if(diff.x()<0){ geom.setLeft( grid.x()); } //expanding to the left + else if(diff.x()>0){ geom.setRight( grid.x()); } //expanding to the right + if(diff.y()<0){ geom.setTop( grid.y()); } //expanding above + else if(diff.y()>0){ geom.setBottom( grid.y()); } //expanding below + //Now convert back to pixel coords (includes edge matching/adjustments) + geom = gridToGeom(geom); + //Check Validity of new geom + if(ValidGeometry(act.section("::::",1,50), geom)){ + item->setGeometry(geom); + ev->acceptProposedAction(); + item->savePluginGeometry(geomToGrid(geom)); + }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<QUrl> urls = ev->mimeData()->urls(); + qDebug() << "Desktop Drop Event:" << urls; + for(int i=0; i<urls.length(); i++){ + //If this file is not in the desktop folder, move/copy it here + // -- TO-DO + + } + }else{ + //Ignore this event + ev->ignore(); + } + } + +}; + +#endif
\ No newline at end of file |