mirror of
https://github.com/anufrievroman/waypaper.git
synced 2024-11-22 15:46:39 +03:00
Adding options menu
This creates a more compact menu, and also addresse partly issue #41
This commit is contained in:
parent
8b197a7141
commit
e20290e683
2
setup.py
2
setup.py
@ -18,7 +18,7 @@ setuptools.setup(
|
||||
]
|
||||
},
|
||||
install_requires=["PyGObject", "importlib_metadata", "platformdirs", "Pillow"],
|
||||
version='2.1.3',
|
||||
version='2.2',
|
||||
python_requires='>3.9',
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
|
@ -94,12 +94,6 @@ class App(Gtk.Window):
|
||||
self.grid.set_column_spacing(0)
|
||||
self.scrolled_window.add(self.grid)
|
||||
|
||||
# Create subfolder toggle:
|
||||
self.include_subfolders_checkbox = Gtk.ToggleButton(label=self.txt.msg_subfolders)
|
||||
self.include_subfolders_checkbox.set_active(self.cf.include_subfolders)
|
||||
self.include_subfolders_checkbox.connect("toggled", self.on_include_subfolders_toggled)
|
||||
self.include_subfolders_checkbox.set_tooltip_text(self.txt.tip_subfolder)
|
||||
|
||||
# Create a backend dropdown menu:
|
||||
self.backend_option_combo = Gtk.ComboBoxText()
|
||||
for backend in self.cf.installed_backends:
|
||||
@ -140,7 +134,6 @@ class App(Gtk.Window):
|
||||
self.sort_option_combo.connect("changed", self.on_sort_option_changed)
|
||||
self.sort_option_combo.set_tooltip_text(self.txt.tip_sorting)
|
||||
|
||||
|
||||
# Create exit button:
|
||||
self.exit_button = Gtk.Button(label=self.txt.msg_exit)
|
||||
self.exit_button.connect("clicked", self.on_exit_clicked)
|
||||
@ -173,12 +166,16 @@ class App(Gtk.Window):
|
||||
# Create a monitor option dropdown menu:
|
||||
self.monitor_option_combo = Gtk.ComboBoxText()
|
||||
|
||||
# Create the options menu button:
|
||||
self.options_button = Gtk.Button(label="Options")
|
||||
self.options_button.connect("clicked", self.on_options_button_clicked)
|
||||
|
||||
# Create a horizontal box for display option and exit button:
|
||||
self.options_box = Gtk.HBox(spacing=10)
|
||||
self.options_box.pack_end(self.exit_button, False, False, 0)
|
||||
self.options_box.pack_end(self.options_button, False, False, 0)
|
||||
self.options_box.pack_end(self.refresh_button, False, False, 0)
|
||||
self.options_box.pack_end(self.random_button, False, False, 0)
|
||||
self.options_box.pack_end(self.include_subfolders_checkbox, False, False, 0)
|
||||
self.options_box.pack_end(self.sort_option_combo, False, False, 0)
|
||||
self.options_box.pack_end(self.color_picker_button, False, False, 0)
|
||||
self.options_box.pack_end(self.fill_option_combo, False, False, 0)
|
||||
@ -192,6 +189,37 @@ class App(Gtk.Window):
|
||||
self.show_all()
|
||||
|
||||
|
||||
def create_menu(self):
|
||||
"""Create a GTK menu and items inside it"""
|
||||
self.menu = Gtk.Menu()
|
||||
|
||||
# Create gifs toggle:
|
||||
self.filter_gifs_checkbox = Gtk.CheckMenuItem(label=self.txt.msg_gifs)
|
||||
self.filter_gifs_checkbox.set_active(self.cf.show_gifs_only)
|
||||
self.filter_gifs_checkbox.connect("toggled", self.on_filter_gifs_toggled)
|
||||
|
||||
# Create subfolder toggle:
|
||||
self.include_subfolders_checkbox = Gtk.CheckMenuItem(label=self.txt.msg_subfolders)
|
||||
self.include_subfolders_checkbox.set_active(self.cf.include_subfolders)
|
||||
self.include_subfolders_checkbox.connect("toggled", self.on_include_subfolders_toggled)
|
||||
|
||||
# Create hidden toggle:
|
||||
self.include_hidden_checkbox = Gtk.CheckMenuItem(label=self.txt.msg_hidden)
|
||||
self.include_hidden_checkbox.set_active(self.cf.show_hidden)
|
||||
self.include_hidden_checkbox.connect("toggled", self.on_hidden_files_toggled)
|
||||
|
||||
self.menu.append(self.filter_gifs_checkbox)
|
||||
self.menu.append(self.include_subfolders_checkbox)
|
||||
self.menu.append(self.include_hidden_checkbox)
|
||||
self.menu.show_all()
|
||||
|
||||
|
||||
def on_options_button_clicked(self, widget):
|
||||
'''Position the menu at the button and show it'''
|
||||
self.create_menu()
|
||||
self.menu.popup_at_widget(widget, Gdk.Gravity.NORTH, Gdk.Gravity.SOUTH, None)
|
||||
|
||||
|
||||
def monitor_option_display(self):
|
||||
"""Display monitor option if backend is swww"""
|
||||
self.options_box.remove(self.monitor_option_combo)
|
||||
@ -257,7 +285,8 @@ class App(Gtk.Window):
|
||||
def process_images(self):
|
||||
"""Load images from the selected folder, resize them, and arrange into a grid"""
|
||||
|
||||
self.image_paths = get_image_paths(self.cf.backend, self.cf.image_folder, self.cf.include_subfolders, self.cf.show_hidden, depth=1)
|
||||
self.image_paths = get_image_paths(self.cf.backend, self.cf.image_folder, self.cf.include_subfolders,
|
||||
self.cf.show_hidden, self.cf.show_gifs_only, depth=1)
|
||||
self.sort_images()
|
||||
|
||||
# Show caching label:
|
||||
@ -338,7 +367,6 @@ class App(Gtk.Window):
|
||||
|
||||
def choose_folder(self):
|
||||
"""Choosing the folder of images, saving the path, and reloading images"""
|
||||
|
||||
dialog = Gtk.FileChooserDialog(
|
||||
self.txt.msg_choosefolder, self, Gtk.FileChooserAction.SELECT_FOLDER,
|
||||
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, self.txt.msg_select, Gtk.ResponseType.OK)
|
||||
@ -356,12 +384,36 @@ class App(Gtk.Window):
|
||||
self.cf.save()
|
||||
|
||||
|
||||
def on_filter_gifs_toggled(self, toggle):
|
||||
"""Toggle only gifs checkbox via menu"""
|
||||
self.cf.show_gifs_only = toggle.get_active()
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def on_include_subfolders_toggled(self, toggle):
|
||||
"""On chosing to include subfolders"""
|
||||
"""Toggle subfolders visibility via menu"""
|
||||
self.cf.include_subfolders = toggle.get_active()
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def toggle_include_subfolders(self):
|
||||
"""Toggle subfolders visibility via key"""
|
||||
self.cf.include_subfolders = not self.cf.include_subfolders
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def on_hidden_files_toggled(self, toggle):
|
||||
"""Toggle visibility of hidden files via menu"""
|
||||
self.cf.show_hidden = toggle.get_active()
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def toggle_hidden_files(self):
|
||||
"""Toggle visibility of hidden files via keys"""
|
||||
self.cf.show_hidden = not self.cf.show_hidden
|
||||
threading.Thread(target=self.process_images).start()
|
||||
|
||||
|
||||
def on_fill_option_changed(self, combo):
|
||||
"""Save fill parameter when it was changed"""
|
||||
self.cf.fill_option = combo.get_active_text()
|
||||
@ -436,13 +488,6 @@ class App(Gtk.Window):
|
||||
self.cf.save()
|
||||
|
||||
|
||||
def toggle_hidden_files(self):
|
||||
"""Toggle visibility of hidden files"""
|
||||
self.cf.show_hidden = not self.cf.show_hidden
|
||||
threading.Thread(target=self.process_images).start()
|
||||
self.cf.save()
|
||||
|
||||
|
||||
def clear_cache(self):
|
||||
"""Delete cache folder and reprocess the images"""
|
||||
try:
|
||||
@ -467,6 +512,9 @@ class App(Gtk.Window):
|
||||
elif event.keyval in [Gdk.KEY_period]:
|
||||
self.toggle_hidden_files()
|
||||
|
||||
elif event.keyval in [Gdk.KEY_s]:
|
||||
self.toggle_include_subfolders()
|
||||
|
||||
elif event.keyval in [Gdk.KEY_h, Gdk.KEY_Left]:
|
||||
self.selected_index = max(self.selected_index - 1, 0)
|
||||
self.load_image_grid()
|
||||
@ -514,7 +562,7 @@ class App(Gtk.Window):
|
||||
self.cf.save()
|
||||
|
||||
# Prevent other default key handling:
|
||||
if event.keyval in [Gdk.KEY_Up, Gdk.KEY_Down, Gdk.KEY_Left, Gdk.KEY_Right, Gdk.KEY_Return, Gdk.KEY_KP_Enter]:
|
||||
if event.keyval in [Gdk.KEY_Up, Gdk.KEY_Down, Gdk.KEY_Left, Gdk.KEY_Right, Gdk.KEY_Return, Gdk.KEY_KP_Enter, Gdk.KEY_period]:
|
||||
return True
|
||||
|
||||
|
||||
|
@ -13,18 +13,14 @@ def has_image_extension(file_path, backend):
|
||||
return ext in image_extensions
|
||||
|
||||
|
||||
def get_image_paths(backend, root_folder, include_subfolders=False, include_hidden=False, depth=None):
|
||||
"""Get a list of file paths depending of weather we include subfolders and how deep we scan"""
|
||||
def get_image_paths(backend, root_folder, include_subfolders=False, include_hidden=False, only_gifs=False, depth=None):
|
||||
"""Get a list of file paths depending on the filters that were requested"""
|
||||
image_paths = []
|
||||
for root, directories, files in os.walk(root_folder):
|
||||
|
||||
# Remove hidden files from consideration:
|
||||
for directory in directories:
|
||||
if directory.startswith('.') and not include_hidden:
|
||||
directories.remove(directory)
|
||||
for file in files:
|
||||
if file.startswith('.') and not include_hidden:
|
||||
files.remove(file)
|
||||
|
||||
# Remove subfolders from consideration:
|
||||
if not include_subfolders and str(root) != str(root_folder):
|
||||
@ -38,16 +34,21 @@ def get_image_paths(backend, root_folder, include_subfolders=False, include_hidd
|
||||
|
||||
# Remove files that are not images from consideration:
|
||||
for filename in files:
|
||||
if filename.startswith('.') and not include_hidden:
|
||||
continue
|
||||
if not has_image_extension(filename, backend):
|
||||
continue
|
||||
if not filename.endswith('.gif') and only_gifs:
|
||||
continue
|
||||
image_paths.append(os.path.join(root, filename))
|
||||
# print(root, directories, files)
|
||||
return image_paths
|
||||
|
||||
|
||||
def get_random_file(backend, folder, include_subfolders, include_hidden=False):
|
||||
"""Pick a random file from the folder"""
|
||||
try:
|
||||
image_paths = get_image_paths(backend, folder, include_subfolders, include_hidden, depth=1)
|
||||
image_paths = get_image_paths(backend, folder, include_subfolders, include_hidden, only_gifs=False, depth=1)
|
||||
return random.choice(image_paths)
|
||||
except:
|
||||
return None
|
||||
|
@ -34,6 +34,7 @@ class Config:
|
||||
self.post_command = ""
|
||||
self.include_subfolders = False
|
||||
self.show_hidden = False
|
||||
self.show_gifs_only = False
|
||||
self.about = AboutData()
|
||||
self.cache_dir = user_cache_path(self.about.applicationName())
|
||||
self.config_dir = user_config_path(self.about.applicationName())
|
||||
@ -73,6 +74,7 @@ class Config:
|
||||
self.lang = config.get("Settings", "language", fallback=self.lang)
|
||||
self.include_subfolders = config.getboolean("Settings", "subfolders", fallback=self.include_subfolders)
|
||||
self.show_hidden = config.getboolean("Settings", "show_hidden", fallback=self.show_hidden)
|
||||
self.show_gifs_only = config.getboolean("Settings", "show_gifs_only", fallback=self.show_gifs_only)
|
||||
self.monitors_str = config.get("Settings", "monitors", fallback=self.selected_monitor, raw=True)
|
||||
self.wallpapers_str = config.get("Settings", "wallpaper", fallback="", raw=True)
|
||||
self.number_of_columns = config.get("Settings", "number_of_columns", fallback=self.number_of_columns)
|
||||
@ -107,10 +109,10 @@ class Config:
|
||||
if 0 > int(self.swww_transition_duration):
|
||||
self.swww_transition_duration = 2
|
||||
|
||||
def save(self):
|
||||
"""Update the parameters and save them to the configuration file"""
|
||||
|
||||
# If only certain monitor was affected, change only its wallpaper:
|
||||
def attribute_selected_wallpaper(self):
|
||||
"""If only certain monitor was affected, change only its wallpaper"""
|
||||
if self.selected_wallpaper == "":
|
||||
return
|
||||
if self.selected_monitor == "All":
|
||||
self.monitors = [self.selected_monitor]
|
||||
self.wallpapers = [self.shorten_path(self.selected_wallpaper)]
|
||||
@ -121,6 +123,11 @@ class Config:
|
||||
self.monitors.append(self.selected_monitor)
|
||||
self.wallpapers.append(self.shorten_path(self.selected_wallpaper))
|
||||
|
||||
def save(self):
|
||||
"""Update the parameters and save them to the configuration file"""
|
||||
|
||||
self.attribute_selected_wallpaper()
|
||||
|
||||
# Write configuration to the file:
|
||||
config = configparser.ConfigParser()
|
||||
config.read(self.config_file)
|
||||
@ -136,6 +143,7 @@ class Config:
|
||||
config.set("Settings", "color", self.color)
|
||||
config.set("Settings", "subfolders", str(self.include_subfolders))
|
||||
config.set("Settings", "show_hidden", str(self.show_hidden))
|
||||
config.set("Settings", "show_gifs_only", str(self.show_gifs_only))
|
||||
config.set("Settings", "post_command", self.post_command)
|
||||
config.set("Settings", "number_of_columns", str(self.number_of_columns))
|
||||
config.set("Settings", "swww_transition_type", str(self.swww_transition_type))
|
||||
|
@ -17,7 +17,9 @@ class English:
|
||||
self.msg_refresh = "Refresh"
|
||||
self.msg_random = "Random"
|
||||
self.msg_exit = "Exit"
|
||||
self.msg_subfolders = "Subfolders"
|
||||
self.msg_subfolders = "Show subfolders"
|
||||
self.msg_hidden = "Show hidden"
|
||||
self.msg_gifs = "Show gifs only"
|
||||
self.msg_changefolder = "Change wallpaper folder"
|
||||
self.msg_choosefolder = "Please choose a folder"
|
||||
self.msg_caching = "Caching wallpapers..."
|
||||
@ -25,7 +27,7 @@ class English:
|
||||
|
||||
self.msg_help = "Waypaper's hotkeys:\n\nhjkl - Navigation (←↓↑→)\nEnter - Set selected wallpaper\nf - Change wallpaper folder\n"
|
||||
self.msg_help += "g - Scroll to top\nG - Scroll to bottom\nR - Set random wallpaper\nr - Recache wallpapers\n"
|
||||
self.msg_help += ". - Include/exclude hidden images\ns - Include/exclude images in subfolders\n? - Help\nq - Exit\n\n"
|
||||
self.msg_help += ". - Toggle hidden images\ns - Toggle images in subfolders\n? - Help\nq - Exit\n\n"
|
||||
self.msg_help += self.msg_info
|
||||
|
||||
self.err_cache = "Error deleting cache"
|
||||
@ -39,7 +41,6 @@ class English:
|
||||
self.err_disp = "Error determining monitor names:"
|
||||
self.err_kill = "Warning related to killall:"
|
||||
|
||||
self.tip_subfolder = "Include/exclude images in subfolders"
|
||||
self.tip_refresh = "Recache the folder of images"
|
||||
self.tip_fill = "Choose fill type"
|
||||
self.tip_backend = "Choose backend"
|
||||
@ -67,6 +68,8 @@ class German:
|
||||
self.msg_random = "Zufällig"
|
||||
self.msg_exit = "Beenden"
|
||||
self.msg_subfolders = "Unterordner"
|
||||
self.msg_hidden = "Hidden"
|
||||
self.msg_gifs = "Show only gifs"
|
||||
self.msg_changefolder = "Hintergrundbild-Ordner ändern"
|
||||
self.msg_choosefolder = "Bitte wählen Sie einen Ordner aus"
|
||||
self.msg_caching = "Hintergrundbilder werden zwischengespeichert..."
|
||||
@ -88,7 +91,6 @@ class German:
|
||||
self.err_disp = "Fehler beim Ermitteln der Monitor-Namen:"
|
||||
self.err_kill = "Warnung im Zusammenhang mit dem Befehl killall:"
|
||||
|
||||
self.tip_subfolder = "Wählen, ob Unterordner mit einbezogen werden sollen"
|
||||
self.tip_refresh = "Erneutes einlesen des Hintergrundbild-Ordners"
|
||||
self.tip_fill = "Skalierungsart auswählen"
|
||||
self.tip_backend = "Backend auswählen"
|
||||
@ -116,6 +118,8 @@ class French:
|
||||
self.msg_random = "Aléatoire"
|
||||
self.msg_exit = "Quitter"
|
||||
self.msg_subfolders = "Sous-dossiers"
|
||||
self.msg_hidden = "Hidden"
|
||||
self.msg_gifs = "Show only gifs"
|
||||
self.msg_changefolder = "Changer de dossier de papier peint"
|
||||
self.msg_choosefolder = "Veuillez choisir un dossier"
|
||||
self.msg_caching = "Mise en cache des papiers peints..."
|
||||
@ -137,7 +141,6 @@ class French:
|
||||
self.err_disp = "Erreur lors de la détermination des noms des moniteurs :"
|
||||
self.err_kill = "Avertissement lié à killall :"
|
||||
|
||||
self.tip_subfolder = "Inclure/exclure les images des sous-dossiers"
|
||||
self.tip_refresh = "Recréer le dossier d'images"
|
||||
self.tip_fill = "Choisir le type de remplissage"
|
||||
self.tip_backend = "Choisir le backend"
|
||||
@ -165,6 +168,8 @@ class Polish:
|
||||
self.msg_random = "Losowo"
|
||||
self.msg_exit = "Wyjście"
|
||||
self.msg_subfolders = "Podkatalogi"
|
||||
self.msg_hidden = "Hidden"
|
||||
self.msg_gifs = "Show only gifs"
|
||||
self.msg_changefolder = "Zmień folder z tapetami"
|
||||
self.msg_choosefolder = "Proszę wybrać folder"
|
||||
self.msg_caching = "Kasowanie tapet..."
|
||||
@ -186,7 +191,6 @@ class Polish:
|
||||
self.err_disp = "Błąd podczas określania nazw monitorów:"
|
||||
self.err_kill = "Ostrzeżenie związane z poleceniem killall:"
|
||||
|
||||
self.tip_subfolder = "Dołącz/wyłącz obrazy z podkatalogów"
|
||||
self.tip_refresh = "Odśwież folder z obrazami"
|
||||
self.tip_fill = "Wybierz typ wypełnienia"
|
||||
self.tip_backend = "Wybierz backend"
|
||||
@ -213,7 +217,9 @@ class Russian:
|
||||
self.msg_refresh = "Обновить"
|
||||
self.msg_random = "Случайно"
|
||||
self.msg_exit = "Выход"
|
||||
self.msg_subfolders = "Подпапки"
|
||||
self.msg_subfolders = "Показать подпапки"
|
||||
self.msg_hidden = "Показать скрытые"
|
||||
self.msg_gifs = "Показать только gif"
|
||||
self.msg_changefolder = "Изменить папку с обоями"
|
||||
self.msg_choosefolder = "Пожалуйста, выберите папку"
|
||||
self.msg_caching = "Кэширование обоев..."
|
||||
@ -221,12 +227,12 @@ class Russian:
|
||||
|
||||
self.msg_help = "Горячие клавиши Waypaper:\n\nhjkl - Навигация (←↓↑→)\nf - Изменить папку с обоями\n"
|
||||
self.msg_help += "g - Прокрутка в начало\nG - Прокрутка в конец\nR - Установить случайные обои\nr - Обновить кэш обоев\n"
|
||||
self.msg_help += ". - Включить/исключить скрытые файлы \ns - Включить/исключить подпапки\n? - Справка\nq - Выход\n\n"
|
||||
self.msg_help += ". - Показать/скрыть скрытые файлы \ns - Показать/скрыть вложенные папки\n? - Справка\nq - Выход\n\n"
|
||||
self.msg_help += self.msg_info
|
||||
|
||||
self.err_cache = "Ошибка при удалении кэша"
|
||||
self.err_backend = "Похоже, что ни один из бэкендов для установки обоев не установлен в системе.\n"
|
||||
self.err_backend += "Используйте менеджер пакетов для установки хотя бы одного из этих бэкендов:\n\n"
|
||||
self.err_backend += "Используйте менеджер пакетов для установки хотя бы одного из следующих бэкендов:\n\n"
|
||||
self.err_backend += "- swaybg (для Wayland)\n- swww (для Wayland)\n"
|
||||
self.err_backend += "- feh (для Xorg)\n- wallutils (для Xorg и Wayland)\n\n"
|
||||
self.err_backend += self.msg_info
|
||||
@ -235,7 +241,6 @@ class Russian:
|
||||
self.err_disp = "Ошибка определения названий мониторов:"
|
||||
self.err_kill = "Предупреждение связанное с killall:"
|
||||
|
||||
self.tip_subfolder = "Включить/отключить изображения в подпапках"
|
||||
self.tip_refresh = "Обновить папку с изображениями"
|
||||
self.tip_fill = "Выбрать тип заполнения"
|
||||
self.tip_backend = "Выбрать бэкенд"
|
||||
@ -263,6 +268,8 @@ class Chinese:
|
||||
self.msg_random = "随机"
|
||||
self.msg_exit = "退出"
|
||||
self.msg_subfolders = "子文件夹"
|
||||
self.msg_hidden = "Show hidden"
|
||||
self.msg_gifs = "Show only gifs"
|
||||
self.msg_changefolder = "更改壁纸文件夹"
|
||||
self.msg_choosefolder = "请选择一个文件夹"
|
||||
self.msg_caching = "缓存壁纸..."
|
||||
@ -284,7 +291,6 @@ class Chinese:
|
||||
self.err_disp = "确定监视器名称时出错:"
|
||||
self.err_kill = "与killall相关的警告:"
|
||||
|
||||
self.tip_subfolder = "在子文件夹中包含/排除图像"
|
||||
self.tip_refresh = "重新缓存图像文件夹"
|
||||
self.tip_fill = "选择填充类型"
|
||||
self.tip_backend = "选择后端"
|
||||
|
Loading…
Reference in New Issue
Block a user