source: lumina/lumina-desktop/LPanel.cpp @ 4d19595

releng/10.0.3releng/10.1
Last change on this file since 4d19595 was 4d19595, checked in by Ken Moore <ken@…>, 5 months ago

Fix up the transparent panel system, by fixing a bug in the desktop placement system.
NOTE: Screen 0 is not always the left-most screen. Instead, make sure to use the desktopGeometry() system for determining the desktop placement locations.

  • Property mode set to 100644
File size: 8.7 KB
Line 
1//===========================================
2//  Lumina-DE source code
3//  Copyright (c) 2012, Ken Moore
4//  Available under the 3-clause BSD license
5//  See the LICENSE file for full details
6//===========================================
7#include "LPanel.h"
8
9LPanel::LPanel(QSettings *file, int scr, int num, QWidget *parent) : QWidget(){
10  //Take care of inputs
11  qDebug() << " - Creating Panel:" << scr << num;
12  bgWindow = parent; //save for later
13  //Setup the widget overlay for the entire panel to provide transparency effects
14  panelArea = new QWidget(this);
15  QBoxLayout *tmp = new QBoxLayout(QBoxLayout::LeftToRight,this);
16        tmp->setContentsMargins(0,0,0,0);
17        this->setLayout(tmp);
18        tmp->addWidget(panelArea);
19  settings = file;
20  screennum = scr;
21  screen = new QDesktopWidget();
22  PPREFIX = "panel"+QString::number(screennum)+"."+QString::number(num)+"/";
23  if(settings->value("defaultpanel","0.0").toString()==QString::number(screennum)+"."+QString::number(num) ){ defaultpanel=true;}
24  else{defaultpanel=false; }
25  horizontal=true; //use this by default initially
26  //Setup the panel
27  qDebug() << " -- Setup Panel";
28  this->setContentsMargins(0,0,0,0);
29  this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
30  this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint );
31  this->setFocusPolicy(Qt::NoFocus);
32  this->setWindowTitle("");
33  this->setAttribute(Qt::WA_X11NetWmWindowTypeDock);
34  this->setAttribute(Qt::WA_AlwaysShowToolTips);
35  this->setObjectName("LuminaPanelWidget");
36  panelArea->setObjectName("LuminaPanelPluginWidget");
37  //LX11::SetAsPanel(this->winId()); //set proper type of window for a panel since Qt can't do it
38  LX11::SetAsSticky(this->winId());
39  layout = new QBoxLayout(QBoxLayout::LeftToRight, this);
40    layout->setContentsMargins(0,0,0,0);
41    layout->setSpacing(1);
42    //layout->setSizeConstraint(QLayout::SetFixedSize);
43  panelArea->setLayout(layout);
44  QTimer::singleShot(1,this, SLOT(UpdatePanel()) ); //start this in a new thread
45  connect(screen, SIGNAL(resized(int)), this, SLOT(UpdatePanel()) ); //in case the screen resolution changes
46}
47
48LPanel::~LPanel(){
49       
50}
51
52//===========
53// PUBLIC SLOTS
54//===========
55void LPanel::UpdatePanel(){
56  //Create/Update the panel as designated in the Settings file
57  settings->sync(); //make sure to catch external settings changes
58  //First set the geometry of the panel and send the EWMH message to reserve that space
59  qDebug() << "Update Panel";
60  QString loc = settings->value(PPREFIX+"location","").toString();
61  if(loc.isEmpty() && defaultpanel){ loc="top"; }
62  if(loc=="top" || loc=="bottom"){ 
63    horizontal=true; 
64    layout->setAlignment(Qt::AlignLeft); 
65    layout->setDirection(QBoxLayout::LeftToRight);
66  }else{
67    horizontal=false;
68    layout->setAlignment(Qt::AlignTop);
69    layout->setDirection(QBoxLayout::TopToBottom);
70  }
71  int ht = settings->value(PPREFIX+"height", 22).toInt(); //this is technically the distance into the screen from the edge
72  /*int xoffset=0;
73  for(int i=0; i<screennum; i++){
74    xoffset = xoffset + screen->screenGeometry(i).width();
75  }*/
76  qDebug() << " - set Geometry";
77  int xwid = screen->screenGeometry(screennum).width();
78  int xhi = screen->screenGeometry(screennum).height();
79  int xloc = screen->screenGeometry(screennum).x();
80  //xloc=xoffset;
81  if(loc=="top"){ //top of screen
82    QSize sz = QSize(xwid, ht);
83    this->setMinimumSize(sz);
84    this->setMaximumSize(sz);
85    this->setGeometry(xloc,0,xwid, ht );
86    LX11::ReservePanelLocation(this->winId(), xloc, 0, this->width(), ht, "top");
87  }else if(loc=="bottom"){ //bottom of screen
88    QSize sz = QSize(xwid, ht);
89    this->setMinimumSize(sz);
90    this->setMaximumSize(sz);
91    this->setGeometry(xloc,xhi-ht,xwid, ht );
92    LX11::ReservePanelLocation(this->winId(), xloc, xhi-ht, this->width(), ht, "bottom");
93  }else if(loc=="left"){ //left side of screen
94    QSize sz = QSize(ht, xhi);
95    this->setMinimumSize(sz);
96    this->setMaximumSize(sz);
97    this->setGeometry(xloc,0, ht, xhi);
98    LX11::ReservePanelLocation(this->winId(), xloc, 0, ht, xhi, "left");
99  }else{ //right side of screen
100    QSize sz = QSize(ht, xhi);
101    this->setMinimumSize(sz);
102    this->setMaximumSize(sz);
103    this->setGeometry(xloc+xwid-ht,0,ht, xhi);
104    LX11::ReservePanelLocation(this->winId(), xloc+xwid-ht, 0, ht, xhi, "right");         
105  }
106  //Now update the appearance of the toolbar
107  QString color = settings->value(PPREFIX+"color", "qlineargradient(spread:pad, x1:0.291182, y1:0, x2:0.693, y2:1, stop:0 rgb(255, 253, 250,100), stop:1 rgba(210, 210, 210,100))").toString();
108  QString style = "QWidget#LuminaPanelPluginWidget{ background: %1; border-radius: 3px; border: 1px solid transparent; }";
109  style = style.arg(color);
110  panelArea->setStyleSheet(style);
111  //Set the panelBrush properly instead ***TODO***
112 
113  //Then go through the plugins and create them as necessary
114  QStringList plugins = settings->value(PPREFIX+"pluginlist", QStringList()).toStringList();
115  if(defaultpanel && plugins.isEmpty()){
116    plugins << "userbutton" << "desktopbar" << "desktopswitcher" << "taskmanager" << "spacer" << "systemtray" << "clock";
117    if(SYSTEM::hasBattery()){ plugins << "battery"; }
118  }else if(defaultpanel && !plugins.contains("userbutton") ){
119    plugins.prepend("userbutton"); //make sure we have this button since that lets the user logout
120  }
121  qDebug() << " - Initialize Plugins: " << plugins;
122  for(int i=0; i<plugins.length(); i++){
123    //Ensure this plugin has a unique ID (NOTE: this numbering does not persist between sessions)
124    if(!plugins[i].contains("---")){
125      int num=1;
126      while( plugins.contains(plugins[i]+"---"+QString::number(this->number())+"."+QString::number(num)) ){
127        num++;
128      }
129      plugins[i] = plugins[i]+"---"+QString::number(this->number())+"."+QString::number(num);
130    }
131    //See if this plugin is already there or in a different spot
132    bool found = false;
133    for(int p=0; p<PLUGINS.length(); p++){
134      if(PLUGINS[p]->type()==plugins[i]){
135        found = true; //already exists
136        //Make sure the plugin layout has the correct orientation
137        if(horizontal){PLUGINS[p]->layout()->setDirection(QBoxLayout::LeftToRight); }
138        else{ PLUGINS[p]->layout()->setDirection(QBoxLayout::TopToBottom); }
139        QTimer::singleShot(0,PLUGINS[p], SLOT( OrientationChange() ) );
140        //Now check the location of the plugin in the panel
141        if(p!=i){ //wrong place in the panel
142          layout->takeAt(p); //remove the item from the current location
143          layout->insertWidget(i, PLUGINS[p]); //add the item into the correct location
144          PLUGINS.move(p,i); //move the identifier in the list to match
145        }
146        break;
147      }
148    }
149    if(!found){
150      //New Plugin
151      qDebug() << " -- New Plugin:" << plugins[i];
152      LPPlugin *plug = NewPP::createPlugin(plugins[i], panelArea, horizontal);
153      if(plug != 0){ 
154        PLUGINS.insert(i, plug);
155        layout->insertWidget(i, PLUGINS[i]);
156      }else{
157        //invalid plugin type
158        plugins.removeAt(i); //remove this invalid plugin from the list
159        i--; //make sure we don't miss the next item with the re-order
160      }
161    }
162  }
163  //Now remove any extra plugins from the end
164  for(int i=plugins.length(); i<PLUGINS.length(); i++){
165    qDebug() << " -- Remove Plugin: " << i;
166    layout->takeAt(i); //remove from the layout
167    delete PLUGINS.takeAt(i); //delete the actual widget
168  }
169  this->update();
170  this->show(); //make sure the panel is visible now
171}
172
173void LPanel::UpdateLocale(){
174  //The panel itself has no text to translate, just forward the signal to all the plugins
175  for(int i=0; i<PLUGINS.length(); i++){
176    QTimer::singleShot(1,PLUGINS[i], SLOT(LocaleChange()));
177  }
178}
179
180void LPanel::UpdateTheme(){
181  //The panel itself has no theme-based icons, just forward the signal to all the plugins
182  for(int i=0; i<PLUGINS.length(); i++){
183    QTimer::singleShot(1,PLUGINS[i], SLOT(ThemeChange()));
184  }     
185}
186
187
188//===========
189// PROTECTED
190//===========
191void LPanel::paintEvent(QPaintEvent *event){
192  QPainter *painter = new QPainter(this);
193  //Make sure the base background of the event rectangle is the associated rectangle from the BGWindow
194  QRect rec(event->rect().x(), event->rect().y(), event->rect().width(), event->rect().height()); //already in global coords? (translating to bgWindow coords crashes Lumina)
195  //Need to translate that rectangle to the background image coordinates
196  qDebug() << "Rec:" << rec.x() << rec.y();
197  rec.moveTo( this->mapToGlobal(rec.topLeft()) ); //Need to change to global coords for the main window
198  qDebug() << "Global Rec:" << rec.x() << rec.y() << screennum;
199  rec.moveTo( rec.x()-screen->screenGeometry(screennum).x(), rec.y() );
200  qDebug() << "Adjusted Global Rec:" << rec.x() << rec.y();
201  painter->drawPixmap(event->rect(), QPixmap::grabWidget(bgWindow, rec) );
202  QWidget::paintEvent(event); //now pass the event along to the normal painting event
203}
204
Note: See TracBrowser for help on using the repository browser.