OBSPlugin/actions/ToggleFilter/ToggleFilter.py

217 lines
7.9 KiB
Python
Raw Permalink Normal View History

2024-07-24 15:49:51 +00:00
from plugins.com_core447_OBSPlugin.OBSActionBase import OBSActionBase
from src.backend.DeckManagement.DeckController import DeckController
from src.backend.PageManagement.Page import Page
from src.backend.PluginManager.PluginBase import PluginBase
from GtkHelper.GtkHelper import ComboRow
import os
import threading
# Import gtk modules
import gi
gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1")
from gi.repository import Gtk, Adw
class ToggleFilter(OBSActionBase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.current_state = -1
def on_ready(self):
self.current_state = -1
# Connect to obs if not connected
if self.plugin_base.backend is not None:
if not self.plugin_base.get_connected():
self.reconnect_obs()
# Show current scene filter status
threading.Thread(target=self.show_current_filter_status, daemon=True, name="show_current_filter_status").start()
def show_current_filter_status(self, new_paused = False):
if self.plugin_base.backend is None:
self.current_state = -1
self.show_error()
return
if not self.plugin_base.backend.get_connected():
self.current_state = -1
self.show_error()
return
if not self.get_settings().get("filter"):
self.current_state = -1
self.show_error()
return
status = self.plugin_base.backend.get_source_filter(self.get_settings().get("scene"), self.get_settings().get("filter"))
if status is None:
self.current_state = -1
self.show_error()
return
if status["filterEnabled"]:
self.show_for_state(1)
else:
self.show_for_state(0)
def show_for_state(self, state: int):
"""
0: Filter disabled
1: Filter enabled
"""
if state == self.current_state:
return
self.current_state = state
image = "scene_item_disabled.png"
if state == -1:
self.show_error()
else:
self.hide_error()
if state == 0:
image = "scene_item_disabled.png"
elif state == 1:
image = "scene_item_enabled.png"
self.set_media(media_path=os.path.join(self.plugin_base.PATH, "assets", image), size=0.75)
def get_config_rows(self) -> list:
super_rows = super().get_config_rows()
self.scene_model = Gtk.StringList()
self.scene_row = Adw.ComboRow(model=self.scene_model, title=self.plugin_base.lm.get("actions.switch.scene-row.label"))
self.filter_model = Gtk.StringList()
self.filter_row = Adw.ComboRow(model=self.filter_model, title=self.plugin_base.lm.get("actions.toggle-scene-filter-enabled-row.label"))
self.connect_signals()
self.load_filter_model()
self.load_configs()
super_rows.append(self.scene_row)
super_rows.append(self.filter_row)
return super_rows
def connect_signals(self):
self.scene_row.connect("notify::selected", self.on_scene_selected)
self.filter_row.connect("notify::selected", self.on_filter_selected)
def disconnect_signals(self):
try:
self.scene_row.disconnect_by_func(self.on_scene_selected)
self.filter_row.disconnect_by_func(self.on_filter_selected)
except TypeError as e:
pass
def load_filter_model(self):
self.disconnect_signals()
# Clear model
while self.scene_model.get_n_items() > 0:
self.scene_model.remove(0)
while self.filter_model.get_n_items() > 0:
self.filter_model.remove(0)
# Load model
if self.plugin_base.backend.get_connected():
scenes = self.plugin_base.backend.get_scene_names()
if scenes is None:
return
for scene in scenes:
self.scene_model.append(scene)
# Ensure selection is made if there's only one scene
if len(scenes) == 1:
self.get_settings()["scene"] = scenes[0]
self.scene_row.set_selected(0)
self.load_filters_for_scene(scenes[0])
self.connect_signals()
def load_filters_for_scene(self, scene_name):
# Clear filters model
while self.filter_model.get_n_items() > 0:
self.filter_model.remove(0)
if self.plugin_base.backend.get_connected():
filters = self.plugin_base.backend.get_source_filters(scene_name)
if filters is None:
self.show_error()
return
for item in filters:
self.filter_model.append(item.get("filterName"))
# Ensure selection is made if there's only one item
if len(filters) == 1:
self.filter_row.set_selected(0)
def load_configs(self):
self.load_config_values()
def load_config_values(self):
self.disconnect_signals()
settings = self.get_settings()
for i, scene_name in enumerate(self.scene_model):
if scene_name.get_string() == settings.get("scene"):
self.scene_row.set_selected(i)
self.load_filters_for_scene(scene_name.get_string())
for j, item_name in enumerate(self.filter_model):
if item_name.get_string() == settings.get("filter"):
self.filter_row.set_selected(j)
break
self.connect_signals()
return
self.scene_row.set_selected(Gtk.INVALID_LIST_POSITION)
self.filter_row.set_selected(Gtk.INVALID_LIST_POSITION)
self.connect_signals()
def on_scene_selected(self, *args):
settings = self.get_settings()
selected_index_scene = self.scene_row.get_selected()
if selected_index_scene != Gtk.INVALID_LIST_POSITION:
scene_name = self.scene_model[selected_index_scene].get_string()
settings["scene"] = scene_name
self.set_settings(settings)
self.load_filters_for_scene(scene_name)
def on_filter_selected(self, *args):
settings = self.get_settings()
selected_index_item = self.filter_row.get_selected()
if selected_index_item != Gtk.INVALID_LIST_POSITION:
settings["filter"] = self.filter_model[selected_index_item].get_string()
self.set_settings(settings)
def on_key_down(self):
if self.plugin_base.backend is None:
self.current_state = -1
self.show_error()
self.set_media(media_path=os.path.join(self.plugin_base.PATH, "assets", "error.png"))
return
if not self.plugin_base.backend.get_connected():
self.current_state = -1
self.show_error()
self.set_media(media_path=os.path.join(self.plugin_base.PATH, "assets", "error.png"))
return
scene_name = self.get_settings().get("scene")
filter_name = self.get_settings().get("filter")
if scene_name in [None, ""]:
self.set_media(media_path=os.path.join(self.plugin_base.PATH, "assets", "error.png"))
return
if filter_name in [None, ""]:
self.set_media(media_path=os.path.join(self.plugin_base.PATH, "assets", "error.png"))
return
if self.current_state == 0:
self.plugin_base.backend.set_source_filter_enabled(scene_name, filter_name, True)
else:
self.plugin_base.backend.set_source_filter_enabled(scene_name, filter_name, False)
self.on_tick()
def on_tick(self):
self.show_current_filter_status()
def reconnect_obs(self):
super().reconnect_obs()
if hasattr(self, "scene_model") and hasattr(self, "filter_model"):
self.load_filter_model()
self.load_configs()