Added 3 of 4 screen grab functionality

This commit is contained in:
itdominator 2023-04-16 23:57:12 -05:00
parent 66b3ab8624
commit a2e99ce302
11 changed files with 164 additions and 24 deletions

View File

@ -8,11 +8,11 @@ from utils.ipc_server import IPCServer
from core.window import Window from core.window import Window
class AppLaunchException(Exception): class AppLaunchException(Exception):
... ...
class Application(IPCServer): class Application(IPCServer):
''' Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes.''' ''' Create Settings and Controller classes. Bind signal to Builder. Inherit from Builtins to bind global methods and classes.'''
@ -26,7 +26,7 @@ class Application(IPCServer):
if not self.is_ipc_alive: if not self.is_ipc_alive:
for arg in unknownargs + [args.new_tab,]: for arg in unknownargs + [args.new_tab,]:
if os.path.isdir(arg): if os.path.isfile(arg):
message = f"FILE|{arg}" message = f"FILE|{arg}"
self.send_ipc_message(message) self.send_ipc_message(message)

View File

@ -12,11 +12,11 @@ from gi.repository import GLib
# Application imports # Application imports
from .mixins.signals_mixins import SignalsMixins from .mixins.signals_mixins import SignalsMixins
from .controller_data import ControllerData from .controller_data import ControllerData
from .screenshot_controller import ScreenshotController
from .containers.core_widget import CoreWidget from .containers.core_widget import CoreWidget
class Controller(SignalsMixins, ControllerData): class Controller(SignalsMixins, ControllerData):
def __init__(self, args, unknownargs): def __init__(self, args, unknownargs):
self.setup_controller_data() self.setup_controller_data()
@ -24,6 +24,7 @@ class Controller(SignalsMixins, ControllerData):
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
self._subscribe_to_events() self._subscribe_to_events()
self._load_widgets()
if args.no_plugins == "false": if args.no_plugins == "false":
self.plugins.launch_plugins() self.plugins.launch_plugins()
@ -51,9 +52,12 @@ class Controller(SignalsMixins, ControllerData):
event_system.subscribe("handle_dir_from_ipc", self.handle_dir_from_ipc) event_system.subscribe("handle_dir_from_ipc", self.handle_dir_from_ipc)
event_system.subscribe("tggl_top_main_menubar", self._tggl_top_main_menubar) event_system.subscribe("tggl_top_main_menubar", self._tggl_top_main_menubar)
def _load_widgets(self):
ScreenshotController()
def load_glade_file(self): def load_glade_file(self):
self.builder = Gtk.Builder() self.builder = Gtk.Builder()
self.builder.add_from_file(settings.get_glade_file()) # self.builder.add_from_file(settings.get_glade_file())
self.builder.expose_object("main_window", self.window) self.builder.expose_object("main_window", self.window)
settings.set_builder(self.builder) settings.set_builder(self.builder)

View File

@ -9,7 +9,6 @@ from plugins.plugins_controller import PluginsController
class ControllerData: class ControllerData:
''' ControllerData contains most of the state of the app at ay given time. It also has some support methods. ''' ''' ControllerData contains most of the state of the app at ay given time. It also has some support methods. '''

View File

