Code fixes

Do not use backend anymore
This commit is contained in:
Ander
2014-11-20 10:56:45 +01:00
parent 9448674301
commit d8839a5559
15 changed files with 2056 additions and 1935 deletions

View File

@@ -2,11 +2,9 @@ from __future__ import unicode_literals
import logging import logging
import os import os
from mopidy import config, ext from mopidy import config, ext
from .touch_screen import TouchScreen from .touch_screen import TouchScreen
from .touch_screen_backend import TouchScreenBackend
__version__ = '0.2.2' __version__ = '0.2.2'
@@ -21,7 +19,8 @@ class Extension(ext.Extension):
version = __version__ version = __version__
def get_default_config(self): def get_default_config(self):
conf_file = os.path.join(os.path.dirname(__file__), 'ext.conf') conf_file = os.path.join(os.path.dirname(__file__),
'ext.conf')
return config.read(conf_file) return config.read(conf_file)
def get_config_schema(self): def get_config_schema(self):
@@ -37,13 +36,10 @@ class Extension(ext.Extension):
schema['gpio_up'] = config.Integer() schema['gpio_up'] = config.Integer()
schema['gpio_down'] = config.Integer() schema['gpio_down'] = config.Integer()
schema['gpio_enter'] = config.Integer() schema['gpio_enter'] = config.Integer()
schema['sdl_fbdev'] = config.String() schema['sdl_fbdev'] = config.String()
schema['sdl_mousdrv'] = config.String() schema['sdl_mousdrv'] = config.String()
schema['sdl_mousedev'] = config.String() schema['sdl_mousedev'] = config.String()
return schema return schema
def setup(self, registry): def setup(self, registry):
registry.add('frontend', TouchScreen) registry.add('frontend', TouchScreen)
# Backend used for controling volume
registry.add('backend', TouchScreenBackend)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,8 @@ class GPIOManager():
# Right Button # Right Button
GPIO.setup(pins['right'], GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(pins['right'], GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(pins['right'], GPIO.BOTH, callback=right, GPIO.add_event_detect(pins['right'], GPIO.BOTH,
callback=right,
bouncetime=30) bouncetime=30)
# Up Button # Up Button
@@ -33,7 +34,8 @@ class GPIOManager():
# Enter Button # Enter Button
GPIO.setup(pins['enter'], GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(pins['enter'], GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(pins['enter'], GPIO.BOTH, callback=right, GPIO.add_event_detect(pins['enter'], GPIO.BOTH,
callback=right,
bouncetime=30) bouncetime=30)

View File

@@ -34,19 +34,24 @@ class InputManager():
if event.type == pygame.MOUSEBUTTONUP: if event.type == pygame.MOUSEBUTTONUP:
if event.button == 4: if event.button == 4:
touch_event = InputEvent(InputManager.swipe, self.down_pos, touch_event = InputEvent(InputManager.swipe,
self.up_pos, True, InputManager.up) self.down_pos,
self.up_pos, True,
InputManager.up)
return touch_event return touch_event
elif event.button == 5: elif event.button == 5:
touch_event = InputEvent(InputManager.swipe, self.down_pos, touch_event = InputEvent(InputManager.swipe,
self.up_pos, True, InputManager.down) self.down_pos,
self.up_pos, True,
InputManager.down)
return touch_event return touch_event
elif event.button == 1 and self.down_button == 1: elif event.button == 1 and self.down_button == 1:
touch_event = self.mouse_up(event) touch_event = self.mouse_up(event)
return touch_event return touch_event
elif event.button == 3 and self.down_button == 3: elif event.button == 3 and self.down_button == 3:
touch_event = InputEvent(InputManager.long_click, touch_event = InputEvent(InputManager.long_click,
self.down_pos, self.up_pos, None, None) self.down_pos, self.up_pos,
None, None)
return touch_event return touch_event
else: else:
return None return None
@@ -78,7 +83,8 @@ class InputManager():
else: else:
return None return None
if direction is not None: if direction is not None:
return InputEvent(InputManager.key, None, None, None, direction) return InputEvent(InputManager.key, None, None, None,
direction)
def mouse_down(self, event): def mouse_down(self, event):
self.down_pos = event.pos self.down_pos = event.pos
@@ -87,26 +93,33 @@ class InputManager():
def mouse_up(self, event): def mouse_up(self, event):
self.up_pos = event.pos self.up_pos = event.pos
if abs(self.down_pos[0] - self.up_pos[0]) < self.max_move_margin: if abs(self.down_pos[0] - self.up_pos[
if abs(self.down_pos[1] - self.up_pos[1]) < self.max_move_margin: 0]) < self.max_move_margin:
if abs(self.down_pos[1] - self.up_pos[
1]) < self.max_move_margin:
if time.time() - InputManager.long_click_min_time > \ if time.time() - InputManager.long_click_min_time > \
self.down_time: self.down_time:
return InputEvent(InputManager.long_click, self.down_pos, return InputEvent(InputManager.long_click,
self.down_pos,
self.up_pos, None, None) self.up_pos, None, None)
else: else:
return InputEvent(InputManager.click, self.down_pos, return InputEvent(InputManager.click,
self.down_pos,
self.up_pos, None, None) self.up_pos, None, None)
elif abs(self.down_pos[1] - self.up_pos[1]) > self.min_swipe_move: elif abs(self.down_pos[1] - self.up_pos[
1]) > self.min_swipe_move:
return InputEvent(InputManager.swipe, self.down_pos, return InputEvent(InputManager.swipe, self.down_pos,
self.up_pos, True, None) self.up_pos, True, None)
elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin: elif self.down_pos[1] - self.up_pos[1] < self.max_move_margin:
if abs(self.down_pos[0] - self.up_pos[0]) > self.min_swipe_move: if abs(self.down_pos[0] - self.up_pos[
0]) > self.min_swipe_move:
return InputEvent(InputManager.swipe, self.down_pos, return InputEvent(InputManager.swipe, self.down_pos,
self.up_pos, False, None) self.up_pos, False, None)
class InputEvent(): class InputEvent():
def __init__(self, event_type, down_pos, current_pos, vertical, direction): def __init__(self, event_type, down_pos, current_pos, vertical,
direction):
self.type = event_type self.type = event_type
self.down_pos = down_pos self.down_pos = down_pos
self.current_pos = current_pos self.current_pos = current_pos

View File

@@ -1,5 +1,4 @@
import logging import logging
import mopidy.models import mopidy.models
from .list_view import ListView from .list_view import ListView
@@ -15,7 +14,8 @@ class LibraryScreen():
self.manager = manager self.manager = manager
self.list_view = ListView((0, self.base_size), ( self.list_view = ListView((0, self.base_size), (
self.size[0], self.size[1] - 2 * self.base_size), self.size[0], self.size[1] - 2 * self.base_size),
self.base_size, manager.fonts['base']) self.base_size,
manager.fonts['base'])
self.directory_list = [] self.directory_list = []
self.current_directory = None self.current_directory = None
self.library = None self.library = None
@@ -23,7 +23,7 @@ class LibraryScreen():
self.lookup_uri(None) self.lookup_uri(None)
def get_dirty_area(self): def get_dirty_area(self):
return self.list_view.get_dirty_area() return self.list_view.get_dirty_area()
def go_inside_directory(self, uri): def go_inside_directory(self, uri):
self.directory_list.append(self.current_directory) self.directory_list.append(self.current_directory)
@@ -46,7 +46,7 @@ class LibraryScreen():
self.lookup_uri(directory) self.lookup_uri(directory)
def update(self, screen, update_all): def update(self, screen, update_all):
self.list_view.render(screen) self.list_view.render(screen)
def touch_event(self, touch_event): def touch_event(self, touch_event):
clicked = self.list_view.touch_event(touch_event) clicked = self.list_view.touch_event(touch_event)
@@ -56,7 +56,8 @@ class LibraryScreen():
if clicked == 0: if clicked == 0:
self.go_up_directory() self.go_up_directory()
else: else:
self.play_uri(self.library[clicked - 1].uri, False) self.play_uri(self.library[clicked - 1].uri,
False)
else: else:
self.play_uri(self.library[clicked].uri, False) self.play_uri(self.library[clicked].uri, False)
else: else:
@@ -65,16 +66,19 @@ class LibraryScreen():
self.go_up_directory() self.go_up_directory()
else: else:
if self.library[ if self.library[
clicked - 1].type == mopidy.models.Ref.TRACK: clicked - 1].type == mopidy.models.Ref.TRACK:
self.play_uri(self.library[clicked - 1].uri, True) self.play_uri(
self.library[clicked - 1].uri, True)
else: else:
self.go_inside_directory( self.go_inside_directory(
self.library[clicked - 1].uri) self.library[clicked - 1].uri)
else: else:
if self.library[clicked].type == mopidy.models.Track: if self.library[
clicked].type == mopidy.models.Track:
self.play_uri(self.library[clicked].uri, True) self.play_uri(self.library[clicked].uri, True)
else: else:
self.go_inside_directory(self.library[clicked].uri) self.go_inside_directory(
self.library[clicked].uri)
def play_uri(self, uri, track): def play_uri(self, uri, track):
self.manager.core.tracklist.clear() self.manager.core.tracklist.clear()

View File

@@ -1,6 +1,7 @@
import logging import logging
from .screen_objects import ScreenObjectsManager, ScrollBar, TouchAndTextItem from .screen_objects import ScreenObjectsManager, ScrollBar, \
TouchAndTextItem
from .input_manager import InputManager from .input_manager import InputManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -21,20 +22,20 @@ class ListView():
self.set_list([]) self.set_list([])
self.selected = [] self.selected = []
def get_dirty_area(self):
return self.screen_objects.get_dirty_area()
# Sets the list for the lisview. It should be an iterable of strings # Sets the list for the lisview. It should be an iterable of strings
def set_list(self, item_list): def set_list(self, item_list):
self.screen_objects.clear() self.screen_objects.clear()
self.list = item_list self.list = item_list
self.list_size = len(item_list) self.list_size = len(item_list)
if self.max_rows < self.list_size: if self.max_rows < self.list_size:
self.scrollbar = True self.scrollbar = True
scroll_bar = ScrollBar( scroll_bar = ScrollBar(
(self.pos[0] + self.size[0] - self.base_size, self.pos[1]), (self.pos[0] + self.size[0] - self.base_size,
(self.base_size, self.size[1]), self.list_size, self.max_rows) self.pos[1]),
self.screen_objects.set_touch_object("scrollbar", scroll_bar) (self.base_size, self.size[1]), self.list_size,
self.max_rows)
self.screen_objects.set_touch_object("scrollbar",
scroll_bar)
else: else:
self.scrollbar = False self.scrollbar = False
self.load_new_item_position(0) self.load_new_item_position(0)
@@ -55,13 +56,12 @@ class ListView():
while i < self.list_size and z < self.max_rows: while i < self.list_size and z < self.max_rows:
item = TouchAndTextItem(self.font, self.list[i], ( item = TouchAndTextItem(self.font, self.list[i], (
self.pos[0], self.pos[1] + self.base_size * z), self.pos[0], self.pos[1] + self.base_size * z),
(width, -1)) (width, -1))
self.screen_objects.set_touch_object(str(i), item) self.screen_objects.set_touch_object(str(i), item)
i += 1 i += 1
z += 1 z += 1
def render(self, surface): def render(self, surface):
self.screen_objects.render(surface) self.screen_objects.render(surface)
@@ -95,14 +95,16 @@ class ListView():
if self.current_item + self.max_rows > self.list_size: if self.current_item + self.max_rows > self.list_size:
self.current_item = self.list_size - self.max_rows self.current_item = self.list_size - self.max_rows
self.load_new_item_position(self.current_item) self.load_new_item_position(self.current_item)
self.screen_objects.get_touch_object("scrollbar").set_item( self.screen_objects.get_touch_object(
"scrollbar").set_item(
self.current_item) self.current_item)
elif direction == -1: elif direction == -1:
self.current_item -= self.max_rows self.current_item -= self.max_rows
if self.current_item < 0: if self.current_item < 0:
self.current_item = 0 self.current_item = 0
self.load_new_item_position(self.current_item) self.load_new_item_position(self.current_item)
self.screen_objects.get_touch_object("scrollbar").set_item( self.screen_objects.get_touch_object(
"scrollbar").set_item(
self.current_item) self.current_item)
self.set_selected(self.selected) self.set_selected(self.selected)
@@ -110,13 +112,15 @@ class ListView():
def set_selected(self, selected): def set_selected(self, selected):
for number in self.selected: for number in self.selected:
try: try:
self.screen_objects.get_touch_object(str(number)).set_active( self.screen_objects.get_touch_object(
str(number)).set_active(
False) False)
except KeyError: except KeyError:
pass pass
for number in selected: for number in selected:
try: try:
self.screen_objects.get_touch_object(str(number)).set_active( self.screen_objects.get_touch_object(
str(number)).set_active(
True) True)
except KeyError: except KeyError:
pass pass

View File

@@ -6,13 +6,14 @@ import time
import urllib import urllib
import urllib2 import urllib2
from threading import Thread from threading import Thread
import pygame import pygame
from .screen_objects import (Progressbar, ScreenObjectsManager, TextItem, from .screen_objects import (Progressbar, ScreenObjectsManager,
TextItem,
TouchAndTextItem) TouchAndTextItem)
from .input_manager import InputManager from .input_manager import InputManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -27,9 +28,7 @@ class MainScreen():
self.cache = cache self.cache = cache
self.image = None self.image = None
self.artists = None self.artists = None
self.dirty_area = [] self.track_duration = "00:00"
self.track_duration = "00:00"
self.image_now_loaded = False
self.touch_text_manager = ScreenObjectsManager() self.touch_text_manager = ScreenObjectsManager()
current_track = self.core.playback.current_track.get() current_track = self.core.playback.current_track.get()
if current_track is None: if current_track is None:
@@ -42,18 +41,13 @@ class MainScreen():
self.touch_text_manager.get_touch_object( self.touch_text_manager.get_touch_object(
"time_progress").set_value( "time_progress").set_value(
self.core.playback.time_position.get() / 1000) self.core.playback.time_position.get() / 1000)
self.touch_text_manager.get_touch_object("time_progress").set_text( self.touch_text_manager.get_touch_object(
"time_progress").set_text(
time.strftime('%M:%S', time.gmtime( time.strftime('%M:%S', time.gmtime(
self.core.playback.time_position.get() / 1000)) + "/" + self.track_duration) self.core.playback.time_position.get() / 1000)) + "/" + self.track_duration)
if update_all: screen.blit(self.image, (
if self.image is not None: self.base_size / 2, self.base_size + self.base_size / 2))
screen.blit(self.image, (self.base_size / 2, self.base_size + self.base_size / 2)) self.touch_text_manager.render(screen)
self.image_now_loaded = False
elif self.image_now_loaded:
self.dirty_area.append(pygame.Rect(self.base_size / 2, self.base_size + self.base_size / 2, self.image.get_rect().width,self.image.get_rect().height))
screen.blit(self.image, (self.base_size / 2, self.base_size + self.base_size / 2))
self.image_now_loaded = False
self.touch_text_manager.render(screen)
return screen return screen
def track_started(self, track): def track_started(self, track):
@@ -61,7 +55,8 @@ class MainScreen():
x = self.base_size * 5 x = self.base_size * 5
width = self.size[0] - self.base_size / 2 - x width = self.size[0] - self.base_size / 2 - x
self.track_duration = time.strftime('%M:%S', time.gmtime(track.length / 1000)) self.track_duration = time.strftime('%M:%S', time.gmtime(
track.length / 1000))
# Load all artists # Load all artists
self.artists = [] self.artists = []
@@ -69,7 +64,8 @@ class MainScreen():
self.artists.append(artist) self.artists.append(artist)
# Track name # Track name
label = TextItem(self.fonts['base'], MainScreen.get_track_name(track), label = TextItem(self.fonts['base'],
MainScreen.get_track_name(track),
(x, self.base_size * 2), (x, self.base_size * 2),
(width, self.size[1])) (width, self.size[1]))
self.touch_text_manager.set_object("track_name", label) self.touch_text_manager.set_object("track_name", label)
@@ -83,7 +79,8 @@ class MainScreen():
# Artist # Artist
label = TextItem(self.fonts['base'], self.get_artist_string(), label = TextItem(self.fonts['base'], self.get_artist_string(),
(x, self.base_size * 4), (width, self.size[1])) (x, self.base_size * 4),
(width, self.size[1]))
self.touch_text_manager.set_object("artist_name", label) self.touch_text_manager.set_object("artist_name", label)
# Previous track button # Previous track button
@@ -94,17 +91,24 @@ class MainScreen():
size_2 = self.fonts['icon'].size(u"\ue61d")[0] size_2 = self.fonts['icon'].size(u"\ue61d")[0]
button = TouchAndTextItem(self.fonts['icon'], u"\ue61d", button = TouchAndTextItem(self.fonts['icon'], u"\ue61d",
(self.size[0] - size_2, self.base_size * 6), (self.size[0] - size_2,
self.base_size * 6),
None) None)
self.touch_text_manager.set_touch_object("next", button) self.touch_text_manager.set_touch_object("next", button)
# Progress # Progress
progress = Progressbar(self.fonts['base'],time.strftime('%M:%S', time.gmtime(0)) + "/" + time.strftime('%M:%S',time.gmtime(0)), progress = Progressbar(self.fonts['base'],
time.strftime('%M:%S', time.gmtime(
0)) + "/" + time.strftime('%M:%S',
time.gmtime(
0)),
(size_1, self.base_size * 6), (size_1, self.base_size * 6),
( (
self.size[0] - size_1 - size_2, self.base_size), self.size[0] - size_1 - size_2,
self.base_size),
track.length / 1000, False) track.length / 1000, False)
self.touch_text_manager.set_touch_object("time_progress", progress) self.touch_text_manager.set_touch_object("time_progress",
progress)
self.track = track self.track = track
if not self.is_image_in_cache(): if not self.is_image_in_cache():
@@ -113,10 +117,6 @@ class MainScreen():
else: else:
self.load_image() self.load_image()
def get_dirty_area(self):
dirty = self.touch_text_manager.get_dirty_area() + self.dirty_area
self.dirty_area = []
return dirty
def get_artist_string(self): def get_artist_string(self):
artists_string = '' artists_string = ''
@@ -175,28 +175,36 @@ class MainScreen():
current = TextItem(self.fonts['base'], current = TextItem(self.fonts['base'],
MainScreen.get_track_name(self.track), MainScreen.get_track_name(self.track),
(self.base_size / 2, self.base_size * 2), (self.base_size / 2,
self.base_size * 2),
(width, -1)) (width, -1))
self.touch_text_manager.set_object("track_name", current) self.touch_text_manager.set_object("track_name", current)
current = TextItem(self.fonts['base'], current = TextItem(self.fonts['base'],
MainScreen.get_track_album_name(self.track), MainScreen.get_track_album_name(
(self.base_size / 2, self.base_size * 3), self.track),
(self.base_size / 2,
self.base_size * 3),
(width, -1)) (width, -1))
self.touch_text_manager.set_object("album_name", current) self.touch_text_manager.set_object("album_name", current)
current = TextItem(self.fonts['base'], self.get_artist_string(), current = TextItem(self.fonts['base'],
(self.base_size / 2, self.base_size * 4), self.get_artist_string(),
(self.base_size / 2,
self.base_size * 4),
(width, -1)) (width, -1))
self.touch_text_manager.set_object("artist_name", current) self.touch_text_manager.set_object("artist_name", current)
def track_playback_ended(self, tl_track, time_position): def track_playback_ended(self, tl_track, time_position):
if self.image is not None: if self.image is not None:
self.dirty_area.append(pygame.Rect(self.base_size / 2, self.base_size + self.base_size / 2, self.image.get_rect().width,self.image.get_rect().height)) self.dirty_area.append(pygame.Rect(self.base_size / 2,
self.base_size + self.base_size / 2,
self.image.get_rect().width,
self.image.get_rect().height))
self.image = None self.image = None
self.track_duration = "00:00" self.track_duration = "00:00"
# There is no cover so it will use all the screen size for the text # There is no cover so it will use all the screen size for the text
width = self.size[0] - self.base_size width = self.size[0] - self.base_size
@@ -223,7 +231,7 @@ class MainScreen():
self.get_cover_folder() + self.get_cover_folder() +
self.get_image_file_name()).convert(), self.get_image_file_name()).convert(),
(size, size)) (size, size))
self.image_now_loaded = True self.image_now_loaded = True
def touch_event(self, event): def touch_event(self, event):
if event.type == InputManager.click: if event.type == InputManager.click:
@@ -233,9 +241,10 @@ class MainScreen():
for key in objects: for key in objects:
if key == "time_progress": if key == "time_progress":
value = self.touch_text_manager.get_touch_object( value = self.touch_text_manager.get_touch_object(
key).get_pos_value(event.current_pos) * 1000 key).get_pos_value(
event.current_pos) * 1000
self.core.playback.seek(value) self.core.playback.seek(value)
elif key == "previous": elif key == "previous":
self.core.playback.previous() self.core.playback.previous()
elif key == "next": elif key == "next":

