[Rigo] use only cached UGC metadata if user is scrolling the TreeView

This improves the scrolling speed greatly and reduces the network
pressure.
This commit is contained in:
Fabio Erculiani
2013-06-11 17:17:21 +02:00
parent 757f300814
commit 8527e65e29
3 changed files with 72 additions and 12 deletions
+54 -1
View File
@@ -20,6 +20,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
"""
from gi.repository import Gtk, Gdk, GObject
import os
from threading import Timer
from entropy.i18n import _
@@ -48,6 +49,12 @@ class AppTreeView(GenericTreeView):
icon_size, store=None):
Gtk.TreeView.__init__(self)
self._scrolling_timer = None
self._scrolled_view = None
self._scrolled_view_vadj = None
def _is_scrolling():
return self._scrolling_timer is not None
self._entropy = entropy_client
self._apc = apc
self._service = rigo_service
@@ -55,7 +62,8 @@ class AppTreeView(GenericTreeView):
tr = CellRendererAppView(icons,
self.create_pango_layout(""),
show_ratings,
Icons.INSTALLED_OVERLAY)
Icons.INSTALLED_OVERLAY,
scrolling_cb=_is_scrolling)
tr.set_pixbuf_width(icon_size)
# create buttons and set initial strings
@@ -105,6 +113,51 @@ class AppTreeView(GenericTreeView):
self.set_search_equal_func(self._app_search, None)
self.set_property("enable-search", True)
def _scrolling_event(self, vadj):
"""
Event received from the Gtk.VAdjustment of the
Gtk.ScrolledView containing this widget.
We expose the scrolling state to upper and lower layers.
"""
if self._scrolling_timer:
return
def unset():
# This may cause a race condition
# because an event of the past can
# reset the state right after scrolling_timer
# has been back set. But we don't really care in
# this case. We don't want to be *that* precise.
self._scrolling_timer = None
def set_timer():
t = Timer(1.0, unset)
t.name = "UnsetScrollingTimer"
t.daemon = True
return t
t = self._scrolling_timer
if t is not None:
t.cancel()
t = set_timer()
t.start()
self._scrolling_timer = t
def set_scrolled_view(self, scrolled_view):
"""
Set the Gtk.ScrolledView container of this TreeView.
"""
vadj = scrolled_view.get_vadjustment()
vadj.connect("value-changed", self._scrolling_event)
self._scrolled_view = scrolled_view
self._scrolled_view_vadj = vadj
def get_vadjustment(self):
sv = self._scrolled_view
if sv:
return sv.get_vadjustment()
def _row_activated_callback(self, path, rowref):
self._apc.emit("application-activated",
self.model.get_application(rowref))
+17 -11
View File
@@ -21,9 +21,9 @@ You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
"""
from gi.repository import Gtk, Gdk, GObject, Pango
from gi.repository import GLib, Gtk, Gdk, GObject, Pango
from threading import Lock
from threading import Lock, Timer
from rigo.em import Ems
from rigo.utils import escape_markup
@@ -62,9 +62,17 @@ class CellRendererAppView(Gtk.CellRendererText):
GObject.PARAM_READWRITE),
}
def __init__(self, icons, layout, show_ratings, overlay_icon_name):
def __init__(self, icons, layout, show_ratings,
overlay_icon_name, scrolling_cb=None):
super(CellRendererAppView, self).__init__()
self._is_scrolling = scrolling_cb
if scrolling_cb is None:
def _is_scrolling(): return False
self._is_scrolling = _is_scrolling
else:
self._is_scrolling = scrolling_cb
# geometry-state values
self.pixbuf_width = 0
self.apptitle_width = 0
@@ -93,7 +101,6 @@ class CellRendererAppView(Gtk.CellRendererText):
# icon not present in theme, probably because running uninstalled
self._installed = icons.load_icon('emblem-system',
self.OVERLAY_SIZE, 0)
return
def _layout_get_pixel_width(self, layout):
return layout.get_size()[0] / Pango.SCALE
@@ -104,7 +111,7 @@ class CellRendererAppView(Gtk.CellRendererText):
def _render_icon(self, cr, app, cell_area, xpad, ypad, is_rtl):
# calc offsets so icon is nicely centered
icon = self.model.get_icon(app)
icon = self.model.get_icon(app, cached=self._is_scrolling())
xo = (self.pixbuf_width - icon.get_width())/2
if not is_rtl:
@@ -142,11 +149,7 @@ class CellRendererAppView(Gtk.CellRendererText):
max_layout_width = cell_area.width - self.pixbuf_width - 3*xpad
def _still_visible():
return self.model.visible(app.get_details().pkg)
stats = app.get_review_stats(_still_visible_cb=_still_visible)
if self.show_ratings and stats:
if self.show_ratings:
max_layout_width -= star_width+6*xpad
if self.props.isactive:
@@ -187,7 +190,10 @@ class CellRendererAppView(Gtk.CellRendererText):
def _still_visible():
return self.model.visible(app.get_details().pkg)
stats = app.get_review_stats(_still_visible_cb=_still_visible)
stats = app.get_review_stats(
_still_visible_cb=_still_visible,
cached=self._is_scrolling())
if not stats:
return
sr = self._stars
+1
View File
@@ -272,6 +272,7 @@ class Rigo(Gtk.Application):
self._entropy, self._service, self._app_view_c, icons,
True, AppListStore.ICON_SIZE, store=None)
self._scrolled_view.add(self._view)
self._view.set_scrolled_view(self._scrolled_view)
self._app_store = AppListStore(
self._entropy, self._entropy_ws,