]> git.sesse.net Git - vlc/commitdiff
Qt: Improved tooltip to view the time at a given mouse position
authorLudovic Fauvet <etix@l0cal.com>
Tue, 12 Apr 2011 08:22:57 +0000 (10:22 +0200)
committerJean-Baptiste Kempf <jb@videolan.org>
Tue, 12 Apr 2011 17:21:00 +0000 (19:21 +0200)
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
modules/gui/qt4/Modules.am
modules/gui/qt4/util/input_slider.cpp
modules/gui/qt4/util/input_slider.hpp
modules/gui/qt4/util/timetooltip.cpp [new file with mode: 0644]
modules/gui/qt4/util/timetooltip.hpp [new file with mode: 0644]

index 6f2bfaa91ebffb985919296d93a104261dccc380..b3a6fd7d8b247bbc494810a599ed96747fed18cf 100644 (file)
@@ -66,6 +66,7 @@ nodist_SOURCES_qt4 = \
                components/sout/profile_selector.moc.cpp \
                components/sout/sout_widgets.moc.cpp \
                util/input_slider.moc.cpp \
+               util/timetooltip.moc.cpp \
                util/customwidgets.moc.cpp \
                util/searchlineedit.moc.cpp \
                util/qvlcapp.moc.cpp \
@@ -297,6 +298,7 @@ SOURCES_qt4 =       qt4.cpp \
                components/sout/profile_selector.cpp \
                components/sout/sout_widgets.cpp \
                util/input_slider.cpp \
+               util/timetooltip.cpp \
                util/customwidgets.cpp \
                util/searchlineedit.cpp \
                util/registry.cpp \
@@ -370,6 +372,7 @@ noinst_HEADERS = \
        components/sout/sout_widgets.hpp \
        components/sout/profiles.hpp \
        util/input_slider.hpp \
+       util/timetooltip.hpp \
        util/customwidgets.hpp \
        util/searchlineedit.hpp \
        util/qvlcframe.hpp \
index eb172f2fc34a6687a82e4d8709f0b36ab168d087..1dde4c3fe38a693ddcf3c387380ee5183ea317cc 100644 (file)
@@ -52,8 +52,14 @@ SeekSlider::SeekSlider( Qt::Orientation q, QWidget *_parent )
     b_isSliding = false;
 
     /* Timer used to fire intermediate updatePos() when sliding */
-    seekLimitTimer = new QTimer(this);
-    seekLimitTimer->setSingleShot(true);
+    seekLimitTimer = new QTimer( this );
+    seekLimitTimer->setSingleShot( true );
+
+    hideTooltipTimer = new QTimer( this );
+    hideTooltipTimer->setSingleShot( true );
+
+    /* Tooltip bubble */
+    mTimeTooltip = new TimeTooltip( this );
 
     /* Properties */
     setRange( MINIMUM, MAXIMUM );
@@ -69,6 +75,9 @@ SeekSlider::SeekSlider( Qt::Orientation q, QWidget *_parent )
 
     CONNECT( this, sliderMoved(int), this, startSeekTimer( int ) );
     CONNECT( seekLimitTimer, timeout(), this, updatePos() );
+    CONNECT( hideTooltipTimer, timeout(), mTimeTooltip, hide() );
+
+    mTimeTooltip->installEventFilter( this );
 }
 
 /***
@@ -139,8 +148,12 @@ void SeekSlider::mouseMoveEvent(QMouseEvent *event)
     }
 
     /* Tooltip */
+     QPoint p( event->globalX() - mTimeTooltip->width() / 2,
+               QWidget::mapToGlobal( pos() ).y() - ( mTimeTooltip->height() + 2 ) );
+
     secstotimestr( psz_length, ( event->x() * inputLength) / size().width() );
-    setToolTip( psz_length );
+    mTimeTooltip->setTime( psz_length );
+    mTimeTooltip->move( p );
     event->accept();
 }
 
@@ -158,6 +171,36 @@ void SeekSlider::wheelEvent( QWheelEvent *event)
     event->accept();
 }
 