View File

@@ -1,6 +1,5 @@
import os import os
import socket import socket
import mopidy import mopidy
from .screen_objects import ScreenObjectsManager, TouchAndTextItem from .screen_objects import ScreenObjectsManager, TouchAndTextItem
@@ -16,29 +15,38 @@ class MenuScreen():
self.screen_objects = ScreenObjectsManager() self.screen_objects = ScreenObjectsManager()
# Exit mopidy button # Exit mopidy button
button = TouchAndTextItem(self.manager.fonts['icon'], u"\ue611", button = TouchAndTextItem(self.manager.fonts['icon'],
u"\ue611",
(0, self.base_size), None) (0, self.base_size), None)
self.screen_objects.set_touch_object("exit_icon", button) self.screen_objects.set_touch_object("exit_icon", button)
button = TouchAndTextItem(self.manager.fonts['base'], "Exit Mopidy", button = TouchAndTextItem(self.manager.fonts['base'],
(button.get_right_pos(), self.base_size), "Exit Mopidy",
(button.get_right_pos(),
self.base_size),
None) None)
self.screen_objects.set_touch_object("exit", button) self.screen_objects.set_touch_object("exit", button)
# Shutdown button # Shutdown button
button = TouchAndTextItem(self.manager.fonts['icon'], u"\ue60b", button = TouchAndTextItem(self.manager.fonts['icon'],
u"\ue60b",
(0, self.base_size * 2), None) (0, self.base_size * 2), None)
self.screen_objects.set_touch_object("shutdown_icon", button) self.screen_objects.set_touch_object("shutdown_icon", button)
button = TouchAndTextItem(self.manager.fonts['base'], "Shutdown", button = TouchAndTextItem(self.manager.fonts['base'],
(button.get_right_pos(), self.base_size * 2), "Shutdown",
(button.get_right_pos(),
self.base_size * 2),
None) None)
self.screen_objects.set_touch_object("shutdown", button) self.screen_objects.set_touch_object("shutdown", button)
# Restart button # Restart button
button = TouchAndTextItem(self.manager.fonts['icon'], u"\ue609", button = TouchAndTextItem(self.manager.fonts['icon'],
u"\ue609",
(0, self.base_size * 3), None) (0, self.base_size * 3), None)
self.screen_objects.set_touch_object("restart_icon", button) self.screen_objects.set_touch_object("restart_icon", button)
button = TouchAndTextItem(self.manager.fonts['base'], "Restart", button = TouchAndTextItem(self.manager.fonts['base'],
(button.get_right_pos(), self.base_size * 3), "Restart",
(button.get_right_pos(),
self.base_size * 3),
None) None)
self.screen_objects.set_touch_object("restart", button) self.screen_objects.set_touch_object("restart", button)
@@ -50,9 +58,6 @@ class MenuScreen():
def update(self, screen, update_all): def update(self, screen, update_all):
self.screen_objects.render(screen) self.screen_objects.render(screen)
def get_dirty_area(self):
return self.screen_objects.get_dirty_area()
def touch_event(self, event): def touch_event(self, event):
if event.type == InputManager.click: if event.type == InputManager.click:
clicked = self.screen_objects.get_touch_objects_in_pos( clicked = self.screen_objects.get_touch_objects_in_pos(

View File

@@ -8,16 +8,14 @@ class PlaylistScreen():
self.manager = manager self.manager = manager
self.list_view = ListView((0, self.base_size), ( self.list_view = ListView((0, self.base_size), (
self.size[0], self.size[1] - 2 * self.base_size), self.size[0], self.size[1] - 2 * self.base_size),
self.base_size, manager.fonts['base']) self.base_size,
manager.fonts['base'])
self.playlists_strings = [] self.playlists_strings = []
self.playlists = [] self.playlists = []
self.playlists_loaded() self.playlists_loaded()
def get_dirty_area(self):
return self.list_view.get_dirty_area()
def update(self, screen, update_all): def update(self, screen, update_all):
self.list_view.render(screen) self.list_view.render(screen)
def playlists_loaded(self): def playlists_loaded(self):
self.playlists_strings = [] self.playlists_strings = []
@@ -31,5 +29,6 @@ class PlaylistScreen():
clicked = self.list_view.touch_event(touch_event) clicked = self.list_view.touch_event(touch_event)
if clicked is not None: if clicked is not None:
self.manager.core.tracklist.clear() self.manager.core.tracklist.clear()
self.manager.core.tracklist.add(uri=self.playlists[clicked].uri) self.manager.core.tracklist.add(
uri=self.playlists[clicked].uri)
self.manager.core.playback.play() self.manager.core.playback.play()

View File

@@ -1,6 +1,5 @@
import logging import logging
import traceback import traceback
import mopidy import mopidy
import mopidy.core import mopidy.core
import pygame import pygame
@@ -10,31 +9,35 @@ from .library_screen import LibraryScreen
from .main_screen import MainScreen from .main_screen import MainScreen
from .menu_screen import MenuScreen from .menu_screen import MenuScreen
from .playlist_screen import PlaylistScreen from .playlist_screen import PlaylistScreen
from .screen_objects import Progressbar, ScreenObjectsManager, TouchAndTextItem from .screen_objects import Progressbar, ScreenObjectsManager, \
TouchAndTextItem
from .input_manager import InputManager from .input_manager import InputManager
from .tracklist import Tracklist from .tracklist import Tracklist
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ScreenManager(): class ScreenManager():
def __init__(self, size, core, backend, cache): def __init__(self, size, core, cache):
self.size = size self.size = size
self.core = core self.core = core
self.backend = backend
self.fonts = {} self.fonts = {}
self.current_screen = 0 self.current_screen = 0
self.base_size = self.size[1] / 8 self.base_size = self.size[1] / 8
font = resource_filename(Requirement.parse("mopidy-touchscreen"), font = resource_filename(
"mopidy_touchscreen/icomoon.ttf") Requirement.parse("mopidy-touchscreen"),
self.fonts['base'] = pygame.font.SysFont("verdana", self.base_size) "mopidy_touchscreen/icomoon.ttf")
self.fonts['base'] = pygame.font.SysFont("verdana",
self.base_size)
self.fonts['icon'] = pygame.font.Font(font, self.base_size) self.fonts['icon'] = pygame.font.Font(font, self.base_size)
try: try:
self.screens = [MainScreen(size, self, cache, core, self.fonts), self.screens = [
Tracklist(size, self.base_size, self), MainScreen(size, self, cache, core, self.fonts),
LibraryScreen(size, self.base_size, self), Tracklist(size, self.base_size, self),
PlaylistScreen(size, self.base_size, self), LibraryScreen(size, self.base_size, self),
MenuScreen(size, self.base_size, self)] PlaylistScreen(size, self.base_size, self),
MenuScreen(size, self.base_size, self)]
except: except:
traceback.print_exc() traceback.print_exc()
self.track = None self.track = None
@@ -42,8 +45,8 @@ class ScreenManager():
self.top_bar_objects = ScreenObjectsManager() self.top_bar_objects = ScreenObjectsManager()
self.down_bar_objects = ScreenObjectsManager() self.down_bar_objects = ScreenObjectsManager()
self.selected_zone = self.top_bar_objects self.selected_zone = self.top_bar_objects
self.dirty_area = [] self.dirty_area = []
self.screen_changed = True self.screen_changed = True
# Top bar # Top bar
self.top_bar = pygame.Surface((self.size[0], self.base_size), self.top_bar = pygame.Surface((self.size[0], self.base_size),
@@ -51,38 +54,45 @@ class ScreenManager():
self.top_bar.fill((0, 0, 0, 128)) self.top_bar.fill((0, 0, 0, 128))
# Play/pause # Play/pause
button = TouchAndTextItem(self.fonts['icon'], u"\ue615 ", (0, 0), None) button = TouchAndTextItem(self.fonts['icon'], u"\ue615 ",
(0, 0), None)
self.top_bar_objects.set_touch_object("pause_play", button) self.top_bar_objects.set_touch_object("pause_play", button)
x = button.get_right_pos() x = button.get_right_pos()
# Random # Random
button = TouchAndTextItem(self.fonts['icon'], u"\ue629 ", (x, 0), None) button = TouchAndTextItem(self.fonts['icon'], u"\ue629 ",
(x, 0), None)
self.top_bar_objects.set_touch_object("random", button) self.top_bar_objects.set_touch_object("random", button)
x = button.get_right_pos() x = button.get_right_pos()
# Repeat # Repeat
button = TouchAndTextItem(self.fonts['icon'], u"\ue626", (x, 0), None) button = TouchAndTextItem(self.fonts['icon'], u"\ue626",
(x, 0), None)
self.top_bar_objects.set_touch_object("repeat", button) self.top_bar_objects.set_touch_object("repeat", button)
x = button.get_right_pos() x = button.get_right_pos()
# Single # Single
button = TouchAndTextItem(self.fonts['base'], " 1 ", (x, 0), None) button = TouchAndTextItem(self.fonts['base'], " 1 ", (x, 0),
None)
self.top_bar_objects.set_touch_object("single", button) self.top_bar_objects.set_touch_object("single", button)
x = button.get_right_pos() x = button.get_right_pos()
# Internet # Internet
button = TouchAndTextItem(self.fonts['icon'], u"\ue602 ", (x, 0), None) button = TouchAndTextItem(self.fonts['icon'], u"\ue602 ",
(x, 0), None)
self.top_bar_objects.set_touch_object("internet", button) self.top_bar_objects.set_touch_object("internet", button)
x = button.get_right_pos() x = button.get_right_pos()
# Mute # Mute
button = TouchAndTextItem(self.fonts['icon'], u"\ue61f ", (x, 0), None) button = TouchAndTextItem(self.fonts['icon'], u"\ue61f ",
(x, 0), None)
self.top_bar_objects.set_touch_object("mute", button) self.top_bar_objects.set_touch_object("mute", button)
x = button.get_right_pos() x = button.get_right_pos()
# Volume # Volume
progress = Progressbar(self.fonts['base'], "100", (x, 0), progress = Progressbar(self.fonts['base'], "100", (x, 0),
(self.size[0] - x, self.base_size), 100, True) (self.size[0] - x, self.base_size),
100, True)
self.top_bar_objects.set_touch_object("volume", progress) self.top_bar_objects.set_touch_object("volume", progress)
progress.set_value(self.core.playback.volume.get()) progress.set_value(self.core.playback.volume.get())
@@ -92,25 +102,29 @@ class ScreenManager():
# Main button # Main button
button = TouchAndTextItem(self.fonts['icon'], u" \ue600", button = TouchAndTextItem(self.fonts['icon'], u" \ue600",
(0, self.base_size * 7), button_size) (0, self.base_size * 7),
button_size)
self.down_bar_objects.set_touch_object("menu_0", button) self.down_bar_objects.set_touch_object("menu_0", button)
x = button.get_right_pos() x = button.get_right_pos()
# Tracklist button # Tracklist button
button = TouchAndTextItem(self.fonts['icon'], u" \ue60d", button = TouchAndTextItem(self.fonts['icon'], u" \ue60d",
(x, self.base_size * 7), button_size) (x, self.base_size * 7),
button_size)
self.down_bar_objects.set_touch_object("menu_1", button) self.down_bar_objects.set_touch_object("menu_1", button)
x = button.get_right_pos() x = button.get_right_pos()
# Library button # Library button
button = TouchAndTextItem(self.fonts['icon'], u" \ue604", button = TouchAndTextItem(self.fonts['icon'], u" \ue604",
(x, self.base_size * 7), button_size) (x, self.base_size * 7),
button_size)
self.down_bar_objects.set_touch_object("menu_2", button) self.down_bar_objects.set_touch_object("menu_2", button)
x = button.get_right_pos() x = button.get_right_pos()
# Playlist button # Playlist button
button = TouchAndTextItem(self.fonts['icon'], u" \ue605", button = TouchAndTextItem(self.fonts['icon'], u" \ue605",
(x, self.base_size * 7), button_size) (x, self.base_size * 7),
button_size)
self.down_bar_objects.set_touch_object("menu_3", button) self.down_bar_objects.set_touch_object("menu_3", button)
x = button.get_right_pos() x = button.get_right_pos()
@@ -121,7 +135,8 @@ class ScreenManager():
# Down bar # Down bar
self.down_bar = pygame.Surface( self.down_bar = pygame.Surface(
(self.size[0], self.size[1] - self.base_size * 7), pygame.SRCALPHA) (self.size[0], self.size[1] - self.base_size * 7),
pygame.SRCALPHA)
self.down_bar.fill((0, 0, 0, 128)) self.down_bar.fill((0, 0, 0, 128))
self.options_changed() self.options_changed()
@@ -135,13 +150,14 @@ class ScreenManager():
def update(self): def update(self):
surface = pygame.Surface(self.size) surface = pygame.Surface(self.size)
surface.fill([200,200,200]) surface.fill([200, 200, 200])
self.screens[self.current_screen].update(surface, self.screen_changed) self.screens[self.current_screen].update(surface,
self.screen_changed)
surface.blit(self.top_bar, (0, 0)) surface.blit(self.top_bar, (0, 0))
surface.blit(self.down_bar, (0, self.base_size * 7)) surface.blit(self.down_bar, (0, self.base_size * 7))
self.top_bar_objects.render(surface) self.top_bar_objects.render(surface)
self.down_bar_objects.render(surface) self.down_bar_objects.render(surface)
self.screen_changed = False self.screen_changed = False
return surface return surface
def track_started(self, track): def track_started(self, track):
@@ -150,12 +166,13 @@ class ScreenManager():
self.screens[1].track_started(track) self.screens[1].track_started(track)
def get_dirty_area(self): def get_dirty_area(self):
self.dirty_area = self.dirty_area + self.top_bar_objects.get_dirty_area() self.dirty_area = self.dirty_area + self.top_bar_objects.get_dirty_area()
self.dirty_area = self.dirty_area + self.down_bar_objects.get_dirty_area() self.dirty_area = self.dirty_area + self.down_bar_objects.get_dirty_area()
self.dirty_area = self.dirty_area + self.screens[self.current_screen].get_dirty_area() self.dirty_area = self.dirty_area + self.screens[
dirty_area = self.dirty_area self.current_screen].get_dirty_area()
self.dirty_area = [] dirty_area = self.dirty_area
return dirty_area self.dirty_area = []
return dirty_area
def track_playback_ended(self, tl_track, time_position): def track_playback_ended(self, tl_track, time_position):
self.screens[0].track_playback_ended(tl_track, time_position) self.screens[0].track_playback_ended(tl_track, time_position)
@@ -166,8 +183,9 @@ class ScreenManager():
if event.type == InputManager.click: if event.type == InputManager.click:
objects = self.top_bar_objects.get_touch_objects_in_pos( objects = self.top_bar_objects.get_touch_objects_in_pos(
event.current_pos) event.current_pos)
objects.extend(self.down_bar_objects.get_touch_objects_in_pos( objects.extend(
event.current_pos)) self.down_bar_objects.get_touch_objects_in_pos(
event.current_pos))
self.click_on_objects(objects, event) self.click_on_objects(objects, event)
elif event.type == InputManager.key and event.direction == InputManager.enter: elif event.type == InputManager.key and event.direction == InputManager.enter:
objects = [self.selected_zone.selected_key] objects = [self.selected_zone.selected_key]
@@ -175,7 +193,8 @@ class ScreenManager():
elif event.type == InputManager.key: elif event.type == InputManager.key:
if event.direction == InputManager.enter: if event.direction == InputManager.enter:
logger.error(self.selected_zone.selected_key) logger.error(self.selected_zone.selected_key)
self.click_on_objects([self.selected_zone.selected_key], event) self.click_on_objects(
[self.selected_zone.selected_key], event)
else: else:
self.change_selection(event, None) self.change_selection(event, None)
self.screens[self.current_screen].touch_event(event) self.screens[self.current_screen].touch_event(event)
@@ -183,16 +202,20 @@ class ScreenManager():
def volume_changed(self, volume): def volume_changed(self, volume):
if not self.core.playback.mute.get(): if not self.core.playback.mute.get():
if volume > 80: if volume > 80:
self.top_bar_objects.get_touch_object("mute").set_text( self.top_bar_objects.get_touch_object(
"mute").set_text(
u"\ue61f", False) u"\ue61f", False)
elif volume > 50: elif volume > 50:
self.top_bar_objects.get_touch_object("mute").set_text( self.top_bar_objects.get_touch_object(
"mute").set_text(
u"\ue620", False) u"\ue620", False)
elif volume > 20: elif volume > 20:
self.top_bar_objects.get_touch_object("mute").set_text( self.top_bar_objects.get_touch_object(
"mute").set_text(
u"\ue621", False) u"\ue621", False)
else: else:
self.top_bar_objects.get_touch_object("mute").set_text( self.top_bar_objects.get_touch_object(
"mute").set_text(
u"\ue622", False) u"\ue622", False)
self.top_bar_objects.get_touch_object("volume").set_value( self.top_bar_objects.get_touch_object("volume").set_value(
volume) volume)
@@ -227,13 +250,12 @@ class ScreenManager():
elif key[:-1] == "menu_": elif key[:-1] == "menu_":
self.change_screen(int(key[-1:])) self.change_screen(int(key[-1:]))
def change_volume(self,event): def change_volume(self, event):
manager = self.top_bar_objects manager = self.top_bar_objects
volume = manager.get_touch_object("volume") volume = manager.get_touch_object("volume")
pos = event.current_pos pos = event.current_pos
value = volume.get_pos_value(pos) value = volume.get_pos_value(pos)
self.backend.tell( self.core.playback.volume = value
{'action': 'volume', 'value': value})
self.volume_changed(value) self.volume_changed(value)
def playback_state_changed(self, old_state, new_state): def playback_state_changed(self, old_state, new_state):
@@ -265,13 +287,14 @@ class ScreenManager():
self.core.tracklist.single.get()) self.core.tracklist.single.get())
def change_screen(self, new_screen): def change_screen(self, new_screen):
self.screen_changed = True self.screen_changed = True
self.down_bar_objects.get_touch_object( self.down_bar_objects.get_touch_object(
"menu_" + str(self.current_screen)).set_active(False) "menu_" + str(self.current_screen)).set_active(False)
self.current_screen = new_screen self.current_screen = new_screen
self.down_bar_objects.get_touch_object( self.down_bar_objects.get_touch_object(
"menu_" + str(new_screen)).set_active(True) "menu_" + str(new_screen)).set_active(True)
self.dirty_area.append(pygame.Rect(0,0,self.size[0],self.size[1])) self.dirty_area.append(
pygame.Rect(0, 0, self.size[0], self.size[1]))
def playlists_loaded(self): def playlists_loaded(self):
self.screens[3].playlists_loaded() self.screens[3].playlists_loaded()
@@ -287,13 +310,17 @@ class ScreenManager():
def change_selection(self, event, pos): def change_selection(self, event, pos):
if self.selected_zone == self.top_bar_objects: if self.selected_zone == self.top_bar_objects:
if not self.top_bar_objects.change_selected(event.direction, pos) and event.direction == InputManager.down: if not self.top_bar_objects.change_selected(
event.direction,
pos) and event.direction == InputManager.down:
pos = self.top_bar_objects.selected.pos pos = self.top_bar_objects.selected.pos
self.selected_zone = self.down_bar_objects self.selected_zone = self.down_bar_objects
self.top_bar_objects.set_selected(None) self.top_bar_objects.set_selected(None)
self.change_selection(event, pos) self.change_selection(event, pos)
elif self.selected_zone == self.down_bar_objects: elif self.selected_zone == self.down_bar_objects:
if not self.down_bar_objects.change_selected(event.direction, pos) and event.direction == InputManager.up: if not self.down_bar_objects.change_selected(
event.direction,
pos) and event.direction == InputManager.up:
pos = self.down_bar_objects.selected.pos pos = self.down_bar_objects.selected.pos
self.selected_zone = self.top_bar_objects self.selected_zone = self.top_bar_objects
self.down_bar_objects.set_selected(None) self.down_bar_objects.set_selected(None)

View File

@@ -1,6 +1,5 @@
import logging import logging
import math import math
import pygame import pygame
from .input_manager import InputManager from .input_manager import InputManager
@@ -15,23 +14,13 @@ class ScreenObjectsManager():
self.text_objects = {} self.text_objects = {}
self.selected = None self.selected = None
self.selected_key = None self.selected_key = None
self.dirty_area = []
def clear(self): def clear(self):
for key in self.touch_objects: self.touch_objects = {}
self.dirty_area.append(self.touch_objects[key].rect_in_pos)
for key in self.text_objects:
self.dirty_area.append(self.text_objects[key].rect_in_pos)
self.touch_objects = {}
self.text_objects = {} self.text_objects = {}
def set_object(self, key, add_object): def set_object(self, key, add_object):
try:
self.dirty_area.append(self.text_objects[key].rect_in_pos)
except KeyError:
pass
self.text_objects[key] = add_object self.text_objects[key] = add_object
self.dirty_area.append(add_object.rect_in_pos)
def get_object(self, key): def get_object(self, key):
return self.text_objects[key] return self.text_objects[key]
@@ -45,19 +34,12 @@ class ScreenObjectsManager():
def render(self, surface): def render(self, surface):
for key in self.text_objects: for key in self.text_objects:
if self.text_objects[key].update(): self.text_objects[key].update()
self.dirty_area.append(self.text_objects[key].rect_in_pos)
self.text_objects[key].render(surface) self.text_objects[key].render(surface)
for key in self.touch_objects: for key in self.touch_objects:
if self.touch_objects[key].update(): self.touch_objects[key].update()
self.dirty_area.append(self.touch_objects[key].rect_in_pos)
self.touch_objects[key].render(surface) self.touch_objects[key].render(surface)
def get_dirty_area(self):
dirty_area = self.dirty_area
self.dirty_area = []
return dirty_area
def get_touch_objects_in_pos(self, pos): def get_touch_objects_in_pos(self, pos):
touched_objects = [] touched_objects = []
for key in self.touch_objects: for key in self.touch_objects:
@@ -89,16 +71,20 @@ class ScreenObjectsManager():
if pos is None: if pos is None:
pos = self.selected.pos pos = self.selected.pos
if direction == InputManager.right: if direction == InputManager.right:
bests = self.find_nearest_objects(self.find_in_quadrant(False, True, pos), True, pos) bests = self.find_nearest_objects(
self.find_in_quadrant(False, True, pos), True, pos)
best_key = self.find_best_object(bests, False, True, pos) best_key = self.find_best_object(bests, False, True, pos)
elif direction == InputManager.left: elif direction == InputManager.left:
bests = self.find_nearest_objects(self.find_in_quadrant(False, False, pos), True, pos) bests = self.find_nearest_objects(
self.find_in_quadrant(False, False, pos), True, pos)
best_key = self.find_best_object(bests, False, False, pos) best_key = self.find_best_object(bests, False, False, pos)
elif direction == InputManager.down: elif direction == InputManager.down:
bests = self.find_nearest_objects(self.find_in_quadrant(True, True, pos), False, pos) bests = self.find_nearest_objects(
self.find_in_quadrant(True, True, pos), False, pos)
best_key = self.find_best_object(bests, True, True, pos) best_key = self.find_best_object(bests, True, True, pos)
elif direction == InputManager.up: elif direction == InputManager.up:
bests = self.find_nearest_objects(self.find_in_quadrant(True, False, pos), False, pos) bests = self.find_nearest_objects(
self.find_in_quadrant(True, False, pos), False, pos)
best_key = self.find_best_object(bests, True, False, pos) best_key = self.find_best_object(bests, True, False, pos)
if best_key is None: if best_key is None:
return False return False
@@ -175,7 +161,8 @@ class ScreenObjectsManager():
if best_pos is None: if best_pos is None:
best_pos = objects[key].pos[1] best_pos = objects[key].pos[1]
best_key = key best_key = key
elif objects[key].pos[1] >= pos[1] and objects[key].pos[1] < best_pos: elif objects[key].pos[1] >= pos[1] and \
objects[key].pos[1] < best_pos:
best_pos = objects[key].pos[1] best_pos = objects[key].pos[1]
best_key = key best_key = key
else: else:
@@ -183,7 +170,8 @@ class ScreenObjectsManager():
if best_pos is None: if best_pos is None:
best_pos = objects[key].pos[1] best_pos = objects[key].pos[1]
best_key = key best_key = key
elif objects[key].pos[1] <= pos[1] and objects[key].pos[1] > best_pos: elif objects[key].pos[1] <= pos[1] and \
objects[key].pos[1] > best_pos:
best_pos = objects[key].pos[1] best_pos = objects[key].pos[1]
best_key = key best_key = key
else: else:
@@ -192,7 +180,8 @@ class ScreenObjectsManager():
if best_pos is None: if best_pos is None:
best_pos = objects[key].pos[0] best_pos = objects[key].pos[0]
best_key = key best_key = key
elif objects[key].pos[0] >= pos[0] and objects[key].pos[0] < best_pos: elif objects[key].pos[0] >= pos[0] and \
objects[key].pos[0] < best_pos:
best_pos = objects[key].pos[0] best_pos = objects[key].pos[0]
best_key = key best_key = key
else: else:
@@ -200,35 +189,28 @@ class ScreenObjectsManager():
if best_pos is None: if best_pos is None:
best_pos = objects[key].pos[0] best_pos = objects[key].pos[0]
best_key = key best_key = key
elif objects[key].pos[0] <= pos[0] and objects[key].pos[0] > best_pos: elif objects[key].pos[0] <= pos[0] and \
objects[key].pos[0] > best_pos:
best_pos = objects[key].pos[0] best_pos = objects[key].pos[0]
best_key = key best_key = key
return best_key return best_key
class BaseItem(): class BaseItem():
def __init__(self, pos, size): def __init__(self, pos, size):
self.pos = pos self.pos = pos
self.size = size self.size = size
self.dirty = True
self.rect = pygame.Rect(0, 0, self.size[0], self.size[1]) 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.rect_in_pos = pygame.Rect(self.pos[0], self.pos[1],
self.size[0],
self.size[1]) self.size[1])
def get_right_pos(self): def get_right_pos(self):
return self.pos[0] + self.size[0] return self.pos[0] + self.size[0]
# Returns if must be redraw
def update(self): def update(self):
if self.dirty: pass
self.dirty = False
return True
else:
return False
class TextItem(BaseItem): class TextItem(BaseItem):
@@ -246,12 +228,14 @@ class TextItem(BaseItem):
else: else:
BaseItem.__init__(self, pos, self.font.size(text)) BaseItem.__init__(self, pos, self.font.size(text))
if size is not None: if size is not None:
if self.pos[0] + self.box.get_rect().width > pos[0] + size[0]: if self.pos[0] + self.box.get_rect().width > pos[0] + \
size[0]:
self.fit_horizontal = False self.fit_horizontal = False
self.step = 0 self.step = 0
else: else:
self.fit_horizontal = True self.fit_horizontal = True
if self.pos[1] + self.box.get_rect().height > pos[1] + size[1]: if self.pos[1] + self.box.get_rect().height > pos[1] + \
size[1]:
self.fit_vertical = False self.fit_vertical = False
else: else:
self.fit_vertical = True self.fit_vertical = True
@@ -262,30 +246,30 @@ class TextItem(BaseItem):
def update(self): def update(self):
if not self.fit_horizontal: if not self.fit_horizontal:
if self.step > self.box.get_rect().width: if self.step > self.box.get_rect().width:
self.step = -self.size[0] self.step = -self.size[0]
else: else:
self.step = self.step + 1 self.step = self.step + 1
return True return True
else: else:
return BaseItem.update(self) return BaseItem.update(self)
def render(self, surface): def render(self, surface):
if self.fit_horizontal: if self.fit_horizontal:
surface.blit(self.box, self.pos, area=self.rect) surface.blit(self.box, self.pos, area=self.rect)
else: else:
surface.blit(self.box, self.pos, area=pygame.Rect(self.step, 0, self.size[0], self.size[1])) surface.blit(self.box, self.pos,
area=pygame.Rect(self.step, 0, self.size[0],
self.size[1]))
def set_text(self, text, change_size): def set_text(self, text, change_size):
if text != self.text: if text != self.text:
self.dirty = True
if change_size: if change_size:
TextItem.__init__(self, self.font, text, self.pos, None) TextItem.__init__(self, self.font, text, self.pos,
None)
else: else:
TextItem.__init__(self, self.font, text, self.pos, self.size) TextItem.__init__(self, self.font, text, self.pos,
return True self.size)
else:
return False
class TouchObject(BaseItem): class TouchObject(BaseItem):
@@ -298,11 +282,9 @@ class TouchObject(BaseItem):
return self.rect_in_pos.collidepoint(pos) return self.rect_in_pos.collidepoint(pos)
def set_active(self, active): def set_active(self, active):
self.dirty = True
self.active = active self.active = active
def set_selected(self, selected): def set_selected(self, selected):
self.dirty = True
self.selected = selected self.selected = selected
@@ -312,21 +294,25 @@ class TouchAndTextItem(TouchObject, TextItem):
TouchObject.__init__(self, pos, self.size) TouchObject.__init__(self, pos, self.size)
self.active_color = (0, 150, 255) self.active_color = (0, 150, 255)
self.selected_color = (150, 0, 255) self.selected_color = (150, 0, 255)
self.active_box = self.font.render(text, True, self.active_color) self.active_box = self.font.render(text, True,
self.selected_box = self.font.render(text, True, self.selected_color) self.active_color)
self.selected_box = self.font.render(text, True,
self.selected_color)
def update(self): def update(self):
return TextItem.update(self) TextItem.update(self)
def set_text(self, text, change_size): def set_text(self, text, change_size):
self.dirty = True
TextItem.set_text(self, text, change_size) TextItem.set_text(self, text, change_size)
self.active_box = self.font.render(text, True, self.active_color) self.active_box = self.font.render(text, True,
self.selected_box = self.font.render(text, True, self.selected_color) self.active_color)
self.selected_box = self.font.render(text, True,
self.selected_color)
def render(self, surface): def render(self, surface):
if not self.fit_horizontal: if not self.fit_horizontal:
self.rect = pygame.Rect(self.step, 0, self.size[0], self.size[1]) self.rect = pygame.Rect(self.step, 0, self.size[0],
self.size[1])
if self.selected: if self.selected:
surface.blit(self.selected_box, self.pos, area=self.rect) surface.blit(self.selected_box, self.pos, area=self.rect)
elif self.active: elif self.active:
@@ -347,14 +333,16 @@ class Progressbar(TouchObject):
self.value_text = value_text self.value_text = value_text
if value_text: if value_text:
self.text = TextItem(font, str(max_value), pos, None) self.text = TextItem(font, str(max_value), pos, None)
self.text.pos = (self.pos[0] + self.size[0] / 2 - self.text.size[0] / self.text.pos = (
2, self.text.pos[1]) self.pos[0] + self.size[0] / 2 - self.text.size[0] /
2, self.text.pos[1])
self.text.set_text(str(self.value), True) self.text.set_text(str(self.value), True)
else: else:
self.text = TextItem(font, text, pos, None) self.text = TextItem(font, text, pos, None)
self.text.pos = (self.pos[0] + self.size[0] / 2 - self.text.size[0] / self.text.pos = (
2, self.text.pos[1]) self.pos[0] + self.size[0] / 2 - self.text.size[0] /
2, self.text.pos[1])
def render(self, surface): def render(self, surface):
surface.blit(self.surface, self.pos) surface.blit(self.surface, self.pos)
@@ -362,12 +350,12 @@ class Progressbar(TouchObject):
def set_value(self, value): def set_value(self, value):
if value != self.value: if value != self.value:
self.dirty = True
self.value = value self.value = value
if self.value_text: if self.value_text:
self.set_text(str(self.value)) self.set_text(str(self.value))
self.text.pos = (self.pos[0] + self.size[0] / 2 - self.text.size[0] / self.text.pos = (
2, self.text.pos[1]) self.pos[0] + self.size[0] / 2 - self.text.size[0] /
2, self.text.pos[1])
self.surface.fill(self.back_color) self.surface.fill(self.back_color)
pos_pixel = value * self.size[0] / self.max pos_pixel = value * self.size[0] / self.max
rect = pygame.Rect(0, 0, pos_pixel, self.size[1]) rect = pygame.Rect(0, 0, pos_pixel, self.size[1])
@@ -378,12 +366,13 @@ class Progressbar(TouchObject):
return x * self.max / self.size[0] return x * self.max / self.size[0]
def set_text(self, text): def set_text(self, text):
self.dirty = self.text.set_text(text, True) self.text.set_text(text, True)
class ScrollBar(TouchObject): class ScrollBar(TouchObject):
def __init__(self, pos, size, max_value, items_on_screen): def __init__(self, pos, size, max_value, items_on_screen):
BaseItem.__init__(self, pos, (pos[0] + size[0], pos[1] + size[1])) BaseItem.__init__(self, pos,
(pos[0] + size[0], pos[1] + size[1]))
self.pos = pos self.pos = pos
self.size = size self.size = size
self.max = max_value self.max = max_value
@@ -403,7 +392,8 @@ class ScrollBar(TouchObject):
def render(self, surface): def render(self, surface):
surface.blit(self.back_bar, self.pos) surface.blit(self.back_bar, self.pos)
surface.blit(self.bar, (self.pos[0], self.pos[1] + self.bar_pos)) surface.blit(self.bar,
(self.pos[0], self.pos[1] + self.bar_pos))
def touch(self, pos): def touch(self, pos):
if pos[1] < self.pos[1] + self.bar_pos: if pos[1] < self.pos[1] + self.bar_pos:
@@ -414,7 +404,7 @@ class ScrollBar(TouchObject):
return 0 return 0
def set_item(self, current_item): def set_item(self, current_item):
self.dirty = True
self.current_item = current_item self.current_item = current_item
self.bar_pos = float(self.current_item) / float(self.max) * float( self.bar_pos = float(self.current_item) / float(
self.max) * float(
self.size[1]) self.size[1])

View File

@@ -9,32 +9,35 @@ from mopidy import core
from .screen_manager import ScreenManager from .screen_manager import ScreenManager
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class TouchScreen(pykka.ThreadingActor, core.CoreListener): class TouchScreen(pykka.ThreadingActor, core.CoreListener):
def __init__(self, config, core): def __init__(self, config, core):
super(TouchScreen, self).__init__() super(TouchScreen, self).__init__()
self.backend = \
pykka.ActorRegistry.get_by_class_name("TouchScreenBackend")[0]
self.core = core self.core = core
self.running = False self.running = False
self.screen_size = (config['touchscreen']['screen_width'], self.screen_size = (config['touchscreen']['screen_width'],
config['touchscreen']['screen_height']) config['touchscreen']['screen_height'])
self.cache_dir = config['touchscreen']['cache_dir'] self.cache_dir = config['touchscreen']['cache_dir']
self.fullscreen = config['touchscreen']['fullscreen'] self.fullscreen = config['touchscreen']['fullscreen']
os.environ["SDL_FBDEV"] = config['touchscreen']['sdl_fbdev'] os.environ["SDL_FBDEV"] = config['touchscreen']['sdl_fbdev']
os.environ["SDL_MOUSEDRV"] = config['touchscreen']['sdl_mousdrv'] os.environ["SDL_MOUSEDRV"] = config['touchscreen'][
os.environ["SDL_MOUSEDEV"] = config['touchscreen']['sdl_mousedev'] 'sdl_mousdrv']
os.environ["SDL_MOUSEDEV"] = config['touchscreen'][
'sdl_mousedev']
pygame.init() pygame.init()
self.cursor = config['touchscreen']['cursor'] self.cursor = config['touchscreen']['cursor']
self.screen_manager = ScreenManager(self.screen_size, self.core, self.screen_manager = ScreenManager(self.screen_size,
self.backend, self.cache_dir) self.core,
self.cache_dir)
# Raspberry pi GPIO # Raspberry pi GPIO
self.gpio = config['touchscreen']['gpio'] self.gpio = config['touchscreen']['gpio']
if self.gpio: if self.gpio:
from .gpio_inpput_manager import GPIOManager from .gpio_inpput_manager import GPIOManager
pins = {} pins = {}
pins['left'] = config['touchscreen']['gpio_left'] pins['left'] = config['touchscreen']['gpio_left']
pins['right'] = config['touchscreen']['gpio_right'] pins['right'] = config['touchscreen']['gpio_right']
@@ -54,7 +57,7 @@ class TouchScreen(pykka.ThreadingActor, core.CoreListener):
while self.running: while self.running:
clock.tick(15) clock.tick(15)
screen.blit(self.screen_manager.update(), (0, 0)) screen.blit(self.screen_manager.update(), (0, 0))
pygame.display.update(self.screen_manager.get_dirty_area()) pygame.display.flip()
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
self.running = False self.running = False
@@ -86,7 +89,8 @@ class TouchScreen(pykka.ThreadingActor, core.CoreListener):
self.screen_manager.volume_changed(volume) self.screen_manager.volume_changed(volume)
def playback_state_changed(self, old_state, new_state): def playback_state_changed(self, old_state, new_state):
self.screen_manager.playback_state_changed(old_state, new_state) self.screen_manager.playback_state_changed(old_state,
new_state)
def tracklist_changed(self): def tracklist_changed(self):
try: try:
@@ -95,7 +99,8 @@ class TouchScreen(pykka.ThreadingActor, core.CoreListener):
traceback.print_exc() traceback.print_exc()
def track_playback_ended(self, tl_track, time_position): def track_playback_ended(self, tl_track, time_position):
self.screen_manager.track_playback_ended(tl_track, time_position) self.screen_manager.track_playback_ended(tl_track,
time_position)
def options_changed(self): def options_changed(self):
try: try:

View File

@@ -1,21 +0,0 @@
import logging
import pykka
from mopidy import backend
logger = logging.getLogger(__name__)
class TouchScreenBackend(pykka.ThreadingActor, backend.Backend):
def __init__(self, config, audio):
super(TouchScreenBackend, self).__init__()
self.audio = audio
def on_receive(self, message):
action = message['action']
if action == 'volume':
self.audio.set_volume(message['value'])
elif action == "mute":
self.audio.set_mute(message['value'])
elif action == "random":
self.audio.set_random(message['value'])

View File

@@ -9,16 +9,14 @@ class Tracklist():
self.manager = manager self.manager = manager
self.list_view = ListView((0, self.base_size), ( self.list_view = ListView((0, self.base_size), (
self.size[0], self.size[1] - 2 * self.base_size), self.size[0], self.size[1] - 2 * self.base_size),
self.base_size, manager.fonts['base']) self.base_size,
manager.fonts['base'])
self.tracks = [] self.tracks = []
self.tracks_strings = [] self.tracks_strings = []
self.update_list() self.update_list()
def get_dirty_area(self):
return self.list_view.get_dirty_area()
def update(self, screen, update_all): def update(self, screen, update_all):
self.list_view.render(screen) self.list_view.render(screen)
def tracklist_changed(self): def tracklist_changed(self):
self.update_list() self.update_list()