Replace crop drawing code with Cairo
Thomas Ross
3 years ago
24 | 24 | |
25 | 25 | gi.require_version("Gtk", "3.0") |
26 | 26 | from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, Gio |
27 | import cairo | |
27 | 28 | import os, sys, getopt, configparser, string, gc |
28 | 29 | import random, urllib.request, gettext, locale |
29 | 30 | import stat, time, subprocess, shutil, filecmp |
4705 | 4706 | | Gdk.EventMask.BUTTON_RELEASE_MASK |
4706 | 4707 | ) |
4707 | 4708 | image.connect( |
4708 | "expose-event", | |
4709 | self.crop_image_expose_cb, | |
4710 | crop_pixbuf, | |
4711 | image_width, | |
4712 | image_height, | |
4709 | "draw", self.draw_crop_image, crop_pixbuf, image_width, image_height, | |
4713 | 4710 | ) |
4714 | 4711 | image.connect( |
4715 | 4712 | "motion_notify_event", |
4716 | 4713 | self.crop_image_mouse_moved, |
4717 | image, | |
4718 | 4714 | 0, |
4719 | 4715 | 0, |
4720 | 4716 | x, |
4726 | 4722 | width_adj, |
4727 | 4723 | height_adj, |
4728 | 4724 | ) |
4729 | image.connect("button_press_event", self.crop_image_button_press, image) | |
4725 | image.connect("button_press_event", self.crop_image_button_press) | |
4730 | 4726 | image.connect("button_release_event", self.crop_image_button_release) |
4731 | 4727 | self.x_changed = x.connect( |
4732 | 4728 | "value-changed", |
4898 | 4894 | self.drawing_crop_rectangle = True |
4899 | 4895 | self.update_rectangle = True |
4900 | 4896 | self.crop_image_mouse_moved( |
4897 | image, | |
4901 | 4898 | None, |
4902 | None, | |
4903 | image, | |
4904 | 4899 | x2, |
4905 | 4900 | y2, |
4906 | 4901 | x, |
4915 | 4910 | self.update_rectangle = False |
4916 | 4911 | self.drawing_crop_rectangle = False |
4917 | 4912 | |
4918 | def crop_image_expose_cb(self, image, event, pixbuf, width, height): | |
4919 | image.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0, width, height) | |
4913 | def draw_crop_image(self, widget, cr, pixbuf, width, height): | |
4914 | Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0) | |
4915 | cr.paint() | |
4916 | ||
4917 | if self.rect is not None: | |
4918 | cr.set_source_rgb(1, 1, 1) | |
4919 | cr.set_operator(cairo.Operator.DIFFERENCE) | |
4920 | cr.rectangle(self.rect[0], self.rect[1], self.rect[2], self.rect[3]) | |
4921 | cr.stroke() | |
4920 | 4922 | |
4921 | 4923 | def crop_image_mouse_moved( |
4922 | 4924 | self, |
4923 | 4925 | widget, |
4924 | 4926 | event, |
4925 | image, | |
4926 | 4927 | x2, |
4927 | 4928 | y2, |
4928 | 4929 | x, |
4938 | 4939 | x2, y2, state = self.get_pointer(event.window) |
4939 | 4940 | if self.drawing_crop_rectangle: |
4940 | 4941 | if self.crop_rectangle != None or self.update_rectangle: |
4941 | gc = image.window.new_gc(function=Gdk.INVERT) | |
4942 | if self.rect != None: | |
4943 | # Get rid of the previous drawn rectangle: | |
4944 | image.window.draw_rectangle( | |
4945 | gc, | |
4946 | False, | |
4947 | self.rect[0], | |
4948 | self.rect[1], | |
4949 | self.rect[2], | |
4950 | self.rect[3], | |
4951 | ) | |
4952 | 4942 | self.rect = [0, 0, 0, 0] |
4953 | 4943 | if self.crop_rectangle[0] > x2: |
4954 | 4944 | self.rect[0] = x2 |
4962 | 4952 | else: |
4963 | 4953 | self.rect[1] = self.crop_rectangle[1] |
4964 | 4954 | self.rect[3] = y2 - self.crop_rectangle[1] |
4965 | image.window.draw_rectangle( | |
4966 | gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3] | |
4955 | ||
4956 | region = cairo.Region( | |
4957 | cairo.RectangleInt(0, 0, image_width, image_height) | |
4967 | 4958 | ) |
4959 | window = widget.get_window() | |
4960 | drawing_context = window.begin_draw_frame(region) | |
4961 | cr = drawing_context.get_cairo_context() | |
4962 | widget.draw(cr) | |
4963 | window.end_draw_frame(drawing_context) | |
4964 | ||
4968 | 4965 | # Convert the rectangle coordinates of the current image |
4969 | 4966 | # to coordinates of pixbuf_original |
4970 | 4967 | if self.rect[0] < 0: |
5040 | 5037 | width.handler_unblock(self.width_changed) |
5041 | 5038 | height.handler_unblock(self.height_changed) |
5042 | 5039 | |
5043 | def crop_image_button_press(self, widget, event, image): | |
5040 | def crop_image_button_press(self, widget, event): | |
5044 | 5041 | x, y, state = self.get_pointer(event.window) |
5045 | 5042 | if state & Gdk.ModifierType.BUTTON1_MASK: |
5046 | 5043 | self.drawing_crop_rectangle = True |
5047 | 5044 | self.crop_rectangle = [x, y] |
5048 | gc = image.window.new_gc(function=Gdk.INVERT) | |
5049 | 5045 | if self.rect != None: |
5050 | # Get rid of the previous drawn rectangle: | |
5051 | image.window.draw_rectangle( | |
5052 | gc, False, self.rect[0], self.rect[1], self.rect[2], self.rect[3] | |
5046 | region = cairo.Region( | |
5047 | cairo.RectangleInt( | |
5048 | self.rect[0], self.rect[1], self.rect[2], self.rect[3] | |
5049 | ) | |
5053 | 5050 | ) |
5051 | window = widget.get_window() | |
5052 | drawing_context = window.begin_draw_frame(region) | |
5053 | cr = drawing_context.get_cairo_context() | |
5054 | widget.draw(cr) | |
5055 | window.end_draw_frame(drawing_context) | |
5054 | 5056 | self.rect = None |
5055 | 5057 | |
5056 | 5058 | def crop_image_button_release(self, widget, event): |