diff -r 000000000000 -r 16d8024aca5e src/hbcore/gui/hbtoolbutton.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbcore/gui/hbtoolbutton.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,573 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (developer.feedback@nokia.com) +** +** This file is part of the HbCore module of the UI Extensions for Mobile. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at developer.feedback@nokia.com. +** +****************************************************************************/ + +#include "hbtoolbutton.h" +#include "hbtoolbutton_p.h" +#include "hbtooltip.h" +#include "hbstyleoptiontoolbutton.h" +#include "hbtoolbarextension.h" +#include "hbtoolbarextension_p.h" +#include "hbaction.h" +#include "hbaction_p.h" +#include +#include "hbcolorscheme.h" +#include "hbtextitem.h" +#include "hbiconitem.h" + +#include +#include + +/*! + @stable + @hbcore + \class HbToolButton + \brief The HbToolButton class provides a quick-access button for actions. + + A tool button is a special button that provides quick-access to + a specific action. Unlike a normal push button HbPushButton, a tool + button represents an action. In other words, HbToolButton is + synchronized with an instance of HbAction. + + The action may also be associated with other parts of the user interface, + as menu items and keyboard shortcuts. Sharing actions in this way helps + make the user interface more consistent and is often less work to implement. + + Tool buttons are normally created indirectly when actions are added to a + toolbar with HbToolBar::addAction(). It is also possible to + construct tool buttons directly in the same way as any other widget, and + arrange them alongside other widgets in layouts. + + The style of a tool button is adjustable with setToolButtonStyle(). + By default a tool button shows only an icon. + + A tool button's background is set as HbIcon. This makes it possible to + specify different images for the normal and pressed states. + + Example usage: + \code + HbAction *action = new HbAction(icon, name, this); + HbToolButton *toolButton = new HbToolButton(action, this); + layout->addItem(toolButton); + \endcode + + \sa HbAction, HbPushButton +*/ + +/*! + \enum HbToolButton::ToolButtonStyle + + This enum defines available tool button styles. + + The tool button style describes how the button's text and icon should be displayed. + */ + +/*! + \var HbToolButton::ToolButtonIcon + + Only display the icon. + */ + +/*! + \var HbToolButton::ToolButtonText + + Only display the text. + */ + +/*! + \var HbToolButton::ToolButtonTextAndIcon + + Display both text and icon. + */ + +/*! + \fn void HbToolButton::triggered(HbAction *action) + + This signal is emitted when the \a action is triggered. + */ + +/*! + \reimp + \fn int HbToolButton::type() const + */ + +HbToolButtonPrivate::HbToolButtonPrivate() : + action(0), + textItem(0), + iconItem(0), + frameItem(0), + customBackground(), + backgroundVisible(true), + buttonStyle(HbToolButton::ToolButtonIcon), + toolBarPosition(HbStyleOptionToolButton::TB_None), + orientation(Qt::Vertical), + mDialogToolBar(false), + mButtonSize(QSizeF()) +{ +} + +HbToolButtonPrivate::~HbToolButtonPrivate() +{ +} + +void HbToolButtonPrivate::createPrimitives() +{ + Q_Q(HbToolButton); + + if (backgroundVisible) { + if (!frameItem) { + frameItem = q->style()->createPrimitive(HbStyle::P_ToolButton_frame, q); + } + } else if (frameItem) { + delete frameItem; + frameItem = 0; + } + + if (action && !action->text().isEmpty()) { + if (!textItem) { + textItem = static_cast(q->style()->createPrimitive(HbStyle::P_ToolButton_text, q)); + textItem->setTextWrapping(Hb::TextWordWrap); + } + textItem->setVisible(buttonStyle & HbToolButton::ToolButtonText); + } else if (textItem) { + delete textItem; + textItem = 0; + } + + if (action && (buttonStyle & HbToolButton::ToolButtonIcon)) { + if (!iconItem) { + iconItem = q->style()->createPrimitive(HbStyle::P_ToolButton_icon, q); + } + } else if (iconItem){ + delete iconItem; + iconItem = 0; + } +} + +void HbToolButtonPrivate::setOrientation(Qt::Orientation orientation) +{ + if (this->orientation != orientation) { + this->orientation = orientation; + Q_Q(HbToolButton); + if (q->isVisible() && polished) { + q->repolish(); + } + } +} + +void HbToolButtonPrivate::setToolBarPosition(HbStyleOptionToolButton::ToolBarPosition position) +{ + Q_Q(HbToolButton); + if (toolBarPosition != position) { + toolBarPosition = position; + // required for toolbar()->action()[i]->setVisible(visible) + // to work for all cases + if (q->isVisible() && polished) { + q->updatePrimitives(); + } + } +} + +void HbToolButtonPrivate::setBackgroundVisible(bool visible) +{ + Q_Q(HbToolButton); + if (backgroundVisible != visible) { + backgroundVisible = visible; + // required to make extension orientation switch from + // landscape to portrait work correctly with automatic more + // extension. + q->repolish(); + } +} + +void HbToolButtonPrivate::setLayoutProperty(const char *name, bool value) +{ + Q_Q(HbToolButton); + q->setProperty(name, value); + if (q->isVisible() && polished) { + q->repolish(); + } +} + +QSizeF HbToolButtonPrivate::getMinimumSize() +{ + Q_Q(HbToolButton); + mRepolishRequested = true; + polishPending = false; + q->updateGeometry(); + QSizeF size = q->minimumSize(); + //Workaround (causing extra polish) + mSizeHintPolish = false; + //workaround ends + return size; +} + +void HbToolButtonPrivate::_q_actionTriggered() +{ + Q_Q(HbToolButton); + emit q->triggered(action); +} + +void HbToolButtonPrivate::_q_actionChanged() +{ + Q_Q(HbToolButton); + if (!action->icon().isNull()) { + if (orientation == Qt::Horizontal) { + buttonStyle = HbToolButton::ToolButtonIcon; + } else if (!action->text().isEmpty()) { + buttonStyle = HbToolButton::ToolButtonTextAndIcon; + } else { + buttonStyle = HbToolButton::ToolButtonIcon; + } + } else { + buttonStyle = HbToolButton::ToolButtonText; + } + // action text/icon may have changed, + if (q->isVisible() && polished) { + q->repolish(); + } +} + +void HbToolButtonPrivate::showToolTip() +{ + Q_Q(HbToolButton); + HbToolTip::showText(q->toolTip(), q, orientation == Qt::Vertical ? Qt::AlignTop : Qt::AlignLeft); +} + +/*! + Constructs a new HbToolButton with \a parent. +*/ +HbToolButton::HbToolButton(QGraphicsItem *parent) : + HbAbstractButton(*new HbToolButtonPrivate, parent) +{ + Q_D(HbToolButton); + d->q_ptr = this; +} + +/*! + Constructs a new HbToolButton with \a action and \a parent. + + Ownership of the \a action is not transferred to the tool button. + */ +HbToolButton::HbToolButton(HbAction *action, QGraphicsItem *parent) : + HbAbstractButton(*new HbToolButtonPrivate, parent) +{ + Q_D(HbToolButton); + d->q_ptr = this; + setAction(action); + setProperty("state", "normal"); +} + +/*! + Destructs the tool button. + */ +HbToolButton::~HbToolButton() +{ +} + +/*! + Returns the action of the button. + + \sa setAction() + */ +HbAction *HbToolButton::action() const +{ + Q_D(const HbToolButton); + return d->action; +} + +/*! + Sets the \a action of the button. + + Ownership of the \a action is not transferred to the tool button. + + \sa action() + */ +void HbToolButton::setAction(HbAction *action) +{ + Q_D(HbToolButton); + if (d->action == action) { + return; + } + + if (d->action) { + disconnect(d->action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); + disconnect(d->action, SIGNAL(changed()), this, SLOT(_q_actionChanged())); + } + + HbAction *oldAction = d->action; + d->action = action; + if (d->action) { + connect(action, SIGNAL(triggered()), this, SLOT(_q_actionTriggered())); + connect(action, SIGNAL(changed()), this, SLOT(_q_actionChanged())); + } + + if (isVisible() && d->polished) { + // If action was null then there is a chance that the iconitem is not yet created. + // If the new action is null then we may need to get rid of the icon completely. + if ((!oldAction && action) || (oldAction && !action)) { + repolish(); // will call createPrimitives() + } + updatePrimitives(); + } +} + +/*! + Returns the background image of the button. + */ +HbIcon HbToolButton::background() const +{ + Q_D(const HbToolButton); + return d->customBackground; +} + +/*! + Sets the \a background image of the button. + */ +void HbToolButton::setBackground(const HbIcon &background) +{ + Q_D(HbToolButton); + if (d->customBackground != background) { + d->customBackground = background; + if (isVisible() || d->polished) + updatePrimitives(); + } +} + +/*! + @beta + Returns the tool button style. + + The default value is \b HbToolButton::ToolButtonIcon. + + \sa setToolButtonStyle() + */ +HbToolButton::ToolButtonStyle HbToolButton::toolButtonStyle() const +{ + Q_D(const HbToolButton); + return d->buttonStyle; +} + +/*! + @beta + Sets the tool button style. + + \sa toolButtonStyle() + */ +void HbToolButton::setToolButtonStyle(HbToolButton::ToolButtonStyle style) +{ + Q_D(HbToolButton); + if (d->buttonStyle != style) { + d->buttonStyle = style; + + // action text/icon may have changed, + // primitives might need to be created/cleaned up + if (size() != QSize(0, 0)) { + repolish(); + } + } +} + +/*! + \reimp + */ +QGraphicsItem *HbToolButton::primitive(HbStyle::Primitive primitive) const +{ + Q_D(const HbToolButton); + switch (primitive) { + case HbStyle::P_ToolButton_frame: + return d->frameItem; + case HbStyle::P_ToolButton_icon: + return d->iconItem; + case HbStyle::P_ToolButton_text: + return d->textItem; + default: + return 0; + } +} + +/*! + \reimp + */ +void HbToolButton::updatePrimitives() +{ + Q_D(HbToolButton); + + HbStyleOptionToolButton option; + if (d->action) { + setCheckable(d->action->isCheckable()); + setChecked(d->action->isChecked()); + setEnabled(d->action->isEnabled()); + HbAction *hbAction = qobject_cast(d->action); + if (hbAction && (!hbAction->toolTip().isEmpty()) && (hbAction->toolTip() != toolTip())) { + setToolTip(hbAction->toolTip()); + } else if(!hbAction && d->action->toolTip() != toolTip()) { + setToolTip(d->action->toolTip()); + } + setVisible(d->action->isVisible()); + } + + initStyleOption(&option); + setProperty("dialogtoolbar", d->mDialogToolBar); + if (d->frameItem) { + style()->updatePrimitive(d->frameItem, HbStyle::P_ToolButton_frame, &option); + } + if (d->textItem) { + style()->updatePrimitive(d->textItem, HbStyle::P_ToolButton_text, &option); + } + if (d->iconItem) { + style()->updatePrimitive(d->iconItem, HbStyle::P_ToolButton_icon, &option); + if (d->action && d->action->icon().flags() & HbIcon::Colorized) { + static_cast(d->iconItem)->setFlags(HbIcon::Colorized); + } + } +} + +/*! + Initializes \a option with the values from this HbToolButton. This method is useful for + subclasses when they need a HbStyleOptionToolButton, but don't want to fill in all the + information themselves. + */ +void HbToolButton::initStyleOption(HbStyleOptionToolButton *option) const +{ + Q_D(const HbToolButton); + HbAbstractButton::initStyleOption(option); + + Q_ASSERT(option); + option->customBackground = d->customBackground; + option->backgroundVisible = d->backgroundVisible; + option->toolBarPosition = d->toolBarPosition; + option->orientation = d->orientation; + option->isCheckable = d->checkable; + option->useSecondaryGraphics = d->mDialogToolBar; + + if (d->action) { + option->text = d->action->text(); + option->icon = d->action->icon(); + } +} + +/*! + \internal + */ +HbToolButton::HbToolButton(HbToolButtonPrivate &dd, QGraphicsItem *parent) : + HbAbstractButton(dd, parent) +{ +} + +/*! + \reimp + */ +void HbToolButton::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + Q_D(HbToolButton); + QGraphicsWidget::resizeEvent(event); + if (event->newSize() != event->oldSize() && d->polished && isVisible()) { + updatePrimitives(); + } + if (action() && action()->toolBarExtension()) { + HbToolBarExtensionPrivate::d_ptr(action()->toolBarExtension())->placeToolBarExtension(); + } +} + +/*! + \reimp + */ +void HbToolButton::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + HbAbstractButton::mousePressEvent(event); + setProperty("state", "pressed"); + updatePrimitives(); +} + +/*! + \reimp + */ +void HbToolButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + HbAbstractButton::mouseReleaseEvent(event); + setProperty("state", "normal"); + updatePrimitives(); +} + +/*! + \reimp + */ +void HbToolButton::nextCheckState() +{ + Q_D(HbToolButton); + HbAbstractButton::nextCheckState(); + if (!d->action) { + return; + } + if ( d->action->toolBarExtension() ) { + HbToolBarExtensionPrivate::d_ptr(d->action->toolBarExtension())->mExtendedButton = this; + d->action->toolBarExtension()->show(); + } + + d->action->trigger(); +} + +/*! + \reimp + */ +bool HbToolButton::event(QEvent *event) +{ + if (event) { + switch (event->type()) { + case QEvent::GraphicsSceneMouseRelease: { + mouseReleaseEvent(static_cast(event)); + return true; + } + case QEvent::GraphicsSceneHelp: { + Q_D(HbToolButton); + // Check whether toolbutton is inside a toolbar. + if (d->toolBarPosition != HbStyleOptionToolButton::TB_None) { + d->showToolTip(); + event->accept(); + return true; + } + } + break; + + default: break; + } + } + + return HbAbstractButton::event(event); +} + +void HbToolButton::polish(HbStyleParameters ¶ms) +{ + Q_D(HbToolButton); + setProperty("orientation", d->orientation); + d->createPrimitives(); + updatePrimitives(); + HbAbstractButton::polish(params); + // workaround for caching problem + setMinimumSize(minimumSize()); + // workaround ends +} + +#include "moc_hbtoolbutton.cpp"