From 912d8016d34a35d75043634ba1acbfde057e58c9 Mon Sep 17 00:00:00 2001 From: 9and3r <9and3r@gmai.com> Date: Sun, 20 Jul 2014 22:27:12 +0200 Subject: [PATCH] Progressbar color Volume control working --- mopidy_touchscreen/.idea/workspace.xml | 334 +++++++++++++++------ mopidy_touchscreen/__init__.py | 12 +- mopidy_touchscreen/main_screen.py | 46 +-- mopidy_touchscreen/screen_manager.py | 45 ++- mopidy_touchscreen/screen_objects.py | 69 +++-- mopidy_touchscreen/touch_manager.py | 40 ++- mopidy_touchscreen/touch_screen.py | 11 +- mopidy_touchscreen/touch_screen_backend.py | 18 ++ setup.py | 1 + 9 files changed, 412 insertions(+), 164 deletions(-) create mode 100644 mopidy_touchscreen/touch_screen_backend.py diff --git a/mopidy_touchscreen/.idea/workspace.xml b/mopidy_touchscreen/.idea/workspace.xml index dbedb36..88d7449 100644 --- a/mopidy_touchscreen/.idea/workspace.xml +++ b/mopidy_touchscreen/.idea/workspace.xml @@ -23,13 +23,23 @@ - - + + - - + + + + + + + + + + + + - + @@ -38,11 +48,9 @@ - - - - - + + + @@ -50,8 +58,8 @@ - - + + @@ -59,30 +67,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -94,11 +78,13 @@ @@ -134,6 +120,7 @@ + @@ -154,7 +141,6 @@ - @@ -330,7 +316,6 @@ - @@ -340,6 +325,7 @@ + @@ -368,13 +354,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + @@ -392,9 +544,7 @@ - - - + @@ -402,9 +552,7 @@ - - - + @@ -422,9 +570,7 @@ - - - + @@ -432,9 +578,7 @@ - - - + @@ -452,9 +596,7 @@ - - - + @@ -462,9 +604,7 @@ - - - + @@ -472,9 +612,7 @@ - - - + @@ -482,59 +620,69 @@ - - - + - + - - + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - - - - - + + + + + + + + + + - + - + - - - - - + + + diff --git a/mopidy_touchscreen/__init__.py b/mopidy_touchscreen/__init__.py index 16984ea..a17b922 100644 --- a/mopidy_touchscreen/__init__.py +++ b/mopidy_touchscreen/__init__.py @@ -3,14 +3,10 @@ from __future__ import unicode_literals import logging import os -# TODO: Remove entirely if you don't register GStreamer elements below -import pygst -pygst.require('0.10') -import gst -import gobject from mopidy import config, ext - +from .touch_screen import TouchScreen +from .touch_screen_backend import TouchScreenBackend __version__ = '0.1.0' @@ -36,8 +32,6 @@ class Extension(ext.Extension): return schema def setup(self, registry): - # You will typically only implement one of the following things - # in a single extension. - from .touch_screen import TouchScreen registry.add('frontend', TouchScreen) + registry.add('backend', TouchScreenBackend) diff --git a/mopidy_touchscreen/main_screen.py b/mopidy_touchscreen/main_screen.py index 5234c18..169b232 100644 --- a/mopidy_touchscreen/main_screen.py +++ b/mopidy_touchscreen/main_screen.py @@ -8,6 +8,7 @@ import urllib import urllib2 import json from mopidy.audio import PlaybackState +from .touch_manager import TouchManager from .screen_objects import ScreenObjectsManager from .dynamic_background import DynamicBackground @@ -16,38 +17,36 @@ logger = logging.getLogger(__name__) class MainScreen(): - def __init__(self,size,manager,cache,core): + def __init__(self,size,manager,cache,core, fonts): self.core = core self.size = size - self.base_size = self.size[1]/12 + self.base_size = self.size[1]/8 + self.fonts = fonts self.manager = manager self.background = DynamicBackground() self.track = None self.cache = cache self.image = None self.touch_text_manager = ScreenObjectsManager(size,self.base_size) - self.touch_text_manager.add_touch_object("pause_play","Play",(0,0),(255,255,255)) - def update(self): - screen = pygame.Surface(self.size) + def update(self, screen): self.background.drawBackground(screen) + if self.track is not None: if self.image is not None: - screen.blit(self.image, (self.base_size, self.base_size*3)) + screen.blit(self.image, (self.base_size, self.base_size*2)) self.touch_text_manager.get_touch_object("time_progress").set_value(self.core.playback.time_position.get()/1000) - self.touch_text_manager.get_object("track_time").set_text(time.strftime('%M:%S', time.gmtime(self.core.playback.time_position.get()/1000))+"/"+time.strftime('%M:%S', time.gmtime(self.track.length/1000))) + self.touch_text_manager.get_touch_object("time_progress").set_text(time.strftime('%M:%S', time.gmtime(self.core.playback.time_position.get()/1000))+"/"+time.strftime('%M:%S', time.gmtime(self.track.length/1000))) self.touch_text_manager.render(screen) return screen def track_started(self, track): - self.image = None - self.touch_text_manager.add_object("track_name",track.name,(self.size[0]/2,self.base_size*3), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) - self.touch_text_manager.add_object("album_name",track.album.name,(self.size[0]/2,self.base_size*4), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) - self.touch_text_manager.add_object("artist_name",self.getFirstArtist(track),(self.size[0]/2,self.base_size*5), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) - self.touch_text_manager.add_object("track_time",time.strftime('%M:%S', time.gmtime(0))+"/"+time.strftime('%M:%S', time.gmtime(0)),(self.size[0]/2,self.base_size*6), (self.size[0]-self.base_size,self.base_size * 7), (255, 255, 255)) - self.touch_text_manager.add_progressbar("time_progress", (self.size[0]/2,self.base_size*7), (self.size[0]-self.base_size,self.base_size*8),track.length/1000) + self.touch_text_manager.add_object("track_name",self.fonts['dejavusans'],track.name,(self.size[0]/2,self.base_size*2), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) + self.touch_text_manager.add_object("album_name",self.fonts['dejavusans'],track.album.name,(self.size[0]/2,self.base_size*3), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) + self.touch_text_manager.add_object("artist_name",self.fonts['dejavusans'],self.getFirstArtist(track),(self.size[0]/2,self.base_size*4), (self.size[0]-self.base_size,self.size[1]), (255, 255, 255)) + self.touch_text_manager.add_progressbar("time_progress", self.fonts['dejavusans'],time.strftime('%M:%S', time.gmtime(0))+"/"+time.strftime('%M:%S', time.gmtime(0)),(0,self.base_size*6), (self.size[0],self.base_size*7),track.length/1000, False) self.track = track if not self.is_image_in_cache(): thread = Thread(target=self.downloadImage()) @@ -90,14 +89,19 @@ class MainScreen(): self.loadImage() def loadImage(self): - size = self.base_size*6 + size = self.base_size*3 self.image = pygame.transform.scale(pygame.image.load(self.getCoverFolder()+self.getImageFileName()).convert(),(size,size)) def touch_event(self, event): - objects = self.touch_text_manager.get_touch_objects_in_pos(event.current_pos) - logger.error(objects) - if objects is not None: - for key in objects: - if key == "time_progress": - value = self.touch_text_manager.get_touch_object(key).get_pos_value(event.current_pos) * 1000 - self.core.playback.seek(value) \ No newline at end of file + if event.type == TouchManager.click: + objects = self.touch_text_manager.get_touch_objects_in_pos(event.current_pos) + if objects is not None: + for key in objects: + if key == "time_progress": + value = self.touch_text_manager.get_touch_object(key).get_pos_value(event.current_pos) * 1000 + self.core.playback.seek(value) + elif event.type == TouchManager.swipe: + if event.direction == TouchManager.left: + self.core.playback.next() + elif event.direction == TouchManager.right: + self.core.playback.previous() \ No newline at end of file diff --git a/mopidy_touchscreen/screen_manager.py b/mopidy_touchscreen/screen_manager.py index dfef78a..b8ed366 100644 --- a/mopidy_touchscreen/screen_manager.py +++ b/mopidy_touchscreen/screen_manager.py @@ -1,5 +1,6 @@ from .main_screen import MainScreen from .touch_manager import TouchManager +from .screen_objects import ScreenObjectsManager import pygame import logging @@ -8,14 +9,37 @@ logger = logging.getLogger(__name__) class ScreenManager(): - def __init__(self, size, core): - self.screen_size = size - self.screens = [MainScreen(size, self, "/home/ander", core)] + def __init__(self, size, core, backend): + self.size = size + self.core = core + self.backend = backend + self.fonts = {} + self.base_size = self.size[1] / 8 + self.fonts['dejavuserif'] = pygame.font.SysFont("dejavuserif", self.base_size) + self.fonts['dejavusans'] = pygame.font.SysFont("dejavusans", self.base_size) + self.screens = [MainScreen(size, self, "/home/ander", core,self.fonts)] self.track = None - self.touch_manager = TouchManager() + self.touch_manager = TouchManager(size) + self.screen_objects_manager = ScreenObjectsManager(size,self.base_size) + x = self.screen_objects_manager.add_touch_object("pause_play",self.fonts['dejavusans'],u" ll",(0,0),(255,255,255)) + x = x + self.base_size / 2 + x = self.screen_objects_manager.add_touch_object("random",self.fonts['dejavuserif'],u"\u2928",(x,0),(255,255,255)) + x = x + self.base_size / 2 + x = self.screen_objects_manager.add_touch_object("repeat",self.fonts['dejavuserif'],u"\u27F21",(x,0),(255,255,255)) + x = x + self.base_size / 2 + x = self.screen_objects_manager.add_touch_object("mute",self.fonts['dejavusans'],"Mute",(x,0),(255,255,255)) + x = x + self.base_size / 2 + self.screen_objects_manager.add_progressbar("volume",self.fonts['dejavusans'],"100", (x,0), (self.size[0],self.base_size),100, True) + self.screen_objects_manager.get_touch_object("volume").set_value(self.core.playback.volume.get()) + self.top_bar = pygame.Surface((self.size[0],self.base_size),pygame.SRCALPHA) + self.top_bar.fill((0,0,0,128)) def update(self): - return self.screens[0].update() + surface = pygame.Surface(self.size) + self.screens[0].update(surface) + surface.blit(self.top_bar,(0,0)) + self.screen_objects_manager.render(surface) + return surface def track_started(self, track): self.track = track @@ -24,7 +48,18 @@ class ScreenManager(): def event(self, event): touch_event = self.touch_manager.event(event) if touch_event is not None: + if touch_event.type == TouchManager.click: + objects = self.screen_objects_manager.get_touch_objects_in_pos(touch_event.current_pos) + if objects is not None: + for key in objects: + if key == "volume": + value = self.screen_objects_manager.get_touch_object(key).get_pos_value(touch_event.current_pos) + self.backend.tell({'action':'volume','value':value}) + self.screen_objects_manager.get_touch_object(key).set_value(value) self.screens[0].touch_event(touch_event) + def volume_changed(self, volume): + self.screen_objects_manager.get_touch_object("volume").set_value(volume) + diff --git a/mopidy_touchscreen/screen_objects.py b/mopidy_touchscreen/screen_objects.py index be8fb4c..4c5615f 100644 --- a/mopidy_touchscreen/screen_objects.py +++ b/mopidy_touchscreen/screen_objects.py @@ -13,20 +13,21 @@ class ScreenObjectsManager(): self.touch_objects = {} self.text_objects = {} - def add_object(self, key, text, pos, pos2, color): - self.text_objects[key] = TextItem(text, pos,pos2,color,self.base_size) + def add_object(self, key, font, text, pos, pos2, color): + self.text_objects[key] = TextItem(font, text, pos,pos2,color,self.base_size) def get_object(self, key): return self.text_objects[key] - def add_touch_object(self, key, text, pos, color): - self.touch_objects[key] = TouchAndTextItem(text, pos, color, self.base_size) + def add_touch_object(self, key, font, text, pos, color): + self.touch_objects[key] = TouchAndTextItem(font, text, pos, color, self.base_size) + return self.touch_objects[key].get_right_pos() def get_touch_object(self,key): return self.touch_objects[key] - def add_progressbar(self, key, pos, pos2, max): - self.touch_objects[key] = Progressbar(pos,pos2,max) + def add_progressbar(self, key, font, text, pos, pos2, max,value_text): + self.touch_objects[key] = Progressbar(font, text,pos,pos2,max,self.base_size,value_text) def render(self, surface): for key in self.text_objects: @@ -54,14 +55,17 @@ class BaseItem(): self.rect = pygame.Rect(0,0,self.size[0],self.size[1]) self.rect_in_pos = pygame.Rect(self.pos[0],self.pos[1],self.size[0],self.size[1]) + def get_right_pos(self): + return self.pos2[0] + class TextItem(BaseItem): - def __init__(self, text, pos,pos2, color,text_size): + def __init__(self, font, text, pos,pos2, color,text_size): if pos2 is not None: BaseItem.__init__(self,pos,pos2) self.text_size = text_size - self.font = pygame.font.SysFont("arial", text_size) + self.font = font self.text = text self.color = color self.box = self.font.render(text, True, self.color) @@ -108,62 +112,69 @@ class TextItem(BaseItem): self.box = self.font.render(self.text, True, self.color) surface.blit(self.box,self.pos,area=self.rect) - def set_text(self, text): - self.__init__(text,self.pos,self.pos2,self.color,self.text_size) + def set_text(self, text, size_mantain): + if size_mantain: + self.__init__(self.font, text,self.pos,None,self.color,self.text_size) + else: + self.__init__(self.font, text,self.pos,self.pos2,self.color,self.text_size) class TouchObject(BaseItem): def __init__(self,pos,pos2): BaseItem.__init__(self,pos,pos2) self.active = False - self.background_box = pygame.Surface(self.size) - self.background_box.fill((0,128,255)) - - def render(self,surface): - surface.blit(self.background_box, self.pos) def is_pos_inside(self, pos): return self.rect_in_pos.collidepoint(pos) class TouchAndTextItem(TouchObject, TextItem): - def __init__(self, text, pos, color,text_size): - TextItem.__init__(self,text, pos,None, color,text_size) + def __init__(self, font, text, pos, color,text_size): + TextItem.__init__(self, font, text, pos,None, color,text_size) TouchObject.__init__(self,pos,self.pos2) def update(self): TextItem.update() - def render(self,surface): - TouchObject.render(self,surface) - TextItem.render(self,surface) +class Progressbar(TouchObject, TextItem): -class Progressbar(TouchObject): - - def __init__(self, pos, pos2, max): + def __init__(self,font,text, pos, pos2, max,size, value_text): BaseItem.__init__(self, pos, pos2) logger.error(pos2) self.value = 0 self.max = max self.back_color = (0,0,0,128) - self.main_color = (255,255,255) + self.main_color = (0,150,255) self.surface = pygame.Surface(self.size, pygame.SRCALPHA) self.surface.fill(self.back_color) + self.value_text = value_text + if value_text: + self.text = TextItem(font,str(self.max),pos,None,(255,255,255),size) + self.text.set_text(str(self.value),True) + else: + self.text = TextItem(font,text,pos,None,(255,255,255),size) + self.text.pos = (self.pos[0] + self.size[0] / 2 - self.text.size[0] /2,self.text.pos[1]) def update(self): pass def render(self, surface): surface.blit(self.surface, self.pos) + self.text.render(surface) def set_value(self, value): - self.value = value - self.surface.fill(self.back_color) - pos_pixel = value * self.size[0] / self.max - rect = pygame.Rect(0,0,pos_pixel,self.size[1]) - self.surface.fill(self.main_color, rect) + if value != self.value: + self.value = value + if self.value_text: + self.set_text(str(self.value)) + self.surface.fill(self.back_color) + pos_pixel = value * self.size[0] / self.max + rect = pygame.Rect(0,0,pos_pixel,self.size[1]) + self.surface.fill(self.main_color, rect) def get_pos_value(self, pos): x = pos[0] - self.pos[0] return x * self.max / self.size[0] + def set_text(self, text): + self.text.set_text(text , True) \ No newline at end of file diff --git a/mopidy_touchscreen/touch_manager.py b/mopidy_touchscreen/touch_manager.py index 401257a..c3563a2 100644 --- a/mopidy_touchscreen/touch_manager.py +++ b/mopidy_touchscreen/touch_manager.py @@ -7,15 +7,25 @@ logger = logging.getLogger(__name__) class TouchManager(): click = 1 + swipe = 2 - def __init__(self): + up = 0 + down = 1 + left = 2 + right = 3 + + def __init__(self,size): self.down_pos = (0, 0) self.up_pos = (0, 0) + self.screen_size = size + self.max_move_margin = self.screen_size[1] / 6 + self.min_swipe_move = self.screen_size[1] / 3 def event(self, event): if event.type == pygame.MOUSEBUTTONUP: return self.mouse_up(event) elif event.type == pygame.MOUSEBUTTONDOWN: + self.mouse_down(event) return None def mouse_down(self, event): @@ -23,11 +33,33 @@ class TouchManager(): def mouse_up(self,event): self.up_pos = event.pos - return TouchEvent(TouchManager.click, self.down_pos, self.up_pos) + if abs(self.down_pos[0] - self.up_pos[0]) < self.max_move_margin: + if abs(self.down_pos[1] - self.up_pos[1]) < self.max_move_margin: + return TouchEvent(TouchManager.click, self.down_pos, self.up_pos, None) + elif abs(self.down_pos[1] - self.up_pos[1]) > self.min_swipe_move: + return TouchEvent(TouchManager.swipe, self.down_pos, self.up_pos, True) + elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin: + logger.error("hemen nago") + logger.error( abs(self.down_pos[1] - self.up_pos[1])) + if abs(self.down_pos[0] - self.up_pos[0]) > self.min_swipe_move: + logger.error("kaixo") + return TouchEvent(TouchManager.swipe, self.down_pos, self.up_pos, False) + class TouchEvent(): - def __init__(self, event_type, down_pos, current_pos): + def __init__(self, event_type, down_pos, current_pos, vertical): self.type = event_type self.down_pos = down_pos - self.current_pos = current_pos \ No newline at end of file + self.current_pos = current_pos + if event_type is TouchManager.swipe: + if vertical: + if self.down_pos[1] < self.current_pos[1]: + self.direction = TouchManager.down + else: + self.direction = TouchManager.up + else: + if self.down_pos[0] < self.current_pos[0]: + self.direction = TouchManager.right + else: + self.direction = TouchManager.left \ No newline at end of file diff --git a/mopidy_touchscreen/touch_screen.py b/mopidy_touchscreen/touch_screen.py index a2c24e4..7d95503 100644 --- a/mopidy_touchscreen/touch_screen.py +++ b/mopidy_touchscreen/touch_screen.py @@ -16,18 +16,20 @@ class TouchScreen(pykka.ThreadingActor, core.CoreListener): def __init__(self, config, core): super(TouchScreen, self).__init__() + self.backend = pykka.ActorRegistry.get_by_class_name("TouchScreenBackend")[0] + logger.error(self.backend) self.core = core self.running = False #self.screen_size=(320, 240) self.screen_size=(800, 600) pygame.init() - self.screen_manager = ScreenManager(self.screen_size,self.core) + self.screen_manager = ScreenManager(self.screen_size,self.core, self.backend) def start_thread(self): clock = pygame.time.Clock() screen = pygame.display.set_mode(self.screen_size) while self.running: - clock.tick(30) + clock.tick(15) screen.blit(self.screen_manager.update(),(0,0)) pygame.display.flip() for event in pygame.event.get(): @@ -49,4 +51,7 @@ class TouchScreen(pykka.ThreadingActor, core.CoreListener): try: self.screen_manager.track_started(tl_track) except: - traceback.print_exc() \ No newline at end of file + traceback.print_exc() + + def volume_changed(self, volume): + self.screen_manager.volume_changed(volume) \ No newline at end of file diff --git a/mopidy_touchscreen/touch_screen_backend.py b/mopidy_touchscreen/touch_screen_backend.py new file mode 100644 index 0000000..dcb8dc1 --- /dev/null +++ b/mopidy_touchscreen/touch_screen_backend.py @@ -0,0 +1,18 @@ +import pykka +from mopidy import backend +import logging + +logger = logging.getLogger(__name__) + +class TouchScreenBackend(pykka.ThreadingActor, backend.Backend): + + def __init__(self, config, audio): + super(TouchScreenBackend, self).__init__() + self.audio = audio + logger.error("backend funciona") + + def on_receive(self, message): + logger.error("heldu naiz") + if message['action'] == 'volume': + logger.error("bolumena aldatzen") + self.audio.set_volume(message['value']) \ No newline at end of file diff --git a/setup.py b/setup.py index d6be008..877d51b 100644 --- a/setup.py +++ b/setup.py @@ -27,6 +27,7 @@ setup( 'setuptools', 'Mopidy >= 0.18', 'Pykka >= 1.1', + 'pygame' ], test_suite='nose.collector', tests_require=[