Add Select Field files

This commit is contained in:
johanneshilden 2017-09-29 20:50:27 +03:00
parent 8627216195
commit 9b7d350b5a
6 changed files with 791 additions and 0 deletions

View File

@ -0,0 +1,373 @@
#include "xx/qtmaterialselectfield.h"
#include "xx/qtmaterialselectfield_p.h"
#include <QEvent>
#include <QFontDatabase>
#include <QEasingCurve>
#include <QTimer>
#include <QPainter>
#include "xxlib/qtmaterialstyle.h"
#include "xx/qtmaterialmenuitem.h"
#include "xx/qtmaterialcollapsiblemenu.h"
#include "xxlib/qtmaterialoverlaywidget.h"
/*!
* \class QtMaterialSelectFieldPrivate
* \internal
*/
QtMaterialSelectFieldPrivate::QtMaterialSelectFieldPrivate(QtMaterialSelectField *q)
: q_ptr(q)
{
}
QtMaterialSelectFieldPrivate::~QtMaterialSelectFieldPrivate()
{
}
void QtMaterialSelectFieldPrivate::init()
{
Q_Q(QtMaterialSelectField);
menuOverlay = new QtMaterialOverlayWidget(q);
menu = new QtMaterialCollapsibleMenu;
selectedIndex = -1;
useThemeColors = true;
q->setStyle(&QtMaterialStyle::instance());
QFontDatabase db;
QFont font(db.font("Roboto", "Regular", 11));
q->setFont(font);
menuOverlay->setParent(q->parentWidget());
menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents);
menuOverlay->installEventFilter(q);
menu->setParent(menuOverlay);
menu->setMaximumHeight(300);
menu->setCollapsedXScale(1);
menu->setExpandYDuration(280);
menu->setExpandYEasingCurve(QEasingCurve::OutQuad);
QObject::connect(menu, SIGNAL(aboutToCollapse()), q, SLOT(makeTransparent()));
QObject::connect(menu, SIGNAL(wasExpanded()), q, SLOT(makeOpaque()));
QObject::connect(menu, SIGNAL(aboutToExpand()), menuOverlay, SLOT(raise()));
QObject::connect(menu, SIGNAL(itemClicked(int)), q, SLOT(setSelectedIndex(int)));
QObject::connect(menu, SIGNAL(itemClicked(int)), q, SLOT(collapseDelayed()));
QObject::connect(menu, SIGNAL(itemClicked(int)), q, SIGNAL(itemSelected(int)));
}
/*!
* \class QtMaterialSelectField
*/
QtMaterialSelectField::QtMaterialSelectField(QWidget *parent)
: QWidget(parent),
d_ptr(new QtMaterialSelectFieldPrivate(this))
{
d_func()->init();
}
QtMaterialSelectField::~QtMaterialSelectField()
{
}
/*!
* \reimp
*/
QSize QtMaterialSelectField::sizeHint() const
{
return QSize(300, 30);
}
void QtMaterialSelectField::addItem(const QString &text)
{
Q_D(QtMaterialSelectField);
QtMaterialMenuItem *item = new QtMaterialMenuItem;
item->setText(text);
item->setHaloVisible(false);
d->menu->addMenuItem(item);
}
QtMaterialMenuItem *QtMaterialSelectField::itemAt(int index) const
{
Q_D(const QtMaterialSelectField);
return d->menu->menuItemAt(index);
}
void QtMaterialSelectField::setPlaceholderText(const QString &text)
{
Q_D(QtMaterialSelectField);
d->placeholderText = text;
update();
}
QString QtMaterialSelectField::placeholderText() const
{
Q_D(const QtMaterialSelectField);
return d->placeholderText;
}
void QtMaterialSelectField::setUseThemeColors(bool value)
{
Q_D(QtMaterialSelectField);
if (d->useThemeColors == value) {
return;
}
d->useThemeColors = value;
update();
}
bool QtMaterialSelectField::useThemeColors() const
{
Q_D(const QtMaterialSelectField);
return d->useThemeColors;
}
void QtMaterialSelectField::setUnderlineColor(const QColor &color)
{
Q_D(QtMaterialSelectField);
d->underlineColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSelectField::underlineColor() const
{
Q_D(const QtMaterialSelectField);
if (d->useThemeColors || !d->underlineColor.isValid()) {
return QtMaterialStyle::instance().themeColor("border");
}
return d->underlineColor;
}
void QtMaterialSelectField::setPlaceholderColor(const QColor &color)
{
Q_D(QtMaterialSelectField);
d->placeholderColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSelectField::placeholderColor() const
{
Q_D(const QtMaterialSelectField);
if (d->useThemeColors || !d->placeholderColor.isValid()) {
return QtMaterialStyle::instance().themeColor("accent3");
}
return d->placeholderColor;
}
void QtMaterialSelectField::setForegroundColor(const QColor &color)
{
Q_D(QtMaterialSelectField);
d->foregroundColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSelectField::foregroundColor() const
{
Q_D(const QtMaterialSelectField);
if (d->useThemeColors || !d->foregroundColor.isValid()) {
return QtMaterialStyle::instance().themeColor("text");
}
return d->foregroundColor;
}
void QtMaterialSelectField::setHighlightedColor(const QColor &color)
{
Q_D(QtMaterialSelectField);
d->highlightedColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSelectField::highlightedColor() const
{
Q_D(const QtMaterialSelectField);
if (d->useThemeColors || !d->highlightedColor.isValid()) {
return QtMaterialStyle::instance().themeColor("primary1");
}
return d->highlightedColor;
}
void QtMaterialSelectField::setDisabledColor(const QColor &color)
{
Q_D(QtMaterialSelectField);
d->disabledColor = color;
setUseThemeColors(false);
}
QColor QtMaterialSelectField::disabledColor() const
{
Q_D(const QtMaterialSelectField);
if (d->useThemeColors || !d->disabledColor.isValid()) {
return QtMaterialStyle::instance().themeColor("disabled");
}
return d->disabledColor;
}
void QtMaterialSelectField::setSelectedIndex(int index)
{
Q_D(QtMaterialSelectField);
QtMaterialMenuItem *menuItem;
if (d->selectedIndex > -1 && (menuItem = d->menu->menuItemAt(d->selectedIndex))) {
menuItem->setHighlighted(false);
}
if (index > -1 && (menuItem = d->menu->menuItemAt(index))) {
menuItem->setHighlighted(true);
d->selectedText = menuItem->text();
}
d->selectedIndex = index;
update();
}
void QtMaterialSelectField::clearSelection()
{
Q_D(QtMaterialSelectField);
setSelectedIndex(-1);
d->selectedText.clear();
}
void QtMaterialSelectField::makeTransparent()
{
Q_D(QtMaterialSelectField);
d->menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, true);
}
void QtMaterialSelectField::makeOpaque()
{
Q_D(QtMaterialSelectField);
d->menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
void QtMaterialSelectField::collapseDelayed()
{
Q_D(QtMaterialSelectField);
QTimer::singleShot(100, d->menu, SLOT(collapse()));
}
/*!
* \reimp
*/
bool QtMaterialSelectField::event(QEvent *event)
{
Q_D(QtMaterialSelectField);
switch (event->type())
{
case QEvent::Move:
case QEvent::Resize:
{
const QSize sh = d->menu->sizeHint();
d->menu->setGeometry(x(), y(), width(), sh.height());
break;
}
case QEvent::MouseButtonRelease:
{
if (isEnabled()) {
QtMaterialMenuItem *item;
for (int i = 0; i < d->menu->itemCount(); ++i) {
item = d->menu->menuItemAt(i);
if (item->isHighlighted()) {
item->setForegroundColor(highlightedColor());
} else {
item->setForegroundColor(foregroundColor());
}
}
d->menu->expand();
}
break;
}
case QEvent::ParentChange:
{
QWidget *widget;
if ((widget = parentWidget())) {
d->menuOverlay->setParent(widget);
}
break;
}
default:
break;
}
return QWidget::event(event);
}
/*!
* \reimp
*/
bool QtMaterialSelectField::eventFilter(QObject *obj, QEvent *event)
{
Q_D(QtMaterialSelectField);
if (QEvent::MouseButtonPress == event->type()) {
d->menu->collapse();
}
return QWidget::eventFilter(obj, event);
}
/*!
* \reimp
*/
void QtMaterialSelectField::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
Q_D(QtMaterialSelectField);
QPainter painter(this);
const int y = height()-1;
const int wd = width()-5;
if (d->selectedText.isEmpty() && !d->placeholderText.isEmpty()) {
if (isEnabled()) {
painter.setPen(placeholderColor());
} else {
painter.setPen(disabledColor());
}
painter.drawText(2, y-8, d->placeholderText);
} else {
painter.drawText(2, y-8, d->selectedText);
}
QPen pen;
pen.setWidth(1);
pen.setColor(underlineColor());
painter.setPen(pen);
painter.setOpacity(1);
painter.drawLine(2.5, y, wd, y);
if (isEnabled())
{
static const int points[] = { wd-14, 12, wd-4, 12, wd-9, 18 };
QPolygon polygon;
polygon.setPoints(3, points);
painter.setPen(Qt::NoPen);
painter.setBrush(underlineColor());
painter.drawPolygon(polygon);
}
}

View File

@ -0,0 +1,67 @@
#ifndef QTMATERIALSELECTFIELD_H
#define QTMATERIALSELECTFIELD_H
#include <QWidget>
class QtMaterialSelectFieldPrivate;
class QtMaterialMenuItem;
class QtMaterialSelectField : public QWidget
{
Q_OBJECT
public:
explicit QtMaterialSelectField(QWidget *parent = 0);
~QtMaterialSelectField();
QSize sizeHint() const Q_DECL_OVERRIDE;
void addItem(const QString &text);
QtMaterialMenuItem *itemAt(int index) const;
void setPlaceholderText(const QString &text);
QString placeholderText() const;
void setUseThemeColors(bool value);
bool useThemeColors() const;
void setUnderlineColor(const QColor &color);
QColor underlineColor() const;
void setPlaceholderColor(const QColor &color);
QColor placeholderColor() const;
void setForegroundColor(const QColor &color);
QColor foregroundColor() const;
void setHighlightedColor(const QColor &color);
QColor highlightedColor() const;
void setDisabledColor(const QColor &color);
QColor disabledColor() const;
signals:
void itemSelected(int index);
public slots:
void setSelectedIndex(int index);
void clearSelection();
protected slots:
void makeTransparent();
void makeOpaque();
void collapseDelayed();
protected:
bool event(QEvent *event) Q_DECL_OVERRIDE;
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
const QScopedPointer<QtMaterialSelectFieldPrivate> d_ptr;
private:
Q_DISABLE_COPY(QtMaterialSelectField)
Q_DECLARE_PRIVATE(QtMaterialSelectField)
};
#endif // QTMATERIALSELECTFIELD_H

View File

@ -0,0 +1,37 @@
#ifndef QTMATERIALSELECTFIELD_P_H
#define QTMATERIALSELECTFIELD_P_H
#include <QtGlobal>
#include <QString>
#include <QColor>
class QtMaterialSelectField;
class QtMaterialOverlayWidget;
class QtMaterialCollapsibleMenu;
class QtMaterialSelectFieldPrivate
{
Q_DISABLE_COPY(QtMaterialSelectFieldPrivate)
Q_DECLARE_PUBLIC(QtMaterialSelectField)
public:
QtMaterialSelectFieldPrivate(QtMaterialSelectField *q);
~QtMaterialSelectFieldPrivate();
void init();
QtMaterialSelectField *const q_ptr;
QtMaterialOverlayWidget *menuOverlay;
QtMaterialCollapsibleMenu *menu;
QString selectedText;
QString placeholderText;
QColor underlineColor;
QColor placeholderColor;
QColor foregroundColor;
QColor highlightedColor;
QColor disabledColor;
int selectedIndex;
bool useThemeColors;
};
#endif // QTMATERIALSELECTFIELD_P_H

View File

@ -0,0 +1,105 @@
#include "yy/selectfieldsettingseditor.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QColorDialog>
#include "xx/qtmaterialselectfield.h"
#include "xx/qtmaterialmenuitem.h"
SelectFieldSettingsEditor::SelectFieldSettingsEditor(QWidget *parent)
: QWidget(parent),
ui(new Ui::SelectFieldSettingsForm),
m_selectField(new QtMaterialSelectField)
{
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
QWidget *widget = new QWidget;
layout->addWidget(widget);
QWidget *canvas = new QWidget;
canvas->setStyleSheet("QWidget { background: white; }");
layout->addWidget(canvas);
ui->setupUi(widget);
layout->setContentsMargins(20, 20, 20, 20);
layout = new QVBoxLayout;
canvas->setLayout(layout);
layout->addWidget(m_selectField);
layout->setAlignment(m_selectField, Qt::AlignCenter);
m_selectField->setPlaceholderText("Please select your favorite language");
{
m_selectField->addItem("C");
m_selectField->addItem("C++");
m_selectField->addItem("PHP");
m_selectField->addItem("Haskell");
m_selectField->addItem("JavaScript");
m_selectField->addItem("ECMAScript");
m_selectField->addItem("OCaml");
m_selectField->addItem("Python");
m_selectField->addItem("F#");
m_selectField->addItem("Clojure");
m_selectField->addItem("Java");
m_selectField->itemAt(2)->setDisabled(true);
}
setupForm();
connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(ui->foregroundColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->underlineColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->placeholderColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->highlightedColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->disabledColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->placeholderLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateWidget()));
connect(ui->clearSelectionToolButton, SIGNAL(clicked(bool)), m_selectField, SLOT(clearSelection()));
}
SelectFieldSettingsEditor::~SelectFieldSettingsEditor()
{
delete ui;
}
void SelectFieldSettingsEditor::setupForm()
{
ui->disabledCheckBox->setChecked(!m_selectField->isEnabled());
ui->useThemeColorsCheckBox->setChecked(m_selectField->useThemeColors());
ui->placeholderLineEdit->setText(m_selectField->placeholderText());
}
void SelectFieldSettingsEditor::updateWidget()
{
m_selectField->setDisabled(ui->disabledCheckBox->isChecked());
m_selectField->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked());
m_selectField->setPlaceholderText(ui->placeholderLineEdit->text());
}
void SelectFieldSettingsEditor::selectColor()
{
QColorDialog dialog;
if (dialog.exec()) {
QColor color = dialog.selectedColor();
QString senderName = sender()->objectName();
if ("foregroundColorToolButton" == senderName) {
m_selectField->setForegroundColor(color);
ui->foregroundColorLineEdit->setText(color.name(QColor::HexRgb));
} else if ("underlineColorToolButton" == senderName) {
m_selectField->setUnderlineColor(color);
ui->underlineColorLineEdit->setText(color.name(QColor::HexRgb));
} else if ("placeholderColorToolButton" == senderName) {
m_selectField->setPlaceholderColor(color);
ui->placeholderColorLineEdit->setText(color.name(QColor::HexRgb));
} else if ("highlightedColorToolButton" == senderName) {
m_selectField->setHighlightedColor(color);
ui->highlightedColorLineEdit->setText(color.name(QColor::HexRgb));
} else if ("disabledColorToolButton" == senderName) {
m_selectField->setDisabledColor(color);
ui->disabledColorLineEdit->setText(color.name(QColor::HexRgb));
}
}
setupForm();
}

View File

@ -0,0 +1,27 @@
#ifndef SELECTFIELDSETTINGSEDITOR_H
#define SELECTFIELDSETTINGSEDITOR_H
#include <QWidget>
#include "ui_selectfieldsettingsform.h"
class QtMaterialSelectField;
class SelectFieldSettingsEditor : public QWidget
{
Q_OBJECT
public:
explicit SelectFieldSettingsEditor(QWidget *parent = 0);
~SelectFieldSettingsEditor();
protected slots:
void setupForm();
void updateWidget();
void selectColor();
private:
Ui::SelectFieldSettingsForm *const ui;
QtMaterialSelectField *const m_selectField;
};
#endif // SELECTFIELDSETTINGSEDITOR_H

View File

@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectFieldSettingsForm</class>
<widget class="QWidget" name="SelectFieldSettingsForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>388</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>202</width>
<height>253</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="disabledLabel">
<property name="text">
<string>Disabled</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disabledCheckBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="foregroundColorLabel">
<property name="text">
<string>Foreground color</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="underlineColorLabel">
<property name="text">
<string>Underline color</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="highlightedColorLabel">
<property name="text">
<string>Highlighted color</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="disabledColorLabel">
<property name="text">
<string>Disabled color</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="placeholderTextLabel">
<property name="text">
<string>Placeholder text</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="clearSelectionLabel">
<property name="text">
<string>Clear selection</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="foregroundColorLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="foregroundColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="underlineColorLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="underlineColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="highlightedColorLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="highlightedColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="disabledColorLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="disabledColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="placeholderLineEdit"/>
</item>
<item row="8" column="1">
<widget class="QToolButton" name="clearSelectionToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="useThemeColorsLabel">
<property name="text">
<string>Use theme colors</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="useThemeColorsCheckBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="placeholderColorLabel">
<property name="text">
<string>Placeholder color</string>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="placeholderColorLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="placeholderColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<zorder>formLayoutWidget</zorder>
<zorder>backgroundColorLabel</zorder>
</widget>
<resources/>
<connections/>
</ui>