diff --git a/WallReel/Core/Image/model.cpp b/WallReel/Core/Image/model.cpp index c71ea49..f760c87 100644 --- a/WallReel/Core/Image/model.cpp +++ b/WallReel/Core/Image/model.cpp @@ -210,6 +210,7 @@ void WallReel::Core::Image::Model::focusOnIndex(int index) { } if (m_focusedIndex != index) { m_focusedIndex = index; + emit focusedIndexChanged(); emit focusedImageChanged(); _updateFocusedProperties(); } diff --git a/WallReel/Core/Image/model.hpp b/WallReel/Core/Image/model.hpp index a34f494..974dd86 100644 --- a/WallReel/Core/Image/model.hpp +++ b/WallReel/Core/Image/model.hpp @@ -49,6 +49,8 @@ class Model : public QAbstractListModel { Q_PROPERTY(int processedCount READ processedCount NOTIFY progressChanged) // Total count of images to be loaded, used to calculate the progress percentage Q_PROPERTY(int totalCount READ totalCount NOTIFY totalCountChanged) + // Current index + Q_PROPERTY(int currentIndex READ focusedIndex WRITE focusOnIndex NOTIFY focusedIndexChanged) // Sorting related properties // How this works: // 1. User interact with QML control components @@ -104,6 +106,8 @@ class Model : public QAbstractListModel { int totalCount() const { return m_watcher.progressMaximum(); } + int focusedIndex() const { return m_focusedIndex; } + QString currentSortType() const; void setCurrentSortType(const QString& type); @@ -126,7 +130,7 @@ class Model : public QAbstractListModel { void loadAndProcess(const QStringList& paths); - Q_INVOKABLE void focusOnIndex(int index); + void focusOnIndex(int index); Q_INVOKABLE void stop(); @@ -146,6 +150,7 @@ class Model : public QAbstractListModel { void isLoadingChanged(); void progressChanged(); void totalCountChanged(); + void focusedIndexChanged(); void currentSortTypeChanged(); // -> _onSortMethodChanged void currentSortReverseChanged(); // -> _onSortMethodChanged void focusedNameChanged(); diff --git a/WallReel/UI/Modules/BottomBar.qml b/WallReel/UI/Modules/BottomBar.qml index 7417a0f..1117fe6 100644 --- a/WallReel/UI/Modules/BottomBar.qml +++ b/WallReel/UI/Modules/BottomBar.qml @@ -6,7 +6,7 @@ import WallReel.UI.Components Item { id: root - required property bool actionsEnabled + property bool actionsEnabled: true property alias availablePalettes: colorCtrl.availablePalettes property alias selectedPalette: colorCtrl.selectedPalette property alias availableColors: colorCtrl.availableColors @@ -52,17 +52,33 @@ Item { Layout.alignment: Qt.AlignVCenter WRTextButton { + id: restoreButton + displayedText: "Restore" onClicked: root.restoreClicked() - enabled: root.actionsEnabled foregroundColor: "#fab387" + + Binding { + target: restoreButton + property: "enabled" + value: root.actionsEnabled + } + } WRTextButton { + id: confirmButton + displayedText: "Confirm" onClicked: root.confirmClicked() - enabled: root.actionsEnabled foregroundColor: "#a6e3a1" + + Binding { + target: confirmButton + property: "enabled" + value: root.actionsEnabled + } + } WRTextButton { diff --git a/WallReel/UI/Modules/ColorControl.qml b/WallReel/UI/Modules/ColorControl.qml index 5ffda49..114548f 100644 --- a/WallReel/UI/Modules/ColorControl.qml +++ b/WallReel/UI/Modules/ColorControl.qml @@ -37,8 +37,6 @@ Item { id: paletteCombo implicitWidth: 200 - // -1 means nothing selected - currentIndex: -1 displayText: currentIndex < 0 ? "— palette —" : currentText model: root.availablePalettes.map((p) => { return p.name; @@ -46,6 +44,15 @@ Item { onActivated: (idx) => { 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 { @@ -56,18 +63,24 @@ Item { model: ["Auto"].concat(root.availableColors.map((c) => { 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) => { 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 { @@ -80,14 +93,27 @@ Item { } Label { - font.pixelSize: 11 - text: { - if (root.colorHex.length > 0) - return root.colorName.length > 0 ? root.colorName + " " + root.colorHex : root.colorHex; + id: textLabel - 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 + } + } } diff --git a/WallReel/UI/Modules/SortControl.qml b/WallReel/UI/Modules/SortControl.qml index 4276f0b..369e490 100644 --- a/WallReel/UI/Modules/SortControl.qml +++ b/WallReel/UI/Modules/SortControl.qml @@ -31,8 +31,16 @@ Item { implicitWidth: 90 model: root.availableSortTypes - currentIndex: root.availableSortTypes.indexOf(root.selectedSortType) - onActivated: root.sortTypeSelected(currentText) + onActivated: (index) => { + return root.sortTypeSelected(root.availableSortTypes[index]); + } + + Binding { + target: sortCombo + property: "currentIndex" + value: root.availableSortTypes.indexOf(root.selectedSortType) + } + } ToolButton { diff --git a/WallReel/UI/Pages/CarouselScreen.qml b/WallReel/UI/Pages/CarouselScreen.qml index 85c7105..3f82293 100644 --- a/WallReel/UI/Pages/CarouselScreen.qml +++ b/WallReel/UI/Pages/CarouselScreen.qml @@ -12,12 +12,12 @@ Item { if (e.key === Qt.Key_Slash) { topBar.requestSearchFocus(); } else if (e.key === Qt.Key_Left) { - if (provider.currentIndex > 0) - provider.currentIndex--; + if (carousel.currentIndex > 0) + carousel.currentIndex--; } else if (e.key === Qt.Key_Right) { - if (provider.currentIndex < carousel.count - 1) - provider.currentIndex++; + if (carousel.currentIndex < carousel.count - 1) + carousel.currentIndex++; } else if (e.key === Qt.Key_Return || e.key === Qt.Key_Enter) provider.confirm(); @@ -59,11 +59,9 @@ Item { id: topBar Layout.fillWidth: true - currentIndex: provider.currentIndex totalCount: carousel.count title: provider.focusedName availableSortTypes: provider.availableSortTypes - selectedSortType: provider.selectedSortType isSortReverse: provider.isSortReverse onSortTypeSelected: (t) => { return provider.setSortType(t); @@ -74,6 +72,19 @@ Item { onSearchTextChanged: () => { return provider.setSearchText(topBar.searchText); } + + Binding { + target: topBar + property: "currentIndex" + value: provider.currentIndex + } + + Binding { + target: topBar + property: "selectedSortType" + value: provider.selectedSortType + } + } Carousel { @@ -88,7 +99,13 @@ Item { focusedItemHeight: provider.imageHeight * provider.imageFocusScale onCurrentIndexChanged: { 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 { + id: bottomBar + Layout.fillWidth: true availablePalettes: provider.availablePalettes - selectedPalette: provider.selectedPalette availableColors: provider.availableColors - selectedColor: provider.selectedColor - colorName: provider.colorName - colorHex: provider.colorHex - colorValue: provider.colorValue onPaletteSelected: (p) => { return provider.selectPalette(p); } @@ -146,7 +160,43 @@ Item { onRestoreClicked: provider.restore() onConfirmClicked: provider.confirm() 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 + } + } } diff --git a/WallReel/UI/Pages/LoadingScreen.qml b/WallReel/UI/Pages/LoadingScreen.qml index 6d02bf7..2c00139 100644 --- a/WallReel/UI/Pages/LoadingScreen.qml +++ b/WallReel/UI/Pages/LoadingScreen.qml @@ -19,7 +19,13 @@ Item { anchors.centerIn: parent width: parent.width * 0.8 - value: totalValue > 0 ? currentValue / totalValue : 0 + + Binding { + target: loadingBar + property: "value" + value: totalValue > 0 ? currentValue / totalValue : 0 + } + } } diff --git a/WallReel/UI/Providers/CarouselProvider.qml b/WallReel/UI/Providers/CarouselProvider.qml index a116dc9..118db0f 100644 --- a/WallReel/UI/Providers/CarouselProvider.qml +++ b/WallReel/UI/Providers/CarouselProvider.qml @@ -13,19 +13,19 @@ QtObject { readonly property int imageWidth: Config.imageWidth readonly property int imageHeight: Config.imageHeight readonly property real imageFocusScale: Config.imageFocusScale - // Shared carousel selection state - property int currentIndex: 0 + // Carousel selection state + readonly property int currentIndex: ImageModel.currentIndex // Image name readonly property string focusedName: ImageModel.focusedName //// Sort readonly property var availableSortTypes: ["None", "Name", "Date", "Size"] - property string selectedSortType: ImageModel.currentSortType - property bool isSortReverse: ImageModel.currentSortReverse + readonly property string selectedSortType: ImageModel.currentSortType + readonly property bool isSortReverse: ImageModel.currentSortReverse //// Palette / Color 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 : [] - 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 colorHex: PaletteManager.color readonly property color colorValue: PaletteManager.color @@ -45,6 +45,10 @@ QtObject { ServiceManager.cancel(); } + function setCurrentIndex(index) { + ImageModel.currentIndex = index; + } + function focusSearch() { searchBar.requestFocus(); } @@ -72,14 +76,4 @@ QtObject { } - onCurrentIndexChanged: () => { - if (!isLoading) - ImageModel.focusOnIndex(currentIndex); - - } - Component.onCompleted: () => { - if (!isLoading) - ImageModel.focusOnIndex(currentIndex); - - } }