+void SeekSlider::enterEvent( QEvent *e )
+{
+    if (isEnabled())
+    {
+        hideTooltipTimer->stop();
+        mTimeTooltip->show();
+    }
+}
+
+void SeekSlider::leaveEvent( QEvent *e )
+{
+    hideTooltipTimer->start(100);
+}
+
+bool SeekSlider::eventFilter( QObject *obj, QEvent *event )
+{
+    // This eventFilter avoids a flicker that occurs if the
+    // mouse cursor leaves the SeekSlider for the TimeTooltip.
+    if (obj == mTimeTooltip)
+    {
+        if (event->type() == QEvent::Enter)
+            hideTooltipTimer->stop();
+        else if (event->type() == QEvent::Leave)
+            hideTooltipTimer->start(100);
+        return false;
+    }
+    else
+        return QSlider::eventFilter( obj, event );
+}
+
 QSize SeekSlider::sizeHint() const
 {
     return ( orientation() == Qt::Horizontal ) ? QSize( 100, 18 )
index 07db0b133f6438c6989ed434f9c6e34a351d7f1e..bd7d953f20b783174bf46994919234a2ed9a12ea 100644 (file)
 #ifndef _INPUTSLIDER_H_
 #define _INPUTSLIDER_H_
 
+#include <vlc_common.h>
+#include "timetooltip.hpp"
+
 #include <QSlider>
 
-#include <vlc_common.h>
 #define MSTRTIME_MAX_SIZE 22
 
 class QMouseEvent;
@@ -47,8 +49,11 @@ protected:
     virtual void mousePressEvent(QMouseEvent* event);
     virtual void mouseReleaseEvent(QMouseEvent* event);
     virtual void wheelEvent(QWheelEvent *event);
+    virtual void enterEvent( QEvent * );
+    virtual void leaveEvent( QEvent * );
 
     virtual void paintEvent( QPaintEvent* event );
+    virtual bool eventFilter(QObject *obj, QEvent *event);
 
     QSize handleSize() const;
     QSize sizeHint() const;
@@ -58,6 +63,8 @@ private:
     int inputLength;        /* InputLength that can change */
     char psz_length[MSTRTIME_MAX_SIZE]; /* Used for the ToolTip */
     QTimer *seekLimitTimer;
+    QTimer *hideTooltipTimer;
+    TimeTooltip *mTimeTooltip;
 
 public slots:
     void setPosition( float, int64_t, int );
diff --git a/modules/gui/qt4/util/timetooltip.cpp b/modules/gui/qt4/util/timetooltip.cpp
new file mode 100644 (file)
index 0000000..a515fcd
--- /dev/null
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * Copyright © 2011 VideoLAN
+ * $Id$
+ *
+ * Authors: Ludovic Fauvet <etix@l0cal.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include "timetooltip.hpp"
+
+#include <QApplication>
+#include <QPainter>
+#include <QPainterPath>
+#include <QBitmap>
+#include <QFontMetrics>
+
+#define TIP_HEIGHT 5
+
+TimeTooltip::TimeTooltip( QWidget *parent ) :
+    QWidget( parent )
+{
+    setWindowFlags( Qt::ToolTip );
+
+    // Tell Qt that it doesn't need to erase the background before
+    // a paintEvent occurs. This should save some CPU cycles.
+    setAttribute( Qt::WA_OpaquePaintEvent );
+
+    // Inherit from the system default font size -5
+    mFont = QFont( "Verdana", qMax( qApp->font().pointSize() - 5, 7 ) );
+
+    QFontMetrics metrics( mFont );
+
+    // Get the bounding box required to print the text and add some padding
+    QRect textbox = metrics.boundingRect( "00:00:00" ).adjusted( -2, -2, 2, 2 );
+    mBox = QRect( 0, 0, textbox.width(), textbox.height() );
+
+    // Resize the widget to fit our needs
+    resize( mBox.width() + 1, mBox.height() + TIP_HEIGHT + 1 );
+
+    // Prepare the painter path for future use so
+    // we only have to generate the text at runtime.
+
+    // Draw the text box
+    mPainterPath.addRect( mBox );
+
+    // Draw the tip
+    int center = mBox.width() / 2;
+    QPolygon polygon;
+    polygon << QPoint( center - 3,   mBox.height() )
+            << QPoint( center,       mBox.height() + TIP_HEIGHT )
+            << QPoint( center + 3,   mBox.height() );
+
+    mPainterPath.addPolygon( polygon );
+
+    // Store the simplified version of the path
+    mPainterPath = mPainterPath.simplified();
+
+    // Create the mask used to erase the background
+    // Note: this is a binary bitmap (black & white)
+    mMask = QBitmap( size() );
+    QPainter painter( &mMask );
+    painter.fillRect( mMask.rect(), Qt::white );
+    painter.setPen( QColor( 0, 0, 0 ) );
+    painter.setBrush( QColor( 0, 0, 0 ) );
+    painter.drawPath( mPainterPath );
+    painter.end();
+
+    setMask( mMask );
+
+    // Set default text
+    setTime("00:00");
+}
+
+void TimeTooltip::setTime( const QString& time )
+{
+    mTime = time;
+    update();
+}
+
+void TimeTooltip::paintEvent( QPaintEvent * )
+{
+    QPainter p( this );
+    p.setRenderHints( QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing );
+
+    p.setPen( Qt::black );
+    p.setBrush( qApp->palette().base() );
+    p.drawPath( mPainterPath );
+
+    p.setFont( mFont );
+    p.setPen( QPen( qApp->palette().text(), 1 ) );
+    p.drawText( mBox, Qt::AlignCenter, mTime );
+}
+
+#undef TIP_HEIGHT
diff --git a/modules/gui/qt4/util/timetooltip.hpp b/modules/gui/qt4/util/timetooltip.hpp
new file mode 100644 (file)
index 0000000..f218d38
--- /dev/null
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright © 2011 VideoLAN
+ * $Id$
+ *
+ * Authors: Ludovic Fauvet <etix@l0cal.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef TIMETOOLTIP_H
+#define TIMETOOLTIP_H
+
+#include <QWidget>
+#include <QBitmap>
+
+class QPaintEvent;
+class QString;
+class QFont;
+class QRect;
+class QPainterPath;
+
+class TimeTooltip : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit TimeTooltip( QWidget *parent = 0 );
+    void setTime( const QString& time );
+
+protected:
+    virtual void paintEvent( QPaintEvent * );
+
+private:
+    QString mTime;
+    QFont mFont;
+    QRect mBox;
+    QPainterPath mPainterPath;
+    QBitmap mMask;
+};
+
+#endif // TIMETOOLTIP_H