@ -0,0 +1,84 @@
# Python imports
# Lib imports
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk as Gdk
from gi.repository import GLib
import pyscreenshot as capture
# Application imports
class ScreenshotController:
def __init__(self):
super(ScreenshotController, self).__init__()
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets()
def _setup_styling(self):
...
def _setup_signals(self):
...
def _subscribe_to_events(self):
event_system.subscribe("grab_entire_screen", self.grab_entire_screen)
event_system.subscribe("grab_active_window", self.grab_active_window)
event_system.subscribe("pass_to_region_handler", self.pass_to_region_handler)
event_system.subscribe("grab_selected_monitor", self.grab_selected_monitor)
def _load_widgets(self):
...
def grab_entire_screen(self):
logger.info("Grabbing Entire Screen...")
window = settings.get_main_window()
@daemon_threaded
def do_grab():
im = capture.grab(childprocess = False)
im.save( settings.generate_screenshot_name() )
GLib.idle_add(window.show)
window.hide()
do_grab()
def grab_active_window(self):
logger.info("Grabbing Active Window...")
event_system.emit("grab_delay")
screen = Gdk.get_default_root_window().get_screen()
w = screen.get_active_window()
pb = Gdk.pixbuf_get_from_window(w, *w.get_geometry())
pb.savev(settings.generate_screenshot_name(), "png", (), ())
def pass_to_region_handler(self):
logger.info("Grabbing Selected Region Stub...")
# window = settings.get_main_window()
# window.hide()
def grab_selected_monitor(self):
logger.info("Grabbing Monitor...")
window = settings.get_main_window()
monitor = event_system.emit_and_await("get_selected_monitor")
x2 = monitor.x + monitor.width
y2 = monitor.y + monitor.height
@daemon_threaded
def do_bounding_box_grab(x1, y1, x2, y2):
im = capture.grab(bbox = (x1, y1, x2, y2), childprocess = False)
im.save( settings.generate_screenshot_name() )
GLib.idle_add(window.show)
event_system.emit("grab_delay")
window.hide()
do_bounding_box_grab(monitor.x, monitor.y, x2, y2)

View File

@ -1,4 +1,5 @@
# Python imports # Python imports
import time
# Lib imports # Lib imports
import gi import gi
@ -15,6 +16,7 @@ class DelayAmount(Gtk.Box):
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
self._subscribe_to_events()
self._load_widgets() self._load_widgets()
self.show_all() self.show_all()
@ -28,6 +30,9 @@ class DelayAmount(Gtk.Box):
def _setup_signals(self): def _setup_signals(self):
... ...
def _subscribe_to_events(self):
event_system.subscribe("grab_delay", self.grab_delay)
def _load_widgets(self): def _load_widgets(self):
label = Gtk.Label("Timeout: ") label = Gtk.Label("Timeout: ")
spinner = Gtk.SpinButton() spinner = Gtk.SpinButton()
@ -36,8 +41,15 @@ class DelayAmount(Gtk.Box):
spinner.set_numeric(True) spinner.set_numeric(True)
spinner.set_snap_to_ticks(True) spinner.set_snap_to_ticks(True)
spinner.set_digits(0) spinner.set_digits(0)
spinner.set_range(1, 120) spinner.set_range(0, 120)
spinner.set_increments(1, 5) spinner.set_increments(1, 5)
self.add(label) self.add(label)
self.add(spinner) self.add(spinner)
def grab_delay(self, wait = None):
delay_amount = self.get_children()[1]
if not wait:
wait = delay_amount.get_value_as_int()
time.sleep(wait)

View File

@ -4,6 +4,8 @@
import gi import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Gio
from gi.repository import GLib
# Application imports # Application imports
from mixins.tree_nixin import TreeMixin from mixins.tree_nixin import TreeMixin
@ -16,6 +18,7 @@ class ImagesList(TreeMixin, Gtk.ScrolledWindow):
self._store = None self._store = None
self._set_file_watcher()
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
self._subscribe_to_events() self._subscribe_to_events()
@ -41,14 +44,31 @@ class ImagesList(TreeMixin, Gtk.ScrolledWindow):
self.referesh_directory_list() self.referesh_directory_list()
self.add(grid) self.add(grid)
def _set_file_watcher(self):
if settings.is_debug():
logger.debug(f"Watcher Will Not Be Set...")
return
images_dir = settings.get_screenshots_dir()
dir_watcher = Gio.File.new_for_path(f"{images_dir}") \
.monitor_directory(Gio.FileMonitorFlags.WATCH_MOVES, Gio.Cancellable())
dir_watcher.connect("changed", self._dir_watch_updates)
def _dir_watch_updates(self, file_monitor, file, other_file = None, eve_type = None, data = None):
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
Gio.FileMonitorEvent.MOVED_OUT]:
self._store.clear()
self.referesh_directory_list()
@threaded @threaded
def referesh_directory_list(self): def referesh_directory_list(self):
images = settings.get_directory_list() images = settings.get_directory_list()
images.sort() images.sort()
if len(images) != len(self._store): for image in images:
self._store.clear() GLib.idle_add(self.add_to_store, (image,))
for image in images:
GLib.idle_add(self.add_to_store, (image,))
def add_to_store(self, image): def add_to_store(self, image):
self._store.append(image) self._store.append(image)

