9and3r 10 anos atrás
pai
commit
194d6fa071

+ 7 - 3
mopidy_touchscreen/graphic_utils/list_view.py

@@ -80,15 +80,19 @@ class ListView():
         else:
             return False
 
-    def render(self, surface, update_all, rects):
+    def set_update_rects(self, rects):
+        for key in self.update_keys:
+                object = self.screen_objects.get_touch_object(key)
+                object.update()
+                rects.append(object.rect_in_pos)
+
+    def render(self, surface, update_all):
         if update_all:
             self.screen_objects.render(surface)
         else:
             for key in self.update_keys:
                 object = self.screen_objects.get_touch_object(key)
-                object.update()
                 object.render(surface)
-                rects.append(object.rect_in_pos)
 
     def touch_event(self, touch_event):
         self.must_update = True

+ 46 - 13
mopidy_touchscreen/graphic_utils/screen_objects.py

@@ -21,6 +21,22 @@ class ScreenObjectsManager:
     def set_object(self, key, add_object):
         self.text_objects[key] = add_object
 
+    def get_update_rects(self):
+        update_rects = []
+        for key in self.text_objects:
+            object = self.text_objects[key]
+            if hasattr(object, "fit_horizontal") and not object.fit_horizontal:
+                update_rects.append(object.rect_in_pos)
+        for key in self.touch_objects:
+            object = self.touch_objects[key]
+            if hasattr(object, "fit_horizontal") and not object.fit_horizontal:
+                update_rects.append(object.rect_in_pos)
+        return update_rects
+
+    def set_horizontal_shift(self, shift):
+        for key in self.text_objects:
+            self.text_objects[key].set_horizontal_shift(shift)
+
     def get_object(self, key):
         return self.text_objects[key]
 
@@ -72,10 +88,11 @@ class ScreenObjectsManager:
             self.selected_key = None
 
 
-class BaseItem():
-    def __init__(self, pos, size):
+class BaseItem:
+    def __init__(self, pos, size, horizontal_shift=0):
         self.pos = pos
         self.size = size
+        self.horizontal_shift = horizontal_shift
         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],
@@ -84,16 +101,31 @@ class BaseItem():
     def get_right_pos(self):
         return self.pos[0] + self.size[0]
 
+    def set_horizontal_shift(self, shift):
+        self.horizontal_shift = shift
+
     def update(self):
         return False
 
 
+class ImageView(BaseItem):
+    def __init__(self, pos, size, horizontal_shift=0):
+        BaseItem.__init__(self, pos, size, horizontal_shift)
+        self.image = None
+
+    def set_image(self, image):
+        self.image = image
+
+    def render(self, surface):
+        if self.image is not None:
+            surface.blit(self.image, (self.pos[0] + self.horizontal_shift, self.pos[1]))
+
 class TextItem(BaseItem):
 
     scroll_speed = 2
 
     def __init__(self, font, text, pos, size, center=False, background=None,
-                 scroll_no_fit=True):
+                 scroll_no_fit=True, horizontal_shift=0):
         self.font = font
         self.text = text
         self.scroll_no_fit = scroll_no_fit
@@ -104,11 +136,11 @@ class TextItem(BaseItem):
         if size is not None:
             if size[1] == -1:
                 height = self.font.size(text)[1]
-                BaseItem.__init__(self, pos, (size[0], height))
+                BaseItem.__init__(self, pos, (size[0], height), horizontal_shift)
             else:
-                BaseItem.__init__(self, pos, size)
+                BaseItem.__init__(self, pos, size, horizontal_shift)
         else:
-            BaseItem.__init__(self, pos, self.font.size(text))
+            BaseItem.__init__(self, pos, self.font.size(text), horizontal_shift)
         if size is not None:
             if self.pos[0] + self.box.get_rect().width > pos[0] + \
                     size[0]:
@@ -155,25 +187,26 @@ class TextItem(BaseItem):
         if self.background:
             surface.fill(self.background, rect=self.rect_in_pos)
             pygame.draw.rect(surface, (0, 0, 0), self.rect_in_pos, 1)
