209 lines
6.9 KiB
QML
209 lines
6.9 KiB
QML
import QtQuick 2.9
|
|
import QtQuick.Controls 2.2
|
|
import QtQuick.Layouts 1.3
|
|
import RustCode 1.0;
|
|
|
|
ApplicationWindow {
|
|
visible: true
|
|
width: 450
|
|
height: 580
|
|
header: ToolBar {
|
|
Label {
|
|
anchors.fill: parent
|
|
text: qsTr("todos")
|
|
font.pixelSize: 30
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
input.forceActiveFocus()
|
|
}
|
|
|
|
Todos {
|
|
id: todoModel
|
|
|
|
Component.onCompleted: {
|
|
add("write bindings.json")
|
|
add("run rust_qt_binding_generator")
|
|
add("check bindings.h")
|
|
add("check bindings.cpp")
|
|
add("check interface.rs")
|
|
add("write implementation.rs")
|
|
add("write main.qml")
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: todoDelegate
|
|
RowLayout {
|
|
// the active tab determines if this item should be shown
|
|
// 0: all, 1: active, 2: completed
|
|
property bool show: filter.currentIndex === 0
|
|
|| (filter.currentIndex === 1 && !completed)
|
|
|| (filter.currentIndex === 2 && completed)
|
|
visible: show
|
|
width: parent.width
|
|
height: show ? implicitHeight : 0
|
|
CheckBox {
|
|
checked: completed
|
|
onToggled: todoModel.setCompleted(index, checked)
|
|
}
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Label {
|
|
id: label
|
|
visible: !editInput.visible
|
|
text: description
|
|
anchors.fill: parent
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.strikeout: completed
|
|
font.pixelSize: 20
|
|
}
|
|
MouseArea {
|
|
id: mouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onDoubleClicked: {
|
|
editInput.text = label.text
|
|
editInput.visible = true
|
|
editInput.forceActiveFocus()
|
|
}
|
|
}
|
|
Button {
|
|
text: 'X'
|
|
visible: (mouse.containsMouse && !editInput.visible)
|
|
|| closeMouse.containsMouse
|
|
anchors.right: parent.right
|
|
MouseArea {
|
|
id: closeMouse
|
|
anchors.fill: parent
|
|
hoverEnabled: true
|
|
onClicked: todoModel.remove(index)
|
|
}
|
|
}
|
|
TextField {
|
|
id: editInput
|
|
visible: false
|
|
anchors.fill: parent
|
|
text: description
|
|
font.pixelSize: label.font.pixelSize
|
|
onAccepted: {
|
|
todoModel.setDescription(index, text)
|
|
visible = false
|
|
}
|
|
onActiveFocusChanged: {
|
|
// hide when focus is lost
|
|
if (!activeFocus) {
|
|
visible = false
|
|
}
|
|
}
|
|
Keys.onPressed: {
|
|
// on escape, set value, hide (and lose focus)
|
|
if (event.key === Qt.Key_Escape) {
|
|
todoModel.setDescription(index, text)
|
|
visible = false
|
|
event.accepted = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Pane {
|
|
anchors.fill: parent
|
|
leftPadding: 0
|
|
Page {
|
|
anchors.fill: parent
|
|
header: RowLayout {
|
|
CheckBox {
|
|
tristate: true
|
|
// if there are no todos, do not show this checkbox
|
|
// but let it take up the same space
|
|
enabled: todoModel.count > 0
|
|
opacity: todoModel.count === 0 ? 0 : 1
|
|
checkState: {
|
|
if (todoModel.activeCount === 0) {
|
|
return Qt.Checked
|
|
} else if (todoModel.activeCount >= todoModel.count) {
|
|
return Qt.Unchecked
|
|
}
|
|
return Qt.PartiallyChecked
|
|
}
|
|
onCheckStateChanged: {
|
|
// if the change is triggered by a user action on this
|
|
// checkbox, check or uncheck all todos
|
|
// otherwise, do nothing
|
|
// (onToggle does not emit for tristate buttons)
|
|
if (activeFocus) {
|
|
var checked = checkState !== Qt.Unchecked
|
|
todoModel.setAll(checked)
|
|
}
|
|
}
|
|
}
|
|
TextField {
|
|
id: input
|
|
Layout.fillWidth: true
|
|
placeholderText: qsTr("What needs to be done?")
|
|
onAccepted: {
|
|
const todo = text.trim()
|
|
if (todo) {
|
|
todoModel.add(todo)
|
|
}
|
|
input.clear()
|
|
}
|
|
}
|
|
}
|
|
Flickable {
|
|
anchors.fill: parent
|
|
ListView {
|
|
anchors.fill: parent
|
|
model: todoModel
|
|
delegate: todoDelegate
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
footer: Pane {
|
|
padding: 0
|
|
ColumnLayout {
|
|
width: parent.width
|
|
TabBar {
|
|
id: filter
|
|
Layout.fillWidth: true
|
|
visible: todoModel.count > 0
|
|
TabButton {
|
|
text: qsTr("All")
|
|
checked: true
|
|
}
|
|
TabButton {
|
|
text: qsTr("Active")
|
|
}
|
|
TabButton {
|
|
text: qsTr("Completed")
|
|
}
|
|
}
|
|
RowLayout {
|
|
visible: todoModel.count > 0
|
|
width: parent.width
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: (todoModel.activeCount === 1)
|
|
? qsTr("1 item left")
|
|
: todoModel.activeCount + qsTr(" items left")
|
|
}
|
|
Button {
|
|
enabled: todoModel.count > todoModel.activeCount
|
|
opacity: enabled
|
|
text: qsTr("Clear completed")
|
|
onClicked: todoModel.clearCompleted()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|