Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 107 additions & 3 deletions src/assets/control.ui
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,110 @@ All Contributors https://github.com/jeffshee/hidamari/graphs/contributors</prope
<property name="page-increment">10</property>
<signal name="value-changed" handler="on_volume_changed" swapped="no"/>
</object>
<object class="GtkAdjustment" id="AdjustmentTimer">
<property name="lower">1</property>
<property name="upper">60</property>
<property name="step-increment">1</property>
<property name="page-increment">5</property>
<signal name="value-changed" handler="on_lucky_timer_changed" swapped="no"/>
</object>
<object class="GtkPopover" id="PopoverLucky">
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-start">8</property>
<property name="margin-end">8</property>
<property name="margin-top">8</property>
<property name="margin-bottom">8</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Feeling Lucky - Run now</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkModelButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">app.feeling_lucky_sync</property>
<property name="text" translatable="yes">Sync monitors</property>
</object>
</child>
<child>
<object class="GtkModelButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">app.feeling_lucky</property>
<property name="text" translatable="yes">Random for each monitor</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Feeling Lucky - Timer</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="ToggleFeelingLuckyTimer">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="action-name">app.feeling_lucky_timeron</property>
<property name="text" translatable="yes">Change from time to time</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<object class="GtkScale" id="ScaleLuckyTimer">
<property name="visible">False</property>
<property name="can-focus">True</property>
<property name="adjustment">AdjustmentTimer</property>
<property name="draw-value">True</property>
<property name="round-digits">0</property>
<property name="digits">0</property>

<marks>
<mark value="0" translatable="yes">0m</mark>
<mark value="60" translatable="yes">1h</mark>
</marks>

</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkPopover" id="PopoverMain">
<property name="can-focus">False</property>
<child>
Expand Down Expand Up @@ -679,7 +783,7 @@ Set a web page as wallpaper</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">💡 Check this website for some really amazing examples!
&lt;a href="https://alteredqualia.com/"&gt;https://alteredqualia.com/&lt;/a&gt;</property>
&lt;a href="https://alteredqualia.com/"&gt;https://alteredqualia.com/&lt;/a&gt;</property>
<property name="use-markup">True</property>
</object>
<packing>
Expand Down Expand Up @@ -844,12 +948,12 @@ Set a web page as wallpaper</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ButtonFeelingLucky">
<object class="GtkMenuButton" id="ButtonFeelingLucky">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">I'm Feeling Lucky</property>
<property name="action-name">app.feeling_lucky</property>
<property name="popover">PopoverLucky</property>
<child>
<object class="GtkImage" id="ButtonPlayPauseIcon1">
<property name="visible">True</property>
Expand Down
4 changes: 4 additions & 0 deletions src/commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
CONFIG_KEY_MUTE = "is_mute"
CONFIG_KEY_VOLUME = "audio_volume"
CONFIG_KEY_STATIC_WALLPAPER = "is_static_wallpaper"
CONFIG_KEY_FEELING_LUCKY = "is_feeling_lucky"
CONFIG_KEY_FEELING_LUCKY_TIMER = "feeling_lucky_timer"
CONFIG_KEY_BLUR_RADIUS = "static_wallpaper_blur_radius"
CONFIG_KEY_PAUSE_WHEN_MAXIMIZED = "is_pause_when_maximized"
CONFIG_KEY_MUTE_WHEN_MAXIMIZED = "is_mute_when_maximized"
Expand All @@ -69,6 +71,8 @@
CONFIG_KEY_MUTE: False,
CONFIG_KEY_VOLUME: 50,
CONFIG_KEY_STATIC_WALLPAPER: True,
CONFIG_KEY_FEELING_LUCKY: False,
CONFIG_KEY_FEELING_LUCKY_TIMER: 5,
CONFIG_KEY_BLUR_RADIUS: 5,
CONFIG_KEY_PAUSE_WHEN_MAXIMIZED: True,
CONFIG_KEY_MUTE_WHEN_MAXIMIZED: False,
Expand Down
77 changes: 76 additions & 1 deletion src/gui/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gio, GLib, GdkPixbuf, Gdk
from gi.repository import Gtk, Gio, GLib, GdkPixbuf, Gdk, GObject

from pydbus import SessionBus
import yt_dlp
Expand Down Expand Up @@ -58,12 +58,26 @@ def __init__(self, version, *args, **kwargs):
self.builder.add_from_resource(APP_UI_RESOURCE_PATH)
except GLib.Error:
self.builder.add_from_file(os.path.abspath("./assets/control.ui"))

# Show timer scale when toggled