View File

@ -14,7 +14,9 @@ class MonitorList(TreeMixin, Gtk.Box):
def __init__(self): def __init__(self):
super(MonitorList, self).__init__() super(MonitorList, self).__init__()
self._store = None self.MONITORS: [] = None
self._monitors_view = None
self._store = None
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -31,20 +33,29 @@ class MonitorList(TreeMixin, Gtk.Box):
... ...
def _subscribe_to_events(self): def _subscribe_to_events(self):
... event_system.subscribe("get_selected_monitor", self.get_selected_monitor)
def _load_widgets(self): def _load_widgets(self):
grid, self._store = self._create_treeview_widget("Monitors") grid, self._store = self._create_treeview_widget("Monitors")
self._monitors_view = grid.get_children()[0]
self._load_monitor_store() self._load_monitor_store()
grid.set_hexpand(True) grid.set_hexpand(True)
self.add(grid) self.add(grid)
def _load_monitor_store(self): def _load_monitor_store(self):
MONITORS = settings.get_monitor_data() self.MONITORS = settings.get_monitor_data()
i = 0 i = 0
for monitor in MONITORS: for monitor in self.MONITORS:
if i > 0: if i > 0:
mon = str(monitor.width) + "x" + str(monitor.height) + "+" + str(monitor.x) + "+" + str(monitor.y) mon = str(monitor.width) + "x" + str(monitor.height) + "+" + str(monitor.x) + "+" + str(monitor.y)
self._store.append([mon]) self._store.append([mon])
i += 1 i += 1
def get_selected_monitor(self):
iter = self._monitors_view.get_selection().get_selected()[1]
path = self._store.get_path(iter)
# Slot 0 is ref monitor. Need to add 1 to get proper slot
return self.MONITORS[int(str(path)) + 1]

View File

@ -37,9 +37,12 @@ class SnapshotButton(Gtk.Button):
self.set_image(image) self.set_image(image)
def _take_snapshot(self, widget = None, eve = None): def _take_snapshot(self, widget = None, eve = None):
type = event_system.emit_and_await("get_screenshot_type").get_label() active = event_system.emit_and_await("get_screenshot_type").get_label()
print(type) if "Entire Screen" in active:
# NOTE: event_system.emit("grab_entire_screen")
# 1. Get type of screenshot if "Active Window" in active:
# 2. Grab screenshot event_system.emit("grab_active_window")
# 3. Emit images list file update if "Select Region" in active:
event_system.emit("pass_to_region_handler")
if "Select Monitor" in active:
event_system.emit("grab_selected_monitor")

View File

@ -15,12 +15,11 @@ from gi.repository import GLib
from core.controller import Controller from core.controller import Controller
class ControllerStartExceptiom(Exception): class ControllerStartExceptiom(Exception):
... ...
class Window(Gtk.ApplicationWindow): class Window(Gtk.ApplicationWindow):
"""docstring for Window.""" """docstring for Window."""

View File

@ -20,7 +20,7 @@ class TreeMixin:
grid.set_model(store) grid.set_model(store)
selec.set_mode(2) selec.set_mode(2)
scroll.set_size_request(145, 96) scroll.set_size_request(145, 72)
column.pack_start(name, True) column.pack_start(name, True)
column.add_attribute(name, "text", 0) column.add_attribute(name, "text", 0)

View File

@ -2,6 +2,7 @@
import os import os
import json import json
import inspect import inspect
import datetime
# Lib imports # Lib imports
import gi import gi
@ -208,3 +209,10 @@ class Settings(StartCheckMixin, Singleton):
files.append(file) files.append(file)
return files return files
def generate_screenshot_name(self):
return f"{self._SCREENSHOTS_DIR}/scrshot_{self.get_time()}.png"
def get_time(self):
now = datetime.datetime.now()
return now.strftime("%Y-%m-%d %H:%M:%S")