agrandissement avec maintient du bon point de référence.
authorpin <pin@fe552daf-6dbe-4428-90eb-1537e0879342>
Mon, 22 Mar 2010 15:46:53 +0000 (15:46 +0000)
committerpin <pin@fe552daf-6dbe-4428-90eb-1537e0879342>
Mon, 22 Mar 2010 15:46:53 +0000 (15:46 +0000)
git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@104 fe552daf-6dbe-4428-90eb-1537e0879342

src/app/widgets/instrumentselector.py

index 330d6cb..70654f6 100755 (executable)
@@ -5,11 +5,13 @@
 $Id$
 $URL$
 """
+import os.path
 import pygame
 from eventutils import event_handler, EventDispatcher, EventHandlerMixin
 from cursors import WarpingCursor
 from config import FRAMERATE
 from globals import BACKGROUND_LAYER
+from globals import FOREGROUND_LAYER
 from globals import CURSOR_LAYER
 from globals import hls_to_rgba_8bits
 
@@ -18,33 +20,29 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
     
     rows = 3
     cols = 3
+    instruments = ['accordeon', 'celesta', 'flute', 'guitare', 'orgue', 'piano', 'tuba', 'violon', 'violoncelle']
 
     def __init__(self) :
         super(InstrumentSelector, self).__init__()
-        self._initCursor()
-        self._initRects()
+        #self._initRects()
         self._initTiles()
+        self._initCursor()
     
-    def _initRects(self) :
+    def _initTiles(self) :
         screen = pygame.display.get_surface()
         tileWidth = int(round(float(screen.get_width()) / self.cols))
         tileHeight = int(round(float(screen.get_height()) / self.rows))
-        
-        rects = []
+
+        self.tiles = []
+        instrus = self.instruments[:]
         for y in range(self.cols) :
             for x in range(self.rows) :
-                upperLeftCorner = (y * tileWidth, x * tileHeight)
+                upperLeftCorner = (x * tileWidth, y * tileHeight)
                 rect = pygame.Rect(upperLeftCorner, (tileWidth, tileHeight))
-                rects.append(rect)
-        self.rects = rects
+                tile = InstrumentTile(instrus.pop(0), self, rect, (x,y))
+                self.add(tile, layer=BACKGROUND_LAYER)
+                self.tiles.append(tile)
     
-    def _initTiles(self) :
-        for rect in self.rects :
-            tile = InstrumentTile(self, rect)
-            self.add(tile, layer=BACKGROUND_LAYER)
-            
-        
-
     def _initCursor(self) :
         self.cursor = WarpingCursor(blinkMode=True)
         self.add(self.cursor, layer=CURSOR_LAYER)
@@ -71,11 +69,92 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
         if event.key == pygame.K_q:
             self.stop()
 
+    #@event_handler(pygame.MOUSEMOTION)
+    @event_handler(pygame.MOUSEBUTTONDOWN)
+    def onMouseMove(self, event) :
+        for tile in reversed(self.sprites()[:-1]) :
+            if tile.rect.collidepoint(*event.pos) :
+                self.raiseTileOver(tile)
+                break
+    
+    def raiseTileOver(self, tile) :
+        self.change_layer(tile, FOREGROUND_LAYER)
+        tile.inflate(tile.coords)
+
+
 
 class InstrumentTile(pygame.sprite.DirtySprite) :
+    
+    @staticmethod
+    def _get_instrument_image(name) :
+        imagePath = os.path.abspath(__file__).split(os.path.sep)[:-1]
+        imagePath.extend(['data', 'instruments'])
+        name, ext = os.path.splitext(name)
+        imagePath.append('%s%s' % (name, ext or '.jpg'))
+        return os.path.sep.join(imagePath)
+    
+    BORDER = 10
+    INFLATE_ZOOM = 0.25
 
-    def __init__(self, group, rect) :
+    def __init__(self, name, group, rect, coords) :
         pygame.sprite.DirtySprite.__init__(self, group)
+        self.name = name
         self.rect = rect
-        self.image = pygame.Surface(rect.size)
-        self.image.fill((0,255,255,64))
+        self.coords = coords
+        
+        
+        innerWidth, innerHeight = [l-self.BORDER*2 for l in self.rect.size]
+        
+        imagePath = InstrumentTile._get_instrument_image(name)
+        img = pygame.image.load(imagePath)
+        iWidth, iHeight = img.get_size()
+        imgRatio = float(iWidth) / iHeight
+        
+        # adapts dimensions
+        iw = innerWidth
+        ih = int(round(innerWidth  / imgRatio))
+
+        if ih > innerHeight:
+            ih = innerHeight
+            iw = int(round(innerHeight * imgRatio))
+        
+        position = ((innerWidth - iw) / 2 + self.BORDER, (innerHeight - ih) / 2 + self.BORDER)
+        
+        img = pygame.transform.smoothscale(img, (iw, ih))
+        
+        bg = pygame.Surface(self.rect.size)
+        bg.fill((255,255,255,255))
+        bg.blit(img, pygame.Rect(position, (iw, ih)))
+        
+        self.image = bg
+    
+    def inflate(self, refPoint) :
+        keep = {}
+        for name in REF_POINTS[refPoint] :
+            keep[name] = getattr(self.rect, name)
+        
+        self.rect.inflate_ip(*[l*self.INFLATE_ZOOM for l in self.rect.size])
+        
+        img = pygame.transform.smoothscale(self.image, self.rect.size)
+        self.image = img
+        
+        for k, v in keep.items() :
+            setattr(self.rect, k, v)
+        
+        self.dirty = 1
+        
+
+
+REF_POINTS = {
+    (0, 0) : ['top', 'left'],
+    (1, 0) : ['top'],
+    (2, 0) : ['top', 'right'],
+
+    (0, 1) : ['left'],
+    (1, 1) : [],
+    (2, 1) : ['right'],
+
+    (0, 2) : ['bottom', 'left'],
+    (1, 2) : ['bottom'],
+    (2, 2) : ['bottom', 'right']
+} 
\ No newline at end of file