/*************************************************************************** * Copyright (C) 2005 by Daniel Stöckel * * the_docter@gmx.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "kommando.h" #include #include #include #include #include "configuration.h" Kommando::Kommando() : QWidget( 0, "Kommando", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder), actMenu(0), navbutton(this), oldNavbuttonIconType(0) { mTopLevelMenus.setAutoDelete(true); //set up the widget's properties resize(); setBackgroundMode( NoBackground ); //set up the navbutton Config& config = Config::getSingleton(); navbutton.move(config.menuRadius(),config.menuRadius()); connect(&navbutton, SIGNAL(clicked()), this, SLOT(slotNavClick())); } void Kommando::slotGlobAccel() { toggle(); } void Kommando::show( ) { Window rep_root, rep_child; int rep_rootx, rep_rooty; unsigned int rep_mask; int mousex, mousey; Display* dpy = qt_xdisplay(); Window win = qt_xrootwin(); XClassHint hint; hint.res_class = 0; hint.res_name = 0; //Get mouse coursor position and the application name of the window under the coursor XQueryPointer (dpy, win, &rep_root, &rep_child, &rep_rootx, &rep_rooty, &mousex, &mousey, &rep_mask); rep_child = XmuClientWindow(dpy,rep_child); if(XGetClassHint(dpy,rep_child,&hint) != 0){ setActTopLevelMenu(hint.res_class); } else { setActTopLevelMenu("default"); } if(hint.res_class){ XFree(hint.res_class); } if(hint.res_name){ XFree(hint.res_name); } Config& config = Config::getSingleton(); move(mousex-config.menuRadius(),mousey-config.menuRadius()); //get the part of the screen the widget is drawn onto and apply a fade effect to it mScreenshot = QPixmap::grabWindow( qt_xrootwin(), x(), y(), width(), height() ); KPixmapEffect::fade( mScreenshot, config.opacity(), config.tintColor() ); QWidget::show(); } void Kommando::hide( ) { selectButton(BUTTON_DESELECT); QWidget::hide(); } void Kommando::toggle( ) { if(!isHidden()){ hide(); } else { show(); } } void Kommando::setActMenu( Menu * newMenu ) { //disconnect everything if(actMenu != 0){ actMenu->disconnect(); actMenu->hideButtons(); } if(newMenu != 0){ if(mTopLevelMenus.containsRef(newMenu)){ navbutton.setIcon("error"); } else { navbutton.setIcon("back"); } //initialize the new menu connect(newMenu, SIGNAL(clicked(int)), this, SLOT(slotOnClick()) ); connect(newMenu, SIGNAL(buttonSelected(int)),this,SLOT(slotButtonSelected(int))); newMenu->showButtons(); } actMenu = newMenu; } void Kommando::setActTopLevelMenu(const QString& appName ) { Menu* menu = 0; for(Menu* it = mTopLevelMenus.first(); it != 0; it = mTopLevelMenus.next()){ if (it->appName() == appName){ menu = it; break; } //get a default menu, assume that a toplevel menu with QString::null or "default" as appname is one if ((it->appName() == QString::null) || (it->appName() == "default")){ menu = it; } } setActMenu(menu); } void Kommando::setTopLevelMenus( const QPtrList& newmenus ) { setActMenu(0); //No need to clear the list, because autoDelete is turned on in //mTopLevelMenus mTopLevelMenus = newmenus; } void Kommando::windowActivationChange( bool oldActive ) { //if the menu loses focus hide it if(oldActive){ hide(); } } void Kommando::paintEvent( QPaintEvent * evt ) { QPainter p(this); p.drawPixmap(evt->rect().topLeft(),mScreenshot,evt->rect()); } void Kommando::wheelEvent( QWheelEvent * evt ) { actMenu->selectButton(actMenu->selectedButtonNum()+evt->delta()/120); } void Kommando::execute( ) { if(!isHidden()){ Menu* temp = actMenu->execute(); if(temp){ setActMenu(temp); } else { hide(); } } } void Kommando::slotOnClick( ) { execute(); } void Kommando::slotNavClick( ) { if(actMenu->selectedButtonNum()==BUTTON_DESELECT){ if(mTopLevelMenus.containsRef(actMenu)){ hide(); } else { setActMenu(actMenu->parentMenu()); } } else { execute(); } } void Kommando::slotButtonSelected( int type ) { if(oldNavbuttonIconType != type){ switch(type){ case 0: if(mTopLevelMenus.containsRef(actMenu)){ navbutton.setIcon("error"); } else { navbutton.setIcon("back"); } break; case RoundButton::Commando: navbutton.setIcon("exec"); break; case RoundButton::Submenu: navbutton.setIcon("folder"); break; } oldNavbuttonIconType=type; } } void Kommando::keyPressEvent( QKeyEvent * evt ) { switch(evt->key()){ case Qt::Key_Left: actMenu->selectButton(actMenu->selectedButtonNum()-1); break; case Qt::Key_Right: actMenu->selectButton(actMenu->selectedButtonNum()+1); break; case Qt::Key_Return: slotNavClick(); break; case Qt::Key_Escape: if(mTopLevelMenus.containsRef(actMenu)){ hide(); } else { setActMenu(actMenu->parentMenu()); } break; case Qt::Key_1: case Qt::Key_2: case Qt::Key_3: case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9: //We want to get the number of the button, so treat the enum as number (yes I know, but it works fine :->) actMenu->selectButton(evt->key() - Qt::Key_1); break; } } void Kommando::setNavButtonSize( unsigned short size ) { navbutton.setRadius(size); Config& config = Config::getSingleton(); navbutton.move(config.menuRadius(),config.menuRadius()); } void Kommando::resize( ) { Config& config = Config::getSingleton(); setFixedSize(config.menuSize(),config.menuSize()); //apply a circular mask QRegion mask(rect(),QRegion::Ellipse); setMask(mask); } void Kommando::selectButton( int num ) { if(!isHidden()) actMenu->selectButton(num); } void Kommando::mousePressEvent(QMouseEvent* evt) { middleMouseButtonState = (evt->button() == Qt::MidButton); } void Kommando::mouseReleaseEvent(QMouseEvent* evt) { if(middleMouseButtonState && (evt->button() == Qt::MidButton)){ middleMouseButtonState = false; slotNavClick(); } } #include "kommando.moc"