You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
6.9 KiB
304 lines
6.9 KiB
/* |
|
* $Id$ |
|
* |
|
* KWin client button tooltip support module |
|
* |
|
* Copyright (c) 2001 |
|
* Karol Szwed <gallium@kde.org> |
|
* |
|
* Uses portions of QToolTip code |
|
* Copyright (c) TrollTech AS |
|
* |
|
* Since Qt installs its own internal event filter when using |
|
* a QToolTip, kwin doesn't obtain the necessary events and hence |
|
* focus problems and loss of window frames occur if they are used |
|
* for kwin styles. Thus, this small class implements a bare subset |
|
* of QToolTip designed especially for kwin client buttons without |
|
* installing any event filters that confuse kwin. |
|
* |
|
* For all normal clients, simply use the KWinButton class instead |
|
* of QButton, which will use a KWinToolTip internally. Other clients |
|
* which rely on QToolButton or QWidget for client buttons may use the |
|
* KWinToolButton and KWinWidgetButton classes to automatically take |
|
* care of tooltips. |
|
* |
|
*/ |
|
|
|
#include <qpoint.h> |
|
#include "kwinbutton.h" |
|
#include "options.h" |
|
#include "workspace.h" |
|
|
|
// This is a hack to ensure that we use Qt fade and scroll effects |
|
|
|
// This code is copied directly from qeffects_p.h |
|
struct QEffects |
|
{ |
|
enum Direction { |
|
LeftScroll = 0x0001, |
|
RightScroll = 0x0002, |
|
UpScroll = 0x0004, |
|
DownScroll = 0x0008 |
|
}; |
|
|
|
typedef uint DirFlags; |
|
}; |
|
|
|
extern void Q_EXPORT qScrollEffect( QWidget*, |
|
QEffects::DirFlags dir = QEffects::DownScroll, int time = -1 ); |
|
extern void Q_EXPORT qFadeEffect( QWidget*, int time = -1 ); |
|
// end qeffects_p.h code |
|
|
|
using namespace KWinInternal; |
|
|
|
|
|
KWinToolTip::KWinToolTip( QWidget* parent, const QString& tip ) |
|
: QLabel( NULL, "KWinToolTip", WStyle_StaysOnTop + |
|
WStyle_Customize + WStyle_NoBorder + WStyle_Tool ) |
|
{ |
|
setMargin(1); |
|
setIndent(0); |
|
setFrameStyle( QFrame::Plain | QFrame::Box ); |
|
setLineWidth(1); |
|
setAlignment( AlignLeft | AlignTop ); |
|
setText(tip); |
|
adjustSize(); |
|
|
|
// Use stock Qt tooltip colors as defined in qapplication.cpp |
|
QColorGroup clrGroup( Qt::black, QColor(255,255,220), |
|
QColor(96,96,96), Qt::black, Qt::black, |
|
Qt::black, QColor(255,255,220) ); |
|
setPalette( QPalette( clrGroup, clrGroup, clrGroup ) ); |
|
|
|
btn = parent; |
|
connect(&hideTimer, SIGNAL(timeout()), SLOT(hideTip())); |
|
connect(&showTimer, SIGNAL(timeout()), SLOT(showTip())); |
|
} |
|
|
|
KWinToolTip::~KWinToolTip() |
|
{ |
|
} |
|
|
|
void KWinToolTip::setTipText( const QString& tip ) |
|
{ |
|
bool visible = isVisible(); |
|
|
|
if (visible) |
|
hide(); |
|
|
|
setText(tip); |
|
adjustSize(); |
|
positionTip(); |
|
|
|
if (visible) |
|
showTip(); |
|
} |
|
|
|
void KWinToolTip::enterTip() |
|
{ |
|
// Show after 1 second |
|
showTimer.start( 1000, TRUE ); |
|
} |
|
|
|
void KWinToolTip::leaveTip() |
|
{ |
|
if (hideTimer.isActive()) |
|
hideTimer.stop(); |
|
if (showTimer.isActive()) |
|
showTimer.stop(); |
|
if (isVisible()) |
|
hide(); |
|
} |
|
|
|
/* Internal */ |
|
void KWinToolTip::showTip() |
|
{ |
|
if (isVisible()) |
|
return; |
|
|
|
// Ignore empty tooltips |
|
if (text().isEmpty()) |
|
return; |
|
|
|
positionTip(); |
|
|
|
// Show tooltips the Qt way |
|
if (options->fadeTooltips()) |
|
qFadeEffect(this); |
|
else if (options->animateTooltips()) |
|
qScrollEffect(this); |
|
else |
|
show(); |
|
raise(); |
|
|
|
// Hide after 10 seconds |
|
hideTimer.start( 10000, TRUE ); |
|
} |
|
|
|
/* Internal */ |
|
void KWinToolTip::hideTip() |
|
{ |
|
if (isVisible()) |
|
hide(); |
|
} |
|
|
|
/* Internal */ |
|
void KWinToolTip::positionTip() |
|
{ |
|
QPoint p = btn->mapToGlobal(btn->rect().bottomLeft()) + QPoint(0, 16); |
|
int screen = QApplication::desktop()->screenNumber(btn->mapToGlobal(btn->rect().center())); |
|
QRect screenGeom = QApplication::desktop()->screenGeometry(screen); |
|
|
|
// Ensure the tooltip is displayed within the current desktop |
|
if ( screenGeom.right() < p.x() + width() ) |
|
p.setX( screenGeom.right() - width()); |
|
if ( screenGeom.bottom() < p.y() + height() ) |
|
p.setY( screenGeom.bottom() - height() ); |
|
if (p.x() < screenGeom.x()) p.setX(screenGeom.x()); |
|
if (p.y() < screenGeom.y()) p.setY(screenGeom.y()); |
|
move(p); |
|
|
|
// Ensure we don't get enter/leave event race conditions when a |
|
// tooltip is over a button. |
|
QRect btnGlobalRect( btn->mapToGlobal(btn->rect().topLeft()), |
|
btn->mapToGlobal(btn->rect().bottomRight()) ); |
|
QRect tipGlobalRect( mapToGlobal(rect().topLeft()), |
|
mapToGlobal(rect().bottomRight()) ); |
|
if (btnGlobalRect.intersects( tipGlobalRect )) |
|
{ |
|
// Only intersects when button is at lower part of screen |
|
p.setY( btn->mapToGlobal(btn->rect().topLeft()).y() - height() - 5 ); |
|
move(p); |
|
} |
|
} |
|
|
|
|
|
// KWinButton class |
|
KWinButton::KWinButton(QWidget *parent, const char *name, const QString& tip) |
|
: QButton(parent, name, WStyle_Customize | WRepaintNoErase | |
|
WResizeNoErase | WStyle_NoBorder ) |
|
{ |
|
buttonTip = options->showTooltips() ? new KWinToolTip(this, tip) : NULL; |
|
} |
|
|
|
KWinButton::~KWinButton() |
|
{ |
|
if (buttonTip) |
|
delete buttonTip; |
|
} |
|
|
|
void KWinButton::setTipText(const QString& newTip) |
|
{ |
|
if (buttonTip) |
|
buttonTip->setTipText( newTip ); |
|
} |
|
|
|
void KWinButton::enterEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->enterTip(); |
|
QButton::enterEvent( e ); |
|
} |
|
|
|
void KWinButton::leaveEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
QButton::leaveEvent( e ); |
|
} |
|
|
|
void KWinButton::mousePressEvent(QMouseEvent* e) |
|
{ |
|
// Hide tooltips if a button is pressed |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
QButton::mousePressEvent( e ); |
|
} |
|
|
|
|
|
// KWinToolButton class |
|
KWinToolButton::KWinToolButton(QWidget *parent, const char *name, const QString& tip) |
|
: QToolButton(parent, name) |
|
{ |
|
buttonTip = options->showTooltips() ? new KWinToolTip(this, tip) : NULL; |
|
} |
|
|
|
KWinToolButton::~KWinToolButton() |
|
{ |
|
if (buttonTip) |
|
delete buttonTip; |
|
} |
|
|
|
void KWinToolButton::setTipText(const QString& newTip) |
|
{ |
|
if (buttonTip) |
|
buttonTip->setTipText( newTip ); |
|
} |
|
|
|
void KWinToolButton::enterEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->enterTip(); |
|
QToolButton::enterEvent( e ); |
|
} |
|
|
|
void KWinToolButton::leaveEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
QToolButton::leaveEvent( e ); |
|
} |
|
|
|
void KWinToolButton::mousePressEvent(QMouseEvent* e) |
|
{ |
|
// Hide tooltips if a button is pressed |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
QToolButton::mousePressEvent( e ); |
|
} |
|
|
|
|
|
// KWinWidgetButton class |
|
KWinWidgetButton::KWinWidgetButton(QWidget *parent, const char *name, |
|
WFlags f, const QString& tip) |
|
: QWidget(parent, name, f) |
|
{ |
|
buttonTip = options->showTooltips() ? new KWinToolTip(this, tip) : NULL; |
|
} |
|
|
|
KWinWidgetButton::~KWinWidgetButton() |
|
{ |
|
if (buttonTip) |
|
delete buttonTip; |
|
} |
|
|
|
void KWinWidgetButton::setTipText(const QString& newTip) |
|
{ |
|
if (buttonTip) |
|
buttonTip->setTipText( newTip ); |
|
} |
|
|
|
void KWinWidgetButton::enterEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->enterTip(); |
|
QWidget::enterEvent( e ); |
|
} |
|
|
|
void KWinWidgetButton::leaveEvent(QEvent *e) |
|
{ |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
QWidget::leaveEvent( e ); |
|
} |
|
|
|
void KWinWidgetButton::mousePressEvent(QMouseEvent* /*e*/) |
|
{ |
|
// Hide tooltips if a button is pressed |
|
if (buttonTip) |
|
buttonTip->leaveTip(); |
|
} |
|
|
|
|
|
#include "kwinbutton.moc" |
|
// vim: ts=4
|
|
|