]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/util/customwidgets.cpp
Qt: emit video window resize events
[vlc] / modules / gui / qt4 / util / customwidgets.cpp
index 8073bf4da79bf7cfddbcd06d6bed074583da7a6e..8b766ead8aa16e7d3555470acae6ea975838e799 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * customwidgets.cpp: Custom widgets
  ****************************************************************************
- * Copyright (C) 2006 the VideoLAN team
+ * Copyright (C) 2006-2011 the VideoLAN team
  * Copyright (C) 2004 Daniel Molkentin <molkentin@kde.org>
  * $Id$
  *
 #endif
 
 #include "customwidgets.hpp"
-#include "qt4.hpp" /*needed for qtr and CONNECT, but not necessary */
+#include "qt4.hpp"               /* needed for qtr,  but not necessary */
 
 #include <QPainter>
-#include <QColorGroup>
 #include <QRect>
 #include <QKeyEvent>
 #include <QWheelEvent>
-#include <QHBoxLayout>
-#include <QStyle>
-#include <QStyleOption>
-#include <vlc_intf_strings.h>
+#include <QPixmap>
+#include <QApplication>
 #include <vlc_keys.h>
-#include <wctype.h> /* twolower() */
 
-ClickLineEdit::ClickLineEdit( const QString &msg, QWidget *parent) : QLineEdit( parent )
-{
-    mDrawClickMsg = true;
-    setClickMessage( msg );
-}
-
-void ClickLineEdit::setClickMessage( const QString &msg )
-{
-    mClickMessage = msg;
-    repaint();
-}
-
-
-void ClickLineEdit::setText( const QString &txt )
-{
-    mDrawClickMsg = txt.isEmpty();
-    repaint();
-    QLineEdit::setText( txt );
-}
-
-void ClickLineEdit::paintEvent( QPaintEvent *pe )
-{
-    QLineEdit::paintEvent( pe );
-    if ( mDrawClickMsg == true && !hasFocus() ) {
-        QPainter p( this );
-        QPen tmp = p.pen();
-        p.setPen( palette().color( QPalette::Disabled, QPalette::Text ) );
-        QRect cr = contentsRect();
-        // Add two pixel margin on the left side
-        cr.setLeft( cr.left() + 3 );
-        p.drawText( cr, Qt::AlignLeft | Qt::AlignVCenter, mClickMessage );
-        p.setPen( tmp );
-        p.end();
-    }
-}
-
-void ClickLineEdit::dropEvent( QDropEvent *ev )
-{
-    mDrawClickMsg = false;
-    QLineEdit::dropEvent( ev );
-}
-
-void ClickLineEdit::focusInEvent( QFocusEvent *ev )
-{
-    if ( mDrawClickMsg == true ) {
-        mDrawClickMsg = false;
-        repaint();
-    }
-    QLineEdit::focusInEvent( ev );
-}
-
-void ClickLineEdit::focusOutEvent( QFocusEvent *ev )
-{
-    if ( text().isEmpty() ) {
-        mDrawClickMsg = true;
-        repaint();
-    }
-    QLineEdit::focusOutEvent( ev );
-}
-
-QVLCFramelessButton::QVLCFramelessButton( QWidget *parent )
-  : QPushButton( parent )
+QFramelessButton::QFramelessButton( QWidget *parent )
+                    : QPushButton( parent )
 {
     setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
 }
 
-void QVLCFramelessButton::paintEvent( QPaintEvent * event )
+void QFramelessButton::paintEvent( QPaintEvent * )
 {
     QPainter painter( this );
     QPixmap pix = icon().pixmap( size() );
@@ -117,95 +53,57 @@ void QVLCFramelessButton::paintEvent( QPaintEvent * event )
     painter.drawPixmap( QRect( pos.x(), pos.y(), pix.width(), pix.height() ), pix );
 }
 
