ménage (par le vide)
[minwii.git] / src / app / widgets / instrumentselector.py
index 70654f6..6861643 100755 (executable)
@@ -10,6 +10,7 @@ import pygame
 from eventutils import event_handler, EventDispatcher, EventHandlerMixin
 from cursors import WarpingCursor
 from config import FRAMERATE
+from config import  INSTRUMENTS
 from globals import BACKGROUND_LAYER
 from globals import FOREGROUND_LAYER
 from globals import CURSOR_LAYER
@@ -20,13 +21,15 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
     
     rows = 3
     cols = 3
-    instruments = ['accordeon', 'celesta', 'flute', 'guitare', 'orgue', 'piano', 'tuba', 'violon', 'violoncelle']
+    instruments = INSTRUMENTS
 
     def __init__(self) :
         super(InstrumentSelector, self).__init__()
         #self._initRects()
         self._initTiles()
         self._initCursor()
+        self._inflatedTile = None
+        self.selectedInstrument = None
     
     def _initTiles(self) :
         screen = pygame.display.get_surface()
@@ -34,11 +37,14 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
         tileHeight = int(round(float(screen.get_height()) / self.rows))
 
         self.tiles = []
-        instrus = self.instruments[:]
+        instrus = list(self.instruments[:])
         for y in range(self.cols) :
             for x in range(self.rows) :
                 upperLeftCorner = (x * tileWidth, y * tileHeight)
                 rect = pygame.Rect(upperLeftCorner, (tileWidth, tileHeight))
+                # !!! s'il y avait plus de 3x3 tuiles !!!, il faudrait alors
+                # changer le tuple (x,y) qui concerne le point d'application de l'homotétie.
+                # Cf. InstrumentTile.inflate
                 tile = InstrumentTile(instrus.pop(0), self, rect, (x,y))
                 self.add(tile, layer=BACKGROUND_LAYER)
                 self.tiles.append(tile)
@@ -69,8 +75,7 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
         if event.key == pygame.K_q:
             self.stop()
 
-    #@event_handler(pygame.MOUSEMOTION)
-    @event_handler(pygame.MOUSEBUTTONDOWN)
+    @event_handler(pygame.MOUSEMOTION)
     def onMouseMove(self, event) :
         for tile in reversed(self.sprites()[:-1]) :
             if tile.rect.collidepoint(*event.pos) :
@@ -78,8 +83,23 @@ class InstrumentSelector(pygame.sprite.LayeredDirty, EventHandlerMixin) :
                 break
     
     def raiseTileOver(self, tile) :
-        self.change_layer(tile, FOREGROUND_LAYER)
-        tile.inflate(tile.coords)
+        if not tile.inflated :
+            self.change_layer(tile, FOREGROUND_LAYER)
+            tile.inflate(tile.coords)
+            
+            if self._inflatedTile :
+                self._inflatedTile.deflate()
+                self.change_layer(self._inflatedTile, BACKGROUND_LAYER)
+            
+            self._inflatedTile = tile
+        
+    @event_handler(pygame.MOUSEBUTTONDOWN)
+    def selectInstrument(self, event) :
+        for tile in reversed(self.sprites()[:-1]) :
+            if tile.rect.collidepoint(*event.pos) :
+                self.selectedInstrument = tile.instrumentDescription
+                self.stop()
+                break
 
 
 
@@ -94,19 +114,32 @@ class InstrumentTile(pygame.sprite.DirtySprite) :
         return os.path.sep.join(imagePath)
     
     BORDER = 10
-    INFLATE_ZOOM = 0.25
+    INFLATE_ZOOM = 0.4
 
-    def __init__(self, name, group, rect, coords) :
+    def __init__(self, instrumentDescription, group, rect, coords) :
         pygame.sprite.DirtySprite.__init__(self, group)
-        self.name = name
+        self.inflated = False
+        self.instrumentDescription = instrumentDescription
         self.rect = rect
+        self._baseRect = rect.copy()
         self.coords = coords
-        
-        
+        imagePath = InstrumentTile._get_instrument_image(instrumentDescription['name'])
+        self._img = pygame.image.load(imagePath)
+        self.update()
+    
+
+    def update(self) :
         innerWidth, innerHeight = [l-self.BORDER*2 for l in self.rect.size]
+        innerSize = innerWidth, innerHeight
+        
+        border = pygame.Surface(self.rect.size)
+        border.fill((0xdd,0xdd,0xdd,255))
         
-        imagePath = InstrumentTile._get_instrument_image(name)
-        img = pygame.image.load(imagePath)
+        bg = pygame.Surface(innerSize)
+        bg.fill((255,255,255,255))
+        bgRect = pygame.Rect((self.BORDER, self.BORDER), innerSize)
+
+        img = self._img
         iWidth, iHeight = img.get_size()
         imgRatio = float(iWidth) / iHeight
         
@@ -118,31 +151,36 @@ class InstrumentTile(pygame.sprite.DirtySprite) :
             ih = innerHeight
             iw = int(round(innerHeight * imgRatio))
         
-        position = ((innerWidth - iw) / 2 + self.BORDER, (innerHeight - ih) / 2 + self.BORDER)
-        
+        imgPosition = ((innerWidth - iw) / 2, (innerHeight - ih) / 2)
+        imgRect = pygame.Rect(imgPosition, (iw, ih))
         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
+        bg.blit(img, imgRect)
+        border.blit(bg, bgRect)
+        self.image = border
     
+
     def inflate(self, refPoint) :
+        self.inflated = True
         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.update()
         self.dirty = 1
-        
+    
+
+    def deflate(self) :
+        self.inflated = False
+        self.rect = self._baseRect.copy()
+        self.update()
+        self.dirty = 1
+            
 
 
 REF_POINTS = {