diff options
author | Gonzalo Odiard <godiard@gmail.com> | 2013-12-24 15:01:29 (GMT) |
---|---|---|
committer | Gonzalo Odiard <godiard@gmail.com> | 2013-12-24 15:01:29 (GMT) |
commit | 0540d0801c386954182f48743ba3b51bf982dc57 (patch) | |
tree | e19fbe2f4caabd1f357556927fee2758acd3310d | |
parent | 2483b1d573160d40430485c003a9d8108fef9709 (diff) |
Resize and move background image in a box - SL #2843
Signed-off-by: Jorge Alberto Gómez López <gomezlopez.jorge96@gmail.com>
Reviewed-by: Gonzalo Odiard <gonzalo@laptop.org>
-rw-r--r-- | historietaactivity.py | 85 | ||||
-rw-r--r-- | icons/contract-coordinates.svg | 79 | ||||
-rw-r--r-- | persistencia.py | 14 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | reorderwindow.py | 352 |
5 files changed, 509 insertions, 23 deletions
diff --git a/historietaactivity.py b/historietaactivity.py index 3df015c..d23ae1b 100644 --- a/historietaactivity.py +++ b/historietaactivity.py @@ -22,6 +22,7 @@ from toolbar import GlobesManager from slideview import SlideView from reorderwindow import ReorderView +from reorderwindow import ImageEditorView import time from sugar3.datastore import datastore @@ -93,6 +94,12 @@ class HistorietaActivity(activity.Activity): toolbar_box.toolbar.insert(reorder_img_btn, -1) reorder_img_btn.show() + bgchange = ToolButton(icon_name='contract-coordinates') + bgchange.set_tooltip(_('Edit background image')) + bgchange.connect('clicked', self.__bgchange_clicked_cb) + toolbar_box.toolbar.insert(bgchange, -1) + bgchange.show() + separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) @@ -277,6 +284,10 @@ class HistorietaActivity(activity.Activity): reorderwin = ReorderView(self) reorderwin.show_all() + def __bgchange_clicked_cb(self, button): + editorwin = ImageEditorView(self.page.get_active_box()) + editorwin.show_all() + def _save_as_pdf(self, widget): file_name = os.path.join(self.get_activity_root(), 'instance', @@ -444,9 +455,10 @@ class Page(Gtk.VBox): self.pack_start(self._internal_box, True, True, 0) self.show_all() - def add_box_from_journal_image(self, image_file_name): + def add_box_from_journal_image(self, image_file_name, x=0, y=0, + w=-1, h=-1): posi = len(self.boxs) - 1 - box = ComicBox(self, image_file_name, posi + 1) + box = ComicBox(self, image_file_name, posi + 1, x, y, w, h) reng = int(posi / 2) column = posi - (reng * 2) @@ -481,10 +493,16 @@ class Page(Gtk.VBox): class ComicBox(Gtk.EventBox): - def __init__(self, page, image_file_name, posi): + def __init__(self, page, image_file_name, posi, + x=0, y=0, width=0, height=0): print ('Cuadro INIT') Gtk.EventBox.__init__(self) + self.img_x = x + self.img_y = y + self.img_w = width + self.img_h = height + self._page = page self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color()) @@ -542,8 +560,7 @@ class ComicBox(Gtk.EventBox): self.show_all() def set_globo_activo(self, globo): - if self._globo_activo is not None and \ - self._globo_activo != globo: + if self._globo_activo is not None and self._globo_activo != globo: self._globo_activo.set_selected(False) if globo is not None: globo.set_selected(True) @@ -625,6 +642,8 @@ class ComicBox(Gtk.EventBox): os.path.join(instance_path, self.image_name)) else: pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image_name) + + """ width_pxb = pixbuf.get_width() height_pxb = pixbuf.get_height() scale = (self.width) / (1.0 * width_pxb) @@ -655,6 +674,62 @@ class ComicBox(Gtk.EventBox): Gdk.cairo_set_source_pixbuf(ct, pixbuf, 0, 0) ct.paint() self.image.flush() + """ + + img_scaled = False + if self.img_w == -1 and pixbuf.get_width() > self.width: + self.img_w = self.width + + width_pxb = pixbuf.get_width() + height_pxb = pixbuf.get_height() + scale = (self.width) / (1.0 * width_pxb) + self.img_h = int(scale * height_pxb) + img_scaled = True + elif self.img_w == -1 and pixbuf.get_width() == self.width: + self.img_w = self.width + self.img_h = pixbuf.get_height() + + self.pixbuf = pixbuf + + self.image = ctx.get_target().create_similar( + cairo.CONTENT_COLOR_ALPHA, self.width, BOX_HEIGHT) + + pixb_scaled = pixbuf.scale_simple( + int(self.img_w), + int(self.img_h), GdkPixbuf.InterpType.BILINEAR) + ct = cairo.Context(self.image) + Gdk.cairo_set_source_pixbuf(ct, pixb_scaled, + self.img_x, self.img_y) + ct.paint() + + if (not self.image_saved) and img_scaled: + self.image_saved = True + # print instance_path + image_file_name = 'image' + str(self.posi) + '.png' + print "Grabamos: " + image_file_name + sav_img = ctx.get_target().create_similar( + cairo.CONTENT_COLOR_ALPHA, self.img_w, self.img_h) + ct2 = cairo.Context(sav_img) + Gdk.cairo_set_source_pixbuf(ct2, pixb_scaled, 0, 0) + ct2.paint() + sav_img.write_to_png(os.path.join(instance_path, + image_file_name)) + img_scaled = False + + # grabamos el nombre de la imagen sin el path + self.image_name = image_file_name + + elif self._page.title_box != self: + self.image = ctx.get_target().create_similar( + cairo.CONTENT_COLOR_ALPHA, self.width, BOX_HEIGHT) + + pixb_scaled = self.pixbuf.scale_simple( + int(self.img_w), + int(self.img_h), GdkPixbuf.InterpType.BILINEAR) + ct = cairo.Context(self.image) + Gdk.cairo_set_source_pixbuf(ct, pixb_scaled, + self.img_x, self.img_y) + ct.paint() if self.image is not None: ctx.save() diff --git a/icons/contract-coordinates.svg b/icons/contract-coordinates.svg new file mode 100644 index 0000000..1f704f3 --- /dev/null +++ b/icons/contract-coordinates.svg @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + version="1.0" + width="55" + height="55" + id="svg2384"> + <defs + id="defs2386" /> + <rect + width="50" + height="50" + x="2.5" + y="2.5" + id="rect2394" + style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:3.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 27.333333,1 C 28.083333,50.75 27.333333,54 27.333333,54" + id="path3168" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 54,27.333333 C 4.2499997,28.083333 1,27.333333 1,27.333333" + id="path3170" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <g + transform="matrix(-1,0,0,-1,72.75,37.25)" + id="g3161" + style="stroke:#ffffff;stroke-opacity:1"> + <path + d="M 28,27 L 37,18" + id="path2387" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 30,17 L 38,17 L 38,25" + id="path3159" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + <g + transform="matrix(-1,0,0,1,72.75,18.25)" + id="g3167" + style="stroke:#ffffff;stroke-opacity:1"> + <path + d="M 28,27 L 37,18" + id="path3169" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 30,17 L 38,17 L 38,25" + id="path3171" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + <g + transform="matrix(1,0,0,-1,-18.25,37.25)" + id="g3173" + style="stroke:#ffffff;stroke-opacity:1"> + <path + d="M 28,27 L 37,18" + id="path3175" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 30,17 L 38,17 L 38,25" + id="path3177" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> + <g + transform="translate(-18.25,18.25)" + id="g3179" + style="stroke:#ffffff;stroke-opacity:1"> + <path + d="M 28,27 L 37,18" + id="path3181" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <path + d="M 30,17 L 38,17 L 38,25" + id="path3183" + style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + </g> +</svg> diff --git a/persistencia.py b/persistencia.py index b6d6c0f..7e7f1d4 100644 --- a/persistencia.py +++ b/persistencia.py @@ -39,6 +39,10 @@ class Persistence: pageData['boxs'] = [] for box in page.boxs: boxData = {} + boxData['img_x'] = box.img_x + boxData['img_y'] = box.img_y + boxData['img_w'] = box.img_w + boxData['img_h'] = box.img_h boxData['image_name'] = box.image_name boxData['globes'] = [] for globo in box.globos: @@ -125,7 +129,15 @@ class Persistence: for boxData in pageData['boxs']: if not primero: # el primero ya esta creado - page.add_box_from_journal_image(boxData['image_name']) + # para compatibilidad de versiones anteriores, + # verificamos si existe o no las nuevas propiedades + # en el archivo de persistencia + if 'img_x' in boxData: + page.add_box_from_journal_image( + boxData['image_name'], boxData['img_x'], + boxData['img_y'], boxData['img_w'], boxData['img_h']) + else: + page.add_box_from_journal_image(boxData['image_name']) primero = False box = page.get_active_box() for globoData in boxData['globes']: diff --git a/po/POTFILES.in b/po/POTFILES.in index bfc3a55..adc0528 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,3 +4,5 @@ historietaactivity.py persistencia.py setup.py toolbar.py +reorderwindow.py +fontcombobox.py diff --git a/reorderwindow.py b/reorderwindow.py index 7a50ebf..c179447 100644 --- a/reorderwindow.py +++ b/reorderwindow.py @@ -1,53 +1,76 @@ +import cairo from gettext import gettext as _ from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GObject -from gi.repository.GdkPixbuf import Pixbuf +from gi.repository import GdkPixbuf from sugar3.graphics import style from sugar3.graphics.toolbutton import ToolButton +HANDLE_SIZE = 18 +MIN_IMAGE_SIZE = 50 -class ReorderView(Gtk.Window): - def __init__(self, activity): + +class BaseWindow(Gtk.Window): + + def __init__(self, width=-1, height=-1): GObject.GObject.__init__(self) self.set_border_width(style.LINE_WIDTH) self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_decorated(False) self.set_resizable(False) - width = Gdk.Screen.width() - style.GRID_CELL_SIZE * 2 - height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 2 + if width == -1: + width = Gdk.Screen.width() - style.GRID_CELL_SIZE * 2 + if height == -1: + height = Gdk.Screen.height() - style.GRID_CELL_SIZE * 2 self.set_size_request(width, height) - self.set_default_size(width, height) - self.toolbar = Gtk.Toolbar() - icon = ToolButton('thumbs-view') - self.toolbar.insert(icon, -1) +class BasicToolbar(Gtk.Toolbar): + + def __init__(self, icon_name, title): + GObject.GObject.__init__(self) + + icon = ToolButton(icon_name) + self.insert(icon, -1) label = Gtk.Label() - title = _('Drag the images to reorder') label.set_markup('<b>%s</b>' % title) label.set_alignment(0, 0.5) tool_item = Gtk.ToolItem() tool_item.set_expand(True) tool_item.add(label) tool_item.show_all() - self.toolbar.insert(tool_item, -1) + self.insert(tool_item, -1) + + self.separator = Gtk.SeparatorToolItem() + self.separator.props.draw = False + self.separator.set_expand(True) + self.insert(self.separator, -1) self.stop = ToolButton(icon_name='dialog-cancel') self.stop.set_tooltip(_('Cancel')) - self.stop.connect('clicked', self.__stop_clicked_cb) - self.toolbar.insert(self.stop, -1) + self.insert(self.stop, -1) self.stop.show() self.confirm = ToolButton(icon_name='dialog-ok') self.confirm.set_tooltip(_('Done')) - self.confirm.connect('clicked', self.__ok_clicked_cb) - self.toolbar.insert(self.confirm, -1) + self.insert(self.confirm, -1) self.confirm.show() + +class ReorderView(BaseWindow): + + def __init__(self, activity): + BaseWindow.__init__(self) + self.toolbar = BasicToolbar('thumbs-view', + _('Drag the images to reorder')) + + self.toolbar.stop.connect('clicked', self.__stop_clicked_cb) + self.toolbar.confirm.connect('clicked', self.__ok_clicked_cb) + self.scrollwin = ReorderObjects(activity) self.vbox = Gtk.VBox() self.vbox.pack_start(self.toolbar, False, False, 0) @@ -71,9 +94,8 @@ class ReorderObjects(Gtk.ScrolledWindow): self.activity = activity self.comicboxes = self.activity.page.boxs - self.liststore = Gtk.ListStore(Pixbuf) + self.liststore = Gtk.ListStore(GdkPixbuf.Pixbuf) self.iconview = Gtk.IconView.new() - #self.iconview.set_columns(2) self.iconview.set_property('item-width', 200) self.iconview.set_model(self.liststore) self.iconview.set_pixbuf_column(0) @@ -84,6 +106,15 @@ class ReorderObjects(Gtk.ScrolledWindow): self.add(self.iconview) + def on_item_activated(self): + model = self.iconview.get_model() + pixbuf = model[self.iconview.get_selected_items()[0]][0] + for comicbox in self.comicboxes[1:]: + if pixbuf is comicbox.thumbnail: + self.editor = ImageEditorView(comicbox) + self.editor.show_all() + break + def reorder_comicboxs(self): sorted_list = [] for row in self.liststore: @@ -102,3 +133,290 @@ class ReorderObjects(Gtk.ScrolledWindow): column = i - (reng * 2) self.activity.page.table.attach( self.comicboxes[i+1], column, column + 1, reng, reng + 1) + + +class ImageElement: + def __init__(self, pixbuf, box, x, y, w, h): + self.box = box + self.pixbuf = pixbuf + self.pixbuf_original = self.pixbuf.scale_simple( + self.pixbuf.get_width(), self.pixbuf.get_height(), + GdkPixbuf.InterpType.BILINEAR) + self.x = x + self.y = y + self.width = w + self.height = h + self.calculate_boundaries() + self.calculate_points() + + def calculate_boundaries(self): + self.boundaries = {} + self.boundaries['min_x'] = self.x + self.boundaries['max_x'] = self.x + self.width + self.boundaries['min_y'] = self.y + self.boundaries['max_y'] = self.y + self.height + + def calculate_points(self): + self.points = {} + self.points["upper_left"] = [self.x, self.y] + self.points["upper_right"] = [self.x + self.width - HANDLE_SIZE, + self.y] + self.points["lower_left"] = [self.x, + self.y + self.height - HANDLE_SIZE] + self.points["lower_right"] = [self.x + self.width - HANDLE_SIZE, + self.y + self.height - HANDLE_SIZE] + + def is_selected(self, x, y): + if (x >= self.boundaries['min_x'] and + x <= self.boundaries['max_x']) and \ + (y >= self.boundaries['min_y'] and + y <= self.boundaries['max_y']): + return True + else: + return False + + def is_resize(self, x, y): + if self.is_in_point(x, y): + return True + else: + return False + + def is_in_point(self, x, y, point=None): + if point is not None: + if (x >= point[0] and x <= (point[0] + HANDLE_SIZE)) \ + and (y >= point[1] and y <= (point[1] + HANDLE_SIZE)): + return True + else: + return False + else: + if self.is_in_point(x, y, self.points["upper_left"]) or \ + self.is_in_point(x, y, self.points["upper_right"]) or \ + self.is_in_point(x, y, self.points["lower_left"]) or \ + self.is_in_point(x, y, self.points["lower_right"]): + return True + else: + return False + + def draw(self, ctx): + self.image = ctx.get_target().create_similar( + cairo.CONTENT_COLOR_ALPHA, self.box.width, + self.box.height) + pixb_scaled = self.pixbuf_original.scale_simple( + self.width, self.height, GdkPixbuf.InterpType.BILINEAR) + ct = cairo.Context(self.image) + Gdk.cairo_set_source_pixbuf(ct, pixb_scaled, self.x, self.y) + ct.paint() + self.pixbuf = pixb_scaled + ctx.save() + ctx.rectangle(0, 0, self.box.width, self.box.height) + ctx.clip() + ctx.set_source_surface(self.image, 0, 0) + ctx.paint() + ctx.restore() + + # draw hadles + self._draw_handle(ctx, self.x, self.y) + self._draw_handle(ctx, self.x + self.width - HANDLE_SIZE, + self.y + self.height - HANDLE_SIZE) + + def _draw_handle(self, ctx, x, y): + ctx.save() + ctx.set_line_width(2) + ctx.set_source_rgb(1, 1, 1) + ctx.rectangle(x, y, HANDLE_SIZE, HANDLE_SIZE) + ctx.stroke_preserve() + ctx.set_source_rgb(0, 0, 0) + ctx.set_dash([2]) + ctx.stroke() + ctx.restore() + + def move(self, x_movement, y_movement, allocation): + self.x = self.x + x_movement + self.y = self.y + y_movement + + if self.x < 0: + self.x = 0 + if self.y < 0: + self.y = 0 + + if self.x + self.width > allocation.width: + self.x -= (self.x + self.width) - (allocation.width) + + if self.y + self.height > allocation.height: + self.y -= (self.y + self.height) - (allocation.height) + + self.calculate_boundaries() + self.calculate_points() + + def resize(self, x_movement, y_movement, allocation, start_x, start_y): + + if self.is_in_point(start_x, start_y, self.points["lower_left"]): + x_final_pos = self.x + x_movement + if x_final_pos < 0: + x_movement -= x_final_pos + self.x += x_movement + self.width -= x_movement + self.height += y_movement + elif self.is_in_point(start_x, start_y, self.points["upper_right"]): + y_final_pos = self.y + y_movement + if y_final_pos < 0: + y_movement -= y_final_pos + self.y += y_movement + self.height -= y_movement + self.width += x_movement + elif self.is_in_point(start_x, start_y, self.points["upper_left"]): + x_final_pos = self.x + x_movement + y_final_pos = self.y + y_movement + if x_final_pos < 0: + x_movement -= x_final_pos + if y_final_pos < 0: + y_movement -= y_final_pos + self.y += y_movement + self.x += x_movement + self.width -= x_movement + self.height -= y_movement + else: + self.height += y_movement + self.width += x_movement + + if self.width < MIN_IMAGE_SIZE: + self.width = MIN_IMAGE_SIZE + if self.height < MIN_IMAGE_SIZE: + self.height = MIN_IMAGE_SIZE + + if self.x + self.width > allocation.width: + self.width -= (self.x + self.width) - (allocation.width) + + if self.y + self.height > allocation.height: + self.height -= (self.y + self.height) - (allocation.height) + + self.calculate_boundaries() + self.calculate_points() + + +class CanvasEditor(Gtk.EventBox): + def __init__(self, comicbox, width, height, window): + Gtk.EventBox.__init__(self) + + self.width = width + self.height = height + self.is_resize = False + self.is_move = False + self.parentw = window + + self.modify_bg(Gtk.StateType.NORMAL, + style.COLOR_WHITE.get_gdk_color()) + self.fixed = Gtk.Fixed() + self.add(self.fixed) + self._drawingarea = Gtk.DrawingArea() + self.fixed.put(self._drawingarea, 0, 0) + + self._drawingarea.add_events( + Gdk.EventMask.POINTER_MOTION_MASK | + Gdk.EventMask.BUTTON_PRESS_MASK | + Gdk.EventMask.BUTTON_RELEASE_MASK | + Gdk.EventMask.BUTTON_MOTION_MASK) + + self.image = ImageElement( + comicbox.pixbuf, self, + comicbox.img_x, comicbox.img_y, + comicbox.img_w, comicbox.img_h) + + self._drawingarea.connect("draw", self.draw_cb) + self.connect("button_press_event", self.pressing) + self.connect("motion_notify_event", self.mouse_move) + self.connect("motion_notify_event", self.moving) + self.connect("button_release_event", self.releassing) + self.redraw() + + def size_allocate(widget, allocation): + self.fixed.set_size_request(self.width, self.height) + self._drawingarea.set_size_request(self.width, self.height) + + self.connect('size_allocate', size_allocate) + self.set_size_request(self.width, self.height) + self.fixed.set_size_request(self.width, self.height) + self._drawingarea.set_size_request(self.width, self.height) + self.show_all() + + def redraw(self): + self._drawingarea.queue_draw() + + def draw_cb(self, widget, context): + self.image.draw(context) + + def pressing(self, widget, event): + if self.image.is_selected(event.x, event.y): + if self.image.is_in_point(event.x, event.y): + self.is_resize = True + self.is_move = False + else: + self.is_resize = False + self.is_move = True + self.start_x = event.x + self.start_y = event.y + + def mouse_move(self, widget, event): + cursor = None + if self.image.is_in_point(event.x, event.y): + cursor = Gdk.Cursor(Gdk.CursorType.SIZING) + elif self.image.is_selected(event.x, event.y): + cursor = Gdk.Cursor(Gdk.CursorType.HAND2) + self.get_window().set_cursor(cursor) + + def moving(self, widget, event): + if self.is_move: + x_movement = event.x - self.start_x + y_movement = event.y - self.start_y + self.image.move(x_movement, y_movement, self.get_allocation()) + self.start_x = event.x + self.start_y = event.y + self.redraw() + elif self.is_resize: + x_movement = event.x - self.start_x + y_movement = event.y - self.start_y + self.image.resize(x_movement, y_movement, self.get_allocation(), + self.start_x, self.start_y) + self.start_x = event.x + self.start_y = event.y + self.redraw() + + def releassing(self, widget, event): + self.is_resize = False + self.is_move = False + self.start_x = -1 + self.start_y = -1 + + +class ImageEditorView(BaseWindow): + + def __init__(self, comicbox): + BaseWindow.__init__(self, comicbox.width, + comicbox.height + style.GRID_CELL_SIZE) + + self.toolbar = BasicToolbar( + 'contract-coordinates', + _('Drag to move or resize using the marked corners')) + self.toolbar.stop.connect('clicked', self.__stop_clicked_cb) + self.toolbar.confirm.connect('clicked', self.__ok_clicked_cb) + + self.comicbox = comicbox + self.canvas = CanvasEditor( + self.comicbox, self.comicbox.width, + self.comicbox.height, self) + + self.vbox = Gtk.VBox() + self.vbox.pack_start(self.toolbar, False, False, 0) + self.vbox.pack_start(self.canvas, True, True, 0) + self.add(self.vbox) + + def __stop_clicked_cb(self, button): + self.destroy() + + def __ok_clicked_cb(self, button): + self.comicbox.img_x = self.canvas.image.x + self.comicbox.img_y = self.canvas.image.y + self.comicbox.img_w = self.canvas.image.width + self.comicbox.img_h = self.canvas.image.height + self.comicbox.redraw() + self.destroy() |