initial commit
This commit is contained in:
3
src/libs/mixins/__init__.py
Normal file
3
src/libs/mixins/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""
|
||||
Libs.Mixins Package
|
||||
"""
|
||||
70
src/libs/mixins/dnd_mixin.py
Normal file
70
src/libs/mixins/dnd_mixin.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# Python imports
|
||||
|
||||
# Lib 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 Gio
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
class DnDMixin:
|
||||
|
||||
def _setup_dnd(self):
|
||||
flags = Gtk.DestDefaults.ALL
|
||||
|
||||
PLAIN_TEXT_TARGET_TYPE = 70
|
||||
URI_TARGET_TYPE = 80
|
||||
|
||||
text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE)
|
||||
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
|
||||
|
||||
# targets = [ text_target, uri_target ]
|
||||
targets = [ uri_target ]
|
||||
|
||||
action = Gdk.DragAction.COPY
|
||||
|
||||
# self.drag_dest_set_target_list(targets)
|
||||
self.drag_dest_set(flags, targets, action)
|
||||
|
||||
self._setup_dnd_signals()
|
||||
|
||||
def _setup_dnd_signals(self):
|
||||
# self.connect("drag-motion", self._on_drag_motion)
|
||||
# self.connect('drag-drop', self._on_drag_set)
|
||||
self.connect("drag-data-received", self._on_drag_data_received)
|
||||
|
||||
def _on_drag_motion(self, widget, drag_context, x, y, time):
|
||||
Gdk.drag_status(drag_context, drag_context.get_actions(), time)
|
||||
|
||||
return False
|
||||
|
||||
def _on_drag_set(self, widget, drag_context, data, info, time):
|
||||
self.drag_get_data(drag_context, drag_context.list_targets()[-1], time)
|
||||
|
||||
return False
|
||||
|
||||
def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
|
||||
if info == 70: return
|
||||
|
||||
if info == 80:
|
||||
uris = data.get_uris()
|
||||
files = []
|
||||
|
||||
if len(uris) == 0:
|
||||
uris = data.get_text().split("\n")
|
||||
|
||||
for uri in uris:
|
||||
gfile = None
|
||||
try:
|
||||
gfile = Gio.File.new_for_uri(uri)
|
||||
except Exception as e:
|
||||
gfile = Gio.File.new_for_path(uri)
|
||||
|
||||
files.append(gfile)
|
||||
|
||||
event_system.emit('set-pre-drop-dnd', (files,))
|
||||
31
src/libs/mixins/ipc_signals_mixin.py
Normal file
31
src/libs/mixins/ipc_signals_mixin.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
from gi.repository import GLib
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
|
||||
class IPCSignalsMixin:
|
||||
""" IPCSignalsMixin handle messages from another starting {APP_NAME} process. """
|
||||
|
||||
def print_to_console(self, message = None):
|
||||
logger.debug(message)
|
||||
|
||||
def handle_file_from_ipc(self, fpath: str) -> None:
|
||||
logger.debug(f"File From IPC: {fpath}")
|
||||
GLib.idle_add(
|
||||
self.broadcast_message, "handle-file", (fpath,)
|
||||
)
|
||||
|
||||
def handle_dir_from_ipc(self, fpath: str) -> None:
|
||||
logger.debug(f"Dir From IPC: {fpath}")
|
||||
GLib.idle_add(
|
||||
self.broadcast_message, "handle-folder", (fpath,)
|
||||
)
|
||||
|
||||
def broadcast_message(self, message_type: str = "none", data: () = ()) -> None:
|
||||
event_system.emit(message_type, data)
|
||||
96
src/libs/mixins/keyboard_signals_mixin.py
Normal file
96
src/libs/mixins/keyboard_signals_mixin.py
Normal file
@@ -0,0 +1,96 @@
|
||||
# Python imports
|
||||
import re
|
||||
|
||||
# Lib 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
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
valid_keyvalue_pat = re.compile(r"[a-z0-9A-Z-_\[\]\(\)\| ]")
|
||||
|
||||
|
||||
|
||||
class KeyboardSignalsMixin:
|
||||
""" KeyboardSignalsMixin keyboard hooks controller. """
|
||||
|
||||
# TODO: Need to set methods that use this to somehow check the keybindings state instead.
|
||||
def unset_keys_and_data(self, widget = None, eve = None):
|
||||
self.ctrl_down = False
|
||||
self.shift_down = False
|
||||
self.alt_down = False
|
||||
|
||||
def unmap_special_keys(self, keyname):
|
||||
if "control" in keyname:
|
||||
self.ctrl_down = False
|
||||
if "shift" in keyname:
|
||||
self.shift_down = False
|
||||
if "alt" in keyname:
|
||||
self.alt_down = False
|
||||
|
||||
def on_global_key_press_controller(self, eve, user_data):
|
||||
keyname = Gdk.keyval_name(user_data.keyval).lower()
|
||||
modifiers = Gdk.ModifierType(user_data.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||
|
||||
self.was_midified_key = True if modifiers != 0 else False
|
||||
|
||||
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
||||
if "control" in keyname:
|
||||
self.ctrl_down = True
|
||||
if "shift" in keyname:
|
||||
self.shift_down = True
|
||||
if "alt" in keyname:
|
||||
self.alt_down = True
|
||||
|
||||
def on_global_key_release_controller(self, widget, event):
|
||||
""" Handler for keyboard events """
|
||||
keyname = Gdk.keyval_name(event.keyval).lower()
|
||||
modifiers = Gdk.ModifierType(event.get_state() & ~Gdk.ModifierType.LOCK_MASK)
|
||||
|
||||
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
||||
should_return = self.was_midified_key and (self.ctrl_down or self.shift_down or self.alt_down)
|
||||
self.unmap_special_keys(keyname)
|
||||
|
||||
if should_return:
|
||||
self.was_midified_key = False
|
||||
return
|
||||
|
||||
mapping = keybindings.lookup(event)
|
||||
logger.debug(f"on_global_key_release_controller > key > {keyname}")
|
||||
logger.debug(f"on_global_key_release_controller > keyval > {event.keyval}")
|
||||
logger.debug(f"on_global_key_release_controller > mapping > {mapping}")
|
||||
|
||||
if mapping:
|
||||
self.handle_mapped_key_event(mapping)
|
||||
else:
|
||||
self.handle_as_key_event_scope(keyname)
|
||||
|
||||
def handle_mapped_key_event(self, mapping):
|
||||
try:
|
||||
self.handle_as_controller_scope(mapping)
|
||||
except Exception:
|
||||
self.handle_as_plugin_scope(mapping)
|
||||
|
||||
def handle_as_controller_scope(self, mapping):
|
||||
getattr(self, mapping)()
|
||||
|
||||
def handle_as_plugin_scope(self, mapping):
|
||||
if "||" in mapping:
|
||||
sender, eve_type = mapping.split("||")
|
||||
else:
|
||||
sender = ""
|
||||
eve_type = mapping
|
||||
|
||||
self.handle_key_event_system(sender, eve_type)
|
||||
|
||||
def handle_as_key_event_scope(self, keyname):
|
||||
if self.ctrl_down and not keyname in ["1", "kp_1", "2", "kp_2", "3", "kp_3", "4", "kp_4"]:
|
||||
self.handle_key_event_system(None, keyname)
|
||||
|
||||
def handle_key_event_system(self, sender, eve_type):
|
||||
event_system.emit(eve_type)
|
||||
26
src/libs/mixins/observable_mixin.py
Normal file
26
src/libs/mixins/observable_mixin.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from ..dto.observable_event import ObservableEvent
|
||||
|
||||
|
||||
|
||||
class ObservableMixin:
|
||||
observers = []
|
||||
|
||||
def add_observer(self, observer: any):
|
||||
if not hasattr(observer, 'notification') or not callable(getattr(observer, 'notification')):
|
||||
raise ValueError(f"Observer '{observer}' must implement a `notification` method.")
|
||||
|
||||
self.observers.append(observer)
|
||||
|
||||
def remove_observer(self, observer: any):
|
||||
if not observer in self.observers: return
|
||||
|
||||
self.observers.remove(observer)
|
||||
|
||||
def notify_observers(self, event: ObservableEvent):
|
||||
for observer in self.observers:
|
||||
observer.notification(event)
|
||||
Reference in New Issue
Block a user