Upgraded region select interface
This commit is contained in:
parent
b527d8ed9f
commit
f731796c99
@ -1,4 +1,5 @@
|
||||
# Python imports
|
||||
import time
|
||||
|
||||
# Lib imports
|
||||
import gi
|
||||
@ -76,9 +77,30 @@ class ScreenshotController:
|
||||
window = settings.get_main_window()
|
||||
window.show()
|
||||
|
||||
def _grab_region(self, region_window):
|
||||
def _grab_region(self, region_window, x1, y1, x2, y2):
|
||||
def show_region_window():
|
||||
# NOTE: No clue why showing window has it move outta prior place.
|
||||
# So, move back to original spot before showing...
|
||||
region_window.move(0, 0)
|
||||
region_window.show()
|
||||
|
||||
@daemon_threaded
|
||||
def do_bounding_box_grab(x1, y1, x2, y2):
|
||||
while region_window.is_visible():
|
||||
...
|
||||
|
||||
time.sleep(0.5)
|
||||
im = capture.grab(bbox = (x1, y1, x2, y2), childprocess = False)
|
||||
im.save( settings.generate_screenshot_name() )
|
||||
GLib.idle_add(show_region_window)
|
||||
|
||||
region_window.hide()
|
||||
offset = 1
|
||||
do_bounding_box_grab(x1 - offset, y1 - offset, x2 + offset, y2 + offset)
|
||||
|
||||
def _old_grab_region(self, region_window):
|
||||
logger.info("Grabbing Selected Region...")
|
||||
x, y = region_window.get_position()
|
||||
x1, y1 = region_window.get_position()
|
||||
w, h = region_window.get_size()
|
||||
x2 = x + w
|
||||
y2 = y + h
|
||||
@ -94,13 +116,14 @@ class ScreenshotController:
|
||||
while region_window.is_visible():
|
||||
...
|
||||
|
||||
time.sleep(0.5)
|
||||
im = capture.grab(bbox = (x1, y1, x2, y2), childprocess = False)
|
||||
im.save( settings.generate_screenshot_name() )
|
||||
GLib.idle_add(show_region_window)
|
||||
|
||||
region_window.hide()
|
||||
offset = 1
|
||||
do_bounding_box_grab(x - offset, y - offset, x2 + offset, y2 + offset)
|
||||
do_bounding_box_grab(x1 - offset, y1 - offset, x2 + offset, y2 + offset)
|
||||
|
||||
|
||||
def grab_selected_monitor(self):
|
||||
|
3
src/core/widgets/_old_region/__init__.py
Normal file
3
src/core/widgets/_old_region/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
Widgets Module
|
||||
"""
|
72
src/core/widgets/_old_region/window.py
Normal file
72
src/core/widgets/_old_region/window.py
Normal file
@ -0,0 +1,72 @@
|
||||
# Python imports
|
||||
|
||||
# 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
|
||||
|
||||
# Application imports
|
||||
from .body_grid import BodyGrid
|
||||
|
||||
|
||||
|
||||
class RegionWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
super(RegionWindow, self).__init__()
|
||||
|
||||
self._set_window_data()
|
||||
self._setup_styling()
|
||||
self._setup_signals()
|
||||
self._subscribe_to_events()
|
||||
self._load_widgets()
|
||||
|
||||
|
||||
def _setup_styling(self):
|
||||
self.set_default_size(600, 480)
|
||||
self.set_keep_above(True)
|
||||
self.set_deletable(False)
|
||||
self.set_decorated(False)
|
||||
self.set_resizable(True)
|
||||
self.set_skip_pager_hint(True)
|
||||
self.set_skip_taskbar_hint(True)
|
||||
self.set_has_resize_grip(True)
|
||||
|
||||
|
||||
def _setup_signals(self):
|
||||
...
|
||||
|
||||
def _subscribe_to_events(self):
|
||||
event_system.subscribe("show_region_window", self._show_region_window)
|
||||
|
||||
def _load_widgets(self):
|
||||
gdk_window = self.get_screen().get_root_window()
|
||||
self.add( BodyGrid(self, gdk_window) )
|
||||
|
||||
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.0) )
|
||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
||||
cr.paint()
|
||||
cr.set_operator(cairo.OPERATOR_OVER)
|
||||
|
||||
|
||||
def _show_region_window(self):
|
||||
self.show()
|
@ -1,3 +1,3 @@
|
||||
"""
|
||||
Widgets Module
|
||||
Region Module
|
||||
"""
|
167
src/core/widgets/region/draw_area.py
Normal file
167
src/core/widgets/region/draw_area.py
Normal file
@ -0,0 +1,167 @@
|
||||
# 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
|
||||
|
||||
# Application imports
|
||||
from .draw_types.draw_cross import DrawCross
|
||||
from .draw_types.draw_grab_region import DrawGrabRegion
|
||||
|
||||
|
||||
|
||||
class DrawArea(Gtk.DrawingArea):
|
||||
def __init__(self):
|
||||
super(DrawArea, self).__init__()
|
||||
|
||||
|
||||
self.draw_type: DrawType = DrawCross()
|
||||
self.region_mode: bool = False
|
||||
self.grab_mode: bool = False
|
||||
self.mouse_x: int = 0
|
||||
self.mouse_y: int = 0
|
||||
|
||||
|
||||
self._setup_style()
|
||||
self._setup_signals()
|
||||
self._load_widgets()
|
||||
|
||||
self.show()
|
||||
|
||||
self._render_start_cross_hair()
|
||||
|
||||
|
||||
def _setup_style(self):
|
||||
self.set_property("can-focus", True)
|
||||
|
||||
def _setup_signals(self):
|
||||
self.add_events( Gdk.EventMask.ALL_EVENTS_MASK )
|
||||
|
||||
self.connect("motion-notify-event", self._motion_notify_event)
|
||||
self.connect("button-press-event", self._button_press_event)
|
||||
self.connect("button-release-event", self._button_release_event)
|
||||
self.connect("realize", self._realize)
|
||||
self.connect("draw", self._draw)
|
||||
|
||||
def _load_widgets(self):
|
||||
...
|
||||
|
||||
def _render_start_cross_hair(self):
|
||||
self.mouse_x = self.get_allocated_width() / 2
|
||||
self.mouse_y = self.get_allocated_height() / 2
|
||||
self.queue_draw()
|
||||
|
||||
def _realize(self, widget):
|
||||
self._hide_cursor()
|
||||
|
||||
def _draw(self, area, cr):
|
||||
self.draw_type.draw(area, cr)
|
||||
|
||||
def _motion_notify_event(self, widget, eve):
|
||||
if self.grab_mode: return
|
||||
self._set_coords(eve)
|
||||
self.queue_draw()
|
||||
|
||||
def _button_press_event(self, widget, eve):
|
||||
if self.grab_mode: return
|
||||
if not eve.button == 1: return
|
||||
self._set_to_region_mode(eve)
|
||||
|
||||
def _button_release_event(self, widget, eve):
|
||||
if self.grab_mode and eve.button == 2: # m-click
|
||||
self._do_grab()
|
||||
return
|
||||
|
||||
if not eve.button in [1, 3]: return # l or r-click
|
||||
|
||||
self._show_cursor()
|
||||
|
||||
if eve.button == 3: # r-click
|
||||
event_system.emit("grab_region_hide", (self.get_parent(),))
|
||||
return
|
||||
|
||||
if self.grab_mode:
|
||||
self._hide_cursor()
|
||||
self._unset_grab_mode(eve)
|
||||
return
|
||||
|
||||
self._set_to_grab_mode(eve)
|
||||
|
||||
def _show_cursor(self):
|
||||
window = self.get_parent()
|
||||
watch_cursor = Gdk.Cursor(Gdk.CursorType.ARROW)
|
||||
window.get_window().set_cursor(watch_cursor)
|
||||
|
||||
def _hide_cursor(self):
|
||||
window = self.get_parent()
|
||||
watch_cursor = Gdk.Cursor(Gdk.CursorType.BLANK_CURSOR )
|
||||
window.get_window().set_cursor(watch_cursor)
|
||||
|
||||
def _set_to_region_mode(self, eve):
|
||||
self.region_mode = True
|
||||
self.draw_type = DrawGrabRegion()
|
||||
self._set_coords(eve)
|
||||
|
||||
def _set_to_grab_mode(self, eve):
|
||||
self._set_coords(eve)
|
||||
self.region_mode = False
|
||||
self.grab_mode = True
|
||||
|
||||
def _unset_grab_mode(self, eve):
|
||||
self.grab_mode = False
|
||||
self.draw_type = DrawCross()
|
||||
self._set_coords(eve)
|
||||
self.queue_draw()
|
||||
|
||||
def _set_coords(self, eve):
|
||||
if not self.region_mode:
|
||||
self.mouse_x = int(eve.x)
|
||||
self.mouse_y = int(eve.y)
|
||||
self.region_start_x = int(eve.x)
|
||||
self.region_start_y = int(eve.y)
|
||||
else:
|
||||
self.region_end_x = int(eve.x)
|
||||
self.region_end_y = int(eve.y)
|
||||
|
||||
def _do_grab(self):
|
||||
sx = self.region_start_x
|
||||
sy = self.region_start_y
|
||||
ex = self.region_end_x
|
||||
ey = self.region_end_y
|
||||
|
||||
x1 = sx
|
||||
y1 = sy
|
||||
x2 = ex
|
||||
y2 = ey
|
||||
|
||||
if sx > ex and sy < ey: # NE to SW
|
||||
x1 = sx - (sx - ex)
|
||||
y1 = sy
|
||||
x2 = sx
|
||||
y2 = sy + (ey - sy)
|
||||
elif not ex > sx and not ey > sy: # SE to NW
|
||||
x1 = ex
|
||||
y1 = ey
|
||||
x2 = sx
|
||||
y2 = sy
|
||||
elif ex > sx and ey < sy: # SW to NE
|
||||
x1 = ex - (ex - sx)
|
||||
y1 = ey
|
||||
x2 = ex
|
||||
y2 = ey + (sy - ey)
|
||||
|
||||
event_system.emit(
|
||||
"grab_region",
|
||||
(
|
||||
self.get_parent(),
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
)
|
||||
)
|
||||
|
||||
|
3
src/core/widgets/region/draw_types/__init__.py
Normal file
3
src/core/widgets/region/draw_types/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
"""
|
||||
Draw Types Module
|
||||
"""
|
31
src/core/widgets/region/draw_types/draw_cross.py
Normal file
31
src/core/widgets/region/draw_types/draw_cross.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from .draw_type_base import DrawTypeBase
|
||||
|
||||
|
||||
|
||||
class DrawCross(DrawTypeBase):
|
||||
def __init__(self):
|
||||
super(DrawCross, self).__init__()
|
||||
|
||||
|
||||
def draw(self, area, cr):
|
||||
if not area.mouse_x or not area.mouse_y: return
|
||||
|
||||
cr.set_source_rgba(1.0, 1.0, 1.0, 1.0)
|
||||
cr.set_line_width(1.0)
|
||||
cr.set_line_cap(2) # 0 = BUTT, 1 = ROUND, 2 = SQUARE
|
||||
cr.set_line_join(1) # 0 = BEVEL, 1 = MITER, 2 = ROUND
|
||||
|
||||
# Horizon
|
||||
cr.move_to(0, area.mouse_y)
|
||||
cr.line_to(area.get_allocated_width(), area.mouse_y)
|
||||
cr.stroke()
|
||||
|
||||
# Vertical
|
||||
cr.move_to(area.mouse_x, 0)
|
||||
cr.line_to(area.mouse_x, area.get_allocated_height())
|
||||
cr.stroke()
|
48
src/core/widgets/region/draw_types/draw_grab_region.py
Normal file
48
src/core/widgets/region/draw_types/draw_grab_region.py
Normal file
@ -0,0 +1,48 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
from .draw_type_base import DrawTypeBase
|
||||
|
||||
|
||||
|
||||
class DrawGrabRegion(DrawTypeBase):
|
||||
def __init__(self):
|
||||
super(DrawGrabRegion, self).__init__()
|
||||
|
||||
|
||||
def draw(self, area, cr):
|
||||
cr.set_source_rgba(1.0, 1.0, 0.0, 1.0)
|
||||
cr.set_line_width(1.0)
|
||||
cr.set_line_cap(2) # 0 = BUTT, 1 = ROUND, 2 = SQUARE
|
||||
cr.set_line_join(1) # 0 = BEVEL, 1 = MITER, 2 = ROUND
|
||||
|
||||
self._draw_start_cross(area, cr)
|
||||
self._draw_end_cross(area, cr)
|
||||
|
||||
def _draw_start_cross(self, area, cr):
|
||||
# Horizon
|
||||
cr.move_to(0, area.region_start_y)
|
||||
cr.line_to(area.get_allocated_width(), area.region_start_y)
|
||||
cr.stroke()
|
||||
|
||||
# Vertical
|
||||
cr.move_to(area.region_start_x, 0)
|
||||
cr.line_to(area.region_start_x, area.get_allocated_height())
|
||||
cr.stroke()
|
||||
|
||||
def _draw_end_cross(self, area, cr):
|
||||
# Horizon
|
||||
cr.move_to(0, area.region_end_y)
|
||||
cr.line_to(area.get_allocated_width(), area.region_end_y)
|
||||
cr.stroke()
|
||||
|
||||
# Vertical
|
||||
cr.move_to(area.region_end_x, 0)
|
||||
cr.line_to(area.region_end_x, area.get_allocated_height())
|
||||
cr.stroke()
|
||||
|
||||
|
||||
|
||||
|
15
src/core/widgets/region/draw_types/draw_type_base.py
Normal file
15
src/core/widgets/region/draw_types/draw_type_base.py
Normal file
@ -0,0 +1,15 @@
|
||||
# Python imports
|
||||
|
||||
# Lib imports
|
||||
|
||||
# Application imports
|
||||
|
||||
|
||||
|
||||
class OverrideExceptionw(Exception):
|
||||
...
|
||||
|
||||
|
||||
class DrawTypeBase:
|
||||
def draw(self, widget, cr):
|
||||
raise OverrideException("Method hasn't been overriden...")
|
@ -9,7 +9,7 @@ from gi.repository import Gtk
|
||||
from gi.repository import Gdk
|
||||
|
||||
# Application imports
|
||||
from .body_grid import BodyGrid
|
||||
from .draw_area import DrawArea
|
||||
|
||||
|
||||
|
||||
@ -25,7 +25,9 @@ class RegionWindow(Gtk.Window):
|
||||
|
||||
|
||||
def _setup_styling(self):
|
||||
self.set_default_size(600, 480)
|
||||
screen = Gdk.Screen.get_default()
|
||||
ctx = self.get_style_context()
|
||||
|
||||
self.set_keep_above(True)
|
||||
self.set_deletable(False)
|
||||
self.set_decorated(False)
|
||||
@ -34,6 +36,14 @@ class RegionWindow(Gtk.Window):
|
||||
self.set_skip_taskbar_hint(True)
|
||||
self.set_has_resize_grip(True)
|
||||
|
||||
self.move(0, 0)
|
||||
self.set_size_request(
|
||||
*self.get_screen_size(
|
||||
Gdk.Display.get_default()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _setup_signals(self):
|
||||
...
|
||||
|
||||
@ -41,8 +51,7 @@ class RegionWindow(Gtk.Window):
|
||||
event_system.subscribe("show_region_window", self._show_region_window)
|
||||
|
||||
def _load_widgets(self):
|
||||
gdk_window = self.get_screen().get_root_window()
|
||||
self.add( BodyGrid(self, gdk_window) )
|
||||
self.add( DrawArea() )
|
||||
|
||||
def _set_window_data(self) -> None:
|
||||
screen = self.get_screen()
|
||||
@ -51,7 +60,6 @@ class RegionWindow(Gtk.Window):
|
||||
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()
|
||||
@ -60,6 +68,19 @@ class RegionWindow(Gtk.Window):
|
||||
styleContext = Gtk.StyleContext()
|
||||
styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
||||
|
||||
def get_screen_size(self, display):
|
||||
mon_geoms = [
|
||||
display.get_monitor(i).get_geometry()
|
||||
for i in range(display.get_n_monitors())
|
||||
]
|
||||
|
||||
x0 = min(r.x for r in mon_geoms)
|
||||
y0 = min(r.y for r in mon_geoms)
|
||||
x1 = max(r.x + r.width for r in mon_geoms)
|
||||
y1 = max(r.y + r.height for r in mon_geoms)
|
||||
|
||||
return x1 - x0, y1 - y0
|
||||
|
||||
def _area_draw(self, widget: Gtk.ApplicationWindow, cr: cairo.Context) -> None:
|
||||
cr.set_source_rgba( *(0, 0, 0, 0.0) )
|
||||
cr.set_operator(cairo.OPERATOR_SOURCE)
|
||||
|
Loading…
Reference in New Issue
Block a user