-QSize QVLCFramelessButton::sizeHint() const
-{
-    return iconSize();
-}
-
-SearchLineEdit::SearchLineEdit( QWidget *parent ) : QLineEdit( parent )
-{
-    clearButton = new QVLCFramelessButton( this );
-    clearButton->setIcon( QIcon( ":/toolbar/clear" ) );
-    clearButton->setIconSize( QSize( 16, 16 ) );
-    clearButton->setCursor( Qt::ArrowCursor );
-    clearButton->setToolTip( qfu(vlc_pgettext("Tooltip|Clear", "Clear")) );
-    clearButton->hide();
-
-    CONNECT( clearButton, clicked(), this, clear() );
-
-    int frameWidth = style()->pixelMetric( QStyle::PM_DefaultFrameWidth, 0, this );
-
-    QFontMetrics metrics( font() );
-    QString styleSheet = QString( "min-height: %1px; "
-                                  "padding-top: 1px; "
-                                  "padding-bottom: 1px; "
-                                  "padding-right: %2px;" )
-                                  .arg( metrics.height() + ( 2 * frameWidth ) )
-                                  .arg( clearButton->sizeHint().width() + 1 );
-    setStyleSheet( styleSheet );
-
-    setMessageVisible( true );
-
-    CONNECT( this, textEdited( const QString& ),
-             this, updateText( const QString& ) );
-}
+QElidingLabel::QElidingLabel( const QString &s, Qt::TextElideMode mode, QWidget * parent )
+                 : QLabel( s, parent ), elideMode( mode )
+{ }
 
-void SearchLineEdit::clear()
+void QElidingLabel::setElideMode( Qt::TextElideMode mode )
 {
-    QLineEdit::clear();
-    clearButton->hide();
-    setMessageVisible( true );
-}
-
-void SearchLineEdit::setMessageVisible( bool on )
-{
-    message = on;
+    elideMode = mode;
     repaint();
-    return;
 }
 
-void SearchLineEdit::updateText( const QString& text )
+void QElidingLabel::paintEvent( QPaintEvent * )
 {
-    clearButton->setVisible( !text.isEmpty() );
+    QPainter p( this );
+    int space = frameWidth() + margin();
+    QRect r = rect().adjusted( space, space, -space, -space );
+    p.drawText( r, fontMetrics().elidedText( text(), elideMode, r.width() ), alignment() );
 }
 
-void SearchLineEdit::resizeEvent ( QResizeEvent * event )
+QString QVLCDebugLevelSpinBox::textFromValue( int v ) const
 {
-  QLineEdit::resizeEvent( event );
-  int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth,0,this);
-  clearButton->resize( clearButton->sizeHint().width(), height() );
-  clearButton->move( width() - clearButton->width() - frameWidth, 0 );
+    QString const texts[] = {
+    /* Note that min level 0 is 'errors' in Qt Ui
+       FIXME: fix debug levels accordingly to documentation */
+    /*  qtr("infos"),*/
+        qtr("errors"),
+        qtr("warnings"),
+        qtr("debug")
+    };
+    if ( v < 0 ) v = 0;
+    if ( v >= 2 ) v = 2;
+
+    return QString( "%1 (%2)" ).arg( v ).arg( texts[v] );
 }
 
-void SearchLineEdit::focusInEvent( QFocusEvent *event )
+VLCQDial::VLCQDial( QWidget *parent ) : QDial( parent )
 {
-  if( message )
-  {
-      setMessageVisible( false );
-  }
-  QLineEdit::focusInEvent( event );
-}
 
-void SearchLineEdit::focusOutEvent( QFocusEvent *event )
-{
-  if( text().isEmpty() )
-  {
-      setMessageVisible( true );
-  }
-  QLineEdit::focusOutEvent( event );
 }
 
