♻️ refactor: f**k implicit bindings

This commit is contained in:
2026-02-27 21:02:01 +01:00
parent 37a8735c96
commit 922ecac3b0
8 changed files with 159 additions and 53 deletions
+1
View File
@@ -210,6 +210,7 @@ void WallReel::Core::Image::Model::focusOnIndex(int index) {
} }
if (m_focusedIndex != index) { if (m_focusedIndex != index) {
m_focusedIndex = index; m_focusedIndex = index;
emit focusedIndexChanged();
emit focusedImageChanged(); emit focusedImageChanged();
_updateFocusedProperties(); _updateFocusedProperties();
} }
+6 -1
View File
@@ -49,6 +49,8 @@ class Model : public QAbstractListModel {
Q_PROPERTY(int processedCount READ processedCount NOTIFY progressChanged) Q_PROPERTY(int processedCount READ processedCount NOTIFY progressChanged)
// Total count of images to be loaded, used to calculate the progress percentage // Total count of images to be loaded, used to calculate the progress percentage
Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged) Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged)
// Current index
Q_PROPERTY(int currentIndex READ focusedIndex WRITE focusOnIndex NOTIFY focusedIndexChanged)
// Sorting related properties // Sorting related properties
// How this works: // How this works:
// 1. User interact with QML control components // 1. User interact with QML control components
@@ -104,6 +106,8 @@ class Model : public QAbstractListModel {
int totalCount() const { return m_watcher.progressMaximum(); } int totalCount() const { return m_watcher.progressMaximum(); }
int focusedIndex() const { return m_focusedIndex; }
QString currentSortType() const; QString currentSortType() const;
void setCurrentSortType(const QString& type); void setCurrentSortType(const QString& type);
@@ -126,7 +130,7 @@ class Model : public QAbstractListModel {
void loadAndProcess(const QStringList& paths); void loadAndProcess(const QStringList& paths);
Q_INVOKABLE void focusOnIndex(int index); void focusOnIndex(int index);
Q_INVOKABLE void stop(); Q_INVOKABLE void stop();
@@ -146,6 +150,7 @@ class Model : public QAbstractListModel {
void isLoadingChanged(); void isLoadingChanged();
void progressChanged(); void progressChanged();
void totalCountChanged(); void totalCountChanged();
void focusedIndexChanged();
void currentSortTypeChanged(); // -> _onSortMethodChanged void currentSortTypeChanged(); // -> _onSortMethodChanged
void currentSortReverseChanged(); // -> _onSortMethodChanged void currentSortReverseChanged(); // -> _onSortMethodChanged
void focusedNameChanged(); void focusedNameChanged();
+19 -3
View File
@@ -6,7 +6,7 @@ import WallReel.UI.Components
Item { Item {
id: root id: root
required property bool actionsEnabled property bool actionsEnabled: true
property alias availablePalettes: colorCtrl.availablePalettes property alias availablePalettes: colorCtrl.availablePalettes
property alias selectedPalette: colorCtrl.selectedPalette property alias selectedPalette: colorCtrl.selectedPalette
property alias availableColors: colorCtrl.availableColors property alias availableColors: colorCtrl.availableColors
@@ -52,17 +52,33 @@ Item {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
WRTextButton { WRTextButton {
id: restoreButton
displayedText: "Restore" displayedText: "Restore"
onClicked: root.restoreClicked() onClicked: root.restoreClicked()
enabled: root.actionsEnabled
foregroundColor: "#fab387" foregroundColor: "#fab387"
Binding {
target: restoreButton
property: "enabled"
value: root.actionsEnabled
}
} }
WRTextButton { WRTextButton {
id: confirmButton
displayedText: "Confirm" displayedText: "Confirm"
onClicked: root.confirmClicked() onClicked: root.confirmClicked()
enabled: root.actionsEnabled
foregroundColor: "#a6e3a1" foregroundColor: "#a6e3a1"
Binding {
target: confirmButton
property: "enabled"
value: root.actionsEnabled
}
} }
WRTextButton { WRTextButton {
+43 -17
View File
@@ -37,8 +37,6 @@ Item {
id: paletteCombo id: paletteCombo
implicitWidth: 200 implicitWidth: 200
// -1 means nothing selected
currentIndex: -1
displayText: currentIndex < 0 ? "— palette —" : currentText displayText: currentIndex < 0 ? "— palette —" : currentText
model: root.availablePalettes.map((p) => { model: root.availablePalettes.map((p) => {
return p.name; return p.name;
@@ -46,6 +44,15 @@ Item {
onActivated: (idx) => { onActivated: (idx) => {
root.paletteSelected(idx >= 0 ? root.availablePalettes[idx] : null); root.paletteSelected(idx >= 0 ? root.availablePalettes[idx] : null);
} }
Binding {
target: paletteCombo
property: "currentIndex"
value: root.selectedPalette ? root.availablePalettes.findIndex((p) => {
return p.name === root.selectedPalette.name;
}) : -1
}
} }
ComboBox { ComboBox {
@@ -56,18 +63,24 @@ Item {
model: ["Auto"].concat(root.availableColors.map((c) => { model: ["Auto"].concat(root.availableColors.map((c) => {
return c.name; return c.name;
})) }))
currentIndex: {
if (!root.selectedColor)
return 0;
const idx = root.availableColors.findIndex((c) => {
return c.name === root.selectedColor.name;
});
return idx >= 0 ? idx + 1 : 0;
}
onActivated: (idx) => { onActivated: (idx) => {
root.colorSelected(idx === 0 ? null : root.availableColors[idx - 1]); root.colorSelected(idx === 0 ? null : root.availableColors[idx - 1]);
} }
Binding {
target: colorCombo
property: "currentIndex"
value: {
if (!root.selectedColor)
return 0;
const idx = root.availableColors.findIndex((c) => {
return c.name === root.selectedColor.name;
});
return idx >= 0 ? idx + 1 : 0;
}
}
} }
Rectangle { Rectangle {
@@ -80,14 +93,27 @@ Item {
} }
Label { Label {
font.pixelSize: 11 id: textLabel
text: {
if (root.colorHex.length > 0)
return root.colorName.length > 0 ? root.colorName + " " + root.colorHex : root.colorHex;
return root.colorName; font.pixelSize: 11
Binding {
target: textLabel
property: "text"
value: {
if (root.colorHex.length > 0)
return root.colorName.length > 0 ? root.colorName + " " + root.colorHex : root.colorHex;
return root.colorName;
}
} }
visible: root.colorName.length > 0 || root.colorHex.length > 0
Binding {
target: textLabel
property: "visible"
value: root.colorName.length > 0 || root.colorHex.length > 0
}
} }
} }
+10 -2
View File
@@ -31,8 +31,16 @@ Item {
implicitWidth: 90 implicitWidth: 90
model: root.availableSortTypes model: root.availableSortTypes
currentIndex: root.availableSortTypes.indexOf(root.selectedSortType) onActivated: (index) => {
onActivated: root.sortTypeSelected(currentText) return root.sortTypeSelected(root.availableSortTypes[index]);
}
Binding {
target: sortCombo
property: "currentIndex"
value: root.availableSortTypes.indexOf(root.selectedSortType)
}
} }
ToolButton { ToolButton {
+63 -13
View File
@@ -12,12 +12,12 @@ Item {
if (e.key === Qt.Key_Slash) { if (e.key === Qt.Key_Slash) {
topBar.requestSearchFocus(); topBar.requestSearchFocus();
} else if (e.key === Qt.Key_Left) { } else if (e.key === Qt.Key_Left) {
if (provider.currentIndex > 0) if (carousel.currentIndex > 0)
provider.currentIndex--; carousel.currentIndex--;
} else if (e.key === Qt.Key_Right) { } else if (e.key === Qt.Key_Right) {
if (provider.currentIndex < carousel.count - 1) if (carousel.currentIndex < carousel.count - 1)
provider.currentIndex++; carousel.currentIndex++;
} else if (e.key === Qt.Key_Return || e.key === Qt.Key_Enter) } else if (e.key === Qt.Key_Return || e.key === Qt.Key_Enter)
provider.confirm(); provider.confirm();
@@ -59,11 +59,9 @@ Item {
id: topBar id: topBar
Layout.fillWidth: true Layout.fillWidth: true
currentIndex: provider.currentIndex
totalCount: carousel.count totalCount: carousel.count
title: provider.focusedName title: provider.focusedName
availableSortTypes: provider.availableSortTypes availableSortTypes: provider.availableSortTypes
selectedSortType: provider.selectedSortType
isSortReverse: provider.isSortReverse isSortReverse: provider.isSortReverse
onSortTypeSelected: (t) => { onSortTypeSelected: (t) => {
return provider.setSortType(t); return provider.setSortType(t);
@@ -74,6 +72,19 @@ Item {
onSearchTextChanged: () => { onSearchTextChanged: () => {
return provider.setSearchText(topBar.searchText); return provider.setSearchText(topBar.searchText);
} }
Binding {
target: topBar
property: "currentIndex"
value: provider.currentIndex
}
Binding {
target: topBar
property: "selectedSortType"
value: provider.selectedSortType
}
} }
Carousel { Carousel {
@@ -88,7 +99,13 @@ Item {
focusedItemHeight: provider.imageHeight * provider.imageFocusScale focusedItemHeight: provider.imageHeight * provider.imageFocusScale
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (provider.currentIndex !== currentIndex) if (provider.currentIndex !== currentIndex)
provider.currentIndex = currentIndex; provider.setCurrentIndex(currentIndex);
}
Component.onCompleted: {
// Sync initial index to provider from Carousel
if (provider.currentIndex !== currentIndex)
provider.setCurrentIndex(currentIndex);
} }
@@ -129,14 +146,11 @@ Item {
} }
BottomBar { BottomBar {
id: bottomBar
Layout.fillWidth: true Layout.fillWidth: true
availablePalettes: provider.availablePalettes availablePalettes: provider.availablePalettes
selectedPalette: provider.selectedPalette
availableColors: provider.availableColors availableColors: provider.availableColors
selectedColor: provider.selectedColor
colorName: provider.colorName
colorHex: provider.colorHex
colorValue: provider.colorValue
onPaletteSelected: (p) => { onPaletteSelected: (p) => {
return provider.selectPalette(p); return provider.selectPalette(p);
} }
@@ -146,7 +160,43 @@ Item {
onRestoreClicked: provider.restore() onRestoreClicked: provider.restore()
onConfirmClicked: provider.confirm() onConfirmClicked: provider.confirm()
onCancelClicked: provider.cancel() onCancelClicked: provider.cancel()
actionsEnabled: !provider.isProcessing
Binding {
target: bottomBar
property: "selectedPalette"
value: provider.selectedPalette
}
Binding {
target: bottomBar
property: "selectedColor"
value: provider.selectedColor
}
Binding {
target: bottomBar
property: "colorName"
value: provider.colorName
}
Binding {
target: bottomBar
property: "colorHex"
value: provider.colorHex
}
Binding {
target: bottomBar
property: "colorValue"
value: provider.colorValue
}
Binding {
target: bottomBar
property: "actionsEnabled"
value: !provider.isProcessing
}
} }
} }
+7 -1
View File
@@ -19,7 +19,13 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
width: parent.width * 0.8 width: parent.width * 0.8
value: totalValue > 0 ? currentValue / totalValue : 0
Binding {
target: loadingBar
property: "value"
value: totalValue > 0 ? currentValue / totalValue : 0
}
} }
} }
+10 -16
View File
@@ -13,19 +13,19 @@ QtObject {
readonly property int imageWidth: Config.imageWidth readonly property int imageWidth: Config.imageWidth
readonly property int imageHeight: Config.imageHeight readonly property int imageHeight: Config.imageHeight
readonly property real imageFocusScale: Config.imageFocusScale readonly property real imageFocusScale: Config.imageFocusScale
// Shared carousel selection state // Carousel selection state
property int currentIndex: 0 readonly property int currentIndex: ImageModel.currentIndex
// Image name // Image name
readonly property string focusedName: ImageModel.focusedName readonly property string focusedName: ImageModel.focusedName
//// Sort //// Sort
readonly property var availableSortTypes: ["None", "Name", "Date", "Size"] readonly property var availableSortTypes: ["None", "Name", "Date", "Size"]
property string selectedSortType: ImageModel.currentSortType readonly property string selectedSortType: ImageModel.currentSortType
property bool isSortReverse: ImageModel.currentSortReverse readonly property bool isSortReverse: ImageModel.currentSortReverse
//// Palette / Color //// Palette / Color
readonly property var availablePalettes: PaletteManager.availablePalettes readonly property var availablePalettes: PaletteManager.availablePalettes
property var selectedPalette: PaletteManager.selectedPalette // PaletteItem | null readonly property var selectedPalette: PaletteManager.selectedPalette // PaletteItem | null
readonly property var availableColors: selectedPalette ? selectedPalette.colors : [] readonly property var availableColors: selectedPalette ? selectedPalette.colors : []
property var selectedColor: PaletteManager.selectedColor // ColorItem | null (null means "auto") readonly property var selectedColor: PaletteManager.selectedColor // ColorItem | null (null means "auto")
readonly property string colorName: PaletteManager.colorName readonly property string colorName: PaletteManager.colorName
readonly property string colorHex: PaletteManager.color readonly property string colorHex: PaletteManager.color
readonly property color colorValue: PaletteManager.color readonly property color colorValue: PaletteManager.color
@@ -45,6 +45,10 @@ QtObject {
ServiceManager.cancel(); ServiceManager.cancel();
} }
function setCurrentIndex(index) {
ImageModel.currentIndex = index;
}
function focusSearch() { function focusSearch() {
searchBar.requestFocus(); searchBar.requestFocus();
} }
@@ -72,14 +76,4 @@ QtObject {
} }
onCurrentIndexChanged: () => {
if (!isLoading)
ImageModel.focusOnIndex(currentIndex);
}
Component.onCompleted: () => {
if (!isLoading)
ImageModel.focusOnIndex(currentIndex);
}
} }