aboutsummaryrefslogtreecommitdiff
path: root/lumina-desktop
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-10-07 11:11:59 -0400
committerKen Moore <moorekou@gmail.com>2015-10-07 11:11:59 -0400
commit8c693c2ef0f7a33f9f9970c342e23e9a5823468a (patch)
tree47cb61f2d7e897f14134a33d039cb260d78a602f /lumina-desktop
parentClean up the quicklaunch buttons a bit more - also add a context menu for rem... (diff)
downloadlumina-8c693c2ef0f7a33f9f9970c342e23e9a5823468a.tar.gz
lumina-8c693c2ef0f7a33f9f9970c342e23e9a5823468a.tar.bz2
lumina-8c693c2ef0f7a33f9f9970c342e23e9a5823468a.zip
Commit the 3rd iteration of the desktop plugin container system.
- Now the desktop plugins are drag-and-drop based, resulting in the user being able to simply drag the plugins around as necessry. - All the plugins now have a special context menu (right-click, or click and hold the left mouse button for 1/2 second), which provides options to start moving/resizing the plugin as well as the removal option. Known Issues: - The cross-application drop event for files is currently flagged as valid - but does not actually run anything yet (to be finished up soon) - Hidden panels are not being updated when plugins are moved around yet - resulting in some screen artifacting on the panel. (to be fixed soon)
Diffstat (limited to 'lumina-desktop')
-rw-r--r--lumina-desktop/LDesktop.cpp302
-rw-r--r--lumina-desktop/LDesktop.h14
-rw-r--r--lumina-desktop/LDesktopPluginSpace.cpp208
-rw-r--r--lumina-desktop/LDesktopPluginSpace.h231
-rw-r--r--lumina-desktop/desktop-plugins/LDPlugin.cpp24
-rw-r--r--lumina-desktop/desktop-plugins/LDPlugin.h83
-rw-r--r--lumina-desktop/desktop-plugins/LDPluginContainer.h152
-rw-r--r--lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp58
-rw-r--r--lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h20
-rw-r--r--lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp3
-rw-r--r--lumina-desktop/lumina-desktop.pro5
11 files changed, 604 insertions, 496 deletions
diff --git a/lumina-desktop/LDesktop.cpp b/lumina-desktop/LDesktop.cpp
index b9491d72..a1aaac67 100644
--- a/lumina-desktop/LDesktop.cpp
+++ b/lumina-desktop/LDesktop.cpp
@@ -65,14 +65,7 @@ void LDesktop::prepareToClose(){
//Now close down any desktop plugins
desktoplocked = true; //make sure that plugin settings are preserved during removal
//Remove all the current containers
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- for(int i=0; i<wins.length(); i++){
- wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed
- bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container
- bgDesktop->removeSubWindow(wins[i]); //remove container from screen
- delete wins[i]; //delete old container
- }
- for(int i=0; i<PLUGINS.length(); i++){delete PLUGINS.takeAt(i); i--; }
+ bgDesktop->cleanup();
}
WId LDesktop::backgroundID(){
@@ -120,8 +113,6 @@ void LDesktop::SystemTerminal(){
void LDesktop::SystemFileManager(){
//Just open the home directory
QString fm = "lumina-open \""+QDir::homePath()+"\"";
- //QString fm = LSession::handle()->sessionSettings()->value("default-filemanager","lumina-fm").toString();
- //if(fm.endsWith(".desktop")){ fm = "lumina-open \""+fm+"\""; }
LSession::LaunchApplication(fm);
}
@@ -196,88 +187,6 @@ void LDesktop::checkResolution(){
issyncing = false;
}
-LDPluginContainer* LDesktop::CreateDesktopPluginContainer(LDPlugin *plug){
- //Verify that a container does not already exist for this plugin
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- for(int i=0; i<wins.length(); i++){
- if(wins[i]->whatsThis()==plug->ID()){ return 0; }
- }
- //Create a new plugin container
- LDPluginContainer *win = new LDPluginContainer(plug, desktoplocked);
- win->loadInitialSize(); //Sizing should be done before adding the window to the area
- if(desktoplocked){
- bgDesktop->addSubWindow(win, Qt::Tool | Qt::FramelessWindowHint);
- }else{
- bgDesktop->addSubWindow(win, Qt::Tool | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint);
- }
- if( !win->hasFixedPosition() ){
- //NOTE: This section *only* runs for new plugins - it does not run for re-creations of old plugins
- //Need to determine the location of the plugin (leave size alone)
- if(DEBUG){ qDebug() << " --- Floating Plugin - find a spot for it"; }
- QPoint pt = findNewPluginLocation(availDPArea, win->size());
- if(pt.x()>=0 && pt.y()>=0){
- win->saveNewPosition(pt);
- win->move(pt);
- if(DEBUG){ qDebug() << " --- Moving to point:" << pt; }
- }
- //Make sure to remove this plugin from the availability region
- availDPArea = availDPArea.subtracted( QRegion(win->geometry()) );
- }
- QApplication::processEvents();
- QTimer::singleShot(300+(5*PLUGINS.length()), win, SLOT(loadInitialPosition()) ); //Now load the position (if one is saved)
- if(DEBUG){
- qDebug() << "Initial DP Geom:" << plug->geometry();
- qDebug() << " - Container Geom:" << win->geometry();
- }
- QApplication::processEvents();
-
- connect(win, SIGNAL(PluginRemoved(QString)), this, SLOT(DesktopPluginRemoved(QString)) );
- return win;
-}
-
-QPoint LDesktop::findNewPluginLocation(QRegion avail, QSize winsize){
- //This just searches through the region of available space until it find the first location where it
- // will fit without overlapping anything else (scanning left->right, top->bottom)
- //return QPoint(-1,-1); //just for testing
- QRect bounds = avail.boundingRect();
- //qDebug() << "Bounds:" << bounds;
- if(bounds.width()<winsize.width() || bounds.height()<winsize.height()){ return QPoint(-1,-1); }
-
- QPoint pt = bounds.topLeft(); //start in upper-left corner
- bool found = false;
- if(DEBUG){ qDebug() << "Check Availability:" << bounds << winsize; }
- while(pt.y()+winsize.height() < bounds.bottom() && !found){
- int dy = winsize.height()/2;
- while(pt.x()+winsize.width() < bounds.right() && !found){
- //Check the horizontal position (incrementing as necessary)
- QRegion intersect = avail.intersected(QRect(pt, winsize)); // full intersection
- if(DEBUG){ qDebug() << "Check X:" << pt << " - Inter:" << intersect.boundingRect(); }
- if(intersect.boundingRect().size()==winsize && intersect.rects().length()==1 ){ found = true; } //use this point
- else{
- QRect inter = avail.intersected(QRect(pt, QSize(winsize.width(),1))).boundingRect(); //1D intersection in X-dir
- int dx = winsize.width() - inter.width();
- if(dx>0 && inter.left() > pt.x()){ pt.setX( inter.left() ); }
- else if(inter.width()==0){ pt.setX( pt.x()+winsize.width() ); }
- else{ pt.setX( pt.x()+inter.width() ); }
- //Also adjust the dy value to the smallest amount
- inter = avail.intersected(QRect(pt, QSize(1,winsize.height()))).boundingRect(); //1D intersection in X-dir
- int ddy = inter.y()-pt.y();
- if(ddy < dy && ddy>0){ dy = ddy; }
- }
-
- }
- if(!found){
- //Nothing in the horizontal direction - increment the vertical dimension
- pt.setX( bounds.left() ); //reset back to the left-most edge
- pt.setY( pt.y()+dy );
- if(DEBUG){ qDebug() << "Check Y:" << pt << dy; }
- }
- }
- //qDebug() << "Found Point:" << found << pt;
- if(!found){ return QPoint(-1,-1); } //no space found - return an invalid point
- else{ return pt; }
-}
-
// =====================
// PRIVATE SLOTS
// =====================
@@ -314,10 +223,9 @@ void LDesktop::InitDesktop(){
bgWindow->setGeometry(LSession::handle()->screenGeom(desktopnumber));
connect(bgWindow, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowMenu(const QPoint&)) );
if(DEBUG){ qDebug() << "Create bgDesktop"; }
- bgDesktop = new QMdiArea(bgWindow);
- //Make sure the desktop area is transparent to show the background
- bgDesktop->setBackground( QBrush(Qt::NoBrush) );
- bgDesktop->setStyleSheet( "QMdiArea{ border: none; background: transparent;}" );
+ bgDesktop = new LDesktopPluginSpace(bgWindow); //new QMdiArea(bgWindow);
+ bgDesktop->SetIconSize(qRound(bgDesktop->height()/14.0)); // (For 1600x900 screens - this comes out to 64 pixel icons)
+ connect(bgDesktop, SIGNAL(PluginRemovedByUser(QString)), this, SLOT(RemoveDeskPlugin(QString)) );
if(DEBUG){ qDebug() << " - Desktop Init Done:" << desktopnumber; }
//Start the update processes
QTimer::singleShot(10,this, SLOT(UpdateMenu()) );
@@ -342,8 +250,6 @@ void LDesktop::SettingsChanged(){
void LDesktop::LocaleChanged(){
//Update any elements which require a re-translation
UpdateMenu(false); //do the full menu refresh
-
-
}
void LDesktop::UpdateMenu(bool fast){
@@ -363,7 +269,7 @@ void LDesktop::UpdateMenu(bool fast){
usewinmenu=false;
for(int i=0; i<items.length(); i++){
if(items[i]=="terminal"){ deskMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(SystemTerminal()) ); }
- else if(items[i]=="filemanager"){ deskMenu->addAction( LXDG::findIcon("Insight-FileManager",""), tr("Browse System"), this, SLOT(SystemFileManager()) ); }
+ else if(items[i]=="filemanager"){ deskMenu->addAction( LXDG::findIcon("user-home",""), tr("Browse System"), this, SLOT(SystemFileManager()) ); }
else if(items[i]=="applications"){ deskMenu->addMenu( LSession::handle()->applicationMenu() ); }
else if(items[i]=="line"){ deskMenu->addSeparator(); }
else if(items[i]=="settings"){ deskMenu->addMenu( LSession::handle()->settingsMenu() ); }
@@ -382,11 +288,6 @@ void LDesktop::UpdateMenu(bool fast){
}
//Now add the system quit options
deskMenu->addSeparator();
- if(!desktoplocked){
- deskMenu->addAction(LXDG::findIcon("document-encrypt",""),tr("Lock Desktop"), this, SLOT(ToggleDesktopLock()) );
- deskMenu->addAction(LXDG::findIcon("snap-orthogonal",""),tr("Snap Plugins to Grid"), this, SLOT(AlignDesktopPlugins()) );
- }else{ deskMenu->addAction(LXDG::findIcon("document-decrypt",""),tr("Unlock Desktop"), this, SLOT(ToggleDesktopLock()) ); }
- deskMenu->addSeparator();
deskMenu->addAction(LXDG::findIcon("system-log-out",""), tr("Log Out"), this, SLOT(SystemLogout()) );
}
@@ -433,177 +334,37 @@ void LDesktop::UpdateDesktop(){
QTimer::singleShot(200, this, SLOT(UnlockSettings()) );
}
//If generating desktop file launchers, add those in
+ QStringList filelist;
if(settings->value(DPREFIX+"generateDesktopIcons",false).toBool()){
QFileInfoList files = LSession::handle()->DesktopFiles();
for(int i=0; i<files.length(); i++){
- plugins << "applauncher::"+files[i].absoluteFilePath()+"---"+DPREFIX;
+ filelist << files[i].absoluteFilePath();
}
}
- //Go through the plugins and remove any existing ones that do not show up on the current list
- for(int i=0; i<PLUGINS.length(); i++){
- if(!plugins.contains(PLUGINS[i]->ID())){
- //Remove this plugin (with settings) - is not currently listed
- DesktopPluginRemoved(PLUGINS[i]->ID(),true); //flag this as an internal removal
- i--;
- }
- }
- //Now get an accounting of all the available/used space (overwriting the private variable)
- QSize ssize = LSession::handle()->screenGeom(desktopnumber).size();
- //qDebug() << "Screen Size:" << ssize << desktopnumber;
- if(bgDesktop->isVisible() && ( (bgDesktop->size().height() <= ssize.height()) && (bgDesktop->size().width() <= ssize.width()) )){ ssize = bgDesktop->size(); qDebug() << " - Adjusted:" << ssize; }
- availDPArea = QRegion(QRect(QPoint(0,0), ssize)); //Note that this is child-geometry space
- //Remove all the space currently occupied
- //qDebug() << "Available Screen Geom:" << avail.boundingRect();
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- for(int i=0; i<wins.length(); i++){
- qDebug() << "Subtracting Geom:" << wins[i]->geometry();
- availDPArea = availDPArea.subtracted( QRegion(wins[i]->geometry()) );
- }
- //Now add/update plugins
- for(int i=0; i<plugins.length(); i++){
- //See if this plugin is already there
- LDPlugin *plug = 0;
- for(int p=0; p<PLUGINS.length(); p++){
- //qDebug() << " -- Existing Plugin:" << PLUGINS[p]->ID() << p << PLUGINS.length();
- if(PLUGINS[p]->ID()==plugins[i]){
- //qDebug() << " -- Found Plugin";
- plug = PLUGINS[p];
- break;
- }
- }
- if(plug==0){
- //New Plugin
- if(DEBUG){qDebug() << " -- New Plugin:" << plugins[i];}
- plug = NewDP::createPlugin(plugins[i], bgDesktop);
- if(plug != 0){
- connect(plug, SIGNAL(OpenDesktopMenu()), this, SLOT(ShowMenu()) );
- if(DEBUG){ qDebug() << " --- Show Plugin"; }
- PLUGINS << plug;
- QApplication::processEvents(); //need a moment between plugin/container creation
- LDPluginContainer *cont = CreateDesktopPluginContainer(plug);
- //Done with this plugin - removed it's area from the available space
- if(DEBUG){ qDebug() << " --- Done Creating Plugin Container" << cont->geometry(); }
- //avail = avail.subtracted( QRegion(cont->geometry()) ); //remove this space from the available region as well
- }
- }
- QApplication::processEvents(); //need to process events between loading of plugins
- }
-}
-
-void LDesktop::ToggleDesktopLock(){
- desktoplocked = !desktoplocked; //flip to other value
- //Remove all the current containers
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- for(int i=0; i<wins.length(); i++){
- wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed
- bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container
- bgDesktop->removeSubWindow(wins[i]); //remove container from screen
- delete wins[i]; //delete old container
- }
- //Now recreate all the containers on the screen
- for(int i=0; i<PLUGINS.length(); i++){
- CreateDesktopPluginContainer(PLUGINS[i]);
- }
- bgDesktop->update(); //refresh visuals
- UpdateMenu(false);
-}
-
-void LDesktop::AlignDesktopPlugins(){
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- QSize fit = bgDesktop->size();
- //Auto-determine the best grid sizing
- // It will try to exactly fit the desktop plugin area, with at least 10-20 grid points
- int xgrid, ygrid;
- xgrid = ygrid = 32;
- //while(fit.width()%xgrid != 0){ xgrid = xgrid-1; }
- //while(fit.height()%ygrid != 0){ ygrid = ygrid-1; }
- //qDebug() << "Grid:" << xgrid << ygrid << fit.width() << fit.height();
- //Make sure there are at least 10 points. It will not fit the area exactly, but should be very close
- //while(xgrid < 10){ xgrid = xgrid*2; }
- //while(ygrid < 10){ ygrid = ygrid*2; }
- //qDebug() << "Grid (adjusted):" << xgrid << ygrid;
- // xgrid = int(fit.width()/xgrid); //now get the exact pixel size of the grid
- //ygrid = int(fit.height()/ygrid); //now get the exact pixel size of the grid
- //qDebug() << "Grid (pixel):" << xgrid << ygrid;
- //qDebug() << " X-Grid:" << xgrid << "("+QString::number(fit.width()/xgrid)+" points)";
- //qDebug() << " Y-Grid:" << ygrid << "("+QString::number(fit.height()/ygrid)+" points)";
- for(int i=0; i<wins.length(); i++){
- //align the plugin on a grid point (that is not right/bottom edge)
- QRect geom = wins[i]->geometry();
- int x, y;
- if(geom.x()<0){ x=0; }
- else{ x = qRound(geom.x()/float(xgrid)) * xgrid; }
- if(x>= fit.width()){ x = fit.width()-xgrid; geom.setWidth(xgrid); }
- if(geom.y()<0){ y=0; }
- else{ y = qRound(geom.y()/float(ygrid)) * ygrid; }
- if(y>= fit.height()){ y = fit.height()-ygrid; geom.setHeight(ygrid); }
- geom.moveTo(x,y);
- //Now adjust the size to also be the appropriate grid multiple
- geom.setWidth( qRound(geom.width()/float(xgrid))*xgrid );
- geom.setHeight( qRound(geom.height()/float(ygrid))*ygrid );
-
- //Now check for edge spillover and adjust accordingly
- int diff = (geom.x()+geom.width()) - bgDesktop->size().width();
- if( diff > 0 ){ geom.moveTo( geom.x() - diff, geom.y() ); }
- else if( diff > -11 ){ geom.setWidth( geom.width()-diff ); }
- diff = (geom.y()+geom.height()) - bgDesktop->size().height();
- if( diff > 0 ){ geom.moveTo( geom.x(), geom.y() - diff ); }
- else if( diff > -11 ){ geom.setHeight( geom.height()-diff ); }
- //Now move the plugin
- wins[i]->setGeometry(geom);
- }
+ UpdateDesktopPluginArea();
+ bgDesktop->LoadItems(plugins, filelist);
}
-void LDesktop::DesktopPluginRemoved(QString ID, bool internal){
- //NOTE: This function is only run when the plugin is deliberately removed
- // The "internal" flag is for whether the plugin was closed by the user (external), or programmatically removed (internal)
- //Close down that plugin instance (NOTE: the container might have already closed by the user)
- if(DEBUG){ qDebug() << "Desktop Plugin Removed:" << ID; }
- //First look for the container (just in case)
- QList<QMdiSubWindow*> wins = bgDesktop->subWindowList();
- for(int i=0; i<wins.length(); i++){
- if(wins[i]->whatsThis() == ID){
- if(DEBUG){ qDebug() << " - Removing Plugin Container"; }
- //wins[i]->setWhatsThis(""); //clear this so it knows it is being temporarily removed
- bgDesktop->removeSubWindow(wins[i]->widget()); //unhook plugin from container
- bgDesktop->removeSubWindow(wins[i]); //remove container from screen
- if(internal){ delete wins[i]; }//delete old container
- break;
- }
- }
-
- //qDebug() << "PLUGINS:" << PLUGINS.length() << ID;
- for(int i=0; i<PLUGINS.length(); i++){
- if(PLUGINS[i]->ID() == ID){
- //qDebug() << "- found ID";
- if(DEBUG){ qDebug() << " - Deleting Desktop Plugin:" << ID; }
- //Special check for auto-generated desktop icons
- if(ID.startsWith("applauncher::")){
- qDebug() << "Desktop Icon Removal:" << !internal;
- PLUGINS[i]->removeSettings(!internal); //Only remove the file if an external removal on an auto-generated shortcut
- }else{
- PLUGINS[i]->removeSettings(true); //Remove any settings associated with this plugin
- }
- delete PLUGINS.takeAt(i);
- break;
- }
- }
-
- //Now remove that plugin from the internal list (then let the plugin system remove the actual plugin)
- QStringList plugins = settings->value(DPREFIX+"pluginlist",QStringList()).toStringList();
- if(DEBUG){ qDebug() << " - Also removing plugin from future list"; }
- if(plugins.removeAll(ID) > 0){
- issyncing = true;
- if(DEBUG){ qDebug() << " - Save modified plugins list"; }
- settings->setValue(DPREFIX+"pluginlist", plugins);
- if(DEBUG){ qDebug() << " - Unlock settings file in 200 ms"; }
+void LDesktop::RemoveDeskPlugin(QString ID){
+ //This is called after a plugin is manually removed by the user
+ // just need to ensure that the plugin is also removed from the settings file
+ QStringList plugs = settings->value(DPREFIX+"pluginlist", QStringList()).toStringList();
+ if(plugs.contains(ID)){
+ plugs.removeAll(ID);
+ issyncing=true; //don't let the change cause a refresh
+ settings->setValue(DPREFIX+"pluginlist", plugs);
+ settings->sync();
QTimer::singleShot(200, this, SLOT(UnlockSettings()) );
+ }else if(ID.startsWith("applauncher::") ){
+ //This was a temporary plugin (desktop file?) check for existance/dir and remove it as necessary
+ QString path = ID.section("---",0,0).section("::",1,50); //full file path
+ QFileInfo info(path);
+ if(info.exists() && info.canonicalPath()==QDir::homePath()+"/Desktop"){
+ //Need to remove this file/dir as well
+ if(!info.isSymLink() && info.isDir()){ QProcess::startDetached("rm -r \""+info.absoluteFilePath()+"\""); }
+ else{ QFile::remove(path); } //just remove the file/symlink directly
+ }
}
- /*if(QFile::exists(QDir::homePath()+"/.lumina/desktop-plugins/"+ID+".conf")){
- if(DEBUG){ qDebug() << " - Removing settings file"; }
- QFile::remove(QDir::homePath()+"/.lumina/desktop-plugins/"+ID+".conf");
- }*/
- if(DEBUG){ qDebug() << " - Done removing plugin"; }
}
void LDesktop::UpdatePanels(){
@@ -670,15 +431,12 @@ void LDesktop::UpdateDesktopPluginArea(){
//Now remove the X offset to place it on the current screen (needs widget-coords, not global)
globalWorkRect = rec; //save this for later
rec.moveTopLeft( QPoint( rec.x()-desktop->screenGeometry(desktopnumber).x() , rec.y() ) );
- //qDebug() << "DPlug Area:" << rec.x() << rec.y() << rec.width() << rec.height();
- if(rec == bgDesktop->geometry()){return; } //nothing changed
+ //qDebug() << "DPlug Area:" << rec << bgDesktop->geometry() << LSession::handle()->desktop()->availableGeometry(bgDesktop);
+ if(rec.size().isNull() || rec == bgDesktop->geometry()){return; } //nothing changed
bgDesktop->setGeometry( rec );
- bgDesktop->setBackground( QBrush(Qt::NoBrush) );
- bgDesktop->update();
+ bgDesktop->UpdateGeom(); //just in case the plugin space itself needs to do anything
//Re-paint the panels (just in case a plugin was underneath it and the panel is transparent)
for(int i=0; i<PANELS.length(); i++){ PANELS[i]->update(); }
- //Also need to re-arrange any desktop plugins to ensure that nothing is out of the screen area
- AlignDesktopPlugins();
//Make sure to re-disable any WM control flags
LSession::handle()->XCB->SetDisableWMActions(bgWindow->winId());
}
diff --git a/lumina-desktop/LDesktop.h b/lumina-desktop/LDesktop.h
index e1900f5a..041f4ba5 100644
--- a/lumina-desktop/LDesktop.h
+++ b/lumina-desktop/LDesktop.h
@@ -28,9 +28,9 @@
#include "LPanel.h"
//#include "Globals.h"
#include "AppMenu.h"
+#include "LDesktopPluginSpace.h"
#include "desktop-plugins/LDPlugin.h"
-#include "desktop-plugins/LDPluginContainer.h"
-#include "desktop-plugins/NewDP.h"
+//#include "desktop-plugins/NewDP.h"
class LDesktop : public QObject{
Q_OBJECT
@@ -66,18 +66,14 @@ private:
bool defaultdesktop, desktoplocked, issyncing, usewinmenu, bgupdating;
QStringList oldBGL;
QList<LPanel*> PANELS;
- QMdiArea *bgDesktop; //desktop widget area
+ LDesktopPluginSpace *bgDesktop; //desktop plugin area
QWidget *bgWindow; //full screen background
QMenu *deskMenu, *winMenu;
- //AppMenu *appmenu;
QLabel *workspacelabel;
QWidgetAction *wkspaceact;
QList<LDPlugin*> PLUGINS;
QString CBG; //current background
QRect globalWorkRect;
- LDPluginContainer* CreateDesktopPluginContainer(LDPlugin*);
-
- QPoint findNewPluginLocation(QRegion avail, QSize winsize);
private slots:
void InitDesktop();
@@ -98,9 +94,7 @@ private slots:
//Desktop plugin system functions
void UpdateDesktop();
- void ToggleDesktopLock();
- void AlignDesktopPlugins();
- void DesktopPluginRemoved(QString ID, bool internal = false);
+ void RemoveDeskPlugin(QString);
void UpdatePanels();
diff --git a/lumina-desktop/LDesktopPluginSpace.cpp b/lumina-desktop/LDesktopPluginSpace.cpp
new file mode 100644
index 00000000..116c4207
--- /dev/null
+++ b/lumina-desktop/LDesktopPluginSpace.cpp
@@ -0,0 +1,208 @@
+//===========================================
+// 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 *parent) : QWidget(parent){
+ this->setObjectName("LuminaDesktopPluginSpace");
+ this->setStyleSheet("QWidget#LuminaDesktopPluginSpace{ border: none; background: transparent; }");
+ this->setAcceptDrops(true);
+ this->setContextMenuPolicy(Qt::NoContextMenu);
+ this->setMouseTracking(true);
+ TopToBottom = true;
+ plugsettings = LSession::handle()->DesktopPluginSettings();
+
+}
+
+LDesktopPluginSpace::~LDesktopPluginSpace(){
+
+}
+
+void LDesktopPluginSpace::LoadItems(QStringList plugs, QStringList files){
+ if(DEBUG){ qDebug() << "Loading Desktop Items:" << plugs << files; }
+ 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())); }
+}
+
+void LDesktopPluginSpace::SetIconSize(int size){
+ if(DEBUG){ qDebug() << "Set Desktop Icon Size:" << size; }
+ QSize newsize = calculateItemSize(size);
+ itemSize = newsize; //save this for all the later icons which are generated (grid size)
+ UpdateGeom();
+ //Now re-set the item icon size
+ QTimer::singleShot(0,this, SLOT(reloadPlugins()) );
+}
+
+void LDesktopPluginSpace::cleanup(){
+ //Perform any final cleanup actions here
+ for(int i=0; i<ITEMS.length(); i++){
+ delete ITEMS.takeAt(i);
+ i--;
+ }
+ plugins.clear();
+ deskitems.clear();
+}
+// ===================
+// PUBLIC SLOTS
+// ===================
+void LDesktopPluginSpace::UpdateGeom(){
+ if(DEBUG){ qDebug() << "Update Desktop Geom:"; }
+ //Currently no special checks - might need to add validation of all current plugin geometries in the future
+}
+
+// ===================
+// PRIVATE
+// ===================
+QSize LDesktopPluginSpace::calculateItemSize(int icosize){
+ //Note: This returns the size in numbers of cells (width = columnspan, height = rowspan)
+ QSize sz;
+ sz.setWidth(1.8*icosize);
+ sz.setWidth( RoundUp(sz.width()/GRIDSIZE)); //always round up to cell numbers
+ sz.setHeight(icosize+ 2.3*this->fontMetrics().height() );
+ sz.setHeight( RoundUp(sz.height()/GRIDSIZE)); //always round up to cell number
+ return sz;
+}
+
+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);
+ plug->setWhatsThis(plugID);
+ //Now get the geometry for the plugin
+ QRect geom = plug->loadPluginGeometry(); //in grid coords
+ if(geom.isNull()){
+ //No previous location - need to calculate initial geom
+ QSize sz = plug->sizeHint();
+ if(plugID.startsWith("applauncher::") ){ sz = itemSize*GRIDSIZE; }
+ geom.setWidth( RoundUp(sz.width()/GRIDSIZE) );
+ geom.setHeight( RoundUp(sz.height()/GRIDSIZE) );
+ geom.moveTo( findOpenSpot(geom.width(), geom.height()) );
+ }else if(!ValidGeometry(plugID, gridToGeom(geom)) ){
+ //Find a new location for the plugin (saved location is invalid)
+ QPoint pt = findOpenSpot(geom.width(), geom.height(), geom.y()-2, geom.x()-2); //try to get it within the same general area
+ geom.moveTo(pt);
+ }
+ 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
+ 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)) );
+ }
+}
+
+QPoint LDesktopPluginSpace::findOpenSpot(int gridwidth, int gridheight, int startRow, int startCol){
+ //Note about the return QPoint: x() is the column number, y() is the row number
+ QPoint pt(0,0);
+ 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(this->height()/GRIDSIZE);
+ colCount = RoundUp(this->width()/GRIDSIZE);
+ 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){
+ //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(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
+ row++;
+ }
+ if(!found){ col++; row=0; } //go to the next column
+ }
+ }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(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){
+ //Decrease the size of the item by 1x1 grid points and try again
+ if(gridwidth>2 && gridheight>2){
+ pt = findOpenSpot(gridwidth-1, gridheight-1, 0, 0);
+ }else{
+ pt.setX(-1); pt.setY(-1); //invalid
+ qDebug() << "Could not find an open spot for a desktop plugin:" << gridwidth << gridheight << startRow << startCol;
+ }
+ }
+ return pt;
+}
+
+// ===================
+// PRIVATE SLOTS
+// ===================
+void LDesktopPluginSpace::reloadPlugins(){
+ //Remove any plugins as necessary
+ QStringList plugs = plugins;
+ QStringList items = deskitems;
+ for(int i=0; i<ITEMS.length(); i++){
+ if(plugs.contains(ITEMS[i]->whatsThis())){ plugs.removeAll(ITEMS[i]->whatsThis()); }
+ else if(ITEMS[i]->whatsThis().contains("---dlink") && items.contains(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50)) ){
+ //Account for the variation in the Plugin ID for desktop files
+ items.removeAll(ITEMS[i]->whatsThis().section("---",0,0).section("::",1,50));
+ }else{ ITEMS[i]->Cleanup(); delete ITEMS.takeAt(i); i--; }
+ }
+
+ //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]);
+ }
+}
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
diff --git a/lumina-desktop/desktop-plugins/LDPlugin.cpp b/lumina-desktop/desktop-plugins/LDPlugin.cpp
index 26ed7eff..c6d2e320 100644
--- a/lumina-desktop/desktop-plugins/LDPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/LDPlugin.cpp
@@ -7,16 +7,36 @@
#include "LDPlugin.h"
#include "../LSession.h"
+#include <LuminaXDG.h>
LDPlugin::LDPlugin(QWidget *parent, QString id) : QFrame(parent){
PLUGID=id;
prefix = id.replace("/","_")+"/";
//qDebug() << "ID:" << PLUGID << prefix;
settings = LSession::handle()->DesktopPluginSettings();
+ //Setup the plugin system control menu
+ menu = new QMenu(this);
+ setupMenu();
+ //Setup the internal timer for when to start/stop drag events
+ dragTimer = new QTimer(this);
+ dragTimer->setSingleShot(true);
+ dragTimer->setInterval(500); //1/2 second to show the plugin menu
+ connect(dragTimer, SIGNAL(timeout()), this, SLOT(showPluginMenu()));
//Use plugin-specific values for stylesheet control (applauncher, desktopview, etc...)
this->setObjectName(id.section("---",0,0).section("::",0,0));
+ this->setContextMenuPolicy(Qt::CustomContextMenu);
+ this->setMouseTracking(false); //only catch mouse movement events if the mouse is clicked/held on the plugin
connect(QApplication::instance(), SIGNAL(LocaleChanged()), this, SLOT(LocaleChange()) );
connect(QApplication::instance(), SIGNAL(IconThemeChanged()), this, SLOT(ThemeChange()) );
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showPluginMenu()) );
+}
+
+void LDPlugin::setupMenu(){
+ menu->clear();
+ menu->addAction( LXDG::findIcon("transform-move",""), tr("Start Moving Item"), this, SLOT(slotStartMove()) );
+ menu->addAction( LXDG::findIcon("transform-scale",""), tr("Start Resizing Item"), this, SLOT(slotStartResize()) );
+ menu->addSeparator();
+ menu->addAction( LXDG::findIcon("edit-delete",""), tr("Remove Item"), this, SLOT(slotRemovePlugin()) );
}
void LDPlugin::setInitialSize(int width, int height){
@@ -33,10 +53,10 @@ void LDPlugin::setInitialSize(int width, int height){
this->resize( settings->value(prefix+"location/width").toInt(), settings->value(prefix+"location/height").toInt());
}
-void LDPlugin::adjustSize(int width, int height){
+/*void LDPlugin::adjustSize(int width, int height){
settings->setValue(prefix+"location/width",width);
settings->setValue(prefix+"location/height",height);
settings->sync();
this->resize(width,height);
emit PluginResized();
-} \ No newline at end of file
+}*/ \ No newline at end of file
diff --git a/lumina-desktop/desktop-plugins/LDPlugin.h b/lumina-desktop/desktop-plugins/LDPlugin.h
index a77674ee..6c34ab9c 100644
--- a/lumina-desktop/desktop-plugins/LDPlugin.h
+++ b/lumina-desktop/desktop-plugins/LDPlugin.h
@@ -23,6 +23,9 @@
#include <QSettings>
#include <QMoveEvent>
#include <QResizeEvent>
+#include <QMouseEvent>
+#include <QTimer>
+#include <QMenu>
class LDPlugin : public QFrame{
Q_OBJECT
@@ -30,6 +33,10 @@ class LDPlugin : public QFrame{
private:
QString PLUGID, prefix;
QSettings *settings;
+ QMenu *menu;
+ QTimer *dragTimer;
+
+ void setupMenu();
public:
LDPlugin(QWidget *parent = 0, QString id="unknown");
@@ -41,7 +48,16 @@ public:
}
void setInitialSize(int width, int height);
- void adjustSize(int width, int height);
+ //void adjustSize(int width, int height);
+
+ void savePluginGeometry(QRect geom){
+ settings->setValue(prefix+"geometry/desktopGridPoints", geom);
+ settings->sync();
+ }
+
+ QRect loadPluginGeometry(){
+ return settings->value(prefix+"geometry/desktopGridPoints", QRect()).toRect();
+ }
void saveSetting(QString var, QVariant val){
//qDebug() << "Saving Setting:" << prefix+var+QString(" = ")+val.toString();
@@ -67,40 +83,63 @@ public:
}
- /*virtual void scalePlugin(double xscale, double yscale){
- //This can be re-implemented in the subclassed plugin as necessary
- // Example: If there are icons in the plugin which should also be re-scaled
-
- int val = settings->value("location/width",0).toInt();
- if(val>0){ val = qRound(val*xscale); }
- settings->setValue("location/width",val);
-
- val = settings->value("location/height",0).toInt();
- if(val>0){ val = qRound(val*yscale); }
- settings->setValue("location/height",val);
-
- val = settings->value("location/x",0).toInt();
- if(val>0){ val = qRound(val*xscale); }
- settings->setValue("location/x",val);
-
- val = settings->value("location/y",0).toInt();
- if(val>0){ val = qRound(val*yscale); }
- settings->setValue("location/y",val);
- }*/
-
public slots:
virtual void LocaleChange(){
//This needs to be re-implemented in the subclassed plugin
//This is where all text is set/translated
+ setupMenu();
}
virtual void ThemeChange(){
//This needs to be re-implemented in the subclassed plugin
//This is where all the visuals are set if using Theme-dependant icons.
+ setupMenu();
+ }
+ void showPluginMenu(){
+ menu->popup( QCursor::pos() );
}
signals:
void OpenDesktopMenu();
void PluginResized();
+
+ //Signals for communication with the desktop layout system (not generally used by hand)
+ void StartMoving(QString); //ID of plugin
+ void StartResizing(QString); //ID of plugin
+ void RemovePlugin(QString); //ID of plugin
+
+private slots:
+ void slotStartMove(){
+ QCursor::setPos( this->mapToGlobal(QPoint(this->width()/2, this->height()/2)) );
+ emit StartMoving(PLUGID);
+ }
+
+ void slotStartResize(){
+ QCursor::setPos( this->mapToGlobal(QPoint(this->width()/2, this->height()/2)) );
+ emit StartResizing(PLUGID);
+ }
+
+ void slotRemovePlugin(){
+ removeSettings(true);
+ emit RemovePlugin(PLUGID);
+ }
+
+protected:
+ void mousePressEvent(QMouseEvent *ev){
+ if(!dragTimer->isActive() && ev->buttons().testFlag(Qt::LeftButton) ){ dragTimer->start(); }
+ QWidget::mousePressEvent(ev);
+ }
+ void mouseReleaseEvent(QMouseEvent *ev){
+ if(dragTimer->isActive()){ dragTimer->stop(); }
+ QWidget::mouseReleaseEvent(ev);
+ }
+ void mouseMoveEvent(QMouseEvent *ev){
+ if(ev->buttons().testFlag(Qt::LeftButton)){
+ if(dragTimer->isActive()){ dragTimer->stop(); }
+ slotStartMove();
+ }
+ QWidget::mouseMoveEvent(ev);
+ }
+
};
#endif
diff --git a/lumina-desktop/desktop-plugins/LDPluginContainer.h b/lumina-desktop/desktop-plugins/LDPluginContainer.h
deleted file mode 100644
index e7388a80..00000000
--- a/lumina-desktop/desktop-plugins/LDPluginContainer.h
+++ /dev/null
@@ -1,152 +0,0 @@
-//===========================================
-// Lumina-DE source code
-// Copyright (c) 2014, Ken Moore
-// Available under the 3-clause BSD license
-// See the LICENSE file for full details
-//===========================================
-// This class is the generic container for a desktop plugin that handles
-// saving/restoring all the movement and sizing
-//===========================================
-#ifndef _LUMINA_DESKTOP_DESKTOP_PLUGIN_CONTAINER_H
-#define _LUMINA_DESKTOP_DESKTOP_PLUGIN_CONTAINER_H
-
-#include <QObject>
-#include <QMdiSubWindow>
-#include <QApplication>
-#include <QSettings>
-#include <QMoveEvent>
-#include <QResizeEvent>
-#include <QCloseEvent>
-#include <QString>
-#include <QFile>
-#include <QIcon>
-#include <QTimer>
-
-#include "LDPlugin.h"
-
-class LDPluginContainer : public QMdiSubWindow{
- Q_OBJECT
-
-private:
- QTimer *syncTimer;
- bool locked, setup;
- LDPlugin *PLUG;
-
-private slots:
- void saveGeometry(){
- if(PLUG==0){ return; }
- //if(!locked && !setup){
- PLUG->saveSetting("location/x", this->pos().x());
- PLUG->saveSetting("location/y", this->pos().y());
- PLUG->saveSetting("location/width", this->width()-4);
- PLUG->saveSetting("location/height", this->height()-4);
- //}
- }
-
-public:
- LDPluginContainer(LDPlugin *plugin = 0, bool islocked = true) : QMdiSubWindow(){
- locked = islocked;
- setup=true;
- PLUG = plugin;
- syncTimer = new QTimer(this);
- syncTimer->setInterval(500); //save settings 1/2 second after it is moved
- syncTimer->setSingleShot(true); //no repeats
- connect(syncTimer, SIGNAL(timeout()), this, SLOT(saveGeometry()) );
- this->setWhatsThis(plugin->ID());
- this->setContentsMargins(0,0,0,0);
- if(!locked){
- //this->setStyleSheet("LDPluginContainer{ border-width: 1px;}");
- this->setWindowTitle( plugin->ID().replace("---"," - ") );
- //this->setWidget( new QWidget() );
- this->setWidget( plugin );
- //this->setWindowIcon(QIcon()); //remove the Qt icon
- }else{
- this->setStyleSheet("LDPluginContainer{ background: transparent; border: none;}");
- this->setWidget(plugin);
- }
- //qDebug() << "New Container:" << PLUG->size() << PLUG->sizeHint();
- connect(PLUG, SIGNAL(PluginResized()), this, SLOT(loadInitialPosition()) );
- }
-
- ~LDPluginContainer(){
- }
-
- void saveNewPosition(QPoint pt){
- //generally only used while a plugin is locked and does not have an initial position
- // This works around an issue with QMdiArea moving the new container out of alignment
- if(PLUG==0){ return; }
- PLUG->saveSetting("location/x",pt.x());
- PLUG->saveSetting("location/y", pt.y());
- }
-
- bool hasFixedPosition(){
- return (PLUG->readSetting("location/x",-12345).toInt() != -12345);
- }
-
-public slots:
- void loadInitialSize(){
- if(PLUG==0){ return; }
- QSize sz(PLUG->readSetting("location/width",100).toInt(), PLUG->readSetting("location/height",100).toInt());
- this->resize(sz);
- }
-
- void loadInitialPosition(){
- QRect set(PLUG->readSetting("location/x",-12345).toInt(), PLUG->readSetting("location/y",-12345).toInt(), PLUG->readSetting("location/width",PLUG->size().width()).toInt() +4, PLUG->readSetting("location/height",PLUG->size().height()).toInt()+4);
- //qDebug() << "Initial Plugin Location:" << set.x() << set.y() << set.width() << set.height();
- if(set.height() < 10){ set.setHeight(10); } //to prevent foot-shooting
- if(set.width() < 10){ set.setWidth(10); } //to prevent foot-shooting
- if(set.x()!=-12345 && set.y()!=-12345){
- //this->move(set.x(), set.y());
- this->setGeometry(set);
- }else{
- qDebug() << " - Found Size:" << set;
- this->resize(set.width(), set.height());
- qDebug() << " - Assigning location:" << this->pos();
- saveNewPosition(this->pos());
- }
- this->show();
- QApplication::processEvents();
- setup=false; //done with setup
- }
-
-
-signals:
- void PluginRemoved(QString);
-
-protected:
- void moveEvent(QMoveEvent *event){
- //qDebug() << "Move Event: " << PLUG->ID() << setup;
- //Save this location to the settings
- if( !setup ){
- if(syncTimer->isActive()){ syncTimer->stop(); }
- syncTimer->start();
- //qDebug() << "DP Move:" << event->pos().x() << event->pos().y();
- }
- QMdiSubWindow::moveEvent(event); //be sure to pass this event along to the container
- }
-
- void resizeEvent(QResizeEvent *event){
- //Save this size info to the settings
- if(!setup){
- //qDebug() << "DP Resize:" << event->size().width() << event->size().height();
- if(syncTimer->isActive()){ syncTimer->stop(); }
- syncTimer->start();
- }
- QMdiSubWindow::resizeEvent(event); //be sure to pass this event along to the container
- }
-
- void closeEvent(QCloseEvent *event){
- //qDebug() << "Desktop Plugin Close Event:" << this->whatsThis();
- if( !this->whatsThis().isEmpty() && !locked){
- //Plugin removed by the user - delete the settings file
- locked = true; //ensure that the save settings routines don't do anything during the close
- emit PluginRemoved( this->whatsThis() );
- }
- if(syncTimer->isActive()){ syncTimer->stop(); } //prevent save routine from running in a moment
- //settings = 0; //ensure we don't touch the settings file after a close event
- QMdiSubWindow::closeEvent(event); //continue closing this window
- }
-
-};
-
-#endif
diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
index ae454511..3acb83fb 100644
--- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.cpp
@@ -9,42 +9,46 @@ AppLauncherPlugin::AppLauncherPlugin(QWidget* parent, QString ID) : LDPlugin(par
button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
button->setAutoRaise(true);
button->setText("...\n..."); //Need to set something here so that initial sizing works properly
-
+ button->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
lay->addWidget(button, 0, Qt::AlignCenter);
connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()) );
- menu = new QMenu(this);
- int icosize = this->readSetting("iconsize",-1).toInt();
+ //menu = new QMenu(this);
+ /*int icosize = this->readSetting("iconsize",-1).toInt();
if(icosize <1){
icosize = LSession::handle()->sessionSettings()->value("DefaultIconSize",64).toInt();
this->saveSetting("iconsize",icosize);
- }
- button->setIconSize(QSize(icosize,icosize));
- this->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openContextMenu()) );
+ }*/
+ //int icosize
+ //button->setIconSize(QSize(icosize,icosize));
+ button->setContextMenuPolicy(Qt::NoContextMenu);
+ //connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(openContextMenu()) );
watcher = new QFileSystemWatcher(this);
connect(watcher, SIGNAL(fileChanged(QString)), this, SLOT( loadButton()) );
//Calculate the initial size of the button
//qDebug() << "Button Size:" << button->size();
//qDebug() << "Calculated:" << icosize+4 << icosize+8+qRound(2.15*button->fontMetrics().height());
//qDebug() << "Preferred Size:" << button->sizeHint();
- QSize sz(qRound(1.1*icosize), icosize+qRound(2.7*button->fontMetrics().height()) );
- button->setFixedSize(sz); //make sure to adjust the button on first show.
- this->setInitialSize(this->sizeHint().width()+2, this->sizeHint().height()+2); //give the container a bit of a buffer
+ //QSize sz(qRound(1.1*icosize), icosize+qRound(2.7*button->fontMetrics().height()) );
+ //button->setFixedSize(sz); //make sure to adjust the button on first show.
+ this->setInitialSize(120, 100); //give the container a bit of a buffer
QTimer::singleShot(100,this, SLOT(loadButton()) );
}
void AppLauncherPlugin::Cleanup(){
//This is run only when the plugin was forcibly closed/removed
- if(QFile::exists(button->whatsThis()) && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){
+ /*if(QFile::exists(button->whatsThis()) && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){
deleteFile();
- }
+ }*/
}
-void AppLauncherPlugin::loadButton(bool onchange){
+void AppLauncherPlugin::loadButton(){
QString def = this->ID().section("::",1,50).section("---",0,0).simplified();
QString path = this->readSetting("applicationpath",def).toString(); //use the default if necessary
//qDebug() << "Default Application Launcher:" << def << path;
bool ok = QFile::exists(path);
+ int icosize = this->width()/1.8; //This is the same calculation as in the LDesktopPluginSpace
+ button->setFixedSize( this->width()-4, this->height()-4);
+ button->setIconSize( QSize(icosize,icosize) );
QString txt;
if(path.endsWith(".desktop") && ok){
XDGDesktop file = LXDG::loadDesktopFile(path, ok);
@@ -82,12 +86,12 @@ void AppLauncherPlugin::loadButton(bool onchange){
}
//Now adjust the visible text as necessary based on font/grid sizing
button->setToolTip(txt);
- int icosize = this->readSetting("iconsize",64).toInt();
- int bwid = qRound(1.1*icosize);
- this->setFixedSize(bwid, icosize+qRound(2.5*button->fontMetrics().height()) ); //make sure to adjust the button on first show.
- if(onchange){ this->adjustSize( bwid+4, icosize+8+qRound(2.5*button->fontMetrics().height())); }
+ //int icosize = this->readSetting("iconsize",64).toInt();
+ //int bwid = qRound(1.1*icosize);
+ //this->setFixedSize(bwid, icosize+qRound(2.5*button->fontMetrics().height()) ); //make sure to adjust the button on first show.
+ //if(onchange){ this->adjustSize( bwid+4, icosize+8+qRound(2.5*button->fontMetrics().height())); }
//qDebug() << "Initial Button Text:" << txt << icosize;
- if(button->fontMetrics().width(txt) > (bwid-2) ){
+ if(button->fontMetrics().width(txt) > (button->width()-2) ){
//int dash = this->fontMetrics().width("-");
//Text too long, try to show it on two lines
txt = txt.section(" ",0,2).replace(" ","\n"); //First take care of any natural breaks
@@ -96,11 +100,11 @@ void AppLauncherPlugin::loadButton(bool onchange){
QStringList txtL = txt.split("\n");
for(int i=0; i<txtL.length(); i++){
if(i>1){ txtL.removeAt(i); i--; } //Only take the first two lines
- else{ txtL[i] = button->fontMetrics().elidedText(txtL[i], Qt::ElideRight, bwid-2); }
+ else{ txtL[i] = button->fontMetrics().elidedText(txtL[i], Qt::ElideRight, (button->width()-2) ); }
}
txt = txtL.join("\n");
}else{
- txt = this->fontMetrics().elidedText(txt,Qt::ElideRight, 2*bwid -4);
+ txt = this->fontMetrics().elidedText(txt,Qt::ElideRight, 2*button->width() -4);
//Now split the line in half for the two lines
txt.insert( (txt.count()/2), "\n");
}
@@ -109,12 +113,12 @@ void AppLauncherPlugin::loadButton(bool onchange){
//qDebug() << " - Setting Button Text:" << txt;
button->setText(txt);
//Now setup the menu again
- menu->clear();
- menu->addAction(LXDG::findIcon("zoom-in",""), tr("Increase Size"), this, SLOT(increaseIconSize()));
+ //menu->clear();
+ /*menu->addAction(LXDG::findIcon("zoom-in",""), tr("Increase Size"), this, SLOT(increaseIconSize()));
menu->addAction(LXDG::findIcon("zoom-out",""), tr("Decrease Size"), this, SLOT(decreaseIconSize()));
if( !button->whatsThis().isEmpty() && button->whatsThis().startsWith(QDir::homePath()+"/Desktop") ){
menu->addAction(LXDG::findIcon("list-remove",""), tr("Delete File"), this, SLOT(deleteFile()) );
- }
+ }*/
QTimer::singleShot(100, this, SLOT(update()) ); //Make sure to re-draw the image in a moment
}
@@ -137,15 +141,15 @@ void AppLauncherPlugin::buttonClicked(){
}
-void AppLauncherPlugin::openContextMenu(){
+/*void AppLauncherPlugin::openContextMenu(){
if(button->underMouse()){
menu->popup(QCursor::pos());
}else{
emit OpenDesktopMenu();
}
-}
+}*/
-void AppLauncherPlugin::increaseIconSize(){
+/*void AppLauncherPlugin::increaseIconSize(){
int icosize = this->readSetting("iconsize",64).toInt();
icosize += 16;
button->setIconSize(QSize(icosize,icosize));
@@ -169,4 +173,4 @@ void AppLauncherPlugin::deleteFile(){
}else{
QFile::remove(button->whatsThis());
}
-} \ No newline at end of file
+}*/ \ No newline at end of file
diff --git a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
index 796d8f04..d6e75fec 100644
--- a/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
+++ b/lumina-desktop/desktop-plugins/applauncher/AppLauncherPlugin.h
@@ -34,20 +34,26 @@ public:
private:
QToolButton *button;
QFileSystemWatcher *watcher;
- QMenu *menu;
+ //QMenu *menu;
private slots:
- void loadButton(bool onchange = false);
+ void loadButton();
void buttonClicked();
- void openContextMenu();
+ //void openContextMenu();
- void increaseIconSize();
- void decreaseIconSize();
- void deleteFile();
+ //void increaseIconSize();
+ //void decreaseIconSize();
+ //void deleteFile();
public slots:
void LocaleChange(){
- loadButton(true); //force reload
+ loadButton(); //force reload
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *ev){
+ LDPlugin::resizeEvent(ev);
+ QTimer::singleShot(10, this, SLOT(loadButton()) );
}
};
#endif
diff --git a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
index b1300ec8..0b48a049 100644
--- a/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
+++ b/lumina-desktop/desktop-plugins/desktopview/DesktopViewPlugin.cpp
@@ -107,7 +107,8 @@ void DesktopViewPlugin::showMenu(const QPoint &pos){
menu->popup(this->mapToGlobal(pos));
}else{
//Pass the context menu request on to the desktop (emit it from the plugin)
- emit OpenDesktopMenu();
+ this->showPluginMenu();
+ //emit OpenDesktopMenu();
}
}
diff --git a/lumina-desktop/lumina-desktop.pro b/lumina-desktop/lumina-desktop.pro
index 35643295..353324b7 100644
--- a/lumina-desktop/lumina-desktop.pro
+++ b/lumina-desktop/lumina-desktop.pro
@@ -31,7 +31,7 @@ SOURCES += main.cpp \
LXcbEventFilter.cpp \
LSession.cpp \
LDesktop.cpp \
-# LDesktopPluginSpace.cpp \
+ LDesktopPluginSpace.cpp \
LPanel.cpp \
LWinInfo.cpp \
AppMenu.cpp \
@@ -71,7 +71,7 @@ HEADERS += Globals.h \
LXcbEventFilter.h \
LSession.h \
LDesktop.h \
-# LDesktopPluginSpace.h \
+ LDesktopPluginSpace.h \
LPanel.h \
LWinInfo.h \
AppMenu.h \
@@ -82,7 +82,6 @@ HEADERS += Globals.h \
panel-plugins/NewPP.h \
panel-plugins/LTBWidget.h \
desktop-plugins/LDPlugin.h \
- desktop-plugins/LDPluginContainer.h \
desktop-plugins/NewDP.h \
panel-plugins/userbutton/LUserButton.h \
panel-plugins/userbutton/UserWidget.h \
bgstack15