Aurorae supports putting the decoration to the left, right or bottom.

You currently don't want to shade the window when the decoration is on the side and the mouse position is not yet adjusted correctly.

svn path=/trunk/KDE/kdebase/workspace/; revision=1118698
This commit is contained in:
Martin Gräßlin 2010-04-25 17:59:34 +00:00
parent 03f5e6f019
commit 87d51dff6b
8 changed files with 283 additions and 80 deletions

View file

@ -90,36 +90,42 @@ QSizeF AuroraeButton::sizeHint(Qt::SizeHint which, const QSizeF& constraint) con
Q_UNUSED(which)
Q_UNUSED(constraint)
const qreal factor = m_theme->buttonSizeFactor();
qreal width = m_theme->themeConfig().buttonWidth()*factor;
qreal height = m_theme->themeConfig().buttonHeight()*factor;
switch (m_type) {
case MinimizeButton:
return QSizeF(m_theme->themeConfig().buttonWidthMinimize()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthMinimize()*factor;
break;
case MaximizeButton:
case RestoreButton:
return QSizeF(m_theme->themeConfig().buttonWidthMaximizeRestore()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthMaximizeRestore()*factor;
break;
case CloseButton:
return QSizeF(m_theme->themeConfig().buttonWidthClose()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthClose()*factor;
break;
case AllDesktopsButton:
return QSizeF(m_theme->themeConfig().buttonWidthAllDesktops()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthAllDesktops()*factor;
break;
case KeepAboveButton:
return QSizeF(m_theme->themeConfig().buttonWidthKeepAbove()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthKeepAbove()*factor;
break;
case KeepBelowButton:
return QSizeF(m_theme->themeConfig().buttonWidthKeepBelow()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthKeepBelow()*factor;
break;
case ShadeButton:
return QSizeF(m_theme->themeConfig().buttonWidthShade()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthShade()*factor;
break;
case HelpButton:
return QSizeF(m_theme->themeConfig().buttonWidthHelp()*factor,
m_theme->themeConfig().buttonHeight()*factor);
width = m_theme->themeConfig().buttonWidthHelp()*factor;
break;
default:
return QSizeF(m_theme->themeConfig().buttonWidth()*factor,
m_theme->themeConfig().buttonHeight()*factor);
break; // nothing
}
if (m_theme->themeConfig().decorationPosition() == DecorationLeft ||
m_theme->themeConfig().decorationPosition() == DecorationRight) {
qSwap(width, height);
}
return QSizeF(width, height);
}
void AuroraeButton::mousePressEvent(QGraphicsSceneMouseEvent* event)
{

View file

@ -69,10 +69,23 @@ void AuroraeScene::init()
if (!m_theme->isValid()) {
return;
}
Qt::Orientation orientation = Qt::Horizontal;
switch ((DecorationPosition)m_theme->themeConfig().decorationPosition()) {
case DecorationLeft: // fall through
case DecorationRight:
orientation = Qt::Vertical;
break;
case DecorationTop: // fall through
case DecorationBottom: // fall through
default: // fall through
orientation = Qt::Horizontal;
break;
}
// left buttons
QGraphicsLinearLayout *leftButtonsLayout = new QGraphicsLinearLayout;
leftButtonsLayout->setSpacing(m_theme->themeConfig().buttonSpacing());
leftButtonsLayout->setContentsMargins(0, 0, 0, 0);
leftButtonsLayout->setOrientation(orientation);
initButtons(leftButtonsLayout, buttonsToDirection(m_leftButtonOrder));
m_leftButtons = new QGraphicsWidget;
@ -83,6 +96,7 @@ void AuroraeScene::init()
QGraphicsLinearLayout *rightButtonsLayout = new QGraphicsLinearLayout;
rightButtonsLayout->setSpacing(m_theme->themeConfig().buttonSpacing());
rightButtonsLayout->setContentsMargins(0, 0, 0, 0);
rightButtonsLayout->setOrientation(orientation);
initButtons(rightButtonsLayout, buttonsToDirection(m_rightButtonOrder));
m_rightButtons = new QGraphicsWidget;
@ -93,6 +107,7 @@ void AuroraeScene::init()
QGraphicsLinearLayout *titleLayout = new QGraphicsLinearLayout;
titleLayout->setSpacing(0);
titleLayout->setContentsMargins(0, 0, 0, 0);
titleLayout->setOrientation(orientation);
m_title = new QGraphicsWidget;
AuroraeTab *tab = new AuroraeTab(m_theme, m_caption);
connect(this, SIGNAL(activeChanged()), tab, SLOT(activeChanged()));
@ -190,9 +205,32 @@ void AuroraeScene::drawBackground(QPainter *painter, const QRectF &rect)
sceneRect().width() - conf.paddingRight() - conf.paddingLeft(),
sceneRect().height() - conf.paddingBottom() - conf.paddingTop());
if (true/*transparentRect().isNull()*/) {
r = QRectF(conf.paddingLeft(), conf.paddingTop(),
switch ((DecorationPosition)conf.decorationPosition()) {
case DecorationTop:
r = QRectF(conf.paddingLeft(), conf.paddingTop(),
sceneRect().width() - conf.paddingRight() - conf.paddingLeft(),
conf.titleEdgeTopMaximized() + titleHeight + conf.titleEdgeBottomMaximized());
break;
case DecorationBottom: {
const int h = conf.titleEdgeTopMaximized() + titleHeight + conf.titleEdgeBottomMaximized();
r = QRectF(conf.paddingLeft(),
height() - conf.paddingBottom() - h,
sceneRect().width() - conf.paddingRight() - conf.paddingLeft(),
h);
break;
}
case DecorationLeft:
r = QRectF(conf.paddingLeft(), conf.paddingTop(),
conf.titleEdgeLeftMaximized() + titleHeight + conf.titleEdgeRightMaximized(),
height() - conf.paddingBottom() - conf.paddingTop());
break;
case DecorationRight: {
const int w = conf.titleEdgeLeftMaximized() + titleHeight + conf.titleEdgeRightMaximized();
r = QRectF(width() - conf.paddingRight() - w, conf.paddingTop(),
w, height() - conf.paddingBottom() - conf.paddingTop());
break;
}
}
}
}
QRectF sourceRect = QRectF(QPointF(0, 0), r.size());
@ -262,26 +300,121 @@ void AuroraeScene::updateLayout()
const qreal titleHeight = qMax((qreal)config.titleHeight(),
config.buttonHeight()*m_theme->buttonSizeFactor() + config.buttonMarginTop());
if (m_maximizeMode == KDecorationDefines::MaximizeFull) { // TODO: check option
const int top = genericTop + config.titleEdgeTopMaximized();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeftMaximized(), top),
m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRightMaximized(), top),
m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle, config.paddingTop() + config.titleEdgeTopMaximized(),
titleWidth, titleHeight);
switch ((DecorationPosition)config.decorationPosition()) {
case DecorationTop: {
const int top = genericTop + config.titleEdgeTopMaximized();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeftMaximized(), top),
m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRightMaximized(), top),
m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle, config.paddingTop() + config.titleEdgeTopMaximized(),
titleWidth, titleHeight);
break;
}
case DecorationBottom: {
const int bottom = height() - config.paddingBottom() - marginTop - config.titleEdgeBottomMaximized();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeftMaximized(),
bottom - config.buttonHeight()),
m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRightMaximized(),
bottom - config.buttonHeight()),
m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle,
height() - config.paddingBottom() - config.titleEdgeBottomMaximized() - titleHeight,
titleWidth, titleHeight);
break;
}
case DecorationLeft: {
const int left = config.paddingLeft() + marginTop + config.titleEdgeLeftMaximized();
m_rightButtons->setGeometry(left,
height() - config.paddingBottom() - config.titleEdgeBottomMaximized() - m_rightButtons->preferredHeight(),
m_rightButtons->preferredWidth(), m_rightButtons->preferredHeight());
m_leftButtons->setGeometry(left, config.paddingTop() + config.titleEdgeTopMaximized(),
m_leftButtons->preferredWidth(), m_leftButtons->preferredHeight());
// title
const int topTitle = m_leftButtons->geometry().bottom() + config.titleBorderRight();
const int realTitleHeight = m_rightButtons->geometry().top() - config.titleBorderLeft() - topTitle;
m_title->setGeometry(left, topTitle, titleHeight, realTitleHeight);
break;
}
case DecorationRight: {
const int left = width() - config.paddingRight() - marginTop - config.titleEdgeRightMaximized() - titleHeight;
m_rightButtons->setGeometry(left,
height() - config.paddingBottom() - config.titleEdgeBottomMaximized() - m_rightButtons->preferredHeight(),
m_rightButtons->preferredWidth(), m_rightButtons->preferredHeight());
m_leftButtons->setGeometry(left, config.paddingTop() + config.titleEdgeTopMaximized(),
m_leftButtons->preferredWidth(), m_leftButtons->preferredHeight());
// title
const int topTitle = m_leftButtons->geometry().bottom() + config.titleBorderRight();
const int realTitleHeight = m_rightButtons->geometry().top() - config.titleBorderLeft() - topTitle;
m_title->setGeometry(left, topTitle, titleHeight, realTitleHeight);
break;
}
}
m_title->layout()->invalidate();
} else {
const int top = genericTop + config.titleEdgeTop();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeft(), top), m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRight(), top), m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle, config.paddingTop() + config.titleEdgeTop(),
titleWidth, titleHeight);
switch ((DecorationPosition)config.decorationPosition()) {
case DecorationTop: {
const int top = genericTop + config.titleEdgeTop();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeft(), top), m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRight(), top), m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle, config.paddingTop() + config.titleEdgeTop(),
titleWidth, titleHeight);
break;
}
case DecorationBottom: {
const int bottom = height() - config.paddingBottom() - marginTop - config.titleEdgeBottom();
m_leftButtons->setGeometry(QRectF(QPointF(left + config.titleEdgeLeft(),
bottom - config.buttonHeight()),
m_leftButtons->size()));
m_rightButtons->setGeometry(QRectF(QPointF(right - config.titleEdgeRight(),
bottom - config.buttonHeight()),
m_rightButtons->size()));
// title
const int leftTitle = m_leftButtons->geometry().right() + config.titleBorderLeft();
const int titleWidth = m_rightButtons->geometry().left() - config.titleBorderRight() - leftTitle;
m_title->setGeometry(leftTitle,
height() - config.paddingBottom() - config.titleEdgeBottom() - titleHeight,
titleWidth, titleHeight);
break;
}
case DecorationLeft: {
const int left = config.paddingLeft() + marginTop + config.titleEdgeLeft();
m_rightButtons->setGeometry(left,
height() - config.paddingBottom() - config.titleEdgeBottom() - m_rightButtons->preferredHeight(),
m_rightButtons->preferredWidth(), m_rightButtons->preferredHeight());
m_leftButtons->setGeometry(left, config.paddingTop() + config.titleEdgeTop(),
m_leftButtons->preferredWidth(), m_leftButtons->preferredHeight());
// title
const int topTitle = m_leftButtons->geometry().bottom() + config.titleBorderRight();
const int realTitleHeight = m_rightButtons->geometry().top() - config.titleBorderLeft() - topTitle;
m_title->setGeometry(left, topTitle, titleHeight, realTitleHeight);
break;
}
case DecorationRight: {
const int left = width() - config.paddingRight() - marginTop - config.titleEdgeRight() - titleHeight;
m_rightButtons->setGeometry(left,
height() - config.paddingBottom() - config.titleEdgeBottom() - m_rightButtons->preferredHeight(),
m_rightButtons->preferredWidth(), m_rightButtons->preferredHeight());
m_leftButtons->setGeometry(left, config.paddingTop() + config.titleEdgeTop(),
m_leftButtons->preferredWidth(), m_leftButtons->preferredHeight());
// title
const int topTitle = m_leftButtons->geometry().bottom() + config.titleBorderRight();
const int realTitleHeight = m_rightButtons->geometry().top() - config.titleBorderLeft() - topTitle;
m_title->setGeometry(left, topTitle, titleHeight, realTitleHeight);
break;
}
}
m_title->layout()->invalidate();
}
}