toggle_feelingluckytimer = self.builder.get_object("ToggleFeelingLuckyTimer")
scale_feelingluckytimer = self.builder.get_object("ScaleLuckyTimer")

toggle_feelingluckytimer.bind_property(
"active",
scale_feelingluckytimer,
"visible",
GObject.BindingFlags.DEFAULT
)

# Handlers declared in `control.ui``
signals = {
"on_volume_changed": self.on_volume_changed,
"on_streaming_activate": self.on_streaming_activate,
"on_web_page_activate": self.on_web_page_activate,
"on_blur_radius_changed": self.on_blur_radius_changed,
"on_lucky_timer_changed": self.on_lucky_timer_changed
}
self.builder.connect_signals(signals)

Expand Down Expand Up @@ -92,6 +106,7 @@ def __init__(self, version, *args, **kwargs):
self.monitors.get_monitor(monitor).set_wallpaper(video_paths['Default'])

self._setup_context_menu() # setup context menu for selecting monitors
self.lucky_timer_id = None

def _connect_server(self):
try:
Expand Down Expand Up @@ -138,6 +153,7 @@ def do_startup(self):
("local_web_page_apply", self.on_local_web_page_apply),
("play_pause", self.on_play_pause),
("feeling_lucky", self.on_feeling_lucky),
("feeling_lucky_sync", self.on_feeling_lucky_sync),
(
"config",
lambda *_: subprocess.run(["xdg-open", os.path.realpath(CONFIG_PATH)]),
Expand All @@ -159,6 +175,11 @@ def do_startup(self):
self.config[CONFIG_KEY_STATIC_WALLPAPER],
self.on_static_wallpaper,
),
(
"feeling_lucky_timeron",
self.config[CONFIG_KEY_FEELING_LUCKY],
self.on_feeling_lucky_timeron,
),
(
"pause_when_maximized",
self.config[CONFIG_KEY_PAUSE_WHEN_MAXIMIZED],
Expand Down Expand Up @@ -308,6 +329,10 @@ def on_feeling_lucky(self, *_):
if self.server is not None:
self.server.feeling_lucky()

def on_feeling_lucky_sync(self, *_):
if self.server is not None:
self.server.feeling_lucky_sync()

def set_mute_toggle_icon(self):
toggle_icon: Gtk.Image = self.builder.get_object("ToggleMuteIcon")
volume, is_mute = self.config[CONFIG_KEY_VOLUME], self.config[CONFIG_KEY_MUTE]
Expand Down Expand Up @@ -342,6 +367,15 @@ def on_volume_changed(self, adjustment):
if self.server is not None:
self.server.volume = self.config[CONFIG_KEY_VOLUME]
self.set_mute_toggle_icon()

def on_lucky_timer_changed(self, adjustment):
# If the timer is on, resets with new selected time
if self.config.get(CONFIG_KEY_FEELING_LUCKY_TIMER) != 0:
action = self.lookup_action("feeling_lucky_timeron")
self.on_feeling_lucky_timeron(action, GLib.Variant.new_boolean(True))
self.config[CONFIG_KEY_FEELING_LUCKY_TIMER] = int(adjustment.get_value())
logger.info(f"[GUI] Feeling Lucky Timer: {self.config[CONFIG_KEY_FEELING_LUCKY_TIMER]}")
self._save_config_delay()

def on_blur_radius_changed(self, adjustment):
self.config[CONFIG_KEY_BLUR_RADIUS] = int(adjustment.get_value())
Expand Down Expand Up @@ -375,6 +409,40 @@ def on_static_wallpaper(self, action, state):
self.server.is_static_wallpaper = self.config[CONFIG_KEY_STATIC_WALLPAPER]
self.set_spin_blur_radius_sensitive()

def on_feeling_lucky_timeron(self, action, state):
action.set_state(state)
is_active = bool(state)
self.config[CONFIG_KEY_FEELING_LUCKY] = is_active
logger.info(f"[GUI] {action.get_name()}: {state}")
self._save_config()
if self.server is not None:
self.server.is_feeling_lucky = self.config[CONFIG_KEY_FEELING_LUCKY]

# If there is a timer running, stops it first
if self.lucky_timer_id is not None:
GLib.source_remove(self.lucky_timer_id)
self.lucky_timer_id = None

# When turned on, starts a new timer
if is_active:
# Converts minutes to seconds
minutes = self.builder.get_object("AdjustmentTimer").get_value()
seconds = int(minutes) * 60

logger.info(f"[GUI] Starting Lucky Timer every {minutes} minutes")

self.lucky_timer_id = GLib.timeout_add_seconds(
seconds,
self._lucky_timer_callback
)

def _lucky_timer_callback(self):
if self.config[CONFIG_KEY_FEELING_LUCKY] and self.server is not None:
logger.info("[GUI] Lucky Timer Triggered!")
self.server.feeling_lucky_sync()
return True
return False

def on_pause_when_maximized(self, action, state):
action.set_state(state)
self.config[CONFIG_KEY_PAUSE_WHEN_MAXIMIZED] = bool(state)
Expand Down Expand Up @@ -490,6 +558,13 @@ def _reload_all_widgets(self):
scale_volume.set_value(self.config[CONFIG_KEY_VOLUME])
adjustment_volume.handler_unblock_by_func(self.on_volume_changed)

scale_lucky_timer: Gtk.Scale = self.builder.get_object("ScaleLuckyTimer")
adjustment_lucky_timer: Gtk.Adjustment = self.builder.get_object("AdjustmentTimer")
# Temporary block signal
adjustment_lucky_timer.handler_block_by_func(self.on_lucky_timer_changed)
scale_lucky_timer.set_value(self.config[CONFIG_KEY_FEELING_LUCKY_TIMER])
adjustment_lucky_timer.handler_unblock_by_func(self.on_lucky_timer_changed)

spin_blur_radius: Gtk.Scale = self.builder.get_object("SpinBlurRadius")
adjustment_blur: Gtk.Adjustment = self.builder.get_object("AdjustmentBlur")
# Temporary block signal
Expand Down
43 changes: 39 additions & 4 deletions src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class HidamariServer(object):
<method name='start_playback'/>
<method name="reload"/>
<method name="feeling_lucky"/>
<method name="feeling_lucky_sync"/>
<method name='show_gui'/>
<method name='quit'/>
<property name="mode" type="s" access="read"/>
Expand All @@ -58,6 +59,7 @@ class HidamariServer(object):
<property name="is_playing" type="b" access="read"/>
<property name="is_paused_by_user" type="b" access="readwrite"/>
<property name="is_static_wallpaper" type="b" access="readwrite"/>
<property name="is_feeling_lucky" type="b" access="readwrite"/>
<property name="is_pause_when_maximized" type="b" access="readwrite"/>
<property name="is_mute_when_maximized" type="b" access="readwrite"/>
</interface>
Expand Down Expand Up @@ -203,17 +205,39 @@ def reload(self):
def feeling_lucky(self):
"""Random play a video from the directory"""
monitors = Monitors().get_monitors()
file_list = get_video_paths()

# Remove current data source from the random selection
current_sources = set(self.config[CONFIG_KEY_DATA_SOURCE].values())
file_list = [f for f in file_list if f not in current_sources]

for monitor in monitors:
file_list = get_video_paths()
# Remove current data source from the random selection
if self.config[CONFIG_KEY_DATA_SOURCE][monitor] in file_list:
file_list.remove(self.config[CONFIG_KEY_DATA_SOURCE][monitor])
if file_list:
video_path = random.choice(file_list)
file_list.remove(video_path)
self.config[CONFIG_KEY_MODE] = MODE_VIDEO
self.config[CONFIG_KEY_DATA_SOURCE][monitor] = video_path
self._save_config()
self.video(video_path)

def feeling_lucky_sync(self):
"""Random play a video from the directory"""
file_list = get_video_paths()

# 1. Filter out videos currently playing on ANY monitor
current_sources = self.config[CONFIG_KEY_DATA_SOURCE].values()
file_list = [f for f in file_list if f not in current_sources]

if file_list:
video_path = random.choice(file_list)
self.config[CONFIG_KEY_MODE] = MODE_VIDEO

# 2. Assign the SAME video_path to EVERY monitor in the config
for monitor_key in self.config[CONFIG_KEY_DATA_SOURCE].keys():
self.config[CONFIG_KEY_DATA_SOURCE][monitor_key] = video_path
self._save_config()

map(self.video(video_path), Monitors().get_monitors())

def show_gui(self):
"""Show main GUI"""
Expand Down Expand Up @@ -307,6 +331,17 @@ def is_static_wallpaper(self, is_static_wallpaper):
player = get_instance(DBUS_NAME_PLAYER)
if player is not None:
player.reload_config()

@property
def is_feeling_lucky(self):
return self.config[CONFIG_KEY_FEELING_LUCKY]

@is_feeling_lucky.setter
def is_feeling_lucky(self, is_feeling_lucky):
self.config[CONFIG_KEY_FEELING_LUCKY] = is_feeling_lucky
player = get_instance(DBUS_NAME_PLAYER)
if player is not None:
player.reload_config()

@property
def is_pause_when_maximized(self):
Expand Down