Skip to content

Commit

Permalink
Merge pull request #22 from korapp/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
korapp authored Feb 13, 2024
2 parents 159aaf3 + 83f4017 commit 228a32a
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 65 deletions.
14 changes: 9 additions & 5 deletions package/contents/ui/ConfigGeneral.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ Kirigami.FormLayout {
id: url
editable: true
onModelChanged: currentIndex = indexOfValue(cfg_url)
onFocusChanged: !focus && onValueChanged(editText)
onActivated: onValueChanged(editText)
onActiveFocusChanged: !activeFocus && setValue(editText)
onHoveredChanged: !hovered && setValue(editText)
onEditTextChanged: editText !== cfg_url && configurationChanged()
onActivated: {
secrets.restore(editText)
setValue(editText)
}
Kirigami.FormData.label: i18n("Home Assistant URL")
Layout.fillWidth: true

function onValueChanged(value) {
cfg_url = value
secrets.restore(editText)
function setValue(value) {
cfg_url = editText = value ? value.replace(/\s+|\/+\s*$/g,'') : ''
}
}

Expand Down
19 changes: 9 additions & 10 deletions package/contents/ui/ConfigItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@ import QtQuick.Controls 2.0

import org.kde.kirigami 2.4 as Kirigami

import "components"

Kirigami.FormLayout {
property var item
readonly property var source: item.entity_id && entities[item.entity_id] || {}

ComboBox {
model: Object.keys(entities).sort()
editable: true
currentIndex: -1
TextField {
Kirigami.FormData.label: i18n("Entity")
Component.onCompleted: {
editText = item.entity_id
currentIndex = model.indexOf(editText)
}
onCurrentTextChanged: {
item.entity_id = currentText
text: item.entity_id
onEditingFinished: {
item.entity_id = text
item = item
}
Autocompletion {
model: Object.keys(entities).sort()
}
}

ComboBox {
Expand Down
106 changes: 56 additions & 50 deletions package/contents/ui/ConfigItems.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ import QtQuick 2.0
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.0

import org.kde.kirigami 2.4 as Kirigami
import org.kde.kirigami 2.5 as Kirigami

import "../code/model.mjs" as Model
import "."

ColumnLayout {
property string cfg_items
property var items: JSON.parse(cfg_items)
property ListModel items: ListModel { dynamicRoles: true }
property var services: ({})
property var entities: ({})
property bool busy: true
property Client ha

Component.onCompleted: {
items.append(JSON.parse(cfg_items))
ha = ClientFactory.getClient(this, plasmoid.configuration.url)
ha.ready.connect(fetchData)
}
Expand Down Expand Up @@ -44,8 +45,13 @@ ColumnLayout {
ListView {
id: itemList
model: Object.keys(entities).length ? items : []
delegate: listItem
spacing: Kirigami.Units.mediumSpacing
delegate: Kirigami.DelegateRecycler {
width: itemList.width
sourceComponent: listItemComponent
}
moveDisplaced: Transition {
NumberAnimation { properties: "y"; duration: Kirigami.Units.longDuration }
}

BusyIndicator {
anchors.centerIn: parent
Expand All @@ -63,42 +69,44 @@ ColumnLayout {
}

Component {
id: listItem
RowLayout {
width: ListView.view.width
DynamicIcon {
name: modelData.icon || entities[modelData.entity_id].attributes.icon || ''
Layout.preferredWidth: parent.height
}
Column {
Label {
text: modelData.name || entities[modelData.entity_id].attributes.friendly_name
id: listItemComponent
Kirigami.SwipeListItem {
id: listItem
readonly property var entity: entities[model.entity_id]
RowLayout {
Kirigami.ListItemDragHandle {
listItem: listItem
listView: itemList
onMoveRequested: items.move(oldIndex, newIndex, 1)
onDropped: save()
}
Label {
text: modelData.entity_id
font: Kirigami.Theme.smallFont
opacity: 0.6
DynamicIcon {
name: model.icon || (entity && entity.attributes.icon) || ''
Layout.preferredWidth: parent.height
Layout.preferredHeight: parent.height
}
Column {
Label {
text: model.name || (entity && entity.attributes.friendly_name) || 'Unknown'
}
Label {
text: model.entity_id
font: Kirigami.Theme.smallFont
opacity: 0.6
}
Layout.fillWidth: true
}
Layout.fillWidth: true
}
ToolButton {
icon.name: 'arrow-up'
enabled: index > 0
onClicked: swapItems(index, index - 1)
}
ToolButton {
icon.name: 'arrow-down'
enabled: index < items.length - 1
onClicked: swapItems(index, index + 1)
}
ToolButton {
icon.name: 'edit-entry'
onClicked: openDialog(new Model.ConfigEntity(modelData), index)
}
ToolButton {
icon.name: 'delete'
onClicked: removeItem(index)
}
actions: [
Kirigami.Action {
iconName: 'edit-entry'
onTriggered: openDialog(new Model.ConfigEntity(model), index)
},
Kirigami.Action {
icon.name: 'delete'
onTriggered: removeItem(index)
}
]
}
}

Expand All @@ -109,11 +117,13 @@ ColumnLayout {
property int index
property var item
signal accepted(int index, var item)
readonly property bool acceptable: !!contentItem.item.entity_id

footer: DialogButtonBox {
standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
onRejected: dialog.close()
onAccepted: dialog.accepted(index, item) || dialog.close()
Component.onCompleted: standardButton(DialogButtonBox.Ok).enabled = Qt.binding(() => acceptable)
}

contentItem: ConfigItem {
Expand All @@ -131,38 +141,34 @@ ColumnLayout {
dialog.open()
dialog.onAccepted.connect((index, item) => {
if (~index) {
return updateItem(item, index)
return updateItem(item.toJSON(), index)
}
return addItem(item)
return addItem(item.toJSON())
})
}

function save() {
cfg_items = JSON.stringify(items, (key, value) => value || undefined)
}

function swapItems(index1, index2) {
if (index1 < 0 || index2 < 0 || index1 > items.length || index2 > items.length) {
return
const array = []
for (let i = 0; i < items.count; i++) {
array.push(items.get(i))
}
[items[index2], items[index1]] = [items[index1], items[index2]]
save()
cfg_items = JSON.stringify(array, (key, value) => value || undefined)
}

function removeItem(index) {
if (index >= items.length || index < 0) return
items.splice(index, 1)
items.remove(index)
save()
}

function addItem(item) {
items.push(item)
items.append(item)
save()
}

function updateItem(item, index) {
if (index >= items.length || index < 0) return
items[index] = item
items.set(index, item)
save()
}

Expand Down
49 changes: 49 additions & 0 deletions package/contents/ui/components/Autocompletion.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import QtQuick 2.7
import QtQuick.Controls 2.5

Popup {
property TextField target: parent
property var model

function getModel() {
return model.filter(i => textMaches(i, target.text))
}

function textMaches(text, search) {
return !!text && text.toLowerCase().includes(search.toLowerCase())
}

function accept(index) {
if (~index) target.text = list.model[index]
close()
}

onTargetChanged: {
if (!target) return
target.pressed.connect(open)
target.accepted.connect(() => accept(list.currentIndex))
target.Keys.onUpPressed.connect(list.decrementCurrentIndex)
target.Keys.onDownPressed.connect(list.incrementCurrentIndex)
target.Keys.onTabPressed.connect(() => list.count && (target.text = list.model[list.currentIndex || 0]))
}

y: target.height
width: target.width
padding: 1
height: Math.min(contentItem.contentHeight + verticalPadding * 2, target.parent.height - y - target.y)
onClosed: target.focus = false

contentItem: ScrollView {
ListView {
id: list
model: visible ? getModel() : null
highlightMoveDuration: 0
delegate: ItemDelegate {
width: ListView.view.width
text: modelData
highlighted: ListView.isCurrentItem
onClicked: accept(index)
}
}
}
}

0 comments on commit 228a32a

Please sign in to comment.