-void SearchLineEdit::paintEvent( QPaintEvent *event )
+void VLCQDial::paintEvent( QPaintEvent *event )
 {
-  QLineEdit::paintEvent( event );
-  if( !message ) return;
-  QStyleOption option;
-  option.initFrom( this );
-  QRect rect = style()->subElementRect( QStyle::SE_LineEditContents, &option, this )
-                  .adjusted( 3, 0, clearButton->width() + 1, 0 );
-  QPainter painter( this );
-  painter.setPen( palette().color( QPalette::Disabled, QPalette::Text ) );
-  painter.drawText( rect, Qt::AlignLeft | Qt::AlignVCenter, qtr( I_PL_FILTER ) );
+    QDial::paintEvent( event );
+    QPainter painter( this );
+    painter.setPen( QPen( palette().color( QPalette::WindowText ) ) );
+    float radius = 0.5 * 0.707106 * qMin( size().width(), size().height() );
+    painter.drawText( QRectF( rect().center().x() + radius,
+                              rect().center().y() + radius,
+                              size().width(),
+                              size().height() ),
+                      0, QString::number( value() ), 0 );
+    painter.end();
 }
 
 /***************************************************************************
@@ -237,8 +135,8 @@ static const vlc_qt_key_t keys[] =
     { Qt::Key_Enter,                 '\r' }, // numeric pad
     { Qt::Key_Insert,                KEY_INSERT },
     { Qt::Key_Delete,                KEY_DELETE },
-    // Qt::Key_Pause
-    // Qt::Key_Print
+    { Qt::Key_Pause,                 KEY_PAUSE },
+    { Qt::Key_Print,                 KEY_PRINT },
     // Qt::Key_SysReq
     // Qt::Key_Clear
     { Qt::Key_Home,                  KEY_HOME },
@@ -256,7 +154,19 @@ static const vlc_qt_key_t keys[] =
     // Qt::Key_CapsLock
     // Qt::Key_NumLock
     // Qt::Key_ScrollLock
-    /* F1 - F35 */
+    /* F1 - F35 - Qt goes to F35, VLC stops at F12 */
+    { Qt::Key_F1,                    KEY_F1 },
+    { Qt::Key_F2,                    KEY_F2 },
+    { Qt::Key_F3,                    KEY_F3 },
+    { Qt::Key_F4,                    KEY_F4 },
+    { Qt::Key_F5,                    KEY_F5 },
+    { Qt::Key_F6,                    KEY_F6 },
+    { Qt::Key_F7,                    KEY_F7 },
+    { Qt::Key_F8,                    KEY_F8 },
+    { Qt::Key_F9,                    KEY_F9 },
+    { Qt::Key_F10,                   KEY_F10 },
+    { Qt::Key_F11,                   KEY_F11 },
+    { Qt::Key_F12,                   KEY_F12 },
     // Qt::Key_Super_L
     // Qt::Key_Super_R
     { Qt::Key_Menu,                  KEY_MENU },
@@ -343,7 +253,8 @@ static const vlc_qt_key_t keys[] =
     // Qt::Key_LaunchMail
     // Qt::Key_LaunchMedia
     /* Qt::Key_Launch0 through Qt::Key_LaunchF */
-    // Qt::Key_MediaLast
+    /* ... */
+    { Qt::Key_Reload,                KEY_BROWSER_REFRESH },
 };
 
 static int keycmp( const void *a, const void *b )
@@ -360,15 +271,13 @@ int qtEventToVLCKey( QKeyEvent *e )
     uint32_t i_vlck = 0;
 
     if( qtk <= 0xff )
-        /* VLC and X11 use lowercase whereas Qt uses uppercase */
-#ifdef __STDC_ISO_10646__
-        i_vlck = towlower( qtk );
-#else
-# error FIXME
-#endif
-    else /* Qt and X11 go to F35, but VLC stops at F12 */
-    if( qtk >= Qt::Key_F1 && qtk <= Qt::Key_F12 )
-        i_vlck = qtk - Qt::Key_F1 + KEY_F1;
+    {
+        /* VLC and X11 use lowercase whereas Qt uses uppercase, this
+         * method should be equal to towlower in case of latin1 */
+        if( qtk >= 'A' && qtk <= 'Z' ) i_vlck = qtk+32;
+        else if( qtk >= 0xC0 && qtk <= 0xDE && qtk != 0xD7) i_vlck = qtk+32;
+        else i_vlck = qtk;
+    }
     else
     {
         const vlc_qt_key_t *map;
@@ -397,25 +306,110 @@ int qtWheelEventToVLCKey( QWheelEvent *e )
     return i_vlck;
 }
 
