zusammenf?hrung
[darcs-mirror-ozeanien.git] / cairoboard.py
index 0457d43..be2e078 100644 (file)
@@ -26,7 +26,7 @@ class CairoBoard(gtk.DrawingArea):
         assert board
         self.board = board
 
-        self.base_pixmap = None
+        self.base_surface = None
         self.hand_x = 0
         self.hand_y = 0
         
@@ -108,7 +108,7 @@ class CairoBoard(gtk.DrawingArea):
             return None
 
     def draw_board(self, board, window):
-        self.draw_base(window)
+        self.draw_cached_base(window)
 
         for col in board.slots:
             for slot in col:
@@ -216,15 +216,15 @@ class CairoBoard(gtk.DrawingArea):
             cr.translate(x, y)
             cr.scale(SCALE, SCALE)
 
-            cr.rectangle(-1, -1, 2, 2)
-            cr.clip()
+            #cr.rectangle(-1, -1, 2, 2)
+            #cr.clip()
 
             matrix = cr.get_matrix()
             if slot.card:
-                self.draw_card(slot.card, cr)
+                self.draw_cached_card(slot.card, cr)
                 cr.set_matrix(matrix)
             if slot.ship:
-                self.draw_ship(slot.ship, cr)
+                self.draw_cached_ship(slot.ship, cr)
                 cr.set_matrix(matrix)
 
             if slot.highlighted:
@@ -245,8 +245,6 @@ class CairoBoard(gtk.DrawingArea):
     draw_hand = draw_slot
 
     def draw_card(self, card, cr):
-        cr.rotate(-(card.rotation * math.pi / 2))
-
         # Meer
         cr.set_source_rgb(0, 0, 1)
         cr.rectangle(-1, -1, 2, 2)
@@ -275,179 +273,369 @@ class CairoBoard(gtk.DrawingArea):
         cr.rectangle(-1, -1, 2, 2)
         cr.stroke()
 
