From fd203712450edbe9a54f66d50edd0f522979762e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Charette?= Date: Sun, 12 Oct 2008 09:39:11 +0000 Subject: [PATCH] allow user to select media image subsection using the mouse svn: r11140 --- src/Editors/_EditMediaRef.py | 102 +++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/src/Editors/_EditMediaRef.py b/src/Editors/_EditMediaRef.py index 6c15eb93e..2854b3a9d 100644 --- a/src/Editors/_EditMediaRef.py +++ b/src/Editors/_EditMediaRef.py @@ -117,9 +117,17 @@ class EditMediaRef(EditReference): self.top.get_widget("type").set_text("") def _setup_fields(self): - ebox = self.top.get_widget('eventbox') - ebox.connect('button-press-event', self.button_press_event) - + ebox_shared = self.top.get_widget('eventbox') + ebox_shared.connect('button-press-event', self.button_press_event) + + if not self.dbstate.db.readonly: + self.button_press_coords = (0, 0) + ebox_ref = self.top.get_widget('eventbox1') + ebox_ref.connect('button-press-event', self.button_press_event_ref) + ebox_ref.connect('button-release-event', self.button_release_event_ref) + ebox_ref.add_events(gtk.gdk.BUTTON_PRESS_MASK) + ebox_ref.add_events(gtk.gdk.BUTTON_RELEASE_MASK) + self.pixmap = self.top.get_widget("pixmap") coord = self.source_ref.get_rectangle() @@ -381,6 +389,94 @@ class EditMediaRef(EditReference): if event.button==1 and event.type == gtk.gdk._2BUTTON_PRESS: self.view_media(obj) + def button_press_event_ref(self, widget, event): + """ + Handle the button-press-event generated by the eventbox + parent of the subpixmap. Remember these coordinates + so we can crop the picture when button-release-event + is received. + """ + self.button_press_coords = (event.x, event.y) + + def button_release_event_ref(self, widget, event): + """ + Handle the button-release-event generated by the eventbox + parent of the subpixmap. Crop the picture accordingly. + """ + + # reset the crop on double-click or click+CTRL + if (event.button==1 and event.type == gtk.gdk._2BUTTON_PRESS) or \ + (event.button==1 and (event.state & gtk.gdk.CONTROL_MASK) ): + self.corner1_x_spinbutton.set_value(0) + self.corner1_y_spinbutton.set_value(0) + self.corner2_x_spinbutton.set_value(100) + self.corner2_y_spinbutton.set_value(100) + + else: + + # ensure the clicks happened at least 5 pixels away from each other + new_x1 = min(self.button_press_coords[0], event.x) + new_y1 = min(self.button_press_coords[1], event.y) + new_x2 = max(self.button_press_coords[0], event.x) + new_y2 = max(self.button_press_coords[1], event.y) + + if new_x2 - new_x1 >= 5 and new_y2 - new_y1 >= 5: + + # get the image size and calculate the X and Y offsets + # (image is centered when smaller than const.THUMBSCALE) + pixbuf = self.subpixmap.get_pixbuf(); + w = pixbuf.get_width() + h = pixbuf.get_height() + x = (const.THUMBSCALE - w) / 2 + y = (const.THUMBSCALE - h) / 2 + + # if the click was outside of the image, + # bring it within the boundaries + if new_x1 < x: + new_x1 = x + if new_y1 < y: + new_y1 = y + if new_x2 >= x + w: + new_x2 = x + w - 1 + if new_y2 >= y + h: + new_y2 = y + h - 1 + + # get the old spinbutton % values + old_x1 = self.corner1_x_spinbutton.get_value() + old_y1 = self.corner1_y_spinbutton.get_value() + old_x2 = self.corner2_x_spinbutton.get_value() + old_y2 = self.corner2_y_spinbutton.get_value() + delta_x = old_x2 - old_x1 # horizontal scale + delta_y = old_y2 - old_y1 # vertical scale + + # Took a while to figure out the math here. + # + # 1) figure out the current crop % values + # by doing the following: + # + # xp = click_location_x / width * 100 + # yp = click_location_y / height * 100 + # + # but remember that click_location_x and _y + # might not be zero-based for non-rectangular + # images, so subtract the pixbuf "x" and "y" + # to bring the values back to zero-based + # + # 2) the minimum value cannot be less than the + # existing crop value, so add the current + # minimum to the new values + + new_x1 = old_x1 + delta_x * (new_x1 - x) / w + new_y1 = old_y1 + delta_y * (new_y1 - y) / h + new_x2 = old_x1 + delta_x * (new_x2 - x) / w + new_y2 = old_y1 + delta_y * (new_y2 - y) / h + + # set the new values + self.corner1_x_spinbutton.set_value(new_x1) + self.corner1_y_spinbutton.set_value(new_y1) + self.corner2_x_spinbutton.set_value(new_x2) + self.corner2_y_spinbutton.set_value(new_y2) + def _update_addmedia(self, obj): """ Called when the add media dialog has been called.