Refactored to reduce Glade dependency...

This commit is contained in:
2022-10-13 20:58:44 -05:00
parent ee812c520f
commit e427cddec9
16 changed files with 361 additions and 220 deletions

3
src/core/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
"""
Gtk Bound Signal Module
"""

87
src/core/controller.py Normal file
View File

@@ -0,0 +1,87 @@
# Python imports
import subprocess
# Gtk imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib
# Application imports
from .mixins.dummy_mixin import DummyMixin
from .controller_data import ControllerData
from .core_widget import CoreWidget
class Controller(DummyMixin, ControllerData):
def __init__(self, args, unknownargs):
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self.setup_controller_data()
self.print_hello_world() # A mixin method from the DummyMixin file
def _setup_styling(self):
...
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe("handle_file_from_ipc", self.handle_file_from_ipc)
def handle_file_from_ipc(self, path: str) -> None:
print(f"Path From IPC: {path}")
def load_glade_file(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(settings.get_glade_file())
settings.set_builder(self.builder)
self.core_widget = CoreWidget()
settings.register_signals_to_builder([self, self.core_widget])
def get_core_widget(self):
return self.core_widget
def on_global_key_release_controller(self, widget: type, event: type) -> None:
"""Handler for keyboard events"""
keyname = Gdk.keyval_name(event.keyval).lower()
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
if "control" in keyname:
self.ctrl_down = False
if "shift" in keyname:
self.shift_down = False
if "alt" in keyname:
self.alt_down = False
mapping = keybindings.lookup(event)
if mapping:
getattr(self, mapping)()
return True
else:
print(f"on_global_key_release_controller > key > {keyname}")
print(f"Add logic or remove this from: {self.__class__}")
def get_clipboard_data(self) -> str:
proc = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout=subprocess.PIPE)
retcode = proc.wait()
data = proc.stdout.read()
return data.decode("utf-8").strip()
def set_clipboard_data(self, data: type) -> None:
proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
proc.stdin.write(data)
proc.stdin.close()
retcode = proc.wait()

View File

@@ -0,0 +1,51 @@
# Python imports
import os
# Lib imports
# Application imports
from plugins.plugins_controller import PluginsController
class ControllerData:
''' ControllerData contains most of the state of the app at ay given time. It also has some support methods. '''
def setup_controller_data(self) -> None:
self.logger = settings.get_logger()
self.builder = None
self.core_widget = None
self.load_glade_file()
self.plugins = PluginsController()
def clear_console(self) -> None:
''' Clears the terminal screen. '''
os.system('cls' if os.name == 'nt' else 'clear')
def call_method(self, _method_name: str, data: type) -> type:
'''
Calls a method from scope of class.
Parameters:
a (obj): self
b (str): method name to be called
c (*): Data (if any) to be passed to the method.
Note: It must be structured according to the given methods requirements.
Returns:
Return data is that which the calling method gives.
'''
method_name = str(_method_name)
method = getattr(self, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}")
return method(*data) if data else method()
def has_method(self, obj: type, method: type) -> type:
''' Checks if a given method exists. '''
return callable(getattr(obj, method, None))
def clear_children(self, widget: type) -> None:
''' Clear children of a gtk widget. '''
for child in widget.get_children():
widget.remove(child)

37
src/core/core_widget.py Normal file
View File

@@ -0,0 +1,37 @@
# Python imports
# Gtk imports
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
# Application imports
class CoreWidget(Gtk.Box):
def __init__(self):
super(CoreWidget, self).__init__()
self._setup_styling()
self._setup_signals()
self._load_widgets()
self.show_all()
def _setup_styling(self):
self.set_orientation(1)
def _setup_signals(self):
...
def _load_widgets(self):
button = Gtk.Button(label="Click Me!")
button.connect("clicked", self._hello_world)
self.add(button)
def _hello_world(self, widget=None, eve=None):
print("Hello, World!")

View File

@@ -0,0 +1,3 @@
"""
Generic Mixins Module
"""

View File

@@ -0,0 +1,5 @@
class DummyMixin:
""" DummyMixin is an example of how mixins are used and structured in a project. """
def print_hello_world(self) -> None:
print("Hello, World!")

76
src/core/window.py Normal file
View File

@@ -0,0 +1,76 @@
# Python imports
import time
import signal
# Lib imports
import gi
import cairo
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib
# Application imports
from core.controller import Controller
class Window(Gtk.ApplicationWindow):
"""docstring for Window."""
def __init__(self, args, unknownargs):
super(Window, self).__init__()
self._set_window_data()
self._setup_styling()
self._setup_signals()
self._load_widgets(args, unknownargs)
self.show_all()
def _setup_styling(self):
self.set_default_size(1670, 830)
self.set_title(f"{app_name}")
self.set_icon_from_file( settings.get_window_icon() )
self.set_gravity(5) # 5 = CENTER
self.set_position(1) # 1 = CENTER, 4 = CENTER_ALWAYS
def _setup_signals(self):
self.connect("delete-event", self._tear_down)
GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self._tear_down)
def _load_widgets(self, args, unknownargs):
controller = Controller(args, unknownargs)
self.add( controller.get_core_widget() )
def _set_window_data(self) -> None:
screen = self.get_screen()
visual = screen.get_rgba_visual()
if visual != None and screen.is_composited():
self.set_visual(visual)
self.set_app_paintable(True)
self.connect("draw", self._area_draw)
# bind css file
cssProvider = Gtk.CssProvider()
cssProvider.load_from_path( settings.get_css_file() )
screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()
styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
def _area_draw(self, widget: Gtk.ApplicationWindow, cr: cairo.Context) -> None:
cr.set_source_rgba(0, 0, 0, 0.54)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
cr.set_operator(cairo.OPERATOR_OVER)
def _tear_down(self, widget=None, eve=None):
time.sleep(event_sleep_time)
Gtk.main_quit()