]> git.sesse.net Git - vlc/blob - modules/gui/qt4/util/timetooltip.cpp
Qt: profiles_editor: display muxers capabilities.
[vlc] / modules / gui / qt4 / util / timetooltip.cpp
1 /*****************************************************************************
2  * Copyright © 2011-2012 VideoLAN
3  * $Id$
4  *
5  * Authors: Ludovic Fauvet <etix@l0cal.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  *****************************************************************************/
21
22 #include "timetooltip.hpp"
23
24 #include <QApplication>
25 #include <QPainter>
26 #include <QPainterPath>
27 #include <QBitmap>
28 #include <QFontMetrics>
29 #include <QDesktopWidget>
30
31 #define TIP_HEIGHT 5
32
33 TimeTooltip::TimeTooltip( QWidget *parent ) :
34     QWidget( parent ), mInitialized( false )
35 {
36     setWindowFlags( Qt::Window                  |
37                     Qt::WindowStaysOnTopHint    |
38                     Qt::FramelessWindowHint     |
39                     Qt::X11BypassWindowManagerHint );
40
41     // Tell Qt that it doesn't need to erase the background before
42     // a paintEvent occurs. This should save some CPU cycles.
43     setAttribute( Qt::WA_OpaquePaintEvent );
44
45 #ifdef Q_WS_WIN
46     /*
47     - This attribute is required on Windows to avoid focus stealing of other windows.
48     - When set on Linux the TimeTooltip appears behind the FSController in fullscreen.
49     */
50     setAttribute( Qt::WA_ShowWithoutActivating );
51 #endif
52
53     // Inherit from the system default font size -5
54     mFont = QFont( "Verdana", qMax( qApp->font().pointSize() - 5, 7 ) );
55     mTipX = -1;
56 }
57
58 void TimeTooltip::adjustPosition()
59 {
60     // Get the bounding box required to print the text and add some padding
61     QFontMetrics metrics( mFont );
62     QRect textbox = metrics.boundingRect( mDisplayedText );
63     textbox.adjust( -2, -2, 2, 2 );
64     textbox.moveTo( 0, 0 );
65
66     // Resize the widget to fit our needs
67     QSize size( textbox.width() + 1, textbox.height() + TIP_HEIGHT + 1 );
68
69     // The desired label position is just above the target
70     QPoint position( mTarget.x() - size.width() / 2,
71         mTarget.y() - size.height() + TIP_HEIGHT / 2 );
72
73     // Keep the tooltip on the same screen if possible
74     QRect screen = QApplication::desktop()->screenGeometry( mTarget );
75     position.setX( qMax( screen.left(), qMin( position.x(),
76         screen.left() + screen.width() - size.width() ) ) );
77     position.setY( qMax( screen.top(), qMin( position.y(),
78         screen.top() + screen.height() - size.height() ) ) );
79
80     move( position );
81
82     int tipX = mTarget.x() - position.x();
83     if( mBox != textbox || mTipX != tipX )
84     {
85         mBox = textbox;
86         mTipX = tipX;
87
88         resize( size );
89         buildPath();
90         setMask( mMask );
91     }
92 }
93
94 void TimeTooltip::buildPath()
95 {
96     // Prepare the painter path for future use so
97     // we only have to generate the text at runtime.
98
99     // Draw the text box
100     mPainterPath = QPainterPath();
101     mPainterPath.addRect( mBox );
102
103     // Draw the tip
104     QPolygon polygon;
105     polygon << QPoint( qMax( 0, mTipX - 3 ), mBox.height() )
106             << QPoint( mTipX, mBox.height() + TIP_HEIGHT )
107             << QPoint( qMin( mTipX + 3, mBox.width() ), mBox.height() );
108     mPainterPath.addPolygon( polygon );
109
110     // Store the simplified version of the path
111     mPainterPath = mPainterPath.simplified();
112
113     // Create the mask used to erase the background
114     // Note: this is a binary bitmap (black & white)
115     mMask = QBitmap( size() );
116     QPainter painter( &mMask );
117     painter.fillRect( mMask.rect(), Qt::white );
118     painter.setPen( Qt::black );
119     painter.setBrush( Qt::black );
120     painter.drawPath( mPainterPath );
121     painter.end();
122 }
123
124 void TimeTooltip::setTip( const QPoint& target, const QString& time, const QString& text )
125 {
126     mInitialized = true;
127     mDisplayedText = time;
128     if ( !text.isEmpty() )
129         mDisplayedText.append( " - " ).append( text );
130
131     if( mTarget != target || time.length() != mTime.length() || mText != text )
132     {
133         mTarget = target;
134         mTime = time;
135         mText = text;
136         adjustPosition();
137     }
138
139     update();
140 }
141
142 void TimeTooltip::show()
143 {
144     QWidget::setVisible( mInitialized );
145 }
146
147 void TimeTooltip::paintEvent( QPaintEvent * )
148 {
149     QPainter p( this );
150     p.setRenderHints( QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing );
151
152     p.setPen( Qt::black );
153     p.setBrush( qApp->palette().base() );
154     p.drawPath( mPainterPath );
155
156     p.setFont( mFont );
157     p.setPen( QPen( qApp->palette().text(), 1 ) );
158     p.drawText( mBox, Qt::AlignCenter, mDisplayedText );
159 }