View file

@ -92,18 +92,34 @@ void AuroraeTab::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
align = Qt::AlignLeft;
}
}
const QRect textRect = painter->fontMetrics().boundingRect(rect().toRect(),
qreal w = rect().width();
qreal h = rect().height();
if (m_theme->themeConfig().decorationPosition() == DecorationLeft ||
m_theme->themeConfig().decorationPosition() == DecorationRight) {
h = rect().width();
w = rect().height();
}
const QRect textRect = painter->fontMetrics().boundingRect(QRect(rect().x(), rect().y(), w, h),
align | conf.verticalAlignment() | Qt::TextSingleLine,
m_caption);
if ((active && conf.haloActive()) ||
(!active && conf.haloInactive())) {
QRect haloRect = textRect;
if (haloRect.width() > rect().width()) {
haloRect.setWidth(rect().width());
if (haloRect.width() > w) {
haloRect.setWidth(w);
}
painter->save();
if (m_theme->themeConfig().decorationPosition() == DecorationLeft) {
painter->translate(rect().bottomLeft());
painter->rotate(270);
} else if (m_theme->themeConfig().decorationPosition() == DecorationRight) {
painter->translate(rect().topRight());
painter->rotate(90);
}
Plasma::PaintUtils::drawHalo(painter, haloRect);
painter->restore();
}
QPixmap pix(rect().size().toSize());
QPixmap pix(w, h);
pix.fill(Qt::transparent);
QPainter p(&pix);
QColor color;
@ -120,7 +136,7 @@ void AuroraeTab::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
}
p.setPen(color);
p.drawText(pix.rect(), align | conf.verticalAlignment() | Qt::TextSingleLine, m_caption);
if (textRect.width() > rect().width()) {
if (textRect.width() > w) {
// Fade out effect
// based on fadeout of tasks applet in Plasma/desktop/applets/tasks/abstracttaskitem.cpp by
// Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
@ -143,28 +159,15 @@ void AuroraeTab::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
p.fillRect(r, alphaGradient);
}
p.end();
painter->drawPixmap(rect().toRect(), pix);
painter->restore();
}
QSizeF AuroraeTab::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
{
QFont titleFont = KGlobalSettings::windowTitleFont();
QFontMetricsF fm(titleFont);
const qreal titleHeight = qMax((qreal)m_theme->themeConfig().titleHeight(),
m_theme->themeConfig().buttonHeight()*m_theme->buttonSizeFactor() +
m_theme->themeConfig().buttonMarginTop());
switch (which) {
case Qt::MinimumSize:
return QSizeF(fm.boundingRect(m_caption.left(3)).width(), titleHeight);
case Qt::PreferredSize:
return QSizeF(fm.boundingRect(m_caption).width(), titleHeight);
case Qt::MaximumSize:
return QSizeF(scene()->sceneRect().width(), titleHeight);
default:
return QGraphicsWidget::sizeHint(which, constraint);
if (m_theme->themeConfig().decorationPosition() == DecorationLeft) {
painter->translate(rect().bottomLeft());
painter->rotate(270);
} else if (m_theme->themeConfig().decorationPosition() == DecorationRight) {
painter->translate(rect().topRight());
painter->rotate(90);
}
return QGraphicsWidget::sizeHint(which, constraint);
painter->drawPixmap(pix.rect(), pix);
painter->restore();
}
void AuroraeTab::buttonSizesChanged()

View file

@ -42,9 +42,6 @@ public Q_SLOTS:
private Q_SLOTS:
void buttonSizesChanged();
protected:
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const;
private:
AuroraeTheme *m_theme;
QString m_caption;

View file

@ -269,13 +269,32 @@ void AuroraeTheme::borders(int& left, int& top, int& right, int& bottom, bool ma
d->themeConfig.buttonHeight()*buttonSizeFactor() +
d->themeConfig.buttonMarginTop());
if (maximized) {
left = 0;
right = 0;
bottom = 0;
top = titleHeight + d->themeConfig.titleEdgeTopMaximized() + d->themeConfig.titleEdgeBottomMaximized();
const qreal title = titleHeight + d->themeConfig.titleEdgeTopMaximized() + d->themeConfig.titleEdgeBottomMaximized();
switch ((DecorationPosition)d->themeConfig.decorationPosition()) {
case DecorationTop:
left = right = bottom = 0;
top = title;
break;
case DecorationBottom:
left = right = top = 0;
bottom = title;
break;
case DecorationLeft:
top = right = bottom = 0;
left = title;
break;
case DecorationRight:
left = top = bottom = 0;
right = title;
break;
default:
left = right = bottom = top = 0;
break;
}
} else {
switch (d->borderSize) {
case KDecoration::BorderTiny:
// TODO: this looks wrong
if (isCompositingActive()) {
left = qMin(0, (int)left - d->themeConfig.borderLeft() - d->themeConfig.paddingLeft());
right = qMin(0, (int)right - d->themeConfig.borderRight() - d->themeConfig.paddingRight());
@ -287,28 +306,54 @@ void AuroraeTheme::borders(int& left, int& top, int& right, int& bottom, bool ma
}
break;
case KDecoration::BorderLarge:
left = right = bottom = 4;
left = right = bottom = top = 4;
break;
case KDecoration::BorderVeryLarge:
left = right = bottom = 8;
left = right = bottom = top = 8;
break;
case KDecoration::BorderHuge:
left = right = bottom = 12;
left = right = bottom = top = 12;
break;
case KDecoration::BorderVeryHuge:
left = right = bottom = 23;
left = right = bottom = top = 23;
break;
case KDecoration::BorderOversized:
left = right = bottom = 36;
left = right = bottom = top = 36;
break;
case KDecoration::BorderNormal:
default:
left = right = bottom = 0;
left = right = bottom = top = 0;
}
const qreal title = titleHeight + d->themeConfig.titleEdgeTop() + d->themeConfig.titleEdgeBottom();
switch ((DecorationPosition)d->themeConfig.decorationPosition()) {
case DecorationTop:
left += d->themeConfig.borderLeft();
right += d->themeConfig.borderRight();
bottom += d->themeConfig.borderBottom();
top = title;
break;
case DecorationBottom:
left += d->themeConfig.borderLeft();
right += d->themeConfig.borderRight();
bottom = title;
top += d->themeConfig.borderTop();
break;
case DecorationLeft:
left = title;
right += d->themeConfig.borderRight();
bottom += d->themeConfig.borderBottom();
top += d->themeConfig.borderTop();
break;
case DecorationRight:
left += d->themeConfig.borderLeft();
right = title;
bottom += d->themeConfig.borderBottom();
top += d->themeConfig.borderTop();
break;
default:
left = right = bottom = top = 0;
break;
}
left += d->themeConfig.borderLeft();
right += d->themeConfig.borderRight();
bottom += d->themeConfig.borderBottom();
top = titleHeight + d->themeConfig.titleEdgeTop() + d->themeConfig.titleEdgeBottom();
}
}

View file

@ -54,6 +54,13 @@ enum AuroraeButtonType {
MenuButton
};
enum DecorationPosition {
DecorationTop = 0,
DecorationLeft,
DecorationRight,
DecorationBottom
};
class /*LIBAURORAE_EXPORT*/ AuroraeTheme : public QObject
{
Q_OBJECT

View file

@ -63,12 +63,14 @@ void ThemeConfig::load(const KConfig &conf)
m_defaultButtonsLeft = general.readEntry("LeftButtons", KDecorationOptions::defaultTitleButtonsLeft());
m_defaultButtonsRight = general.readEntry("RightButtons", KDecorationOptions::defaultTitleButtonsRight());
m_shadow = general.readEntry("Shadow", true);
m_decorationPosition = general.readEntry("DecorationPosition", 0);
KConfigGroup border(&conf, "Layout");
// default values taken from KCommonDecoration::layoutMetric() in kcommondecoration.cpp
m_borderLeft = border.readEntry("BorderLeft", 5);
m_borderRight = border.readEntry("BorderRight", 5);
m_borderBottom = border.readEntry("BorderBottom", 5);
m_borderTop = border.readEntry("BorderTop", 0);
m_titleEdgeTop = border.readEntry("TitleEdgeTop", 5);
m_titleEdgeBottom = border.readEntry("TitleEdgeBottom", 5);

View file

@ -81,6 +81,9 @@ public:
int borderBottom() const {
return m_borderBottom;
}
int borderTop() const {
return m_borderTop;
}
int titleEdgeTop() const {
return m_titleEdgeTop;
@ -182,6 +185,10 @@ public:
return m_shadow;
}
int decorationPosition() const {
return m_decorationPosition;
}
private:
QColor m_activeTextColor;
QColor m_inactiveTextColor;
@ -198,6 +205,7 @@ private:
int m_borderLeft;
int m_borderRight;
int m_borderBottom;
int m_borderTop;
// title
int m_titleEdgeTop;
@ -239,6 +247,8 @@ private:
QString m_defaultButtonsLeft;
QString m_defaultButtonsRight;
bool m_shadow;
int m_decorationPosition;
};
}