diff options
Diffstat (limited to 'src/frontend/keychooser')
5 files changed, 211 insertions, 149 deletions
diff --git a/src/frontend/keychooser/cscrollbutton.cpp b/src/frontend/keychooser/cscrollbutton.cpp index 742bc53..3287eef 100644 --- a/src/frontend/keychooser/cscrollbutton.cpp +++ b/src/frontend/keychooser/cscrollbutton.cpp @@ -2,20 +2,14 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2009 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ - - #include "cscrollbutton.h" - -#include <stdlib.h> -#include <math.h> - -//Qt includes +#include <cmath> #include <QEvent> #include <QApplication> #include <QCursor> @@ -23,63 +17,67 @@ #include <QMouseEvent> #include <QWheelEvent> -CScrollButton::CScrollButton(QWidget *parent) : QToolButton(parent) { - setFocusPolicy(Qt::WheelFocus); - setCursor(Qt::SplitVCursor ); - - m_isLocked = false; - connect(this, SIGNAL(pressed() ), SLOT(was_pressed() )); - connect(this, SIGNAL(released()), SLOT(was_released())); -} - -bool CScrollButton::isLocked( ) const { - return m_isLocked; +CScrollButton::CScrollButton(QWidget *parent) + : QToolButton(parent), m_isLocked(false) +{ + setFocusPolicy(Qt::WheelFocus); + setCursor(Qt::SplitVCursor); } -void CScrollButton::was_pressed( ) { - QApplication::setOverrideCursor(Qt::BlankCursor); - m_isLocked = true; - lock_Point = get_lock_Point(); - - emit lock() - ; +CScrollButton::~CScrollButton() { + // Intentionally empty } -void CScrollButton::was_released( ) { - QApplication::restoreOverrideCursor(); - m_isLocked = false; - - emit unlock(); +void CScrollButton::mousePressEvent(QMouseEvent *e) { + if (m_isLocked) return; + if (e->button() != Qt::LeftButton) return; + m_isLocked = true; + grabMouse(Qt::BlankCursor); + emit lock(); } -const QPoint CScrollButton::get_lock_Point() const { - return mapToGlobal( QPoint( width()/2, height()/2 ) ); +void CScrollButton::mouseReleaseEvent(QMouseEvent *e) { + if (!m_isLocked) return; + if (e->button() != Qt::LeftButton) return; + m_isLocked = false; + releaseMouse(); + emit unlock(); } -void CScrollButton::mouseMoveEvent( QMouseEvent* e ) { - if (m_isLocked) { - int vchange = (QCursor::pos().y() - lock_Point.y()); - - if (abs(vchange) < 10) { - vchange = (int)((vchange>0 ? 1 : -1) * pow(abs(vchange), 0.3)); - } - else if (abs(vchange) < 30) { - vchange = (int)((vchange>0 ? 1 : -1) * pow(abs(vchange), 0.6)); - } - else if (abs(vchange) < 40) { - vchange = (int)((vchange>0 ? 1 : -1) * pow(abs(vchange), 1.2)); - } - else { - vchange = (int)((vchange>0 ? 1 : -1) * pow(abs(vchange), 2.0)); - } - - if (vchange) { //not emit 0 - emit change_requested( vchange ); - } - - QCursor::setPos( lock_Point ); - } - else { - QToolButton::mouseMoveEvent(e); - } +void CScrollButton::mouseMoveEvent(QMouseEvent *e) { + if (m_isLocked) { + // Recalculate the center of the widget (might change during grab): + QPoint center(mapToGlobal(QPoint(width() / 2, height() / 2))); + + // Calculate movement change: + int vchange = (e->globalY() - center.y()); + + if (vchange != 0) { + // Calculate the real change we are going to emit: + int avchange(vchange >= 0 ? vchange : -vchange); + if (avchange < 10) { + avchange = (int) pow(avchange, 0.3); + } else if (avchange < 30) { + avchange = (int) pow(avchange, 0.6); + } else if (avchange < 40) { + avchange = (int) pow(avchange, 1.2); + } else { + avchange = (int) pow(avchange, 2.0); + } + + // Emit the change request signal only when necessary: + if (avchange != 0) { + if (vchange > 0) { + emit change_requested(avchange); + } else if (vchange < 0) { + emit change_requested(-avchange); + } + } + } + + // Move the mouse cursor to the center of this widget: + QCursor::setPos(center); + } else { + QToolButton::mouseMoveEvent(e); + } } diff --git a/src/frontend/keychooser/cscrollbutton.h b/src/frontend/keychooser/cscrollbutton.h index 3a38f37..3af4ca8 100644 --- a/src/frontend/keychooser/cscrollbutton.h +++ b/src/frontend/keychooser/cscrollbutton.h @@ -2,84 +2,79 @@ * * This file is part of BibleTime's source code, http://www.bibletime.info/. * -* Copyright 1999-2008 by the BibleTime developers. +* Copyright 1999-2009 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ - - #ifndef CSRCOLLBUTTON_H #define CSRCOLLBUTTON_H - #include <QToolButton> - class QMouseEvent; class QWidget; class QMouseEvent; class QWheelEvent; -/** This Class implements the direct chooser button used in the KeyChooser Widget - * @author The BibleTime team - */ -class CScrollButton : public QToolButton { - Q_OBJECT -public: - /** - * The constructor - */ - CScrollButton(QWidget *parent=0); - bool isLocked() const; +/** +* This Class implements the direct chooser button used in the KeyChooser Widget. +* \author The BibleTime team. +*/ +class CScrollButton: public QToolButton { + Q_OBJECT + public: + CScrollButton(QWidget *parent = 0); + virtual ~CScrollButton(); + + signals: + /** + * \brief The lock() signal is emitted when the button grabs the mouse + * and enters the locked state. + */ + void lock(); + + /** + * \brief The unlock() signal is emitted when the button releases the + * leaves the locked state. + */ + void unlock(); + + /** + * \brief Indicates a change the user made by moving the mouse. + * + * \param count the number of items to be changed in the KeyChooser + * ComboBox. + */ + void change_requested(int count); -signals: - /** - * is emitted when the button enters locked state - */ - void lock() - ; - /** - * is emitted when the button leaves locked state - */ - void unlock(); - /** - * indicates a change the user made by moving the mouse - * @param count the number of items to be changed in the KeyChooser ComboBox - */ - void change_requested(int count); + protected: + /** + * \brief Grabs the mouse on left button click and emits lock(). + */ + virtual void mousePressEvent(QMouseEvent *e); -protected slots: - /* - * used to process the button press events - */ - void was_pressed(); - /** - * used to process the button release events - */ - void was_released(); + /** + * \brief If the mouse is grabbed and we release the left mouse button, + * releases the mouse and emits unlock(). + */ + virtual void mouseReleaseEvent(QMouseEvent *e); -protected: - /** - * Reimplementation from @ref QWidget#mouseMoveEvent - processes - * the mouse move events - */ - virtual void mouseMoveEvent( QMouseEvent* e ); - /** - * used to find the lock point - the middle of the button - * @return the lock point - */ - const QPoint get_lock_Point() const; + /** + * \brief Reimplementation from \ref QWidget#mouseMoveEvent - processes + * the mouse move events + */ + virtual void mouseMoveEvent(QMouseEvent *e); -private: - /** - * Indicates whether the button is in locked state or not - */ - bool m_isLocked; - /** - * stores the lock point - */ - QPoint lock_Point; + protected: + /** + * \brief Indicates whether the button is in locked state or not. + * + * If the button is in the locked state, this means the mouse is grabbed + * and any mouse move events invoke calculation about whether to emit the + * \ref CScrollButton#change_requested signal. + */ + bool m_isLocked; }; #endif diff --git a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp index e4b05c3..c738353 100644 --- a/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp +++ b/src/frontend/keychooser/versekeychooser/btdropdownchooserbutton.cpp @@ -14,15 +14,15 @@ #include <QWheelEvent> #include <QDebug> -const unsigned int ARROW_HEIGHT = 12; +const unsigned int ARROW_HEIGHT = 15; BtDropdownChooserButton::BtDropdownChooserButton(CKeyReferenceWidget* ref) : QToolButton(), m_ref(ref) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - - setAutoRaise(true); + + setAutoRaise(false); setArrowType(Qt::NoArrow); setFixedHeight(ARROW_HEIGHT); setFocusPolicy(Qt::NoFocus); diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp index 0815a89..11c5ddc 100644 --- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp +++ b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.cpp @@ -21,21 +21,23 @@ #include "util/directoryutil.h" //Qt includes -#include <QString> -#include <QStringList> -#include <QEvent> -#include <QPixmap> #include <QApplication> -#include <QHBoxLayout> -#include <QToolButton> #include <QDebug> +#include <QHBoxLayout> #include <QLineEdit> +#include <QEvent> +#include <QMouseEvent> +#include <QPixmap> +#include <QString> +#include <QStringList> +#include <QToolButton> CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVerseKey *key, QWidget *parent, const char* /*name*/) : QWidget(parent), - m_key(new CSwordVerseKey(mod)) + m_key(new CSwordVerseKey(mod)), + m_dropDownHoverTimer(this) { updatelock = false; @@ -52,7 +54,7 @@ CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVers m_bookScroller = new CScrollerWidgetSet(this); m_textbox = new QLineEdit( this ); - m_textbox->setStyleSheet("QLineEdit{margin:0px;}"); + m_textbox->setContentsMargins(0, 0, 0, 0); setKey(key); // The order of these two functions is important. setModule(); @@ -60,34 +62,39 @@ CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVers m_chapterScroller = new CScrollerWidgetSet(this); m_verseScroller = new CScrollerWidgetSet(this); - m_bookDropdownButton = new BtBookDropdownChooserButton(this); - m_chapterDropdownButton = new BtChapterDropdownChooserButton(this); - m_verseDropdownButton = new BtVerseDropdownChooserButton(this); - - QHBoxLayout* dropdownButtonsLayout = new QHBoxLayout(); - QVBoxLayout* editorAndButtonsLayout = new QVBoxLayout(); - dropdownButtonsLayout->setContentsMargins(0,0,0,0); - editorAndButtonsLayout->setContentsMargins(0,0,0,0); - dropdownButtonsLayout->setSpacing(0); - editorAndButtonsLayout->setSpacing(0); - - dropdownButtonsLayout->addWidget(m_bookDropdownButton, 2); - dropdownButtonsLayout->addWidget(m_chapterDropdownButton,1); - dropdownButtonsLayout->addWidget(m_verseDropdownButton,1); - editorAndButtonsLayout->addWidget(m_textbox); - editorAndButtonsLayout->addLayout(dropdownButtonsLayout); - QHBoxLayout* m_mainLayout = new QHBoxLayout( this ); m_mainLayout->setContentsMargins(0,0,0,0); m_mainLayout->setSpacing(0); m_mainLayout->addWidget(clearRef); m_mainLayout->addWidget(m_bookScroller); - m_mainLayout->addLayout(editorAndButtonsLayout); + m_mainLayout->addWidget(m_textbox); m_mainLayout->addWidget(m_chapterScroller); m_mainLayout->addWidget(m_verseScroller); setTabOrder(m_textbox, 0); + m_dropDownButtons = new QWidget(0); + m_dropDownButtons->setWindowFlags(Qt::Popup); + m_dropDownButtons->setAttribute(Qt::WA_WindowPropagation); + m_dropDownButtons->setCursor(Qt::ArrowCursor); + QHBoxLayout *dropDownButtonsLayout(new QHBoxLayout(m_dropDownButtons)); + m_bookDropdownButton = new BtBookDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_bookDropdownButton, 2); + m_chapterDropdownButton = new BtChapterDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_chapterDropdownButton, 1); + m_verseDropdownButton = new BtVerseDropdownChooserButton(this); + dropDownButtonsLayout->addWidget(m_verseDropdownButton, 1); + dropDownButtonsLayout->setContentsMargins(0, 0, 0, 0); + dropDownButtonsLayout->setSpacing(0); + m_dropDownButtons->setLayout(dropDownButtonsLayout); + m_dropDownButtons->hide(); + + m_dropDownButtons->installEventFilter(this); + + m_dropDownHoverTimer.setInterval(500); + m_dropDownHoverTimer.setSingleShot(true); + connect(&m_dropDownHoverTimer, SIGNAL(timeout()), + m_dropDownButtons, SLOT(hide())); QString scrollButtonToolTip(tr("Scroll through the entries of the list. Press the button and move the mouse to increase or decrease the item.")); m_bookScroller->setToolTips( @@ -120,6 +127,10 @@ CKeyReferenceWidget::CKeyReferenceWidget( CSwordBibleModuleInfo *mod, CSwordVers connect(m_verseScroller, SIGNAL(scroller_released()), SLOT(slotUpdateUnlock())); } +CKeyReferenceWidget::~CKeyReferenceWidget() { + delete m_dropDownButtons; +} + void CKeyReferenceWidget::setModule(CSwordBibleModuleInfo *m) { if (m) //can be null @@ -129,6 +140,48 @@ void CKeyReferenceWidget::setModule(CSwordBibleModuleInfo *m) } } +bool CKeyReferenceWidget::eventFilter(QObject *o, QEvent *e) { + if (o != m_dropDownButtons) return false; + switch (e->type()) { + case QEvent::Enter: + m_dropDownHoverTimer.stop(); + return true; + case QEvent::Leave: + m_dropDownHoverTimer.start(); + return true; + default: + return false; + } +} + +void CKeyReferenceWidget::enterEvent(QEvent *) { + m_dropDownHoverTimer.stop(); + + resetDropDownButtons(); + + m_dropDownButtons->raise(); + m_dropDownButtons->show(); +} + +void CKeyReferenceWidget::leaveEvent(QEvent *) { + m_dropDownHoverTimer.start(); +} + +void CKeyReferenceWidget::resizeEvent(QResizeEvent *event) { + if (m_dropDownButtons->isVisible()) { + resetDropDownButtons(); + } + QWidget::resizeEvent(event); +} + +void CKeyReferenceWidget::resetDropDownButtons() { + m_dropDownButtons->setParent(window()); + int h(m_dropDownButtons->layout()->minimumSize().height()); + QPoint topLeft(mapTo(window(), QPoint(m_textbox->x(), height()))); + m_dropDownButtons->setGeometry(topLeft.x(), topLeft.y(), + m_textbox->width(), h); +} + void CKeyReferenceWidget::slotClearRef( ) { m_textbox->setText(""); @@ -137,7 +190,14 @@ void CKeyReferenceWidget::slotClearRef( ) void CKeyReferenceWidget::updateText() { - m_textbox->setText(m_key->key()); + QString text(m_key->key()); + m_textbox->setText(text); + QFontMetrics fm(m_textbox->font()); + int nw(m_textbox->minimumSizeHint().width() + fm.width(text)); + if (nw > m_textbox->minimumWidth()) { + m_textbox->setMinimumWidth(nw); + m_textbox->updateGeometry(); + } } bool CKeyReferenceWidget::setKey(CSwordVerseKey *key) diff --git a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h index d6d5eee..0ecb7a9 100644 --- a/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h +++ b/src/frontend/keychooser/versekeychooser/ckeyreferencewidget.h @@ -16,6 +16,7 @@ #include <QWidget> #include <boost/scoped_ptr.hpp> +#include <QTimer> class CLexiconKeyChooser; @@ -32,14 +33,20 @@ public: * the constructor */ CKeyReferenceWidget(CSwordBibleModuleInfo *, CSwordVerseKey*, QWidget *parent=0, const char *name=0); + ~CKeyReferenceWidget(); bool setKey(CSwordVerseKey* key); QLineEdit* textbox(); void setModule(CSwordBibleModuleInfo *m = 0); + bool eventFilter(QObject *o, QEvent *e); signals: void changed(CSwordVerseKey* key); protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void resizeEvent(QResizeEvent *event); + void resetDropDownButtons(); void updateText(); protected slots: // Protected slots @@ -74,6 +81,8 @@ private: CScrollerWidgetSet *m_chapterScroller; CScrollerWidgetSet *m_verseScroller; + QWidget *m_dropDownButtons; + QTimer m_dropDownHoverTimer; BtDropdownChooserButton* m_bookDropdownButton; BtDropdownChooserButton* m_chapterDropdownButton; BtDropdownChooserButton* m_verseDropdownButton; |