[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:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user