src/hbinput/inputwidgets/hbinputcharpreviewpane.cpp
changeset 2 06ff229162e9
parent 1 f7ac710697a9
child 3 11d3954df52a
child 4 ae1717029441
equal deleted inserted replaced
1:f7ac710697a9 2:06ff229162e9
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbInput module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 // Qt includes
       
    26 #include <QGraphicsLinearLayout>
       
    27 #include <QSignalMapper>
       
    28 #include <QPainter>
       
    29 #include <QSizePolicy>
       
    30 #include <QGraphicsDropShadowEffect>
       
    31 
       
    32 #include <hbeffect.h>
       
    33 #include <hbinputsettingproxy.h>
       
    34 #include <hbmainwindow.h>
       
    35 #include <hbcolorscheme.h>
       
    36 #include <hbframedrawer.h>
       
    37 #include <hbframeitem.h>
       
    38 #include <hbdeviceprofile.h>
       
    39 #include <private/hbdialog_p.h>
       
    40 #include <hbtextitem.h>
       
    41 #include <hbmainwindow.h>
       
    42 #include <hbinstance.h>
       
    43 
       
    44 #include "hbinputpreviewlabel.h"
       
    45 #include "hbinputcharpreviewpane.h"
       
    46 
       
    47 const int HbPreviewZoomDelta = 7;
       
    48 const qreal HbPreviewBoundaryDelta = 1.5;
       
    49 const qreal HbBoundaryLabelWidthFactor = 0.75;
       
    50 const qreal HbLabelwidthFactor = 0.50;
       
    51 
       
    52 /// @cond
       
    53 
       
    54 /*
       
    55 Character preview widget for Accented characters.
       
    56 Implements character preview for characters mapped in the preview Pane.
       
    57 */
       
    58 class HbAccentedCharPreviewPane: public HbWidget
       
    59 {
       
    60 public:
       
    61     /*!
       
    62     Constructor.
       
    63     @param parent of the widget.
       
    64     */
       
    65     HbAccentedCharPreviewPane(QGraphicsItem *parent = 0)
       
    66         :HbWidget(parent),
       
    67         mTextItem(0)
       
    68     {
       
    69         HbFrameItem *n = new HbFrameItem(parent);
       
    70         n->frameDrawer().setFrameType(HbFrameDrawer::ThreePiecesHorizontal);
       
    71         n->frameDrawer().setFrameGraphicsName("qtg_fr_character_preview");
       
    72 
       
    73 
       
    74         setBackgroundItem( n );
       
    75         mTextItem = static_cast<HbTextItem*>(style()->createPrimitive(HbStyle::P_Label_text, this));
       
    76     }
       
    77     /*!
       
    78     update the text and frame primitives
       
    79     */
       
    80     void updatePrimitives()
       
    81     {
       
    82         HbWidget::updatePrimitives();
       
    83         if (mTextItem) {
       
    84             mTextItem->setFontSpec(HbFontSpec(HbFontSpec::Primary));
       
    85             mTextItem->setAlignment(Qt::AlignCenter);
       
    86         }
       
    87     }
       
    88     /*!
       
    89     Destroys the object.
       
    90     */
       
    91     ~HbAccentedCharPreviewPane() {
       
    92     }
       
    93 
       
    94 public:
       
    95     HbTextItem* mTextItem;
       
    96 };
       
    97 
       
    98 class HbCharPreviewPanePrivate: public HbDialogPrivate
       
    99 {
       
   100     Q_DECLARE_PUBLIC(HbCharPreviewPane)
       
   101 
       
   102 public:
       
   103     HbCharPreviewPanePrivate();
       
   104     ~HbCharPreviewPanePrivate();
       
   105     void clearCharacters();
       
   106     void updateCharacters();
       
   107     void init();
       
   108 
       
   109 // private slots
       
   110     void _q_showAccentedPreviewPane(QString character, QRectF sceneBoundingRect);
       
   111     void _q_hideAccentedPreviewPane();
       
   112     void _q_hidePreviewPanePopup();
       
   113 public:
       
   114     QStringList mCharacterList;
       
   115     QSignalMapper *mReleaseMapper;
       
   116     QGraphicsLinearLayout* mCandLayout;
       
   117     QSizeF mItemSize;
       
   118     HbAccentedCharPreviewPane* mAccentedPreviewPane;
       
   119 };
       
   120 
       
   121 void HbCharPreviewPanePrivate::init()
       
   122 {
       
   123     Q_Q(HbCharPreviewPane);
       
   124 
       
   125     HbFrameItem *n = new HbFrameItem( q );
       
   126     n->frameDrawer().setFrameType(HbFrameDrawer::ThreePiecesHorizontal);
       
   127     n->frameDrawer().setFrameGraphicsName("qtg_fr_character_preview");
       
   128 
       
   129     q->setBackgroundItem( n );
       
   130 }
       
   131 
       
   132 HbCharPreviewPanePrivate::HbCharPreviewPanePrivate()
       
   133     : mReleaseMapper(0),
       
   134     mCandLayout(0)
       
   135 {
       
   136     mAccentedPreviewPane = new HbAccentedCharPreviewPane();
       
   137 }
       
   138 
       
   139 HbCharPreviewPanePrivate::~HbCharPreviewPanePrivate()
       
   140 {
       
   141     if(mAccentedPreviewPane) {
       
   142         delete mAccentedPreviewPane;
       
   143     }
       
   144     if(mReleaseMapper) {
       
   145         delete mReleaseMapper;
       
   146     }
       
   147 }
       
   148 
       
   149 void HbCharPreviewPanePrivate::clearCharacters()
       
   150 {
       
   151     Q_Q(HbCharPreviewPane);
       
   152     for (int i = mCandLayout->count() - 1; i >= 0; i--) {
       
   153         QGraphicsLayoutItem* layoutitem = mCandLayout->itemAt(i);
       
   154         mCandLayout->removeAt(i);
       
   155         delete layoutitem;
       
   156     }
       
   157     mCandLayout->updateGeometry();
       
   158     q->adjustSize();
       
   159 }
       
   160 
       
   161 void HbCharPreviewPanePrivate::updateCharacters()
       
   162 {
       
   163     Q_Q(HbCharPreviewPane);
       
   164 	// need to set the minimum size to an invalid value here in order to make sure that the size does not become 0
       
   165 	mCandLayout->setMinimumSize(-1,-1);
       
   166     for (int i = 0; i < mCharacterList.count(); i++) {
       
   167         HbPreviewLabel* label = new HbPreviewLabel(mCharacterList[i]);
       
   168         label->setPreferredHeight(mItemSize.height() + HbPreviewZoomDelta);
       
   169         if (mCharacterList.count() > 1 && i != mCharacterList.count()-1) {
       
   170             label->setPreferredWidth(HbBoundaryLabelWidthFactor * mItemSize.width());
       
   171             label->setTextGeometry(mItemSize.width(), mItemSize.height());
       
   172         } else {
       
   173             label->setPreferredWidth(HbLabelwidthFactor * mItemSize.width());
       
   174             label->setTextGeometry(mItemSize.width(), mItemSize.height());
       
   175         }
       
   176 
       
   177         QObject::connect(label, SIGNAL(showAccentedPreview(QString,QRectF)), q, SLOT(_q_showAccentedPreviewPane(QString,QRectF)));
       
   178         QObject::connect(label, SIGNAL(selected()), mReleaseMapper, SLOT(map()));
       
   179         QObject::connect(label, SIGNAL(hideAccentedPreview()), q, SLOT(_q_hideAccentedPreviewPane()));
       
   180         QObject::connect(label, SIGNAL(hidePreview()), q, SLOT(_q_hidePreviewPanePopup()));
       
   181         mReleaseMapper->setMapping(label, mCharacterList[i]);
       
   182         mCandLayout->addItem(label);
       
   183         mCandLayout->setItemSpacing(i, 0.0);
       
   184     }
       
   185 
       
   186     mCandLayout->setContentsMargins(mItemSize.width() / 4, 0, mItemSize.width() / 4, 0);
       
   187     mCandLayout->updateGeometry();
       
   188     q->adjustSize();
       
   189 }
       
   190 
       
   191 /*!
       
   192 Sets the character for preview and shows in it's Pane.
       
   193 @param character The character for preview.
       
   194 @param itemSceneBoundingRect of the QGraphicsItem.
       
   195 */
       
   196 void HbCharPreviewPanePrivate::_q_showAccentedPreviewPane(QString character, QRectF itemSceneBoundingRect)
       
   197 {
       
   198     Q_Q(HbCharPreviewPane);
       
   199     mAccentedPreviewPane->setZValue(q->zValue()+1);
       
   200     q->scene()->addItem(mAccentedPreviewPane);
       
   201     // let's validate.
       
   202     if (!itemSceneBoundingRect.isValid()) {
       
   203         return;
       
   204     }
       
   205 	QColor color = HbColorScheme::color("qtc_editor_normal");
       
   206     // we need to show the accented char preview preview just above the
       
   207     // passed QRectF of the item which is passed.
       
   208     QPointF pos = itemSceneBoundingRect.topLeft();
       
   209     pos.setY(pos.y() - mItemSize.height() +  HbPreviewZoomDelta + HbPreviewBoundaryDelta);
       
   210 
       
   211     // let's adjust x position of the character preview pane so that it
       
   212     // is aligned at the center of the items for which we want to show
       
   213     // the preview.
       
   214     pos.setX(itemSceneBoundingRect.x() - itemSceneBoundingRect.width()/4);
       
   215 
       
   216     // set final position for the character preview pane
       
   217     mAccentedPreviewPane->setPos(pos);
       
   218     mAccentedPreviewPane->mTextItem->setText(character);
       
   219     if (color.isValid()) {
       
   220         mAccentedPreviewPane->mTextItem->setTextColor(color);
       
   221     }
       
   222     mAccentedPreviewPane->updatePrimitives();
       
   223     QSizeF paneSize = itemSceneBoundingRect.size();
       
   224     QRectF rect;
       
   225     rect.setWidth(HbBoundaryLabelWidthFactor * mItemSize.width());
       
   226     rect.setHeight(mItemSize.height());
       
   227     rect.setY(paneSize.height()/2 - mItemSize.height()/2 - HbPreviewZoomDelta - HbPreviewBoundaryDelta);
       
   228     mAccentedPreviewPane->mTextItem->setGeometry(rect);
       
   229 
       
   230     // show it!
       
   231     mAccentedPreviewPane->show();
       
   232 }
       
   233 /*
       
   234 hides the accented single character preview pane whenever user tries to hover on it
       
   235 as the the character is inputed in the editor only when mouse is released from preview pane
       
   236 */
       
   237 void HbCharPreviewPanePrivate::_q_hideAccentedPreviewPane()
       
   238 {
       
   239     mAccentedPreviewPane->hide();
       
   240 }
       
   241 
       
   242 /*
       
   243 hides the accented single character preview pane as well as charcters Preview Pane
       
   244 */
       
   245 void HbCharPreviewPanePrivate::_q_hidePreviewPanePopup()
       
   246 {
       
   247     Q_Q(HbCharPreviewPane);
       
   248     mAccentedPreviewPane->hide();
       
   249     if (q->isVisible()) {
       
   250         q->hide();
       
   251     }
       
   252 }
       
   253 
       
   254 /// @endcond
       
   255 
       
   256 /*!
       
   257 @proto
       
   258 @hbinput
       
   259 \class HbCharPreviewPane
       
   260 \deprecated class HbCharPreviewPane
       
   261 \brief Character preview widget for virtual keyboards.
       
   262 
       
   263 
       
   264 Implements character preview for virtual keyboards. Shows a list of clickable
       
   265 characters and maps the clicks to owning keyboard's charFromPreviewSelected slot.
       
   266 For first level of preview popup we have a linear layout, we create a HbPreviewLabel
       
   267 and add the labels to this layout. For second level of preview popup as user clicks
       
   268 on the lebel of preview pane we display preview of the accented character on the preview pane.
       
   269 
       
   270 \sa HbInputVkbWidget
       
   271 \sa HbPreviewLabel
       
   272 */
       
   273 
       
   274 /*!
       
   275 \deprecated HbCharPreviewPane::HbCharPreviewPane(QGraphicsItem*)
       
   276     is deprecated.
       
   277 */
       
   278 HbCharPreviewPane::HbCharPreviewPane(QGraphicsItem* parent)
       
   279     : HbDialog(*new HbCharPreviewPanePrivate, parent)
       
   280 {
       
   281     Q_D(HbCharPreviewPane);
       
   282 
       
   283     d->q_ptr = this;
       
   284 
       
   285     d->mCandLayout = new QGraphicsLinearLayout(Qt::Horizontal);
       
   286     setLayout(d->mCandLayout);
       
   287 
       
   288     d->setPriority(HbPopupPrivate::VirtualKeyboard + 1);  // Should be visible on top of VKB
       
   289 
       
   290     // set some properties
       
   291     setFocusPolicy(Qt::ClickFocus);
       
   292     setModal(false);
       
   293     setDismissPolicy(HbPopup::TapAnywhere);
       
   294     setBackgroundFaded(false);
       
   295 
       
   296 #if QT_VERSION >= 0x040600
       
   297     // Make sure the preview pane never steals focus.
       
   298     setFlag(QGraphicsItem::ItemIsPanel, true);
       
   299     setActive(false);
       
   300 
       
   301     // enable drop shadow for the preview pane
       
   302     QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
       
   303     effect->setBlurRadius(8);
       
   304     setGraphicsEffect(effect);
       
   305 #endif
       
   306 
       
   307     // signal mapper for getting events
       
   308     d->mReleaseMapper = new QSignalMapper(this);
       
   309 
       
   310     QObject::connect(d->mReleaseMapper, SIGNAL(mapped(QString)), this, SIGNAL(charFromPreviewSelected(QString)));
       
   311     setTimeout(NoTimeout);
       
   312     d->init();
       
   313 
       
   314     // This is important we need to switch off all the effects.
       
   315     // if we dont switch off the effect, and if there is a call to 'show' while a 'hide' animation is
       
   316     // in progress the hide call will be ignored.
       
   317     // this will lead to a problem where we will not able to see all the character
       
   318     // preview in case the user is typing very fast.
       
   319 #ifdef HB_EFFECTS
       
   320     HbEffect::disable(this);
       
   321 #endif // HB_EFFECTS
       
   322 }
       
   323 
       
   324 /*!
       
   325 \deprecated HbCharPreviewPane::~HbCharPreviewPane()
       
   326     is deprecated.
       
   327 */
       
   328 HbCharPreviewPane::~HbCharPreviewPane()
       
   329 {
       
   330 }
       
   331 
       
   332 /*!
       
   333 \deprecated HbCharPreviewPane::showCharacters(const QStringList&, const QRectF &)
       
   334     is deprecated.
       
   335 */
       
   336 void HbCharPreviewPane::showCharacters(const QStringList& characterList, const QRectF &itemSceneBoundingRect)
       
   337 {
       
   338     Q_D(HbCharPreviewPane);
       
   339     // let's validate.
       
   340     if (!itemSceneBoundingRect.isValid()) {
       
   341         return;
       
   342     }
       
   343 
       
   344     if (characterList.size() > 1) {
       
   345         setModal(true);
       
   346     } else {
       
   347         setModal(false);
       
   348     }
       
   349 
       
   350     d->mCharacterList = characterList;
       
   351     // let's store items size.
       
   352     d->mItemSize = itemSceneBoundingRect.size();
       
   353 
       
   354     // we need to clear previous character.
       
   355     d->clearCharacters();
       
   356 
       
   357     // update new candidates
       
   358     d->updateCharacters();
       
   359 
       
   360     updateGeometry();
       
   361 
       
   362     // we need to show the preview just above the
       
   363     // passed QRectF of the item which is passed.
       
   364     QPointF pos = itemSceneBoundingRect.topLeft();
       
   365     pos.setY(pos.y() - size().height());
       
   366 
       
   367     // let's adjust x position of the character preview pane so that it
       
   368     // is aligned at the center of the items for which we want to show
       
   369     // the preview.
       
   370     pos.setX(itemSceneBoundingRect.center().x() - size().width()/2);
       
   371 
       
   372     // We need to adjust the character preview pane's postion
       
   373     // such that it is visible in in the current screen.
       
   374     if (pos.x() < 0) {
       
   375         pos.setX(0);
       
   376     } else {
       
   377         const int screenWidth = HbDeviceProfile::profile(this).logicalSize().width();
       
   378         const qreal requiredWidth = pos.x() + (geometry().width());
       
   379         if ( requiredWidth > screenWidth) {
       
   380             pos.setX(screenWidth-(geometry().width()));
       
   381         }
       
   382     }
       
   383 
       
   384     // set final position for the character preview pane
       
   385     setPos(pos);
       
   386 
       
   387     // we need to reset mousePressLocation to None.
       
   388     // We are handling character preview pane a bit differently than a usual popup.
       
   389     // A HbDialog closes the popup on a mouse release. And there is a problem  when we
       
   390     // have long pressed on a button and the preview pane is showing  set of characters,
       
   391     // same time if we do a long press on another button preview will be shown on the next
       
   392     // button but as soon as we release the button HbDialog's internal logic closes the
       
   393     // preview pane. since popup closes on mouse release event. To aviod this situation we
       
   394     // need to reset mousePressLocation. Since this behaviour is very specific to preview pane
       
   395     // we need to fix it here.
       
   396     d->mousePressLocation = HbPopupPrivate::None;
       
   397 
       
   398 	// set the background as a panel if the foreground is a panel to provide focus handling
       
   399 	if ((flags() & QGraphicsItem::ItemIsPanel) && isModal()) {
       
   400 		d->backgroundItem->setFlag(QGraphicsItem::ItemIsPanel);
       
   401 	}
       
   402     // show it!
       
   403     show();
       
   404 }
       
   405 
       
   406 #include "moc_hbinputcharpreviewpane.cpp"
       
   407 // End Of File
       
   408