mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-30 17:24:08 +00:00
Reimplemented the status bar as internal widget instead of top-level borderless window.
Now the status bar behavior is much more reliable on X11 systems, no more lags when moving GoldenDict window around or when resizing it. Works better with compositing window managers as well. Also, the new status bar also supports images, which is good for warnings and error messages. The status bar is fully styled and can change its appearence based on user's CSS, if needed.
This commit is contained in:
parent
83acbcf10c
commit
354066c292
119
mainstatusbar.cc
119
mainstatusbar.cc
|
@ -8,126 +8,89 @@
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
MainStatusBar::MainStatusBar(QWidget *parent) : QFrame(parent)
|
MainStatusBar::MainStatusBar(QWidget *parent) : QWidget(parent)
|
||||||
{
|
{
|
||||||
// style
|
textWidget = new QLabel(QString(), this);
|
||||||
setWindowFlags( Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint );
|
textWidget->setObjectName("text");
|
||||||
setFrameStyle( QFrame::Box | QFrame::Plain );
|
textWidget->setFont(QApplication::font("QStatusBar"));
|
||||||
setLineWidth(0);
|
textWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
|
picWidget = new QLabel(QString(), this);
|
||||||
|
picWidget->setObjectName("icon");
|
||||||
|
picWidget->setPixmap(QPixmap());
|
||||||
|
picWidget->setScaledContents(true);
|
||||||
|
picWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||||
|
|
||||||
// components
|
|
||||||
label = new QLabel(QString(), this);
|
|
||||||
label->setTextFormat(Qt::PlainText);
|
|
||||||
timer = new QTimer(this);
|
timer = new QTimer(this);
|
||||||
|
|
||||||
// layout
|
// layout
|
||||||
QVBoxLayout * layout = new QVBoxLayout;
|
QHBoxLayout * layout = new QHBoxLayout;
|
||||||
layout->addWidget(label);
|
layout->setSpacing(0);
|
||||||
layout->setSizeConstraint(QLayout::SetFixedSize);
|
layout->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
layout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
layout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
layout->setMargin(4);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->addWidget(picWidget);
|
||||||
|
layout->addWidget(textWidget);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
parentWidget()->installEventFilter( this );
|
|
||||||
|
|
||||||
connect( timer, SIGNAL( timeout() ), SLOT( clearMessage() ) );
|
connect( timer, SIGNAL( timeout() ), SLOT( clearMessage() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainStatusBar::clearMessage()
|
void MainStatusBar::clearMessage()
|
||||||
{
|
{
|
||||||
message = QString();
|
textWidget->setText(QString());
|
||||||
label->setText(message);
|
picWidget->setPixmap(QPixmap());
|
||||||
timer->stop();
|
timer->stop();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainStatusBar::currentMessage() const
|
QString MainStatusBar::currentMessage() const
|
||||||
{
|
{
|
||||||
return message;
|
return textWidget->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainStatusBar::showMessage(const QString & str, int timeout)
|
void MainStatusBar::showMessage(const QString & str, int timeout, const QPixmap & pixmap)
|
||||||
{
|
{
|
||||||
message = str;
|
textWidget->setText( str );
|
||||||
|
picWidget->setPixmap( pixmap );
|
||||||
|
|
||||||
if ( timeout > 0 )
|
if ( timeout > 0 )
|
||||||
{
|
|
||||||
timer->start( timeout );
|
|
||||||
}
|
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainStatusBar::refresh(bool forceHide)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( forceHide )
|
|
||||||
{
|
{
|
||||||
hide();
|
timer->start( timeout );
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !message.isEmpty() )
|
refresh();
|
||||||
{
|
}
|
||||||
|
|
||||||
int maxLabelLength = parentWidget()->width() - 2 * layout()->margin();
|
void MainStatusBar::refresh()
|
||||||
label->setText( label->fontMetrics().elidedText( message, Qt::ElideRight, maxLabelLength ) );
|
{
|
||||||
|
if ( !currentMessage().isEmpty() )
|
||||||
|
{
|
||||||
|
if ( !picWidget->pixmap()->isNull() )
|
||||||
|
{
|
||||||
|
picWidget->setFixedSize( textWidget->height(), textWidget->height() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
picWidget->setFixedSize( 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
adjustSize();
|
adjustSize();
|
||||||
|
|
||||||
// move(pGeom.left(), pGeom.bottom() - size().height() + 1 );
|
move( QPoint( 0, parentWidget()->height() - height() ) );
|
||||||
|
|
||||||
move(parentWidget()->mapToGlobal(QPoint(0, parentWidget()->height() - height() + 1)));
|
|
||||||
|
|
||||||
if ( parentWidget()->isHidden() )
|
|
||||||
{
|
|
||||||
hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( parentWidget()->isMinimized() )
|
|
||||||
{
|
|
||||||
hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
raise();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainStatusBar::mousePressEvent ( QMouseEvent * )
|
void MainStatusBar::mousePressEvent ( QMouseEvent * )
|
||||||
{
|
{
|
||||||
clearMessage();
|
clearMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainStatusBar::eventFilter(QObject *, QEvent * e)
|
|
||||||
{
|
|
||||||
switch ( e->type() ) {
|
|
||||||
case QEvent::Hide:
|
|
||||||
case QEvent::WindowDeactivate:
|
|
||||||
#ifdef Q_WS_X11
|
|
||||||
// workaround for X11 idiosyncrasies
|
|
||||||
// qDebug() << e->type();
|
|
||||||
refresh(true);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case QEvent::Resize:
|
|
||||||
case QEvent::FocusOut:
|
|
||||||
case QEvent::Move:
|
|
||||||
case QEvent::WindowStateChange:
|
|
||||||
case QEvent::WindowActivate:
|
|
||||||
// qDebug() << e->type();
|
|
||||||
refresh();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
class MainStatusBar : public QFrame
|
class MainStatusBar : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -20,18 +20,21 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showMessage(const QString & text, int timeout = 0);
|
void showMessage(const QString & text, int timeout = 0, const QPixmap & pixmap = QPixmap());
|
||||||
void clearMessage();
|
void clearMessage();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void mousePressEvent(QMouseEvent * event);
|
virtual void mousePressEvent(QMouseEvent * event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLabel * label;
|
// component to display a small picture
|
||||||
|
QLabel * picWidget;
|
||||||
|
|
||||||
|
// component to display text
|
||||||
|
QLabel * textWidget;
|
||||||
|
|
||||||
QTimer * timer;
|
QTimer * timer;
|
||||||
QString message;
|
void refresh();
|
||||||
bool eventFilter(QObject *obj, QEvent * event);
|
|
||||||
void refresh(bool forceHide = false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINSTATUSBAR_HH
|
#endif // MAINSTATUSBAR_HH
|
||||||
|
|
|
@ -2110,7 +2110,10 @@ void MainWindow::toggleMenuBarTriggered(bool announce)
|
||||||
if ( cfg.preferences.hideMenubar )
|
if ( cfg.preferences.hideMenubar )
|
||||||
{
|
{
|
||||||
mainStatusBar->showMessage(
|
mainStatusBar->showMessage(
|
||||||
tr( "You have chosen to hide a menubar. Use %1 to show it back." ).arg( tr( "Ctrl+M" ) ), 10000 );
|
tr( "You have chosen to hide a menubar. Use %1 to show it back." )
|
||||||
|
.arg( QString( "<b>%1</b>" ) ).arg( tr( "Ctrl+M" ) ),
|
||||||
|
10000,
|
||||||
|
QPixmap( ":/icons/warning.png" ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
16
qt-style.css
16
qt-style.css
|
@ -19,4 +19,20 @@ ArticleView #searchText[noResults="true"]
|
||||||
border: 1px solid grey;
|
border: 1px solid grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MainStatusBar #text
|
||||||
|
{
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-top: 1px solid palette(dark);
|
||||||
|
border-right: 1px solid palette(dark);
|
||||||
|
background: palette(window);
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainStatusBar #icon
|
||||||
|
{
|
||||||
|
border-top: 1px solid palette(dark);
|
||||||
|
background: palette(window);
|
||||||
|
padding: 2px;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 0px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue