Created
December 11, 2016 23:18
-
-
Save oz123/acf6d757a1a1137bc0c514b5fb606bb4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
from __future__ import division | |
import math | |
import time | |
import cairo | |
import gi | |
gi.require_version('Gtk', '3.0') | |
from gi.repository import Gtk, Gdk | |
from gi.repository.GdkPixbuf import Pixbuf | |
def clear_surface(w, h, surface): | |
cr = cairo.Context(surface) | |
cr.set_source_rgb(0, 0, 0) | |
cr.paint() | |
del cr | |
def draw_brush(widget, x, y, odata, width=12.5, r=220/255, g=240/255, b=90/255, alpha=0.5): | |
cr = cairo.Context(widget.surface) | |
cr.set_source_rgba(r, g, b, alpha) | |
cr.set_line_width(width) | |
cr.set_line_cap(1) | |
cr.set_line_join(cairo.LINE_JOIN_ROUND) | |
cr.new_path() | |
head = odata[-2] | |
point = odata[-1] | |
cr.move_to(head['x'], head['y']+2.5) | |
cr.line_to(point['x'], point['y']+1.5) | |
cr.stroke() | |
class Example(Gtk.Window): | |
def __init__(self): | |
super(Example, self).__init__() | |
self.set_border_width(8) | |
self.odata = [] | |
self.box = Gtk.Box(spacing=6) | |
self.add(self.box) | |
da = Gtk.DrawingArea() | |
self.box.pack_start(da, True, True, 0) | |
window = Gdk.get_default_root_window() | |
self.set_default_size(400, 400) | |
da.surface = None | |
da.connect('draw', self.draw) | |
da.connect('configure-event', self.configure_event_cb) | |
da.connect('motion-notify-event', self.motion_notify_event_cb) | |
da.connect('button-press-event', self.button_press_event_cb) | |
da.connect('button-release-event', self.button_release) | |
da.set_events(da.get_events() | | |
Gdk.EventMask.BUTTON_PRESS_MASK | | |
Gdk.EventMask.POINTER_MOTION_MASK | | |
Gdk.EventMask.BUTTON_RELEASE_MASK) | |
self.da = da | |
self.connect('destroy', self.close_window) | |
self.show_all() | |
def button_release(self, widget, event): | |
self.odata = [] | |
def draw(self, widget, cr): | |
cr.set_source_surface(self.da.surface, 0, 0) | |
cr.paint() | |
return False | |
def configure_event_cb(self, widget, event): | |
""" | |
Called the windows is first created. Here we also load the | |
background image, via the call to clear | |
""" | |
self.odata = [] | |
if self.da.surface is not None: | |
del self.da.surface | |
self.da.surface = None | |
win = widget.get_window() | |
w = widget.get_allocated_width() | |
h = widget.get_allocated_height() | |
widget.surface = win.create_similar_surface( | |
cairo.CONTENT_COLOR, | |
w, h) | |
clear_surface(w, h, widget.surface) | |
return True | |
def button_press_event_cb(self, widget, event): | |
""" | |
When the signal handler returns True, it means no further processing is done. | |
E.g. there will be no propagation further. On the contrary, sending False, | |
propagates the signal further. | |
See documentation here: | |
https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget-button-press-event | |
""" | |
if widget.surface is None: | |
return False | |
if event.button == Gdk.BUTTON_PRIMARY: | |
if self.odata: | |
self.odata = [] | |
point = {'x': event.x, 'y': event.y, 'd': False} | |
self.odata.append(point) | |
pass | |
elif event.button == Gdk.BUTTON_SECONDARY: | |
win = widget.get_window() | |
width = widget.get_allocated_width() | |
height = widget.get_allocated_height() | |
pixbuf = Gdk.pixbuf_get_from_window(win, 0, 0, | |
width, height) | |
clear_surface(width*0.95, height*0.95, widget.surface) | |
widget.queue_draw() | |
return False | |
def motion_notify_event_cb(self, widget, event): | |
if widget.surface is None: | |
return False | |
if event.state & Gdk.EventMask.BUTTON_PRESS_MASK: | |
point = {'x': event.x, 'y': event.y, 'd': False} | |
self.odata.append(point) | |
draw_brush(self.da, event.x, event.y, self.odata) | |
widget.queue_draw() | |
return True | |
def close_window(self, window): | |
if self.da is not None: | |
del self.da.surface | |
self.da.surface = None | |
Gtk.main_quit() | |
def main(): | |
Example() | |
Gtk.main() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment