set QPixmapCache size to 10mb. Wastly improves startup and redrawing performance...
[amarok.git] / src / context / ContextView.cpp
blob10b44ecc069c8bf9a39df68b28647fb6893f8839
1 /***************************************************************************
2 * copyright : (C) 2007 Leo Franchi <lfranchi@gmail.com> *
3 * *
4 * Significant parts of this code is inspired *
5 * and/or copied from KDE Plasma sources, available *
6 * at kdebase/workspace/plasma *
8 **************************************************************************/
10 /***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
19 #include "ContextView.h"
21 #include "amarok.h"
22 #include "amarokconfig.h"
23 #include "ColumnApplet.h"
24 #include "Context.h"
25 #include "ContextScene.h"
26 #include "DataEngineManager.h"
27 #include "debug.h"
28 #include "enginecontroller.h"
29 #include "Svg.h"
30 #include "Theme.h"
32 #include <QFile>
33 #include <QPixmapCache>
34 #include <QWheelEvent>
36 #include <KPluginInfo>
37 #include <KServiceTypeTrader>
38 #include <KMenu>
40 #define DEBUG_PREFIX "ContextView"
42 namespace Context
45 ContextView* ContextView::s_self = 0;
48 ContextView::ContextView( QWidget* parent )
49 : QGraphicsView( parent )
50 , EngineObserver( EngineController::instance() )
51 , m_columns( 0 )
52 , m_background( 0 )
53 , m_logo( 0 )
55 DEBUG_BLOCK
57 s_self = this;
59 //make sure cache is large enough for background
60 QPixmapCache::setCacheLimit ( 10 * 1024 );
63 // setFrameShape( QFrame::NoFrame );
64 setAutoFillBackground( true );
66 setScene( new ContextScene( rect(), this ) );
67 scene()->setItemIndexMethod( QGraphicsScene::BspTreeIndex );
68 //TODO: Figure out a way to use rubberband and ScrollHandDrag
69 //setDragMode( QGraphicsView::RubberBandDrag );
70 setTransformationAnchor( QGraphicsView::AnchorUnderMouse );
71 setCacheMode( QGraphicsView::CacheBackground );
72 setInteractive( true );
73 setAcceptDrops( true );
74 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
75 setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
76 setMouseTracking( true );
78 // here we initialize all the Plasma paths to Amarok paths
79 Theme::self()->setApplication( "amarok" );
80 contextScene()->setAppletMimeType( "text/x-amarokappletservicename" );
82 m_background = new Svg( "widgets/amarok-wallpaper", this );
83 m_logo = new Svg( "widgets/amarok-logo", this );
84 m_logo->resize();
85 m_width = 300; // TODO hardcoding for now, do we want this configurable?
86 m_aspectRatio = (qreal)m_logo->size().height() / (qreal)m_logo->size().width();
87 m_logo->resize( (int)m_width, (int)( m_width * m_aspectRatio ) );
89 m_columns = new ColumnApplet();
90 scene()->addItem( m_columns );
91 m_columns->init();
93 connect(scene(), SIGNAL( appletRemoved( QObject * ) ), m_columns, SLOT( appletRemoved( QObject* ) ) );
96 showHome();
99 ContextView::~ContextView()
101 DEBUG_BLOCK
102 clear( m_curState );
105 void ContextView::clear()
107 delete m_columns;
110 void ContextView::clear( const ContextState& state )
112 QString name = "amarok_";
114 if( state == Home )
115 name += "home";
116 else if( state == Current )
117 name += "current";
118 else
119 return; // startup, or some other wierd case
120 name += "rc";
122 // now we save the state, remembering the column info etc
123 KConfig appletConfig( name );
124 // erase previous config
125 foreach( const QString& group, appletConfig.groupList() )
126 appletConfig.deleteGroup( group );
128 m_columns->saveToConfig( appletConfig );
130 contextScene()->clearApplets();
134 void ContextView::engineStateChanged( Engine::State state, Engine::State oldState )
136 DEBUG_BLOCK
137 Q_UNUSED( oldState ); Q_UNUSED( state );
139 switch( state )
141 case Engine::Playing:
142 showCurrentTrack();
143 break;
145 case Engine::Empty:
146 showHome();
147 break;
149 default:
154 void ContextView::showHome()
156 DEBUG_BLOCK
157 clear( m_curState );
158 m_curState = Home;
159 loadConfig();
160 messageNotify( m_curState );
163 void ContextView::showCurrentTrack()
165 DEBUG_BLOCK
166 clear( m_curState );
167 m_curState = Current;
168 loadConfig();
169 messageNotify( Current );
172 // loads applets onto the ContextScene from saved data, using m_curState
173 void ContextView::loadConfig()
175 DEBUG_BLOCK
176 QString cur = "amarok_";
177 if( m_curState == Home )
178 cur += QString( "home" );
179 else if( m_curState == Current )
180 cur += QString( "current" );
181 cur += "rc";
183 contextScene()->clearApplets();
184 KConfig appletConfig( cur, KConfig::OnlyLocal );
185 m_columns->loadConfig( appletConfig );
188 void ContextView::engineNewMetaData( const MetaBundle&, bool )
190 ; //clear();
194 Applet* ContextView::addApplet(const QString& name, const QStringList& args)
196 QVariantList argList;
197 QStringListIterator i(args);
198 while( i.hasNext() )
199 argList << QVariant( i.next() );
201 AppletPointer applet = contextScene()->addApplet( name, argList );
203 return m_columns->addApplet( applet );
206 void ContextView::zoomIn()
208 //TODO: Change level of detail when zooming
209 // 10/8 == 1.25
210 scale( 1.25, 1.25 );
213 void ContextView::zoomOut()
215 // 8/10 == .8
216 scale( .8, .8 );
219 ContextScene* ContextView::contextScene()
221 return static_cast<ContextScene*>( scene() );
224 void ContextView::drawBackground( QPainter * painter, const QRectF & rect )
226 painter->save();
227 m_background->paint( painter, rect );
228 painter->restore();
229 QSize size = m_logo->size();
231 QSize pos = m_background->size() - size;
232 qreal newHeight = m_aspectRatio * m_width;
233 m_logo->resize( QSize( (int)m_width, (int)newHeight ) );
234 painter->save();
235 m_logo->paint( painter, QRectF( pos.width() - 10.0, pos.height() - 5.0, size.width(), size.height() ) );
236 painter->restore();
240 void ContextView::resizeEvent( QResizeEvent* event )
242 DEBUG_BLOCK
243 Q_UNUSED( event )
244 if ( testAttribute( Qt::WA_PendingResizeEvent ) ) {
245 return; // lets not do this more than necessary, shall we?
248 scene()->setSceneRect( rect() );
250 m_background->resize( width(), height() );
251 // m_logo->
252 m_columns->update();
255 void ContextView::wheelEvent( QWheelEvent* event )
257 if ( scene() && scene()->itemAt( event->pos() ) ) {
258 QGraphicsView::wheelEvent( event );
259 return;
262 if ( event->modifiers() & Qt::ControlModifier ) {
263 if ( event->delta() < 0 ) {
264 zoomOut();
265 } else {
266 zoomIn();
271 void ContextView::contextMenuEvent(QContextMenuEvent *event)
273 if ( !scene() ) {
274 QGraphicsView::contextMenuEvent( event );
275 return;
278 QPointF point = event->pos();
279 QPointF globalPoint = event->globalPos();
281 QGraphicsItem* item = scene()->itemAt(point);
282 Plasma::Applet* applet = 0;
284 while (item) {
285 applet = qgraphicsitem_cast<Plasma::Applet*>(item);
286 if (applet) {
287 break;
290 item = item->parentItem();
293 KMenu desktopMenu;
294 //kDebug() << "context menu event " << immutable;
295 if (!applet) {
296 if (contextScene() && contextScene()->isImmutable()) {
297 QGraphicsView::contextMenuEvent(event);
298 return;
301 //FIXME: change this to show this only in debug mode (or not at all?)
302 // before final release
304 } else if (applet->isImmutable()) {
305 QGraphicsView::contextMenuEvent(event);
306 return;
307 } else {
308 //desktopMenu.addSeparator();
309 bool hasEntries = false;
310 if (applet->hasConfigurationInterface()) {
311 QAction* configureApplet = new QAction(i18n("%1 Settings...", applet->name()), this);
312 connect(configureApplet, SIGNAL(triggered(bool)),
313 applet, SLOT(showConfigurationInterface()));
314 desktopMenu.addAction(configureApplet);
315 hasEntries = true;
318 if (!contextScene() || !contextScene()->isImmutable()) {
319 QAction* closeApplet = new QAction(i18n("Close this %1", applet->name()), this);
320 connect(closeApplet, SIGNAL(triggered(bool)),
321 applet, SLOT(deleteLater()));
322 desktopMenu.addAction(closeApplet);
323 hasEntries = true;
326 if (!hasEntries) {
327 QGraphicsView::contextMenuEvent(event);
328 return;
332 event->accept();
333 desktopMenu.exec(globalPoint.toPoint());
337 } // Context namespace
339 #include "ContextView.moc"