0e6479503c02ca7cd4180b23c51b82f013c3b5ae
[minwii.git] / src / app / widgets / playingscreen.py
1 # -*- coding: utf-8 -*-
2 """
3 Écran de jeu MinWii :
4 bandes arc-en-ciel représentant un clavier.
5
6 $Id$
7 $URL$
8 """
9 import pygame
10 from colorsys import hls_to_rgb
11 from gradients import gradients
12 from math import floor
13 # TODO : positionner cette constance en fonction de la résolution d'affichage
14 # externaliser la conf.
15 BORDER = 5 # 5px
16 FIRST_HUE = 0.6
17 OFF_LUMINANCE = 0.1
18 OFF_SATURATION = 1
19 ON_TOP_LUMINANCE = 0.6
20 ON_BOTTOM_LUMINANCE = 0.9
21 ON_SATURATION = 1
22
23 class _PlayingScreenBase(pygame.sprite.Group) :
24 def __init__(self, distinctNotes=[]) :
25 """
26 distinctNotes : notes disctinctes présentes dans la chanson
27 triées du plus grave au plus aigu.
28 """
29 super(_PlayingScreenBase, self).__init__()
30 self.distinctNotes = distinctNotes
31 self.keyboardLength = 0
32 self.keyboardRects = []
33 self._initRects()
34 self._initColumns()
35
36
37
38 def _initRects(self) :
39 """ création des espaces réservés pour
40 afficher les colonnes.
41 """
42 ambitus = self.distinctNotes[-1].midi - self.distinctNotes[0].midi
43 if ambitus <= 12 :
44 self.keyboardLength = 8
45 else :
46 self.keyboardLength = 11
47
48 screen = pygame.display.get_surface()
49
50 # taille de la zone d'affichage utile (bordure autour)
51 dispWidth = screen.get_width() - 2 * BORDER
52 dispHeight = screen.get_height() - 2 * BORDER
53
54 columnWidth = int(round(float(dispWidth) / self.keyboardLength))
55
56 rects = []
57 for i in range(self.keyboardLength) :
58 upperLeftCorner = (i*columnWidth + BORDER, BORDER)
59 rect = pygame.Rect(upperLeftCorner, (columnWidth, dispHeight))
60 rects.append(rect)
61
62 self.keyboardRects = rects
63
64 def _initColumns(self) :
65
66 hueStep = FIRST_HUE / (self.keyboardLength - 1)
67 for i, rect in enumerate(self.keyboardRects) :
68 hue = FIRST_HUE - hueStep * i
69 c = Column(hue, rect)
70 self.add(c)
71
72
73 def drawColumns(self) :
74 pass
75
76 def highlightColumn(self, index) :
77 for i, sprite in enumerate(self.sprites()) :
78 sprite.update(i==index)
79
80
81
82 class SongPlayingScreen(_PlayingScreenBase) :
83
84 def __init__(self, song) :
85 super(SongPlayingScreen, self).__init__(song.distinctNotes)
86 self.song = song
87
88 class SongPlayingScreenTest(_PlayingScreenBase) :
89 def __init__(self) :
90 class C:pass
91 o = C()
92 o.midi=1
93 super(SongPlayingScreenTest, self).__init__([o])
94 self.__running = True
95 pygame.display.flip()
96 #while self.__running :
97 # events = pygame.event.get()
98 # for event in events:
99 # self.input(event)
100 # pygame.display.flip()
101
102 def input(self, event) :
103 if event.type == pygame.KEYDOWN:
104 if event.key == pygame.K_q:
105 self.__running = False
106 uni = event.unicode
107 if uni.isdigit() and int(uni) <=8 :
108 self.highlightColumn(int(uni))
109
110
111 # if event.key == pygame.K_i:
112 # self.backToInstrumentChoice = True
113 # self.done = True
114 #
115 # if event.key == pygame.K_w:
116 # self.nextLevel = 0
117 # self.done = True
118 #
119 # if event.key == pygame.K_e:
120 # self.nextLevel = 1
121 # self.done = True
122 #
123 # if event.key == pygame.K_r:
124 # self.nextLevel = 2
125 # self.done = True
126 #
127 # if event.key == pygame.K_t:
128 # self.nextLevel = 3
129 # self.done = True
130
131
132 class Column(pygame.sprite.Sprite) :
133
134 def __init__(self, hue, rect) :
135 pygame.sprite.Sprite.__init__(self)
136 sur = pygame.surface.Surface(rect.size)
137 rgba = hls_to_rgba_8bits(hue, OFF_LUMINANCE, OFF_SATURATION)
138 sur.fill(rgba)
139 self.stateOff = sur
140
141 topRgba = hls_to_rgba_8bits(hue, ON_TOP_LUMINANCE, ON_SATURATION)
142 bottomRgba = hls_to_rgba_8bits(hue, ON_BOTTOM_LUMINANCE, ON_SATURATION)
143 size = rect.inflate(2*rect.width,0).size
144 self.stateOn = gradients.vertical(rect.size, topRgba, bottomRgba)
145
146 self.image = self.stateOn
147 self.rect = rect
148
149 def update(self, state) :
150 if state :
151 self.image = self.stateOn
152 else :
153 self.image = self.stateOff
154
155 def hls_to_rgba_8bits(h, l, s) :
156 #convert to rgb ranging from 0 to 255
157 rgba = [floor(255 * i) for i in hls_to_rgb(h, l, s) + (1,)]
158 return tuple(rgba)
159