Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJRG 2 <jrg2@ubuntu.(none)>2013-12-20 00:45:24 (GMT)
committer JRG 2 <jrg2@ubuntu.(none)>2013-12-20 00:45:24 (GMT)
commit644b65d3dcb76db1c6269a17790891feefb5eeeb (patch)
tree0ac731d9663d86c49b53942c165d539d2f322724
parentb5fa8c2d65dec5d13ad1390f526129be2fb38bd3 (diff)
Move backgroundmove_background
-rw-r--r--historietaactivity.py112
-rw-r--r--persistencia.py15
-rw-r--r--reorderwindow.py326
3 files changed, 418 insertions, 35 deletions
diff --git a/historietaactivity.py b/historietaactivity.py
index e9e4e90..698a17f 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',
@@ -442,9 +453,9 @@ 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)
@@ -479,10 +490,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())
@@ -626,40 +643,67 @@ class ComicBox(Gtk.EventBox):
pixbuf = GdkPixbuf.Pixbuf.new_from_file(self.image_name)
self.thumbnail = GdkPixbuf.Pixbuf.new_from_file_at_size(
self.image_name, 200, 200)
- width_pxb = pixbuf.get_width()
- height_pxb = pixbuf.get_height()
- scale = (self.width) / (1.0 * width_pxb)
- self.image_height = int(scale * height_pxb)
- self.image = ctx.get_target().create_similar(
- cairo.CONTENT_COLOR_ALPHA, self.width, self.image_height)
-
- if (scale != 1):
- # falta tener en cuenta el caso de una imagen
- # que venga del journal y tenga el tamanio justo,
- # es decir con scale = 1
- pixb_scaled = pixbuf.scale_simple(
- int(self.width),
- int(self.image_height), GdkPixbuf.InterpType.BILINEAR)
- ct = cairo.Context(self.image)
- Gdk.cairo_set_source_pixbuf(ct, pixb_scaled, 0, 0)
- ct.paint()
- if (not self.image_saved):
- self.image_saved = True
- # print instance_path
- image_file_name = 'image' + str(self.posi) + '.png'
- self.image.write_to_png(os.path.join(instance_path,
- image_file_name))
- # grabamos el nombre de la imagen sin el path
- self.image_name = image_file_name
- else:
- ct = cairo.Context(self.image)
- 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()
- ctx.rectangle(0, 0, self.width, self.height)
+ ctx.rectangle(0, 0, self.width, BOX_HEIGHT)
ctx.clip()
ctx.set_source_surface(self.image, 0, 0)
ctx.paint()
diff --git a/persistencia.py b/persistencia.py
index b6d6c0f..38220b3 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,16 @@ 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 boxData.has_key('img_x'):
+ 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'],
+ 0, 0, -1, -1)
primero = False
box = page.get_active_box()
for globoData in boxData['globes']:
diff --git a/reorderwindow.py b/reorderwindow.py
index 5bb2f10..36c4d98 100644
--- a/reorderwindow.py
+++ b/reorderwindow.py
@@ -1,14 +1,46 @@
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GObject
+from gi.repository import GdkPixbuf
from sugar3.graphics import style
from sugar3.graphics.toolbutton import ToolButton
from gi.repository.GdkPixbuf import Pixbuf
+import cairo
import gettext
_ = lambda msg: gettext.dgettext('sugar', msg)
+class UpdateToolbar(Gtk.Toolbar):
+ def __init__(self):
+ GObject.GObject.__init__(self)
+
+ 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.insert(self.stop, -1)
+ self.stop.show()
+
+ self.confirm = ToolButton(icon_name='dialog-ok')
+ self.confirm.set_tooltip(_('Done'))
+ self.insert(self.confirm, -1)
+ self.confirm.show()
+
+
+class BaseWindow(Gtk.Window):
+ def __init__(self, width=400, height=400):
+ 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)
+ self.set_size_request(height, width)
+
+
class ReorderView(Gtk.Window):
def __init__(self, activity):
GObject.GObject.__init__(self)
@@ -68,6 +100,7 @@ class ReorderObjects(Gtk.ScrolledWindow):
self.iconview.set_model(self.liststore)
self.iconview.set_pixbuf_column(0)
self.iconview.set_reorderable(True)
+ #self.iconview.connect('item-activated', self.on_item_activated)
for comicbox in self.comicboxes[1:]:
try:
@@ -77,6 +110,16 @@ 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:
@@ -95,3 +138,286 @@ 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-18, self.y]
+ self.points["lower_left"] = [self.x, self.y+self.height - 18]
+ self.points["lower_right"] = [self.x+self.width-18, \
+ self.y+self.height-18]
+
+ 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]+18)) \
+ and (y >= point[1] and y <= (point[1]+18)):
+ 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()
+
+ 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 < 50:
+ self.width = 50
+ if self.height < 50:
+ self.height = 50
+
+ 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.draw_in_context(context)
+
+ def draw_in_context(self, ctx):
+ self.image.draw(ctx)
+
+ 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)
+
+ self.toolbar = UpdateToolbar()
+ 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()