refactor: extract image selection logic into dedicated helper

Introduces a new ImagePicker helper that consolidates duplicate wallpaper
selection logic from Hyprpaper.cpp and ConfigManager.cpp into a single
reusable function.

- Add new ImagePicker.{hpp,cpp} with getRandomImageFromDirectory() helper
- Function handles directory scanning, file extension validation, and random selection
- Supports excluding current wallpaper to avoid duplicate selections
- Updates both wallpaper loading code paths to use the new helper
- Uses std::shuffle instead of random index for better randomization

This change improves code maintainability by removing duplicate logic and
centralizing image selection behavior in a single location.
This commit is contained in:
y0usaf 2025-02-04 16:11:01 -05:00
parent 9f59bf577b
commit f04fb592a1
4 changed files with 49 additions and 33 deletions

View file

@ -4,6 +4,7 @@
#include <signal.h>
#include <sys/types.h>
#include "helpers/RandomGenerator.hpp"
#include "helpers/ImagePicker.hpp"
CHyprpaper::CHyprpaper() = default;
@ -180,21 +181,13 @@ void CHyprpaper::preloadAllWallpapersFromConfig() {
unloadWallpaper(path);
}
std::vector<std::filesystem::path> images;
for (auto& entry : std::filesystem::directory_iterator(wp)) {
if (entry.is_regular_file()) {
auto ext = entry.path().extension().string();
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".jxl")
images.push_back(entry.path());
}
}
if (!images.empty()) {
// Use CRandomGenerator instead
wp = images[CRandomGenerator::get().getRandomIndex(images.size())].string();
} else {
// Use our helper to pick a random image.
std::string randomImage = getRandomImageFromDirectory(wp);
if (randomImage.empty()) {
Debug::log(LOG, "No valid images in directory {}", wp);
continue;
}
wp = randomImage;
}
// For non-directory requests, skip if already loaded.

View file

@ -3,6 +3,7 @@
#include <hyprutils/path/Path.hpp>
#include <filesystem>
#include "../helpers/RandomGenerator.hpp"
#include "../helpers/ImagePicker.hpp"
// Utility function to safely expand a tilde at the beginning of a path.
static std::string expandTilde(const std::string& path) {
@ -61,28 +62,13 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
}
}
std::vector<std::filesystem::path> images;
for (auto& entry : std::filesystem::directory_iterator(WALLPAPER)) {
if (entry.is_regular_file()) {
auto ext = entry.path().extension().string();
if (ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".jxl") {
if (entry.path().string() != currentWallpaper) {
images.push_back(entry.path());
}
}
}
// Use our helper with an exclusion to avoid reselecting the same image.
std::string randomImage = getRandomImageFromDirectory(WALLPAPER, currentWallpaper);
if (randomImage.empty()) {
result.setError("No valid images in directory");
return result;
}
if (images.empty()) {
if (!currentWallpaper.empty()) {
images.push_back(currentWallpaper);
} else {
result.setError("No valid images in directory");
return result;
}
}
WALLPAPER = images[CRandomGenerator::get().getRandomIndex(images.size())].string();
WALLPAPER = randomImage;
}
if (!g_pHyprpaper->isPreloaded(WALLPAPER)) {

View file

@ -0,0 +1,30 @@
#include "ImagePicker.hpp"
#include "RandomGenerator.hpp"
#include <filesystem>
#include <vector>
#include <algorithm>
std::string getRandomImageFromDirectory(const std::string &dirPath, const std::string &ignore) {
std::vector<std::filesystem::path> images;
for (const auto &entry : std::filesystem::directory_iterator(dirPath)) {
if (entry.is_regular_file()) {
auto ext = entry.path().extension().string();
if ((ext == ".png" || ext == ".jpg" || ext == ".jpeg" ||
ext == ".webp" || ext == ".jxl")) {
if (ignore.empty() || entry.path().string() != ignore) {
images.push_back(entry.path());
}
}
}
}
if (images.empty()) {
// If no alternative was found but the ignored file exists, return it.
if (!ignore.empty() && std::filesystem::exists(ignore))
return ignore;
return "";
}
std::shuffle(images.begin(), images.end(), CRandomGenerator::get().getGenerator());
return images.front().string();
}

View file

@ -0,0 +1,7 @@
#pragma once
#include <string>
// Returns a random image path from the given directory.
// If 'ignore' is provided, that file (if present) will be excluded from the selection.
// Returns an empty string if no valid image is found.
std::string getRandomImageFromDirectory(const std::string &dirPath, const std::string &ignore = "");