summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Bache-Wiig <jbache@trolltech.com>2010-03-18 14:58:46 (GMT)
committerJens Bache-Wiig <jbache@trolltech.com>2010-03-18 15:02:25 (GMT)
commit49542b562cd5ed0f64fcd1705595f05700e16400 (patch)
tree081683b7674d186af09c172e34ac967febe1bd3c
parentb0eeea8a2ff13e1449dd98ef5c43c1c89e2e357b (diff)
downloadQt-49542b562cd5ed0f64fcd1705595f05700e16400.zip
Qt-49542b562cd5ed0f64fcd1705595f05700e16400.tar.gz
Qt-49542b562cd5ed0f64fcd1705595f05700e16400.tar.bz2
Redesigned filter widgets
I redesigned the filter widget so that the reset button is contained within the line edit and only shown when edited. This is typically what KDE and GNOME does. The base icon also changed to use platform dependant icons on X11 and a new clear icon for other platforms. Since hinttext is now a feature of QLineEdit, I could safely remove this code as well. Unfortunately Oxygen is reporting incorrect contents margins for line edits. In essence it incorrectly offsets the frame so I had to add some magic to support that in particular. Reviewed-by: ogoffart
-rw-r--r--tools/designer/src/components/formeditor/formeditor.qrc1
-rw-r--r--tools/designer/src/components/formeditor/images/cleartext.pngbin0 -> 760 bytes
-rw-r--r--tools/designer/src/lib/shared/filterwidget.cpp163
-rw-r--r--tools/designer/src/lib/shared/filterwidget_p.h52
4 files changed, 116 insertions, 100 deletions
diff --git a/tools/designer/src/components/formeditor/formeditor.qrc b/tools/designer/src/components/formeditor/formeditor.qrc
index 83cc9c7..6510814 100644
--- a/tools/designer/src/components/formeditor/formeditor.qrc
+++ b/tools/designer/src/components/formeditor/formeditor.qrc
@@ -63,6 +63,7 @@
<file>images/qtlogo.png</file>
<file>images/qt3logo.png</file>
<file>images/resetproperty.png</file>
+ <file>images/cleartext.png</file>
<file>images/sort.png</file>
<file>images/edit.png</file>
<file>images/reload.png</file>
diff --git a/tools/designer/src/components/formeditor/images/cleartext.png b/tools/designer/src/components/formeditor/images/cleartext.png
new file mode 100644
index 0000000..74133ba
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cleartext.png
Binary files differ
diff --git a/tools/designer/src/lib/shared/filterwidget.cpp b/tools/designer/src/lib/shared/filterwidget.cpp
index 6c73a08..84810cb 100644
--- a/tools/designer/src/lib/shared/filterwidget.cpp
+++ b/tools/designer/src/lib/shared/filterwidget.cpp
@@ -44,13 +44,17 @@
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
-#include <QtGui/QPushButton>
#include <QtGui/QLineEdit>
#include <QtGui/QFocusEvent>
#include <QtGui/QPalette>
#include <QtGui/QCursor>
+#include <QtGui/QToolButton>
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
#include <QtCore/QDebug>
+#include <QtCore/QPropertyAnimation>
enum { debugFilter = 0 };
@@ -61,12 +65,44 @@ namespace qdesigner_internal {
HintLineEdit::HintLineEdit(QWidget *parent) :
QLineEdit(parent),
m_defaultFocusPolicy(focusPolicy()),
- m_hintColor(QColor(0xbbbbbb)),
- m_refuseFocus(false),
- m_showingHintText(false)
+ m_refuseFocus(false)
{
}
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setCursor(Qt::ArrowCursor);
+}
+
+void IconButton::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ // Note isDown should really use the active state but in most styles
+ // this has no proper feedback
+ QPixmap iconpixmap = icon().pixmap(ICONBUTTON_SIZE, ICONBUTTON_SIZE, isDown() ?
+ QIcon::Selected : QIcon::Normal);
+ QRect pixmapRect = QRect(0, 0, iconpixmap.width(), iconpixmap.height());
+ pixmapRect.moveCenter(rect().center());
+ painter.setOpacity(m_fader);
+ painter.drawPixmap(pixmapRect, iconpixmap);
+}
+
+void IconButton::animateShow(bool visible)
+{
+ if (visible) {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(1.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(0.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ }
+}
+
bool HintLineEdit::refuseFocus() const
{
return m_refuseFocus;
@@ -111,92 +147,60 @@ void HintLineEdit::focusInEvent(QFocusEvent *e)
}
}
- hideHintText();
QLineEdit::focusInEvent(e);
}
-void HintLineEdit::focusOutEvent(QFocusEvent *e)
+// ------------------- FilterWidget
+FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
+ QWidget(parent),
+ m_editor(new HintLineEdit(this)),
+ m_button(new IconButton(m_editor)),
+ m_buttonwidth(0)
{
- if (debugFilter)
- qDebug() << Q_FUNC_INFO;
- // Focus out: Switch to displaying the hint text unless there is user input
- showHintText();
- QLineEdit::focusOutEvent(e);
-}
+ m_editor->setPlaceholderText(tr("Filter"));
-QString HintLineEdit::hintText() const
-{
- return m_hintText;
-}
+ // Let the style determine minimum height for our widget
+ QSize size(ICONBUTTON_SIZE + 2, ICONBUTTON_SIZE + 2);
-void HintLineEdit::setHintText(const QString &ht)
-{
- if (ht == m_hintText)
- return;
- hideHintText();
- m_hintText = ht;
- if (!hasFocus() && !ht.isEmpty())
- showHintText();
-}
+ QStyleOptionFrame frameOpt;
+ frameOpt.initFrom(m_editor);
+ QSize adjustedSize = style()->sizeFromContents(QStyle::CT_LineEdit, &frameOpt, size, m_editor);
-void HintLineEdit::showHintText(bool force)
-{
- if (m_showingHintText || m_hintText.isEmpty())
- return;
- if (force || text().isEmpty()) {
- m_showingHintText = true;
- setText(m_hintText);
- setTextColor(m_hintColor, &m_textColor);
- }
-}
-void HintLineEdit::hideHintText()
-{
- if (m_showingHintText && !m_hintText.isEmpty()) {
- m_showingHintText = false;
- setText(QString());
- setTextColor(m_textColor);
+ // Note KDE does not reserve space for the highlight color
+ if (style()->inherits("OxygenStyle")) {
+ adjustedSize = adjustedSize.expandedTo(QSize(0, 32));
+ size = size.expandedTo(QSize(24, 0));
}
-}
-bool HintLineEdit::isShowingHintText() const
-{
- return m_showingHintText;
-}
+ m_editor->setMinimumHeight(adjustedSize.height());
-QString HintLineEdit::typedText() const
-{
- return m_showingHintText ? QString() : text();
-}
+ // Make room for clear icon
+ QMargins margins = m_editor->textMargins();
+ if (layoutDirection() == Qt::LeftToRight)
+ margins.setRight(size.width());
+ else
+ margins.setLeft(size.width());
-void HintLineEdit::setTextColor(const QColor &newColor, QColor *oldColor)
-{
- QPalette pal = palette();
- if (oldColor)
- *oldColor = pal.color(QPalette::Text);
- pal.setColor(QPalette::Text, newColor);
- setPalette(pal);}
+ m_editor->setTextMargins(margins);
-// ------------------- FilterWidget
-FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
- QWidget(parent),
- m_button(new QPushButton),
- m_editor(new HintLineEdit)
-{
- m_editor->setHintText(tr("<Filter>"));
QHBoxLayout *l = new QHBoxLayout(this);
l->setMargin(0);
l->setSpacing(0);
-
if (lm == LayoutAlignRight)
l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
l->addWidget(m_editor);
- m_button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
- m_button->setIconSize(QSize(8, 8));
- m_button->setFlat(true);
- l->addWidget(m_button);
+ // KDE has custom icons for this. Notice that icon namings are counter intuitive
+ // If these icons are not avaiable we use the freedesktop standard name before
+ // falling back to a bundled resource
+ QIcon icon = QIcon::fromTheme(layoutDirection() == Qt::LeftToRight ?
+ QLatin1String("edit-clear-locationbar-rtl") :
+ QLatin1String("edit-clear-locationbar-ltr"),
+ QIcon::fromTheme("edit-clear", createIconSet(QLatin1String("cleartext.png"))));
+ m_button->setIcon(icon);
+ m_button->setToolTip(tr("Clear text"));
connect(m_button, SIGNAL(clicked()), this, SLOT(reset()));
connect(m_editor, SIGNAL(textChanged(QString)), this, SLOT(checkButton(QString)));
connect(m_editor, SIGNAL(textEdited(QString)), this, SIGNAL(filterChanged(QString)));
@@ -204,25 +208,38 @@ FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
QString FilterWidget::text() const
{
- return m_editor->typedText();
+ return m_editor->text();
}
void FilterWidget::checkButton(const QString &)
{
- m_button->setEnabled(!text().isEmpty());
+ m_button->animateShow(!m_editor->text().isEmpty());
}
void FilterWidget::reset()
{
if (debugFilter)
qDebug() << Q_FUNC_INFO;
- if (!text().isEmpty()) {
+
+ if (!m_editor->text().isEmpty()) {
// Editor has lost focus once this is pressed
- m_editor->showHintText(true);
+ m_editor->clear();
emit filterChanged(QString());
}
}
+void FilterWidget::resizeEvent(QResizeEvent *)
+{
+ QRect contentRect = m_editor->rect();
+ if (layoutDirection() == Qt::LeftToRight) {
+ const int iconoffset = m_editor->textMargins().right() + 4;
+ m_button->setGeometry(contentRect.adjusted(m_editor->width() - iconoffset, 0, 0, 0));
+ } else {
+ const int iconoffset = m_editor->textMargins().left() + 4;
+ m_button->setGeometry(contentRect.adjusted(0, 0, -m_editor->width() + iconoffset, 0));
+ }
+}
+
bool FilterWidget::refuseFocus() const
{
return m_editor->refuseFocus();
diff --git a/tools/designer/src/lib/shared/filterwidget_p.h b/tools/designer/src/lib/shared/filterwidget_p.h
index 025d708..423b30e 100644
--- a/tools/designer/src/lib/shared/filterwidget_p.h
+++ b/tools/designer/src/lib/shared/filterwidget_p.h
@@ -58,58 +58,55 @@
#include <QtGui/QWidget>
#include <QtGui/QLineEdit>
#include <QtGui/QColor>
+#include <QtGui/QToolButton>
QT_BEGIN_NAMESPACE
-class QPushButton;
+class QToolButton;
namespace qdesigner_internal {
-/* A line edit that displays a grayed hintText (like "Type Here to Filter")
- * when not focused and empty. When connecting to the changed signals and
- * querying text, one has to be aware that the text is set to that hint
- * text if isShowingHintText() returns true (that is, does not contain
- * valid user input). This widget should never have initial focus
+/* This widget should never have initial focus
* (ie, be the first widget of a dialog, else, the hint cannot be displayed.
* For situations, where it is the only focusable control (widget box),
* there is a special "refuseFocus()" mode, in which it clears the focus
* policy and focusses explicitly on click (note that setting Qt::ClickFocus
* is not sufficient for that as an ActivationFocus will occur). */
+#define ICONBUTTON_SIZE 16
+
class QDESIGNER_SHARED_EXPORT HintLineEdit : public QLineEdit {
Q_OBJECT
public:
explicit HintLineEdit(QWidget *parent = 0);
- QString hintText() const;
-
- bool isShowingHintText() const;
-
- // Convenience for accessing the text that returns "" in case of isShowingHintText().
- QString typedText() const;
-
bool refuseFocus() const;
void setRefuseFocus(bool v);
-public slots:
- void setHintText(const QString &ht);
- void showHintText(bool force = false);
- void hideHintText();
-
protected:
virtual void mousePressEvent(QMouseEvent *event);
virtual void focusInEvent(QFocusEvent *e);
- virtual void focusOutEvent(QFocusEvent *e);
private:
- void setTextColor(const QColor &newColor, QColor *oldColor = 0);
-
const Qt::FocusPolicy m_defaultFocusPolicy;
- const QColor m_hintColor;
- QColor m_textColor;
bool m_refuseFocus;
- QString m_hintText;
- bool m_showingHintText;
+};
+
+// IconButton: This is a simple helper class that represents clickable icons
+
+class IconButton: public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(float fader READ fader WRITE setFader)
+public:
+ IconButton(QWidget *parent);
+ void paintEvent(QPaintEvent *event);
+ float fader() { return m_fader; }
+ void setFader(float value) { m_fader = value; update(); }
+ void animateShow(bool visible);
+
+private:
+ float m_fader;
};
// FilterWidget: For filtering item views, with reset button Uses HintLineEdit.
@@ -128,7 +125,7 @@ public:
explicit FilterWidget(QWidget *parent = 0, LayoutMode lm = LayoutAlignRight);
QString text() const;
-
+ void resizeEvent(QResizeEvent *);
bool refuseFocus() const; // see HintLineEdit
void setRefuseFocus(bool v);
@@ -142,8 +139,9 @@ private slots:
void checkButton(const QString &text);
private:
- QPushButton *m_button;
HintLineEdit *m_editor;
+ IconButton *m_button;
+ int m_buttonwidth;
};
} // namespace qdesigner_internal