-    def draw_base(self,window):
-        if not self.base_pixmap:
-            self.base_pixmap = gtk.gdk.Pixmap(window,
-                    2*GRIDPAD + 9*GRIDWIDTH, 2*GRIDPAD + 6*GRIDWIDTH)
+    def draw_base(self, cr):
+        cr.translate(GRIDPAD, GRIDPAD)
+        cr.scale(GRIDWIDTH, GRIDWIDTH)
+
+        # Sea Background
+        # Unten
+        pat = cairo.LinearGradient (0, 5, 0, 5.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1,1)
+        pat.add_color_stop_rgba(1, 0, 0, 1,0)
+        cr.rectangle(1, 5, 7, 0.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            self.base_pixmap.draw_drawable(self.base_pixmap.new_gc(), window, 0, 0, 0, 0,
-                    2*GRIDPAD + 9*GRIDWIDTH, 2*GRIDPAD + 6*GRIDWIDTH)
+        # Oben
+        pat = cairo.LinearGradient (0, 0, 0, -0.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1,1)
+        pat.add_color_stop_rgba(1, 0, 0, 1,0)
+        cr.rectangle(1, -0.5, 7, 0.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            cr = self.base_pixmap.cairo_create()
+        # Links
+        pat = cairo.LinearGradient (1, 0, 0.5, 0)
+        pat.add_color_stop_rgba(0, 0, 0, 1,1)
+        pat.add_color_stop_rgba(1, 0, 0, 1,0)
+        cr.rectangle(0.5, 0, 0.5, 5)
+        cr.set_source(pat)
+        cr.fill()
 
+        # Rechts
+        pat = cairo.LinearGradient (8, 0, 8.5, 0)
+        pat.add_color_stop_rgba(0, 0, 0, 1,1)
+        pat.add_color_stop_rgba(1, 0, 0, 1,0)
+        cr.rectangle(8, 0, 0.5, 5)
+        cr.set_source(pat)
+        cr.fill()
 
-            cr.translate(GRIDPAD, GRIDPAD)
-            cr.scale(GRIDWIDTH, GRIDWIDTH)
+        # Oben Links
+        pat = cairo.RadialGradient(1,0,0, 1,0, 0.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1, 1)
+        pat.add_color_stop_rgba(1, 0, 0, 1, 0)
+        cr.rectangle(0.5, -0.5, 0.5, 0.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            # Sea Background
-            # Unten
-            pat = cairo.LinearGradient (0, 5, 0, 5.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1,1)
-            pat.add_color_stop_rgba(1, 0, 0, 1,0)
-            cr.rectangle(1, 5, 7, 0.5)
-            cr.set_source(pat)
-            cr.fill()
+        # Oben Rechts
+        pat = cairo.RadialGradient(8,0,0, 8,0, 0.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1, 1)
+        pat.add_color_stop_rgba(1, 0, 0, 1, 0)
+        cr.rectangle(8, -0.5, 8.5, 0.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            # Oben
-            pat = cairo.LinearGradient (0, 0, 0, -0.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1,1)
-            pat.add_color_stop_rgba(1, 0, 0, 1,0)
-            cr.rectangle(1, -0.5, 7, 0.5)
-            cr.set_source(pat)
-            cr.fill()
+        # Unten Rechts
+        pat = cairo.RadialGradient(8,5,0, 8,5, 0.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1, 1)
+        pat.add_color_stop_rgba(1, 0, 0, 1, 0)
+        cr.rectangle(8, 5, 8.5, 5.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            # Links
-            pat = cairo.LinearGradient (1, 0, 0.5, 0)
-            pat.add_color_stop_rgba(0, 0, 0, 1,1)
-            pat.add_color_stop_rgba(1, 0, 0, 1,0)
-            cr.rectangle(0.5, 0, 0.5, 5)
-            cr.set_source(pat)
-            cr.fill()
+        # Unten Links
+        pat = cairo.RadialGradient(1,5,0, 1,5, 0.5)
+        pat.add_color_stop_rgba(0, 0, 0, 1, 1)
+        pat.add_color_stop_rgba(1, 0, 0, 1, 0)
+        cr.rectangle(0.5, 5, 1, 5.5)
+        cr.set_source(pat)
+        cr.fill()
 
-            # Rechts
-            pat = cairo.LinearGradient (8, 0, 8.5, 0)
-            pat.add_color_stop_rgba(0, 0, 0, 1,1)
-            pat.add_color_stop_rgba(1, 0, 0, 1,0)
-            cr.rectangle(8, 0, 0.5, 5)
-            cr.set_source(pat)
-            cr.fill()
 
-            # Oben Links
-            pat = cairo.RadialGradient(1,0,0, 1,0, 0.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1, 1)
-            pat.add_color_stop_rgba(1, 0, 0, 1, 0)
-            cr.rectangle(0.5, -0.5, 0.5, 0.5)
-            cr.set_source(pat)
-            cr.fill()
+        # Frame
+        cr.set_source_rgb(1,1,1)
+        cr.set_line_width(0.05)
+        cr.set_line_cap(cairo.LINE_CAP_ROUND)
+        for x in range(0,8):
+            cr.move_to(1+x, 0)
+            cr.line_to(1+x, 5.5)
+            cr.stroke()
+        for y in range(0,6):
+            cr.move_to(0.5, y)
+            cr.line_to(8.5, y)
+            cr.stroke()
 
-            # Oben Rechts
-            pat = cairo.RadialGradient(8,0,0, 8,0, 0.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1, 1)
-            pat.add_color_stop_rgba(1, 0, 0, 1, 0)
-            cr.rectangle(8, -0.5, 8.5, 0.5)
-            cr.set_source(pat)
-            cr.fill()
+    def draw_cached_ship(self,ship,cr):
+        cr.rotate(-(ship.rotation * math.pi / 2))
+        cr.rotate(math.pi / 2) # Koordinaten unten passen sonst nicht
 
-            # Unten Rechts
-            pat = cairo.RadialGradient(8,5,0, 8,5, 0.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1, 1)
-            pat.add_color_stop_rgba(1, 0, 0, 1, 0)
-            cr.rectangle(8, 5, 8.5, 5.5)
-            cr.set_source(pat)
-            cr.fill()
+        if not ship.guiinfo:
+            ship.guiinfo = cr.get_target().create_similar(cairo.CONTENT_COLOR_ALPHA, 
+                    GRIDWIDTH + GRIDPAD, GRIDWIDTH + GRIDPAD)
+            scr = cairo.Context(ship.guiinfo)
+            scr.translate((GRIDWIDTH + GRIDPAD)/2, (GRIDWIDTH+GRIDPAD)/2)
+            scr.scale(SCALE, SCALE)
 
-            # Unten Links
-            pat = cairo.RadialGradient(1,5,0, 1,5, 0.5)
-            pat.add_color_stop_rgba(0, 0, 0, 1, 1)
-            pat.add_color_stop_rgba(1, 0, 0, 1, 0)
-            cr.rectangle(0.5, 5, 1, 5.5)
-            cr.set_source(pat)
-            cr.fill()
+            self.draw_ship(ship, scr)
 
+        cr.scale(1.0/SCALE, 1.0/SCALE)
+        cr.set_source_surface(ship.guiinfo,-(GRIDWIDTH + GRIDPAD)/2,-(GRIDWIDTH + GRIDPAD)/2)
+        cr.paint()
 
-            # Frame
-            cr.set_source_rgb(1,1,1)
-            cr.set_line_width(0.05)
-            cr.set_line_cap(cairo.LINE_CAP_ROUND)
-            for x in range(0,8):
-                cr.move_to(1+x, 0)
-                cr.line_to(1+x, 5.5)
-                cr.stroke()
-            for y in range(0,6):
-                cr.move_to(0.5, y)
-                cr.line_to(8.5, y)
-                cr.stroke()
-
-        window.draw_drawable(window.new_gc(), self.base_pixmap, 0, 0, 0, 0,
+    def draw_cached_card(self,card,cr):
+        cr.rotate(-(card.rotation * math.pi / 2))
+
+        if not card.guiinfo:
+            card.guiinfo = cr.get_target().create_similar(cairo.CONTENT_COLOR_ALPHA, 
+                    GRIDWIDTH + GRIDPAD, GRIDWIDTH + GRIDPAD)
+            scr = cairo.Context(card.guiinfo)
+            scr.translate((GRIDWIDTH + GRIDPAD)/2, (GRIDWIDTH+GRIDPAD)/2)
+            scr.scale(SCALE, SCALE)
+
+            self.draw_card(card, scr)
+
+        cr.scale(1.0/SCALE, 1.0/SCALE)
+        cr.set_source_surface(card.guiinfo,-(GRIDWIDTH + GRIDPAD)/2,-(GRIDWIDTH + GRIDPAD)/2)
+        cr.paint()
+
+    def draw_cached_base(self,window):
+        ocr = window.cairo_create()
+        if not self.base_surface:
+            self.base_surface = ocr.get_target().create_similar(cairo.CONTENT_COLOR_ALPHA, 
+                    2*GRIDPAD + 9*GRIDWIDTH, 2*GRIDPAD + 6*GRIDWIDTH)
+
+            cr = cairo.Context(self.base_surface)
+            self.draw_base(cr)
+
+        ocr.set_source_surface(self.base_surface,0,0)
+        ocr.rectangle(0,0,
                 2*GRIDPAD + 9*GRIDWIDTH, 2*GRIDPAD + 6*GRIDWIDTH)
+        ocr.fill()
 
 class GrassBoard(CairoBoard):
-        #Karte füllen
-        def draw_card(self, card, cr):
-            cr.rotate(-(card.rotation * math.pi / 2))
-            orientation=0;
-            cr.set_source_rgb(0.6, 0.4, 0.3)
-            cr.rectangle(-1, -1, 2, 2)
-            cr.fill()
-            p2c = [ (0.7,0), (0,-0.7), (-0.7,0), (0,0.7) ]
-            matrix=cr.get_matrix()
-            self.draw_gras(card, cr, orientation)
-            for island in card.islands:
-                for dir in island:
-                    cr.translate(*p2c[dir])
-                    self.draw_flower(card, cr)
-                    cr.set_matrix(matrix)
-            #self.draw_gras(card, cr, orientation)
-            #self.draw_flower(card, cr)
-
-        #Einen Grashalm malen
-       def draw_gras(self, card, cr, orientation):
-            #x=random.uniform(0.1,0.2)
-            #y=random.uniform(0.2,0.3)
-            matrix=cr.get_matrix()
-            if orientation == 0: 
-                cr.scale(0.15, 0.25)
-            else:
-                cr.scale(-x, y)
-            cr.set_source_rgb(0, 1, 0)
-            cr.move_to(-1,-1)
-            cr.curve_to(0,-1,1,0,1,1)
-            cr.curve_to(0,1,0,-1,-1,-1)
+    #Karte füllen
+    def draw_card(self, card, cr):
+        orientation=0;
+        cr.set_source_rgb(0.6, 0.4, 0.3)
+        cr.rectangle(-1, -1, 2, 2)
+        cr.fill()
+        p2c = [ (0.7,0), (0,-0.7), (-0.7,0), (0,0.7) ]
+        between_p2c = [ (0.6,-0.6), (-0.6,-0.6), (-0.6,0.6), (0.6,0.6) ]
+        matrix=cr.get_matrix()
+        for c in [
+                    (-0.7,-0.6), 
+                    (0,-0.65),
+                    (-0.5,-0.6),
+                    (0.4,-0.55),
+                    (0.8,-0.6),
+                    (-0.3,-0.4),
+                    (0.6,-0.35),
+                    (-0.85,-0.3),
+                    (0.3,-0.3),
+                    (0,-0.25),
+                    (-0.6,-0.2),
+                    (0.75,-0.2),
+                    (0.5,-0.1),
+                    (-0.5,0),
+                    (0.3,0.1),
+                    (-0.1,0.1),
+                    (-0.8,0.2),
+                    (0.7,0.2),
+                    (-0.4,0.3),
+                    (0.85,0.3),
+                    (-0.1,0.35),
+                    (0.25,0.4),
+                    (-0.75,0.4),
+                    (0.6,0.45),
+                    (-0.45,0.5),
+                    (0,0.6),
+                    (-0.8,0.7),
+                    (0.75,0.7),
+                    (-0.4,0.75),
+                    (0.5,0.75),
+                    (0.15,0.8),
+                    (-0.2,0.85),
+                    (-0.85,0.9),
+                    (0.85,0.9),
+                    (0,0.95),
+                    (-0.5,1),
+                    (0.45,1),
+                    
+                ]:
+            cr.translate(*c)
+            self.draw_gras(card, cr, 0)
+            self.draw_gras(card, cr, 1)
+            cr.set_matrix(matrix)
+
+        for island in card.islands:
+            for dir in island:
+                cr.translate(*p2c[dir])
+                self.draw_flower(card, cr)
+                cr.set_matrix(matrix)
+            for dir in island[:-1]:
+                cr.translate(*between_p2c[dir])
+                self.draw_flower(card, cr)
+                cr.set_matrix(matrix)
+        #self.draw_gras(card, cr, orientation)
+        #self.draw_flower(card, cr)
+
+    #Einen Grashalm malen
+    def draw_gras(self, card, cr, orientation):
+        x=random.uniform(0.1,0.2)
+        y=random.uniform(0.2,0.3)
+        matrix=cr.get_matrix()
+        if orientation == 0: 
+            cr.scale(x, y)
+        else:
+            cr.scale(-x, y)
+        cr.translate(-1,-1)
+        cr.set_source_rgb(0, 1, 0)
+        cr.move_to(-1,-1)
+        cr.curve_to(0,-1,1,0,1,1)
+        cr.curve_to(0,1,0,-1,-1,-1)
+        cr.fill_preserve()
+        cr.set_source_rgb(0, 0, 0)
+        cr.set_line_width(0.1)
+        cr.stroke()
+        cr.set_matrix(matrix)
+            
+    #Eine Blume malen
+    def draw_flower(self, card,cr):
+        cr.rotate(random.uniform(0,2*math.pi))
+        matrix=cr.get_matrix()
+        cr.scale(0.25, 0.25)
+        color = ( 
+                    random.random(),
+                    random.random(),
+                    random.random() )
+
+        for n in range(5):
+            cr.set_source_rgb(*color)
+            cr.move_to(0,0)
+            cr.curve_to(0,-0.8,-0.2,-1,-1,-1)
+            cr.curve_to(-1,-0.2,-0.8,0.2,0,0)
             cr.fill_preserve()
             cr.set_source_rgb(0, 0, 0)
             cr.set_line_width(0.1)
             cr.stroke()
-            cr.set_matrix(matrix)
-            
-       #Eine Blume malen
-        def draw_flower(self, card,cr):
-            matrix=cr.get_matrix()
-            cr.scale(0.25, 0.25)
-            for n in range(5):
-                cr.set_source_rgb(1, 0, 0)
-                cr.move_to(0,0)
-                cr.curve_to(0,-0.8,-0.2,-1,-1,-1)
-                cr.curve_to(-1,-0.2,-0.8,0.2,0,0)
-                cr.fill_preserve()
-                cr.set_source_rgb(0, 0, 0)
-                cr.set_line_width(0.1)
-                cr.stroke()
-                cr.rotate(2* math.pi / 5)
-            cr.set_matrix(matrix)
-        # Meer
-        #cr.set_source_rgb(0, 0, 1)
-        #cr.rectangle(-1, -1, 2, 2)
-        #cr.fill()
+            cr.rotate(2* math.pi / 5)
+        cr.set_matrix(matrix)
+    
+    def draw_ship(self, ship, cr):
+        
+        # Grundkörper (noch abzurunden)
+        cr.move_to(-0.5, -0.75)
+        cr.line_to(0.5, -0.75)
+        cr.line_to(0.5, 0.5)
+        cr.line_to(-0.5, 0.5)
+        cr.close_path()
+        cr.set_source_rgb(1, 0.2, 0.2)
+        cr.fill_preserve()
+        cr.set_source_rgb(0, 0, 0)
+        cr.set_line_width(0.05)
+        cr.stroke()
 
-        #cr.set_source_rgb(0, 1, 0)
-        #cr.set_line_cap(cairo.LINE_CAP_ROUND)
-        #cr.set_line_width(0.9)
+        # Griff
+        cr.move_to(-0.25, 0.25)
+        cr.line_to(-0.55,  0.75)
+        cr.line_to( 0.55,  0.75)
+        cr.line_to( 0.25, 0.25)
+        cr.set_line_width(0.1)
+        cr.set_line_join(cairo.LINE_JOIN_ROUND)
+        cr.stroke()
+        
+        # Motor
+        cr.arc(0, -0.1 , 0.3, 0, 2*math.pi)
+        cr.set_source_rgb(0, 0, 0)
+        cr.fill()
 
-        #p2c = [ (1,0), (0,-1), (-1,0), (0,1) ]
+        # Augen
+        for _ in range(2):
+            cr.scale(-1,1)
+            cr.arc(0.3, -0.55 , 0.15, 0, 2*math.pi)
+            cr.set_source_rgb(1, 1, 1)
+            cr.fill_preserve()
+            cr.set_source_rgb(0, 0, 0)
+            cr.set_line_width(0.05)
+            cr.stroke()
+            cr.arc(0.25, -0.6 , 0.05, 0, 2*math.pi)
+            cr.set_source_rgb(0, 0, 0)
+            cr.fill()
+
+    def draw_base(self,cr):
+        cr.translate(GRIDPAD, GRIDPAD)
+        cr.scale(GRIDWIDTH, GRIDWIDTH)
+
+        # Sea Background
+
+        # Unten
+        pat = cairo.LinearGradient (0, 5, 0, 5.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4,1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4,0)
+        cr.rectangle(1, 5, 7, 0.5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Oben
+        pat = cairo.LinearGradient (0, 0, 0, -0.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4,1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4,0)
+        cr.rectangle(1, -0.5, 7, 0.5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Links
+        pat = cairo.LinearGradient (1, 0, 0.5, 0)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4,1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4,0)
+        cr.rectangle(0.5, 0, 0.5, 5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Rechts
+        pat = cairo.LinearGradient (8, 0, 8.5, 0)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4,1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4,0)
+        cr.rectangle(8, 0, 0.5, 5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Oben Links
+        pat = cairo.RadialGradient(1,0,0, 1,0, 0.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4, 1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4, 0)
+        cr.rectangle(0.5, -0.5, 0.5, 0.5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Oben Rechts
+        pat = cairo.RadialGradient(8,0,0, 8,0, 0.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4, 1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4, 0)
+        cr.rectangle(8, -0.5, 8.5, 0.5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Unten Rechts
+        pat = cairo.RadialGradient(8,5,0, 8,5, 0.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4, 1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4, 0)
+        cr.rectangle(8, 5, 8.5, 5.5)
+        cr.set_source(pat)
+        cr.fill()
+
+        # Unten Links
+        pat = cairo.RadialGradient(1,5,0, 1,5, 0.5)
+        pat.add_color_stop_rgba(0.3, 0.6, 0.4, 0.4, 1)
+        pat.add_color_stop_rgba(1, 0.6, 0.4, 0.4, 0)
+        cr.rectangle(0.5, 5, 0.5, 5.5)
+        cr.set_source(pat)
+        cr.fill()
+
+
+        # Frame
+        cr.set_source_rgb(1,1,1)
+        cr.set_line_width(0.05)
+        cr.set_line_cap(cairo.LINE_CAP_ROUND)
+        for x in range(0,8):
+            cr.move_to(1+x, 0)
+            cr.line_to(1+x, 5.5)
+            cr.stroke()
+        for y in range(0,6):
+            cr.move_to(0.5, y)
+            cr.line_to(8.5, y)
+            cr.stroke()
 
-        # Land
-        #for island in card.islands:
-        #    point = island[0]
-        #    cr.move_to( *p2c[point] )
-        #    for point in island[1:] + island[0:1]:
-        #        cr.line_to( *p2c[point] )
-        #    cr.stroke()
-        
-        # Border
-        #cr.set_source_rgb(0, 0, 0)
-        #cr.set_line_cap(cairo.LINE_CAP_ROUND)
-        #cr.set_line_width(0.05)
-        #cr.rectangle(-1, -1, 2, 2)
-        #cr.stroke()
 
 # vim:ts=4:sw=4:sts=4:et