Commit 32b4d470 authored by David Redondo's avatar David Redondo 🏎

Draw the entire CheckBox control via the QStyle

Instead of doing the layout ourselves just let everything be done by the style.
This also ensures the order and position of the different parts is exactly the
same. Additionally respect the icon property of a CheckBox.
parent 1b0e307b
......@@ -9,33 +9,20 @@
import QtQuick 2.6
import QtQuick.Templates @QQC2_VERSION@ as T
import QtQuick.Controls @QQC2_VERSION@
import org.kde.qqc2desktopstyle.private 1.0 as StylePrivate
import org.kde.kirigami 2.4 as Kirigami
import "private"
T.CheckBox {
id: controlRoot
@DISABLE_UNDER_QQC2_2_4@ palette: Kirigami.Theme.palette
implicitWidth: Math.max(background ? background.implicitWidth : 0,
contentItem.implicitWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0,
Math.max(contentItem.implicitHeight,
indicator ? indicator.implicitHeight : 0) + topPadding + bottomPadding)
baselineOffset: contentItem.y + contentItem.baselineOffset
spacing: indicator && typeof indicator.pixelMetric === "function" ? indicator.pixelMetric("checkboxlabelspacing") : Kirigami.Units.smallSpacing
implicitWidth: background.implicitWidth
implicitHeight: background.implicitHeight
hoverEnabled: true
indicator: CheckIndicator {
LayoutMirroring.enabled: controlRoot.mirrored
LayoutMirroring.childrenInherit: true
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
control: controlRoot
}
contentItem: Item {}
indicator: Item {}
Kirigami.MnemonicData.enabled: controlRoot.enabled && controlRoot.visible
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.ActionElement
......@@ -47,22 +34,23 @@ T.CheckBox {
onActivated: controlRoot.toggle();
}
contentItem: Label {
readonly property int indicatorEffectiveWidth: controlRoot.indicator && typeof controlRoot.indicator.pixelMetric === "function"
? controlRoot.indicator.pixelMetric("indicatorwidth") : controlRoot.indicator.width
leftPadding: controlRoot.indicator && !controlRoot.mirrored ? indicatorEffectiveWidth + controlRoot.spacing : 0
rightPadding: controlRoot.indicator && controlRoot.mirrored ? indicatorEffectiveWidth + controlRoot.spacing : 0
opacity: controlRoot.enabled ? 1 : 0.6
text: controlRoot.Kirigami.MnemonicData.richTextLabel
font: controlRoot.font
elide: Text.ElideRight
visible: controlRoot.text
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
FocusRect {
control: controlRoot
background: StylePrivate.StyleItem {
id: styleItem
anchors.fill: parent
control: controlRoot
elementType: "checkbox"
sunken: control.pressed
on: control.checked
hover: control.hovered
enabled: control.enabled
text: controlRoot.Kirigami.MnemonicData.mnemonicLabel
hasFocus: controlRoot.activeFocus
properties: {
"icon": controlRoot.icon && controlRoot.display !== T.AbstractButton.TextOnly ? (controlRoot.icon.name || controlRoot.icon.source) : "",
"iconColor": controlRoot.icon && controlRoot.icon.color.a > 0 ? controlRoot.icon.color : Kirigami.Theme.textColor,
"iconWidth": controlRoot.icon && controlRoot.icon.width ? controlRoot.icon.width : 0,
"iconHeight": controlRoot.icon && controlRoot.icon.height ? controlRoot.icon.height : 0,
"partiallyChecked": control.checkState === Qt.PartiallyChecked
}
}
}
......@@ -505,6 +505,26 @@ void KQuickStyleItem::initStyleOption()
if (m_properties.value(QStringLiteral("partiallyChecked")).toBool())
opt->state |= QStyle::State_NoChange;
opt->text = text();
const QVariant icon = m_properties[QStringLiteral("icon")];
if (icon.canConvert<QIcon>()) {
opt->icon = icon.value<QIcon>();
} else if (icon.canConvert<QUrl>() && icon.value<QUrl>().isLocalFile()) {
opt->icon = QIcon(icon.value<QUrl>().toLocalFile());
} else if (icon.canConvert<QString>()) {
opt->icon = m_theme->iconFromTheme(icon.value<QString>(), m_properties[QStringLiteral("iconColor")].value<QColor>());
}
auto iconSize = QSize(m_properties[QStringLiteral("iconWidth")].toInt(), m_properties[QStringLiteral("iconHeight")].toInt());
if (iconSize.isEmpty()) {
int e = KQuickStyleItem::style()->pixelMetric(QStyle::PM_ButtonIconSize, m_styleoption, nullptr);
if (iconSize.width() <= 0) {
iconSize.setWidth(e);
}
if (iconSize.height() <= 0) {
iconSize.setHeight(e);
}
}
opt->iconSize = iconSize;
}
break;
case Edit: {
......@@ -907,9 +927,17 @@ QSize KQuickStyleItem::sizeFromContents(int width, int height)
case RadioButton:
size = KQuickStyleItem::style()->sizeFromContents(QStyle::CT_RadioButton, m_styleoption, QSize(width,height));
break;
case CheckBox:
size = KQuickStyleItem::style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height));
case CheckBox: {
QStyleOptionButton *btn = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
QSize contentSize = btn->fontMetrics.size(Qt::TextShowMnemonic, btn->text);
QSize iconSize;
if (!btn->icon.isNull()) {
contentSize.setWidth(contentSize.width() + btn->iconSize.width());
contentSize.setHeight(std::max(contentSize.height(), btn->iconSize.height()));
}
size = KQuickStyleItem::style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, contentSize);
break;
}
case ToolBar:
size = QSize(200, styleName().contains(QLatin1String("windows")) ? 30 : 42);
break;
......
import QtQuick 2.3
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
ApplicationWindow {
height: layout.implicitHeight
width: layout.implicitWidth
ColumnLayout {
id: layout
CheckBox {
}
CheckBox {
text: "text"
}
CheckBox {
icon.name: "checkmark"
}
CheckBox {
text: "text plus icon"
icon.name: "checkmark"
}
CheckBox {
text: "focused"
focus: true
}
CheckBox {
text: "checked"
checkState: Qt.Checked
}
CheckBox {
text: "partially checked"
checkState: Qt.PartiallyChecked
tristate: true
}
CheckBox {
text: "disabled"
enabled: false
}
CheckBox {
text: "disabled and checked"
enabled: false
checkState: Qt.Checked
}
CheckBox {
text: "disabled and icon"
enabled: false
icon.name: "checkmark"
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment