Commit 96929b1b authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf

Qt: change the LocationBar Class file

parent d3803618
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "components/playlist/standardpanel.hpp" #include "components/playlist/standardpanel.hpp"
#include "components/playlist/selector.hpp" #include "components/playlist/selector.hpp"
#include "components/playlist/playlist.hpp" #include "components/playlist/playlist.hpp"
#include "components/playlist/playlist_model.hpp"
#include "input_manager.hpp" /* art signal */ #include "input_manager.hpp" /* art signal */
#include "main_interface.hpp" /* DropEvent TODO remove this*/ #include "main_interface.hpp" /* DropEvent TODO remove this*/
...@@ -160,3 +161,192 @@ void PlaylistWidget::forceShow() ...@@ -160,3 +161,192 @@ void PlaylistWidget::forceShow()
rightPanel->show(); rightPanel->show();
updateGeometry(); updateGeometry();
} }
#include <QSignalMapper>
#include <QMenu>
#include <QPainter>
LocationBar::LocationBar( PLModel *m )
{
model = m;
mapper = new QSignalMapper( this );
CONNECT( mapper, mapped( int ), this, invoke( int ) );
btnMore = new LocationButton( "...", false, true, this );
menuMore = new QMenu( this );
btnMore->setMenu( menuMore );
}
void LocationBar::setIndex( const QModelIndex &index )
{
qDeleteAll( buttons );
buttons.clear();
qDeleteAll( actions );
actions.clear();
QModelIndex i = index;
bool first = true;
while( true )
{
PLItem *item = model->getItem( i );
char *fb_name = input_item_GetTitleFbName( item->inputItem() );
QString text = qfu(fb_name);
free(fb_name);
QAbstractButton *btn = new LocationButton( text, first, !first, this );
btn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed );
buttons.append( btn );
QAction *action = new QAction( text, this );
actions.append( action );
CONNECT( btn, clicked(), action, trigger() );
mapper->setMapping( action, item->id() );
CONNECT( action, triggered(), mapper, map() );
first = false;
if( i.isValid() ) i = i.parent();
else break;
}
QString prefix;
for( int a = actions.count() - 1; a >= 0 ; a-- )
{
actions[a]->setText( prefix + actions[a]->text() );
prefix += QString(" ");
}
if( isVisible() ) layOut( size() );
}
void LocationBar::setRootIndex()
{
setIndex( QModelIndex() );
}
void LocationBar::invoke( int i_id )
{
QModelIndex index = model->index( i_id, 0 );
emit invoked ( index );
}
void LocationBar::layOut( const QSize& size )
{
menuMore->clear();
widths.clear();
int count = buttons.count();
int totalWidth = 0;
for( int i = 0; i < count; i++ )
{
int w = buttons[i]->sizeHint().width();
widths.append( w );
totalWidth += w;
if( totalWidth > size.width() ) break;
}
int x = 0;
int shown = widths.count();
if( totalWidth > size.width() && count > 1 )
{
QSize sz = btnMore->sizeHint();
btnMore->setGeometry( 0, 0, sz.width(), size.height() );
btnMore->show();
x = sz.width();
totalWidth += x;
}
else
{
btnMore->hide();
}
for( int i = count - 1; i >= 0; i-- )
{
if( totalWidth <= size.width() || i == 0)
{
buttons[i]->setGeometry( x, 0, qMin( size.width() - x, widths[i] ), size.height() );
buttons[i]->show();
x += widths[i];
totalWidth -= widths[i];
}
else
{
menuMore->addAction( actions[i] );
buttons[i]->hide();
if( i < shown ) totalWidth -= widths[i];
}
}
}
void LocationBar::resizeEvent ( QResizeEvent * event )
{
layOut( event->size() );
}
QSize LocationBar::sizeHint() const
{
return btnMore->sizeHint();
}
LocationButton::LocationButton( const QString &text, bool bold,
bool arrow, QWidget * parent )
: b_arrow( arrow ), QPushButton( parent )
{
QFont font;
font.setBold( bold );
setFont( font );
setText( text );
}
#define PADDING 4
void LocationButton::paintEvent ( QPaintEvent * event )
{
QStyleOptionButton option;
option.initFrom( this );
option.state |= QStyle::State_Enabled;
QPainter p( this );
if( underMouse() )
{
p.save();
p.setRenderHint( QPainter::Antialiasing, true );
QColor c = palette().color( QPalette::Highlight );
p.setPen( c );
p.setBrush( c.lighter( 150 ) );
p.setOpacity( 0.2 );
p.drawRoundedRect( option.rect.adjusted( 0, 2, 0, -2 ), 5, 5 );
p.restore();
}
QRect r = option.rect.adjusted( PADDING, 0, -PADDING - (b_arrow ? 10 : 0), 0 );
QString str( text() );
/* This check is absurd, but either it is not done properly inside elidedText(),
or boundingRect() is wrong */
if( r.width() < fontMetrics().boundingRect( text() ).width() )
str = fontMetrics().elidedText( text(), Qt::ElideRight, r.width() );
p.drawText( r, Qt::AlignVCenter | Qt::AlignLeft, str );
if( b_arrow )
{
option.rect.setWidth( 10 );
option.rect.moveRight( rect().right() );
style()->drawPrimitive( QStyle::PE_IndicatorArrowRight, &option, &p );
}
}
QSize LocationButton::sizeHint() const
{
QSize s( fontMetrics().boundingRect( text() ).size() );
/* Add two pixels to width: font metrics are buggy, if you pass text through elidation
with exactly the width of its bounding rect, sometimes it still elides */
s.setWidth( s.width() + ( 2 * PADDING ) + ( b_arrow ? 10 : 0 ) + 2 );
s.setHeight( s.height() + 2 * PADDING );
return s;
}
#undef PADDING
...@@ -77,4 +77,44 @@ protected: ...@@ -77,4 +77,44 @@ protected:
}; };
class LocationButton : public QPushButton
{
public:
LocationButton( const QString &, bool bold, bool arrow, QWidget * parent = NULL );
QSize sizeHint() const;
private:
void paintEvent ( QPaintEvent * event );
QFontMetrics *metrics;
bool b_arrow;
};
class PLModel;
class LocationBar : public QWidget
{
Q_OBJECT
public:
LocationBar( PLModel * );
void setIndex( const QModelIndex & );
QSize sizeHint() const;
signals:
void invoked( const QModelIndex & );
public slots:
void setRootIndex();
private slots:
void invoke( int i_item_id );
private:
void layOut( const QSize& size );
void resizeEvent ( QResizeEvent * event );
PLModel *model;
QSignalMapper *mapper;
QHBoxLayout *box;
QList<QWidget*> buttons;
QList<QAction*> actions;
LocationButton *btnMore;
QMenu *menuMore;
QList<int> widths;
};
#endif #endif
...@@ -43,11 +43,9 @@ ...@@ -43,11 +43,9 @@
#include <QModelIndexList> #include <QModelIndexList>
#include <QLabel> #include <QLabel>
#include <QMenu> #include <QMenu>
#include <QSignalMapper>
#include <QWheelEvent> #include <QWheelEvent>
#include <QToolButton> #include <QToolButton>
#include <QFontMetrics> #include <QFontMetrics>
#include <QPainter>
#include <QStackedLayout> #include <QStackedLayout>
#include <assert.h> #include <assert.h>
...@@ -461,187 +459,3 @@ void StandardPLPanel::browseInto( input_item_t *p_input ) ...@@ -461,187 +459,3 @@ void StandardPLPanel::browseInto( input_item_t *p_input )
} }
LocationBar::LocationBar( PLModel *m )
{
model = m;
mapper = new QSignalMapper( this );
CONNECT( mapper, mapped( int ), this, invoke( int ) );
btnMore = new LocationButton( "...", false, true, this );
menuMore = new QMenu( this );
btnMore->setMenu( menuMore );
}
void LocationBar::setIndex( const QModelIndex &index )
{
qDeleteAll( buttons );
buttons.clear();
qDeleteAll( actions );
actions.clear();
QModelIndex i = index;
bool first = true;
while( true )
{
PLItem *item = model->getItem( i );
char *fb_name = input_item_GetTitleFbName( item->inputItem() );
QString text = qfu(fb_name);
free(fb_name);
QAbstractButton *btn = new LocationButton( text, first, !first, this );
btn->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Fixed );
buttons.append( btn );
QAction *action = new QAction( text, this );
actions.append( action );
CONNECT( btn, clicked(), action, trigger() );
mapper->setMapping( action, item->id() );
CONNECT( action, triggered(), mapper, map() );
first = false;
if( i.isValid() ) i = i.parent();
else break;
}
QString prefix;
for( int a = actions.count() - 1; a >= 0 ; a-- )
{
actions[a]->setText( prefix + actions[a]->text() );
prefix += QString(" ");
}
if( isVisible() ) layOut( size() );
}
void LocationBar::setRootIndex()
{
setIndex( QModelIndex() );
}
void LocationBar::invoke( int i_id )
{
QModelIndex index = model->index( i_id, 0 );
emit invoked ( index );
}
void LocationBar::layOut( const QSize& size )
{
menuMore->clear();
widths.clear();
int count = buttons.count();
int totalWidth = 0;
for( int i = 0; i < count; i++ )
{
int w = buttons[i]->sizeHint().width();
widths.append( w );
totalWidth += w;
if( totalWidth > size.width() ) break;
}
int x = 0;
int shown = widths.count();
if( totalWidth > size.width() && count > 1 )
{
QSize sz = btnMore->sizeHint();
btnMore->setGeometry( 0, 0, sz.width(), size.height() );
btnMore->show();
x = sz.width();
totalWidth += x;
}
else
{
btnMore->hide();
}
for( int i = count - 1; i >= 0; i-- )
{
if( totalWidth <= size.width() || i == 0)
{
buttons[i]->setGeometry( x, 0, qMin( size.width() - x, widths[i] ), size.height() );
buttons[i]->show();
x += widths[i];
totalWidth -= widths[i];
}
else
{
menuMore->addAction( actions[i] );
buttons[i]->hide();
if( i < shown ) totalWidth -= widths[i];
}
}
}
void LocationBar::resizeEvent ( QResizeEvent * event )
{
layOut( event->size() );
}
QSize LocationBar::sizeHint() const
{
return btnMore->sizeHint();
}
LocationButton::LocationButton( const QString &text, bool bold,
bool arrow, QWidget * parent )
: b_arrow( arrow ), QPushButton( parent )
{
QFont font;
font.setBold( bold );
setFont( font );
setText( text );
}
#define PADDING 4
void LocationButton::paintEvent ( QPaintEvent * event )
{
QStyleOptionButton option;
option.initFrom( this );
option.state |= QStyle::State_Enabled;
QPainter p( this );
if( underMouse() )
{
p.save();
p.setRenderHint( QPainter::Antialiasing, true );
QColor c = palette().color( QPalette::Highlight );
p.setPen( c );
p.setBrush( c.lighter( 150 ) );
p.setOpacity( 0.2 );
p.drawRoundedRect( option.rect.adjusted( 0, 2, 0, -2 ), 5, 5 );
p.restore();
}
QRect r = option.rect.adjusted( PADDING, 0, -PADDING - (b_arrow ? 10 : 0), 0 );
QString str( text() );
/* This check is absurd, but either it is not done properly inside elidedText(),
or boundingRect() is wrong */
if( r.width() < fontMetrics().boundingRect( text() ).width() )
str = fontMetrics().elidedText( text(), Qt::ElideRight, r.width() );
p.drawText( r, Qt::AlignVCenter | Qt::AlignLeft, str );
if( b_arrow )
{
option.rect.setWidth( 10 );
option.rect.moveRight( rect().right() );
style()->drawPrimitive( QStyle::PE_IndicatorArrowRight, &option, &p );
}
}
QSize LocationButton::sizeHint() const
{
QSize s( fontMetrics().boundingRect( text() ).size() );
/* Add two pixels to width: font metrics are buggy, if you pass text through elidation
with exactly the width of its bounding rect, sometimes it still elides */
s.setWidth( s.width() + ( 2 * PADDING ) + ( b_arrow ? 10 : 0 ) + 2 );
s.setHeight( s.height() + 2 * PADDING );
return s;
}
#undef PADDING
...@@ -120,42 +120,4 @@ private slots: ...@@ -120,42 +120,4 @@ private slots:
void browseInto( input_item_t * ); void browseInto( input_item_t * );
}; };
class LocationButton : public QPushButton
{
public:
LocationButton( const QString &, bool bold, bool arrow, QWidget * parent = NULL );
QSize sizeHint() const;
private:
void paintEvent ( QPaintEvent * event );
QFontMetrics *metrics;
bool b_arrow;
};
class LocationBar : public QWidget
{
Q_OBJECT
public:
LocationBar( PLModel * );
void setIndex( const QModelIndex & );
QSize sizeHint() const;
signals:
void invoked( const QModelIndex & );
public slots:
void setRootIndex();
private slots:
void invoke( int i_item_id );
private:
void layOut( const QSize& size );
void resizeEvent ( QResizeEvent * event );
PLModel *model;
QSignalMapper *mapper;
QHBoxLayout *box;
QList<QWidget*> buttons;
QList<QAction*> actions;
LocationButton *btnMore;
QMenu *menuMore;
QList<int> widths;
};
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment