X-Git-Url: https://scm.cri.ensmp.fr/git/minwii.git/blobdiff_plain/0a9a61ff4ffe961742224a52f060104cd0e80bde..ea641d921996c040ee1af76c71ea98d75fa853af:/src/app/widgets/column.py diff --git a/src/app/widgets/column.py b/src/app/widgets/column.py new file mode 100755 index 0000000..a5001d3 --- /dev/null +++ b/src/app/widgets/column.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +""" +bande qui compose le clavier minwii + +$Id$ +$URL$ +""" +import pygame +from colorsys import hls_to_rgb +from gradients import gradients +import events +from eventutils import event_handler, EventDispatcher, EventHandlerMixin +from math import floor +from globals import BACKGROUND_LAYER +from globals import FOREGROUND_LAYER +from config import OFF_LUMINANCE +from config import OFF_SATURATION +from config import ON_TOP_LUMINANCE +from config import ON_BOTTOM_LUMINANCE +from config import ON_SATURATION +from config import ON_COLUMN_OVERSIZING +from config import ON_COLUMN_ALPHA +from config import FONT +from config import FONT_COLOR + + +class Column(pygame.sprite.DirtySprite, EventHandlerMixin) : + + def __init__(self, group, hue, rect, tone) : + pygame.sprite.DirtySprite.__init__(self, group) + self.state = False + + # nom de l'intonation + self.tone = tone + toneName = FONT.render(tone.nom, True, FONT_COLOR) + + # état off : surface unie et nom de l'intonation + sur = pygame.surface.Surface(rect.size) + rgba = hls_to_rgba_8bits(hue, OFF_LUMINANCE, OFF_SATURATION) + sur.fill(rgba) + w, h = rect.w, rect.h + tw, th, = toneName.get_size() + toneRect = pygame.Rect(((w - tw) / 2, h - th), (tw, th)) + sur.blit(toneName, toneRect) + self.surOff = sur + self.rectOff = rect + + + # état on : surface dégradée avec nom de la note avec largeur agrandie + topRgba = hls_to_rgba_8bits(hue, ON_TOP_LUMINANCE, ON_SATURATION, ON_COLUMN_ALPHA) + bottomRgba = hls_to_rgba_8bits(hue, ON_BOTTOM_LUMINANCE, ON_SATURATION, ON_COLUMN_ALPHA) + onWidth = rect.width * ON_COLUMN_OVERSIZING + onLeft = rect.centerx - onWidth / 2 + rectOn = pygame.Rect((onLeft, 0), + (onWidth, rect.height)) + self.surOn = gradients.vertical(rectOn.size, topRgba, bottomRgba) + w, h = rectOn.w, rectOn.h + toneRect = pygame.Rect(((w - tw) / 2, h - th), (tw, th)) + self.surOn.blit(toneName, toneRect) + self.rectOn = rectOn + + self.image = self.surOff + self.rect = rect + #EventDispatcher.addEventListener(pygame.MOUSEBUTTONDOWN, self.onMouseDown) + #EventDispatcher.addEventListener(pygame.MOUSEBUTTONUP, self.onMouseUp) + + def update(self, state, syllabus='') : + group = self.groups()[0] + if state == self.state : + # no changes + return + if state : + group.change_layer(self, FOREGROUND_LAYER) + sur = self.surOn + if syllabus : + sur = sur.copy() + renderedSyl = FONT.render(syllabus, True, FONT_COLOR) + sw, sh, = renderedSyl.get_size() + w, h = self.rectOn.w, self.rectOn.h + sylRect = pygame.Rect(((w - sw) / 2, (h - sh) / 2), (sw, sh)) + sur.blit(renderedSyl, sylRect) + + self.image = sur + self.rect = self.rectOn + else : + group.change_layer(self, BACKGROUND_LAYER) + self.image = self.surOff + self.rect = self.rectOff + self.state = state + self.dirty = 1 + + @event_handler(pygame.MOUSEBUTTONDOWN) + def onMouseDown(self, event) : + if self.rect.collidepoint(*event.pos) : + self.update(True) + self.raiseNoteOn() + + @event_handler(pygame.MOUSEBUTTONUP) + def onMouseUp(self, event) : + self.update(False) + self.raiseNoteOff() + + def raiseNoteOn(self) : + evt = pygame.event.Event(events.NOTEON, tone=self.tone) + pygame.event.post(evt) + + def raiseNoteOff(self) : + evt = pygame.event.Event(events.NOTEOFF, tone=self.tone) + pygame.event.post(evt) + + + +def hls_to_rgba_8bits(h, l, s, a=1) : + #convert to rgb ranging from 0 to 255 + rgba = [floor(255 * i) for i in hls_to_rgb(h, l, s) + (a,)] + return tuple(rgba)