Permalink
Browse files

Added "capture selection" feature.

  • Loading branch information...
ozcan committed May 15, 2013
1 parent 1968f60 commit d7696830d6dacc48a4fd7eedc79582f9e532e5df
Showing with 159 additions and 3 deletions.
  1. +151 −3 enlinuxclipper/clipper.py
  2. +8 −0 enlinuxclipper/indicator.py
View
@@ -1,4 +1,4 @@
from gi.repository import Gdk
from gi.repository import Gdk, Gtk
import cairo
import subprocess
@@ -78,9 +78,9 @@ def capture_window(self):
)
def capture_selection(self):
""" Not implemented yet. """
""" Create new SelectionWindow instance """
pass
SelectionWindow()
def play_capture_sound(self):
""" Play sound effect when screen or window captured. """
@@ -90,3 +90,151 @@ def play_capture_sound(self):
subprocess.call(['/usr/bin/canberra-gtk-play',
'--id', 'screen-capture'])
class SelectionWindow(Gtk.Window):
def __init__(self):
""" Init Selection Window """
super(SelectionWindow, self).__init__()
# basic window properties
self.set_app_paintable(True)
self.set_decorated(False)
self.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 1))
self.fullscreen()
# configure masks and connect events
event_mask = (Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK |
Gdk.EventMask.EXPOSURE_MASK |
Gdk.EventMask.KEY_PRESS_MASK |
Gdk.EventMask.KEY_RELEASE_MASK |
Gdk.EventMask.ENTER_NOTIFY_MASK |
Gdk.EventMask.LEAVE_NOTIFY_MASK |
Gdk.EventMask.POINTER_MOTION_MASK |
Gdk.EventMask.POINTER_MOTION_HINT_MASK)
self.add_events(event_mask)
self.connect("draw", self.on_draw)
self.connect("button-press-event", self.on_button_press)
self.connect("button-release-event", self.on_button_release)
self.connect("motion-notify-event", self.on_motion_notify)
self.connect('key-press-event', self.on_keypress)
# init true rgba transparency
self.screen = self.get_screen()
self.visual = self.screen.get_rgba_visual()
if self.visual != None and self.screen.is_composited():
self.set_visual(self.visual)
# get screenshot
root_win = Gdk.get_default_root_window()
width, height = root_win.get_width(), root_win.get_height()
self.screenshot = Gdk.Window.create_similar_surface(root_win,
cairo.CONTENT_COLOR,
width, height)
cairo_context = cairo.Context(self.screenshot)
Gdk.cairo_set_source_window(cairo_context, root_win, 0, 0)
cairo_context.paint()
# show window and init default rectangle
self.show_all()
self.clear_rectangle()
def clear_rectangle(self):
""" Set default rectangle """
self.drawing = False
self.finished = False
self.mousex1 = 0
self.mousey1 = 0
self.mousex2 = 0
self.mousey2 = 0
self.queue_draw()
def on_motion_notify(self, widget, event):
""" Started draw and moving mouse. """
if self.drawing:
self.mousex2 = event.x
self.mousey2 = event.y
# call on_draw function to update window.
self.queue_draw()
def on_button_press(self, widget, event):
""" Start drawing """
self.drawing = True
self.mousex1 = event.x
self.mousey1 = event.y
def on_button_release(self, widget, event):
""" Finish drawing """
self.finished = True
self.drawing = False
self.mousex2 = event.x
self.mousey2 = event.y
def on_draw(self, widget, cr):
""" This function drawing rectangle and other things. """
# fill window with semi-transparent screenshot
cr.set_source_surface(self.screenshot, 0, 0)
cr.paint_with_alpha(0.6)
# if we have a rectangle to draw.
if self.drawing or self.finished:
# draw normal screenshot into rectangle area
cr.set_source_surface(self.screenshot, 0, 0)
cr.rectangle(self.mousex1,self.mousey1,self.mousex2 - self.mousex1,self.mousey2 - self.mousey1)
cr.fill()
# draw border for rectangle.
cr.set_source_rgba(1, 0, 0, 0.5)
cr.set_dash([5,5,10,5], 0)
cr.set_line_width(1.0)
cr.rectangle(self.mousex1,self.mousey1,self.mousex2 - self.mousex1,self.mousey2 - self.mousey1)
cr.stroke()
def on_keypress(self, widget, event):
""" This function looks for key events. """
# get key name
keyval = Gdk.keyval_name(event.keyval).lower()
if keyval == 'escape':
# close window
self.hide()
self.destroy()
elif keyval == 'delete':
# delete current rectangle and set it to default
self.clear_rectangle()
elif keyval == 'return' and self.finished:
# hide selection window and play capture sound.
self.hide()
Clipper().play_capture_sound()
# create new image surface
# mousex2 - mousex1 = width
# mousey2 - mousey1 = height
# abs: because people can start drawing right to left
# int: because mouse coordinates are float.
clip = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(abs(self.mousex2 - self.mousex1)), int(abs(self.mousey2 - self.mousey1)))
clip_context = cairo.Context(clip)
# min: (look abs).
clip_context.set_source_surface(self.screenshot, 0 - min(int(self.mousex1), int(self.mousex2)), 0 - min(int(self.mousey1), int(self.mousey2)))
clip_context.paint()
# write to stream and upload
dummy_file = StringIO.StringIO()
clip.write_to_png(dummy_file)
now = datetime.datetime.now()
ENAPI.create_note(title=_("Clip ") + now.strftime("%Y-%m-%d %H:%M"),
attachment_data=dummy_file.getvalue(),
attachment_mime='image/png'
)
self.destroy()
@@ -73,6 +73,7 @@ def update_popup_menu(self):
menu.append(capture_window)
capture_selection = Gtk.MenuItem(_("Capture Selection"))
capture_selection.connect('activate', self.capture_selection_callback)
menu.append(capture_selection)
create_from_file = Gtk.MenuItem(_("Create from file"))
@@ -133,6 +134,13 @@ def capture_window_callback(self, event):
"""
Clipper().capture_window()
def capture_selection_callback(self, event):
"""
Works as capture screen.
"""
Clipper().capture_selection()
def create_from_clipboard_callback(self, event):
"""
Get image data from X clipboard if available, and create new note with

0 comments on commit d769683

Please sign in to comment.