OSDN Git Service

implemented copy/paste layer to clipboard;
authorMartin Renold <martinxyz@gmx.ch>
Tue, 25 Nov 2008 19:51:57 +0000 (19:51 +0000)
committerMartin Renold <martinxyz@gmx.ch>
Tue, 25 Nov 2008 19:51:57 +0000 (19:51 +0000)
still yet very comfortable, tile rendering code needs refactoring now

svn://svn.gna.org/svn/mypaint/trunk@148

gui/drawwindow.py
lib/document.py
lib/layer.py
lib/tiledsurface.py

index e4874a9..3157d44 100644 (file)
@@ -79,6 +79,9 @@ class Window(gtk.Window):
               <menuitem action='Undo'/>
               <menuitem action='Redo'/>
               <separator/>
+              <menuitem action='CopyLayer'/>
+              <menuitem action='PasteLayer'/>
+              <separator/>
               <menuitem action='ModifyLastStroke'/>
               <menuitem action='ModifyEnd'/>
             </menu>
@@ -180,6 +183,8 @@ class Window(gtk.Window):
             ('EditMenu',           None, 'Edit'),
             ('Undo',               None, 'Undo', '<control>Z', None, self.undo_cb),
             ('Redo',               None, 'Redo', '<control>Y', None, self.redo_cb),
+            ('CopyLayer',          None, 'Copy Layer to Clipboard', '<control>C', None, self.copy_cb),
+            ('PasteLayer',         None, 'Paste Layer from Clipboard', '<control>V', None, self.paste_cb),
             ('ModifyLastStroke',   None, 'Modify Last Stroke', 'm', None, self.modify_last_stroke_cb),
             ('ModifyEnd',          None, 'Stop Modifying', 'n', None, self.modify_end_cb),
 
@@ -348,6 +353,20 @@ class Window(gtk.Window):
     def redo_cb(self, action):
         self.doc.redo()
 
+    def copy_cb(self, action):
+        pixbuf = self.doc.render_current_layer_as_pixbuf()
+        cb = gtk.Clipboard()
+        cb.set_image(pixbuf)
+
+    def paste_cb(self, action):
+        cb = gtk.Clipboard()
+        def callback(clipboard, pixbuf, trash):
+            if not pixbuf:
+                print 'The clipboard doeas not contain any image to paste!'
+                return
+            self.doc.load_layer_from_pixbuf(pixbuf)
+        cb.request_image(callback)
+
     def get_recent_strokes(self, max_count):
         assert max_count > 0
         result = self.layer.strokes[:] # copy
index 7ca71a6..22ebe03 100644 (file)
@@ -185,15 +185,20 @@ class Document():
                 t += cmd.stroke.total_painting_time
         return t
 
-    def render_as_pixbuf(self, x, y, w, h):
+    def render_as_pixbuf(self, x, y, w, h, layers=None):
         from gtk import gdk
         pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, False, 8, w, h)
         pixbuf.fill(0xffffffff)
         arr = pixbuf.get_pixels_array()
         arr = mypaintlib.gdkpixbuf2numpy(arr)
-        self.render(arr, -x, -y)
+        self.render(arr, -x, -y, layers)
         return pixbuf
 
+    def render_current_layer_as_pixbuf(self):
+        l = self.layers[self.layer_idx]
+        bbox = list(l.surface.get_bbox())
+        return self.render_as_pixbuf(*bbox + [[l]])
+
     def add_layer(self, insert_idx=None):
         if insert_idx is None:
             insert_idx = self.layer_idx+1
@@ -202,12 +207,15 @@ class Document():
     def load_layer_from_data(self, data):
         self.do(command.LoadLayer(self, data))
 
-    def load_from_pixbuf(self, pixbuf):
-        self.clear()
+    def load_layer_from_pixbuf(self, pixbuf):
         arr = pixbuf.get_pixels_array()
         arr = mypaintlib.gdkpixbuf2numpy(arr)
         self.load_layer_from_data(arr)
 
+    def load_from_pixbuf(self, pixbuf):
+        self.clear()
+        self.load_layer_from_pixbuf(pixbuf)
+
     def save(self, filename):
         trash, ext = os.path.splitext(filename)
         ext = ext.lower().replace('.', '')
index 6d2d96d..b2ba418 100644 (file)
@@ -151,12 +151,14 @@ class Layer:
 
         def render_from_empty():
             #print 'full rerender'
-            if self.background is not None:
-                surface.load_from_data(self.background)
-            else:
-                surface.clear()
+            try:
+                if self.background is not None:
+                    surface.load_from_data(self.background)
+                else:
+                    surface.clear()
+            finally:
+                self.rendered.background = self.background
             self.rendered.strokes = []
-            self.rendered.background = self.background
             render_new_strokes()
 
         cost = len(self.strokes)
index 520587f..ee036ec 100644 (file)
@@ -147,7 +147,18 @@ class TiledSurface(mypaintlib.TiledSurface):
         im.save(filename)
 
     def load_from_data(self, data):
-        self.clear()
+        dirty_tiles = set(self.tiledict.keys())
+        self.tiledict = {}
+
+        if data.shape[0] % N or data.shape[1] % N:
+            s = list(data.shape)
+            print 'reshaping', s
+            s[0] = ((s[0]+N-1) / N) * N
+            s[1] = ((s[1]+N-1) / N) * N
+            data_new = zeros(s, data.dtype)
+            data_new[:data.shape[0],:data.shape[1],:] = data
+            data = data_new
+
         for x, y, rgba in self.iter_tiles_memory(0, 0, data.shape[1], data.shape[0], readonly=False):
             # FIXME: will be buggy at border?
             tmp = data[y:y+N,x:x+N,:].astype('float32') / 255.0
@@ -164,6 +175,13 @@ class TiledSurface(mypaintlib.TiledSurface):
                 rgba[:,:,0:3] = tmp
                 rgba[:,:,3]   = 1<<15
 
+        dirty_tiles.update(self.tiledict.keys())
+        bbox = get_tiles_bbox(dirty_tiles)
+        self.notify_observers(*bbox)
+
+
+
     def get_bbox(self):
+        # FIXME: should get precise bbox instead of tile bbox
         return get_tiles_bbox(self.tiledict)