-QString VLCKeyToString( int val )
+QString VLCKeyToString( unsigned val, bool locale )
 {
-    char *base = KeyToString (val & ~KEY_MODIFIER);
+    char *base = vlc_keycode2str (val, locale);
+    if (base == NULL)
+        return qtr( "Unset" );
+
+    QString r = qfu( base );
+
+    free( base );
+    return r;
+}
 
-    QString r = "";
-    if( val & KEY_MODIFIER_CTRL )
-        r+= qfu( "Ctrl+" );
-    if( val & KEY_MODIFIER_ALT )
-        r+= qfu( "Alt+" );
-    if( val & KEY_MODIFIER_SHIFT )
-        r+= qfu( "Shift+" );
+/* Animated Icon implementation */
+SpinningIcon::SpinningIcon( QWidget *parent ) : QLabel( parent )
+{
+    QList<QString> frames;
+    frames << ":/util/wait1";
+    frames << ":/util/wait2";
+    frames << ":/util/wait3";
+    frames << ":/util/wait4";
+    animator = new PixmapAnimator( this, frames );
+    CONNECT( animator, pixmapReady( const QPixmap & ), this, setPixmap( const QPixmap & ) );
+    CONNECT( animator, pixmapReady( const QPixmap & ), this, repaint() );
+    setScaledContents( true );
+    setFixedSize( 16, 16 );
+    animator->setCurrentTime( 0 );
+}
 
-    if (base)
+QToolButtonExt::QToolButtonExt(QWidget *parent, int ms )
+    : QToolButton( parent ),
+      shortClick( false ),
+      longClick( false )
+{
+    setAutoRepeat( true );
+    /* default to twice the doubleclick delay */
+    setAutoRepeatDelay( ( ms > 0 )? ms : 2 * QApplication::doubleClickInterval() );
+    setAutoRepeatInterval( 100 );
+    connect( this, SIGNAL(released()), this, SLOT(releasedSlot()) );
+    connect( this, SIGNAL(clicked()), this, SLOT(clickedSlot()) );
+}
+
+/* table illustrating the different scenarios and the events generated
+ * ====================
+ *
+ *  event     isDown()
+ *
+ *  released  false   }
+ *  clicked   false   }= short click
+ *
+ *  released  false    = cancelled click (mouse released outside of button area,
+ *                                        before long click delay kicks in)
+ *
+ *  released  true    }
+ *  clicked   true    }= long click (multiple of these generated)
+ *  released  false    = stop long click (mouse released / moved outside of
+ *                                        button area)
+ * (clicked   false)   = stop long click (additional event if mouse released
+ *                                        inside of button area)
+ */
+
+void QToolButtonExt::releasedSlot()
+{
+    if( isDown() )
     {
-        r += qfu( base );
-        free( base );
+        // we are beginning a long click
+        longClick = true;
+        shortClick = false;
     }
     else
-        r += qtr( "Unset" );
-    return r;
+    {
+        if( longClick )
+        {
+            // we are stopping a long click
+            longClick = false;
+            shortClick = false;
+        }
+        else
+        {
+            // we are generating a short click
+            longClick = false;
+            shortClick = true;
+        }
+    }
 }
 
+void QToolButtonExt::clickedSlot()
+{
+    if( longClick )
+        emit longClicked();
+    else if( shortClick )
+        emit shortClicked();
+}
+
+YesNoCheckBox::YesNoCheckBox( QWidget *parent ) : QCheckBox( parent )
+{
+    setEnabled( false );
+    setStyleSheet("\
+                  QCheckBox::indicator:unchecked:hover,\
+                  QCheckBox::indicator:unchecked {\
+                      image: url(:/menu/quit);\
+                  }\
+                  QCheckBox::indicator:checked:hover,\
+                  QCheckBox::indicator:checked {\
+                      image: url(:/valid);\
+                  }\
+        ");
+}