+        pos = (self.pos[0] + self.horizontal_shift, self.pos[1])
         if self.fit_horizontal:
             surface.blit(
-                self.box, ((self.pos[0] + self.margin),
+                self.box, ((pos[0] + self.margin),
                            self.pos[1]), area=self.rect)
         else:
             if self.scroll_no_fit:
-                surface.blit(self.box, self.pos,
+                surface.blit(self.box, pos,
                              area=pygame.Rect(self.step, 0, self.size[0],
                                               self.size[1]))
                 if self.step_2 is not None:
-                    surface.blit(self.box, (self.pos[0]+self.step_2,
-                                            self.pos[1]),
+                    surface.blit(self.box, (pos[0]+self.step_2,
+                                            pos[1]),
                                  area=pygame.Rect(0, 0,
                                                   self.size[0] -
                                                   self.step_2,
                                                   self.size[1]))
             else:
                 step = self.box.get_rect().width - self.size[0]
-                surface.blit(self.box, self.pos,
+                surface.blit(self.box, pos,
                              area=pygame.Rect(step, 0, self.size[0],
                                               self.size[1]))
 
@@ -182,11 +215,11 @@ class TextItem(BaseItem):
             if change_size:
                 TextItem.__init__(self, self.font, text, self.pos,
                                   None, self.center, self.background,
-                                  self.scroll_no_fit)
+                                  self.scroll_no_fit, self.horizontal_shift)
             else:
                 TextItem.__init__(self, self.font, text, self.pos,
                                   self.size, self.center, self.background,
-                                  self.scroll_no_fit)
+                                  self.scroll_no_fit, self.horizontal_shift)
 
     def add_text(self, add_text, change_size):
         self.set_text(self.text+add_text, change_size)

+ 84 - 0
mopidy_touchscreen/graphic_utils/view_pager.py

@@ -0,0 +1,84 @@
+__author__ = 'ander'
+
+from ..screens.base_screen import BaseScreen
+import traceback
+
+
+class ViewPager:
+
+    def __init__(self, size, manager):
+        self.size = size
+        self.objets_manager = [manager.create_objects_manager(), manager.create_objects_manager(), manager.create_objects_manager()]
+        self.pos = 0
+        self.manager = manager
+        self.next = False
+        self.direction = 0
+        self.previous = False
+        self.speed = self.size[0] / 15
+        self.update = False
+        self.update_rects = []
+
+    def notify_changed(self):
+        try:
+            for i in range(0, 3, 1):
+                self.manager.set_page_values(self.objets_manager[i], i)
+            self.update = True
+        except:
+            traceback.print_exc()
+
+    def change_to_page(self, page):
+        self.direction = page
+        self.update = True
+
+    def should_update(self):
+        if self.update:
+            return BaseScreen.update_all
+        else:
+            if len(self.update_rects)>0:
+                return BaseScreen.update_partial
+            else:
+                return BaseScreen.no_update
+
+    def shift(self):
+        if self.direction == 1:
+            if -self.pos > self.size[0]:
+                self.pos = 0
+                self.direction = 0
+                aux = self.objets_manager[0]
+                self.objets_manager[0] = self.objets_manager[1]
+                self.objets_manager[1] = self.objets_manager[2]
+                self.objets_manager[2] = aux
+                self.notify_changed()
+            else:
+                self.pos -= self.speed
+            self.objets_manager[2].set_horizontal_shift(self.size[0] + self.pos)
+            self.objets_manager[1].set_horizontal_shift(self.pos)
+        elif self.direction == -1:
+            if self.pos > self.size[0]:
+                self.pos = 0
+                self.direction = 0
+                aux = self.objets_manager[2]
+                self.objets_manager[2] = self.objets_manager[1]
+                self.objets_manager[1] = self.objets_manager[0]
+                self.objets_manager[0] = aux
+                self.notify_changed()
+            else:
+                self.pos += self.speed
+            self.objets_manager[0].set_horizontal_shift(-self.size[0] + self.pos)
+            self.objets_manager[1].set_horizontal_shift(self.pos)
+
+    def render(self, screen, update_type):
+        if self.direction != 0:
+            self.shift()
+        if self.pos != 0:
+            if self.direction == 1:
+                self.objets_manager[2].render(screen)
+            elif self.direction == -1:
+                self.objets_manager[0].render(screen)
+        else:
+            self.update = False
+            self.update_rects = self.objets_manager[1].get_update_rects()
+            #if update_type == BaseScreen.update_partial:
+                #rects += self.update_rects
+
+        self.objets_manager[1].render(screen)

+ 11 - 8
mopidy_touchscreen/screen_manager.py

@@ -147,23 +147,26 @@ class ScreenManager():
                 if self.background.should_update():
                     return BaseScreen.update_all
                 else:
-                    if self.screens[self.current_screen].should_update():
-                        return BaseScreen.update_partial
-                    else:
-                        return BaseScreen.no_update
+                    return self.screens[self.current_screen].should_update()
 
     def update(self, screen):
         update_type = self.get_update_type()
         if update_type != BaseScreen.no_update:
             rects = []
-            surface = self.background.draw_background()
             if self.keyboard:
+                surface = self.background.draw_background()
                 self.keyboard.update(surface)
             else:
+                if update_type == BaseScreen.update_partial:
+                    self.screens[self.current_screen].set_update_rects(rects)
+                    surface = self.background.draw_background()
+                else:
+                    surface = self.background.draw_background()
                 self.screens[self.current_screen].\
-                    update(surface, update_type, rects)
-                surface.blit(self.down_bar, (0, self.size[1] - self.base_size))
-                self.down_bar_objects.render(surface)
+                    update(surface, update_type)
+                if update_type == BaseScreen.update_all:
+                    surface.blit(self.down_bar, (0, self.size[1] - self.base_size))
+                    self.down_bar_objects.render(surface)
 
             if update_type == BaseScreen.update_all or len(rects) < 1:
                 screen.blit(surface, (0, 0))

+ 4 - 1
mopidy_touchscreen/screens/base_screen.py

@@ -10,7 +10,7 @@ class BaseScreen():
         self.manager = manager
         self.fonts = fonts
 
-    def update(self, surface, update_type, rects):
+    def update(self, surface, update_type):
         """
         Draw this screen to the surface
 
@@ -26,5 +26,8 @@ class BaseScreen():
     def change_screen(self, direction):
         return False
 
+    def set_update_rects(self, rects):
+        pass
+
     def should_update(self):
         return BaseScreen.update_partial

+ 9 - 3
mopidy_touchscreen/screens/library_screen.py

@@ -38,11 +38,17 @@ class LibraryScreen(BaseScreen):
             self.browse_uri(directory)
 
     def should_update(self):
-        return self.list_view.should_update()
+        if self.list_view.should_update():
+            return BaseScreen.update_partial
+        else:
+            return BaseScreen.no_update
 
-    def update(self, screen, update_type, rects):
+    def set_update_rects(self, rects):
+        self.list_view.set_update_rects(rects)
+
+    def update(self, screen, update_type):
         update_all = (update_type == BaseScreen.update_all)
-        self.list_view.render(screen, update_all, rects)
+        self.list_view.render(screen, update_all)
 
     def touch_event(self, touch_event):
         clicked = self.list_view.touch_event(touch_event)

+ 126 - 131
mopidy_touchscreen/screens/main_screen.py

@@ -14,8 +14,9 @@ import mopidy.core
 
 import pygame
 
-from ..graphic_utils import Progressbar, \
+from ..graphic_utils import ImageView, Progressbar, \
     ScreenObjectsManager, TextItem, TouchAndTextItem
+from ..graphic_utils.view_pager import ViewPager
 from ..input import InputManager
 
 
@@ -28,6 +29,8 @@ class MainScreen(BaseScreen):
         BaseScreen.__init__(self, size, base_size, manager, fonts)
         self.core = core
         self.track = None
+        self.previous_track = None
+        self.next_track = None
         self.cache = cache
         self.image = None
         self.artists = None
@@ -36,6 +39,7 @@ class MainScreen(BaseScreen):
         self.update_keys = []
         self.current_track_pos = 0
         self.track_duration = "00:00"
+        self.view_pager = ViewPager(self.size, self)
         self.touch_text_manager = ScreenObjectsManager()
         current_track = self.core.playback.current_track.get()
         if current_track is None:
@@ -66,46 +70,48 @@ class MainScreen(BaseScreen):
                                100, True)
         self.touch_text_manager.set_touch_object("volume", progress)
         progress.set_value(self.core.playback.volume.get())
+
         self.progress_show = False
 
-    def should_update(self):
-        if len(self.update_keys) > 0:
-            return True
+    def should_update(self, rects):
+        update = self.view_pager.should_update()
+        if update is not BaseScreen.no_update:
+            return update
+        elif len(self.update_keys) > 0:
+            return BaseScreen.update_partial
         else:
             if self.progress_show:
                 track_pos_millis = self.core.playback.time_position.get()
                 new_track_pos = track_pos_millis / 1000
                 if new_track_pos != self.current_track_pos:
-                    return True
+                    return BaseScreen.update_partial
                 else:
-                    return False
+                    return BaseScreen.no_update
             else:
-                return False
+                return BaseScreen.no_update
+
+    def set_update_rects(self, rects):
+        progress = self.update_progress()
+        if progress is not None:
+            self.update_keys.append("time_progress")
+            rects.append(progress.rect_in_pos)
 
-    def update(self, screen, update_type, rects):
+    def update(self, screen, update_type):
         if update_type == BaseScreen.update_all:
             screen.blit(self.top_bar, (0, 0))
-            self.update_progress(screen, rects)
+            self.update_progress()
             self.touch_text_manager.render(screen)
-            if self.image is not None:
-                screen.blit(self.image, (
-                    self.base_size / 2, self.base_size +
-                    self.base_size / 2))
+            self.view_pager.render(screen, update_type)
 
         if update_type == BaseScreen.update_partial \
                 and self.track is not None:
-
-            progress = self.update_progress(screen, rects)
-            if progress is not None:
-                progress.render(screen)
-                rects.append(progress.rect_in_pos)
             for key in self.update_keys:
                 object = self.touch_text_manager.get_object(key)
                 object.update()
                 object.render(screen)
-                rects.append(object.rect_in_pos)
+            self.view_pager.render(screen, update_type)
 
-    def update_progress(self, screen, rects):
+    def update_progress(self):
         if self.progress_show:
                 track_pos_millis = self.core.playback.time_position.get()
                 new_track_pos = track_pos_millis / 1000
@@ -122,11 +128,79 @@ class MainScreen(BaseScreen):
                     return progress
         return None
 
+    def create_objects_manager(self):
+
+        touch_text_manager = ScreenObjectsManager()
+        x = self.size[1] - self.base_size * 3
+        width = self.size[0] - self.base_size / 2 - x
+
+        # Track name
+        label = TextItem(self.fonts['base'],
+                         "",
+                         (x, (self.size[1]-self.base_size*3)/2
+                          - self.base_size*0.5),
+                         (width, -1))
+        touch_text_manager.set_object("track_name", label)
+
+        # Album name
+        label = TextItem(self.fonts['base'],
+                         "",
+                         (x, (self.size[1]-self.base_size*3)/2
+                          + self.base_size*0.5),
+                         (width, -1))
+        touch_text_manager.set_object("album_name", label)
+
+        # Artist
+        label = TextItem(self.fonts['base'],
+                         "",
+                         (x, (self.size[1]-self.base_size*3)/2
+                          + self.base_size*1.5),
+                         (width, -1))
+        touch_text_manager.set_object("artist_name", label)
+
+        # Cover image
+        pos = (self.base_size / 2, self.base_size +
+                    self.base_size / 2)
+        size = self.size[1] - self.base_size * 4
+        cover = ImageView(pos, (size, size))
+        touch_text_manager.set_object("cover_image", cover)
+
+        return touch_text_manager
+
+    def set_page_values(self, screen_objects_manager, pos):
+        if pos == 0:
+            track = self.previous_track
+        elif pos == 1:
+            track = self.track
+        elif pos == 2:
+            track = self.next_track
+        if track is None:
+            return False
+        else:
+            screen_objects_manager.get_object("track_name").set_horizontal_shift(200)
+            screen_objects_manager.get_object("track_name").set_text(MainScreen.get_track_name(track), False)
+            screen_objects_manager.get_object("album_name").set_text(MainScreen.get_track_album_name(track), False)
+            screen_objects_manager.get_object("artist_name").set_text(MainScreen.get_artist_string(track), False)
+            return True
+
     def track_started(self, track):
+        self.next_track = track
+
         self.update_keys = []
         self.image = None
-        x = self.size[1] - self.base_size * 3
-        width = self.size[0] - self.base_size / 2 - x
+        self.view_pager.notify_changed()
+
+        if self.previous_track is not None and track.uri == self.previous_track.uri:
+            logger.error("sartu naiz")
+            self.view_pager.change_to_page(-1)
+            image_view = self.view_pager.objets_manager[0].get_object("cover_image")
+        else:
+            self.view_pager.change_to_page(1)
+            image_view = self.view_pager.objets_manager[2].get_object("cover_image")
+        image_view.set_image(None)
+
+        self.previous_track = self.track
+        self.track = track
 
         # Previous track button
         button = TouchAndTextItem(self.fonts['icon'], u"\ue61c",
@@ -167,61 +241,19 @@ class MainScreen(BaseScreen):
         for artist in track.artists:
             self.artists.append(artist)
 
-        # Track name
-        label = TextItem(self.fonts['base'],
-                         MainScreen.get_track_name(track),
-                         (x, (self.size[1]-self.base_size*3)/2
-                          - self.base_size*0.5),
-                         (width, -1))
-        if not label.fit_horizontal:
-            self.update_keys.append("track_name")
-        self.touch_text_manager.set_object("track_name", label)
-
-        # Album name
-        label = TextItem(self.fonts['base'],
-                         MainScreen.get_track_album_name
-                         (track),
-                         (x, (self.size[1]-self.base_size*3)/2
-                          + self.base_size*0.5),
-                         (width, -1))
-        if not label.fit_horizontal:
-            self.update_keys.append("album_name")
-        self.touch_text_manager.set_object("album_name", label)
-
-        # Artist
-        label = TextItem(self.fonts['base'],
-                         self.get_artist_string(),
-                         (x, (self.size[1]-self.base_size*3)/2
-                          + self.base_size*1.5),
-                         (width, -1))
-        if not label.fit_horizontal:
-            self.update_keys.append("artist_name")
-        self.touch_text_manager.set_object("artist_name", label)
-
-        self.track = track
         if not self.is_image_in_cache():
-            thread = Thread(target=self.download_image)
+            thread = Thread(target=self.download_image, args=[image_view])
             thread.start()
         else:
-            thread = Thread(target=self.load_image)
+            thread = Thread(target=self.load_image, args=[image_view])
             thread.start()
 
     def stream_title_changed(self, title):
         self.touch_text_manager.get_object("track_name").set_text(title, False)
 
-    def get_artist_string(self):
-        artists_string = ''
-        for artist in self.artists:
-            artists_string += artist.name + ', '
-        if len(artists_string) > 2:
-            artists_string = artists_string[:-2]
-        elif len(artists_string) == 0:
-            artists_string = "Unknow Artist"
-        return artists_string
-
     def get_image_file_name(self):
         name = MainScreen.get_track_album_name(
-            self.track) + '-' + self.get_artist_string()
+            self.track) + '-' + self.get_artist_string(self.track)
         md5name = hashlib.md5(name.encode('utf-8')).hexdigest()
         return md5name
 
@@ -235,18 +267,19 @@ class MainScreen(BaseScreen):
         return os.path.isfile(
             self.get_cover_folder() + self.get_image_file_name())
 
-    def download_image(self):
+    def download_image(self, image_view):
+
         image_uris = self.core.library.get_images(
             {self.track.uri}).get()[self.track.uri]
         if len(image_uris) > 0:
             urllib.urlretrieve(image_uris[0].uri,
                                self.get_cover_folder() +
                                self.get_image_file_name())
-            self.load_image()
+            self.load_image(image_view)
         else:
-            self.download_image_last_fm(0)
+            self.download_image_last_fm(0, image_view)
 
-    def download_image_last_fm(self, artist_index):
+    def download_image_last_fm(self, artist_index, image_view):
         if artist_index < len(self.artists):
             try:
                 safe_artist = urllib.quote_plus(
@@ -265,81 +298,26 @@ class MainScreen(BaseScreen):
                 urllib.urlretrieve(image,
                                    self.get_cover_folder() +
                                    self.get_image_file_name())
-                self.load_image()
+                self.load_image(image_view)
             except:
-                self.download_image_last_fm(artist_index + 1)
+                self.download_image_last_fm(artist_index + 1, image_view)
         else:
 
             logger.info("Cover could not be downloaded")
 
-            # There is no cover
-            # so it will use all the screen size for the text
-            width = self.size[0] - self.base_size
-
-            current = TextItem(self.fonts['base'],
-                               MainScreen.get_track_name
-                               (self.track),
-                               (self.base_size / 2,
-                                self.base_size * 2),
-                               (width, -1))
-            if not current.fit_horizontal:
-                self.update_keys.append("track_name")
-            self.touch_text_manager.set_object("track_name", current)
-
-            current = TextItem(self.fonts['base'],
-                               MainScreen.get_track_album_name
-                               (self.track),
-                               (self.base_size / 2,
-                                self.base_size * 3),
-                               (width, -1))
-            if not current.fit_horizontal:
-                self.update_keys.append("album_name")
-            self.touch_text_manager.set_object("album_name", current)
-
-            current = TextItem(self.fonts['base'],
-                               self.get_artist_string(),
-                               (self.base_size / 2,
-                                self.base_size * 4),
-                               (width, -1))
-            if not current.fit_horizontal:
-                self.update_keys.append("artist_name")
-            self.touch_text_manager.set_object("artist_name", current)
-
-            self.background.set_background_image(None)
-
     def track_playback_ended(self, tl_track, time_position):
         self.background.set_background_image(None)
         self.image = None
         self.track_duration = "00:00"
 
-        width = self.size[0] - self.base_size
-
-        current = TextItem(self.fonts['base'], "",
-                           (self.base_size / 2,
-                            self.base_size * 2),
-                           (width, -1))
-        self.touch_text_manager.set_object("track_name", current)
-
-        current = TextItem(self.fonts['base'], "",
-                           (self.base_size / 2,
-                            self.base_size * 3),
-                           (width, -1))
-        self.touch_text_manager.set_object("album_name", current)
-
-        current = TextItem(self.fonts['base'], "",
-                           (self.base_size / 2,
-                            self.base_size * 4),
-                           (width, -1))
-        self.touch_text_manager.set_object("artist_name", current)
-
-    def load_image(self):
+    def load_image(self, image_view):
         size = self.size[1] - self.base_size * 4
         image_original = pygame.image.load(
             self.get_cover_folder() +
             self.get_image_file_name())
         image = pygame.transform.scale(image_original, (size, size))
         image = image.convert()
-        self.image = image
+        image_view.set_image(image)
         self.background.set_background_image(image_original)
 
     def touch_event(self, event):
@@ -459,15 +437,32 @@ class MainScreen(BaseScreen):
 
     @staticmethod
     def get_track_name(track):
-        if track.name is None:
+        if track is None:
+            return ""
+        elif track.name is None:
             return track.uri
         else:
             return track.name
 
     @staticmethod
     def get_track_album_name(track):
+        if track is None:
+            return ""
         if track.album is not None and track.album.name is not None \
                 and len(track.album.name) > 0:
             return track.album.name
         else:
             return "Unknow Album"
+
+    @staticmethod
+    def get_artist_string(track):
+        artists_string = ''
+        if track is None:
+            return artists_string
+        for artist in track.artists:
+            artists_string += artist.name + ', '
+        if len(artists_string) > 2:
+            artists_string = artists_string[:-2]
+        elif len(artists_string) == 0:
+            artists_string = "Unknow Artist"
+        return artists_string

+ 9 - 3
mopidy_touchscreen/screens/menu_screen.py

@@ -20,11 +20,17 @@ class MenuScreen(BaseScreen):
         self.list.set_list(self.list_items)
 
     def should_update(self):
-        return self.list.should_update()
+        if self.list.should_update():
+            return BaseScreen.update_partial
+        else:
+            return BaseScreen.no_update
+
+    def set_update_rects(self, rects):
+        self.list_view.set_update_rects(rects)
 
-    def update(self, screen, update_type, rects):
+    def update(self, screen, update_type):
         update_all = (update_type == BaseScreen.update_all)
-        self.list.render(screen, update_all, rects)
+        self.list.render(screen, update_all)
 
     def touch_event(self, event):
         clicked = self.list.touch_event(event)

+ 9 - 3
mopidy_touchscreen/screens/playlist_screen.py

@@ -18,11 +18,17 @@ class PlaylistScreen(BaseScreen):
         self.playlists_loaded()
 
     def should_update(self):
-        return self.list_view.should_update()
+        if self.list_view.should_update():
+            return BaseScreen.update_partial
+        else:
+            return BaseScreen.no_update
 
-    def update(self, screen, update_type, rects):
+    def set_update_rects(self, rects):
+        self.list_view.set_update_rects(rects)
+
+    def update(self, screen, update_type):
         update_all = (update_type == BaseScreen.update_all)
-        self.list_view.render(screen, update_all, rects)
+        self.list.render(screen, update_all)
 
     def playlists_loaded(self):
         self.selected_playlist = None

+ 9 - 3
mopidy_touchscreen/screens/search_screen.py

@@ -74,13 +74,19 @@ class SearchScreen(BaseScreen):
         self.set_query("Search")
 
     def should_update(self):
-        return self.list_view.should_update()
+        if self.list_view.should_update():
+            return BaseScreen.update_partial
+        else:
+            return BaseScreen.no_update
+
+    def set_update_rects(self, rects):
+        self.list_view.set_update_rects(rects)
 
-    def update(self, screen, update_type, rects):
+    def update(self, screen, update_type):
         screen.blit(self.top_bar, (0, 0))
         self.screen_objects.render(screen)
         update_all = (update_type == BaseScreen.update_all)
-        self.list_view.render(screen, update_all, rects)
+        self.list_view.render(screen, update_all)
 
     def set_mode(self, mode=mode_track_name):
         if mode is not self.mode:

+ 9 - 3
mopidy_touchscreen/screens/tracklist.py

@@ -20,11 +20,17 @@ class Tracklist(BaseScreen):
             self.manager.core.playback.current_tl_track.get())
 
     def should_update(self):
-        return self.list_view.should_update()
+        if self.list_view.should_update():
+            return BaseScreen.update_partial
+        else:
+            return BaseScreen.no_update
 
-    def update(self, screen, update_type, rects):
+    def set_update_rects(self, rects):
+        self.list_view.set_update_rects(rects)
+
+    def update(self, screen, update_type):
         update_all = (update_type == BaseScreen.update_all)
-        self.list_view.render(screen, update_all, rects)
+        self.list_view.render(screen, update_all)
 
     def tracklist_changed(self):
         self.update_list()