def __init__(self, helper, doc, icon_size=48): TileButton.__init__(self) self._pressed = False label = helper.get_appname(doc) icon = helper.get_icon_at_size(doc, icon_size, icon_size) stats = helper.get_review_stats(doc) doc.installed = doc.available = None self.is_installed = helper.is_installed(doc) self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY, self.INSTALLED_OVERLAY_SIZE, 0) # flags self.box.set_orientation(Gtk.Orientation.HORIZONTAL) self.box.set_spacing(StockEms.SMALL) self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM) self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1) self.box.pack_start(self.content_left, False, False, 0) self.box.pack_start(self.content_right, False, False, 0) self.image = _parse_icon(icon, icon_size) self.content_left.pack_start(self.image, False, False, 0) self.title = Gtk.Label.new(self._MARKUP % GObject.markup_escape_text(label)) self.title.set_alignment(0.0, 0.5) self.title.set_use_markup(True) self.title.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.title, False, False, 0) categories = helper.get_categories(doc) if categories is not None: self.category = Gtk.Label.new('<span font_desc="%i">%s</span>' % (em(0.6), GObject.markup_escape_text(categories))) self.category.set_use_markup(True) self.category.set_alignment(0.0, 0.5) self.category.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.category, False, False, 4) stats_a11y = None if stats is not None: self.stars = Star(size=StarSize.SMALL) self.stars.render_outline = True self.stars.set_rating(stats.ratings_average) self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, StockEms.SMALL) self.rating_box.pack_start(self.stars, False, False, 0) self.n_ratings = Gtk.Label.new( '<span font_desc="%i"> (%i)</span>' % ( em(0.45), stats.ratings_total)) self.n_ratings.set_use_markup(True) self.n_ratings.set_name("subtle-label") self.n_ratings.set_alignment(0.0, 0.5) self.rating_box.pack_start(self.n_ratings, False, False, 0) self.content_right.pack_start(self.rating_box, False, False, 0) # TRANSLATORS: this is an accessibility description for eg orca and # is not visible in the ui stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % { 'stars': stats.ratings_average, 'reviews': stats.ratings_total} #work out width tile needs to be to ensure ratings text is all visible req_width = (self.stars.size_request().width + self.image.size_request().width + self.n_ratings.size_request().width + StockEms.MEDIUM * 3 ) global _global_featured_tile_width _global_featured_tile_width = max(_global_featured_tile_width, req_width) details = AppDetails(db=helper.db, doc=doc) price = details.price or _("Free") if price == '0.00': price = _("Free") if price != _("Free"): price = 'US$ ' + price self.price = Gtk.Label.new( '<span font_desc="%i">%s</span>' % (em(0.6), price)) self.price.set_use_markup(True) self.price.set_name("subtle-label") self.price.set_alignment(0.0, 0.5) self.content_right.pack_start(self.price, False, False, 0) self.set_name("featured-tile") a11y_name = '. '.join([t for t in [label, categories, stats_a11y, price] if t]) self.get_accessible().set_name(a11y_name) backend = get_install_backend() backend.connect("transaction-finished", self.on_transaction_finished, helper, doc) self.connect("enter-notify-event", self.on_enter) self.connect("leave-notify-event", self.on_leave) self.connect("button-press-event", self.on_press) self.connect("button-release-event", self.on_release) return
def __init__(self, helper, doc, icon_size=48): TileButton.__init__(self) self._pressed = False label = helper.get_appname(doc) icon = helper.get_icon_at_size(doc, icon_size, icon_size) stats = helper.get_review_stats(doc) helper.update_availability(doc) helper.connect("needs-refresh", self._on_needs_refresh, doc, icon_size) self.is_installed = helper.is_installed(doc) self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY, self.INSTALLED_OVERLAY_SIZE, 0) # flags self.box.set_orientation(Gtk.Orientation.HORIZONTAL) self.box.set_spacing(StockEms.SMALL) self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM) self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1) self.box.pack_start(self.content_left, False, False, 0) self.box.pack_start(self.content_right, False, False, 0) self.image = Gtk.Image() _update_icon(self.image, icon, icon_size) self.content_left.pack_start(self.image, False, False, 0) self.title = Gtk.Label.new(self._MARKUP % GObject.markup_escape_text(label)) self.title.set_alignment(0.0, 0.5) self.title.set_use_markup(True) self.title.set_tooltip_text(label) self.title.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.title, False, False, 0) categories = helper.get_categories(doc) if categories is not None: self.category = Gtk.Label.new( '<span font_desc="%i">%s</span>' % (em(0.6), GObject.markup_escape_text(categories))) self.category.set_use_markup(True) self.category.set_alignment(0.0, 0.5) self.category.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.category, False, False, 4) stats_a11y = None if stats is not None: self.stars = Star(size=StarSize.SMALL) self.stars.render_outline = True self.stars.set_rating(stats.ratings_average) self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, StockEms.SMALL) self.rating_box.pack_start(self.stars, False, False, 0) self.n_ratings = Gtk.Label.new( '<span font_desc="%i"> (%i)</span>' % (em(0.45), stats.ratings_total)) self.n_ratings.set_use_markup(True) self.n_ratings.set_name("subtle-label") self.n_ratings.set_alignment(0.0, 0.5) self.rating_box.pack_start(self.n_ratings, False, False, 0) self.content_right.pack_start(self.rating_box, False, False, 0) # TRANSLATORS: this is an accessibility description for eg orca and # is not visible in the ui stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % { 'stars': stats.ratings_average, 'reviews': stats.ratings_total } # work out width tile needs to be to ensure ratings text is all # visible req_width = (self.stars.size_request().width + self.image.size_request().width + self.n_ratings.size_request().width + StockEms.MEDIUM * 3) global _global_featured_tile_width _global_featured_tile_width = max(_global_featured_tile_width, req_width) details = AppDetails(db=helper.db, doc=doc) # TRANSLATORS: Free here means Gratis price = details.price or _("Free") if price == '0.00': # TRANSLATORS: Free here means Gratis price = _("Free") # TRANSLATORS: Free here means Gratis if price != _("Free"): price = 'US$ ' + price self.price = Gtk.Label.new('<span font_desc="%i">%s</span>' % (em(0.6), price)) self.price.set_use_markup(True) self.price.set_name("subtle-label") self.price.set_alignment(0.0, 0.5) self.content_right.pack_start(self.price, False, False, 0) self.set_name("featured-tile") a11y_name = '. '.join( [t for t in [label, categories, stats_a11y, price] if t]) self.get_accessible().set_name(a11y_name) backend = get_install_backend() backend.connect("transaction-finished", self.on_transaction_finished, helper, doc) self.connect("enter-notify-event", self.on_enter) self.connect("leave-notify-event", self.on_leave) self.connect("button-press-event", self.on_press) self.connect("button-release-event", self.on_release)
class FeaturedTile(TileButton): INSTALLED_OVERLAY_SIZE = 22 _MARKUP = '<b><small>%s</small></b>' def __init__(self, helper, doc, icon_size=48): TileButton.__init__(self) self._pressed = False label = helper.get_appname(doc) icon = helper.get_icon_at_size(doc, icon_size, icon_size) stats = helper.get_review_stats(doc) doc.installed = doc.available = None self.is_installed = helper.is_installed(doc) self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY, self.INSTALLED_OVERLAY_SIZE, 0) # flags self.box.set_orientation(Gtk.Orientation.HORIZONTAL) self.box.set_spacing(StockEms.SMALL) self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM) self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1) self.box.pack_start(self.content_left, False, False, 0) self.box.pack_start(self.content_right, False, False, 0) self.image = _parse_icon(icon, icon_size) self.content_left.pack_start(self.image, False, False, 0) self.title = Gtk.Label.new(self._MARKUP % GObject.markup_escape_text(label)) self.title.set_alignment(0.0, 0.5) self.title.set_use_markup(True) self.title.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.title, False, False, 0) categories = helper.get_categories(doc) if categories is not None: self.category = Gtk.Label.new('<span font_desc="%i">%s</span>' % (em(0.6), GObject.markup_escape_text(categories))) self.category.set_use_markup(True) self.category.set_alignment(0.0, 0.5) self.category.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.category, False, False, 4) stats_a11y = None if stats is not None: self.stars = Star(size=StarSize.SMALL) self.stars.render_outline = True self.stars.set_rating(stats.ratings_average) self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, StockEms.SMALL) self.rating_box.pack_start(self.stars, False, False, 0) self.n_ratings = Gtk.Label.new( '<span font_desc="%i"> (%i)</span>' % ( em(0.45), stats.ratings_total)) self.n_ratings.set_use_markup(True) self.n_ratings.set_name("subtle-label") self.n_ratings.set_alignment(0.0, 0.5) self.rating_box.pack_start(self.n_ratings, False, False, 0) self.content_right.pack_start(self.rating_box, False, False, 0) # TRANSLATORS: this is an accessibility description for eg orca and # is not visible in the ui stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % { 'stars': stats.ratings_average, 'reviews': stats.ratings_total} #work out width tile needs to be to ensure ratings text is all visible req_width = (self.stars.size_request().width + self.image.size_request().width + self.n_ratings.size_request().width + StockEms.MEDIUM * 3 ) global _global_featured_tile_width _global_featured_tile_width = max(_global_featured_tile_width, req_width) details = AppDetails(db=helper.db, doc=doc) price = details.price or _("Free") if price == '0.00': price = _("Free") if price != _("Free"): price = 'US$ ' + price self.price = Gtk.Label.new( '<span font_desc="%i">%s</span>' % (em(0.6), price)) self.price.set_use_markup(True) self.price.set_name("subtle-label") self.price.set_alignment(0.0, 0.5) self.content_right.pack_start(self.price, False, False, 0) self.set_name("featured-tile") a11y_name = '. '.join([t for t in [label, categories, stats_a11y, price] if t]) self.get_accessible().set_name(a11y_name) backend = get_install_backend() backend.connect("transaction-finished", self.on_transaction_finished, helper, doc) self.connect("enter-notify-event", self.on_enter) self.connect("leave-notify-event", self.on_leave) self.connect("button-press-event", self.on_press) self.connect("button-release-event", self.on_release) return def do_get_preferred_width(self): w = _global_featured_tile_width return w, w def do_draw(self, cr): cr.save() A = self.get_allocation() if self._pressed: cr.translate(1, 1) if self.has_focus(): Gtk.render_focus(self.get_style_context(), cr, 3, 3, A.width-6, A.height-6) for child in self: self.propagate_draw(child, cr) if self.is_installed: # paint installed tick overlay if self.get_direction() != Gtk.TextDirection.RTL: x = y = 36 else: x = A.width - 56 y = 36 Gdk.cairo_set_source_pixbuf(cr, self._overlay, x, y) cr.paint() cr.restore() return def on_transaction_finished(self, backend, result, helper, doc): trans_pkgname = str(result.pkgname) pkgname = helper.get_pkgname(doc) if trans_pkgname != pkgname: return # update installed state helper.update_availability(doc) self.is_installed = helper.is_installed(doc) self.queue_draw() return def on_enter(self, widget, event): window = self.get_window() window.set_cursor(_HAND) return True def on_leave(self, widget, event): window = self.get_window() window.set_cursor(None) self._pressed = False return True def on_press(self, widget, event): self._pressed = True return def on_release(self, widget, event): if not self._pressed: return self.emit("clicked") self._pressed = False return
class FeaturedTile(TileButton): INSTALLED_OVERLAY_SIZE = 22 _MARKUP = '<b><small>%s</small></b>' def __init__(self, helper, doc, icon_size=48): TileButton.__init__(self) self._pressed = False label = helper.get_appname(doc) icon = helper.get_icon_at_size(doc, icon_size, icon_size) stats = helper.get_review_stats(doc) helper.update_availability(doc) helper.connect("needs-refresh", self._on_needs_refresh, doc, icon_size) self.is_installed = helper.is_installed(doc) self._overlay = helper.icons.load_icon(Icons.INSTALLED_OVERLAY, self.INSTALLED_OVERLAY_SIZE, 0) # flags self.box.set_orientation(Gtk.Orientation.HORIZONTAL) self.box.set_spacing(StockEms.SMALL) self.content_left = Gtk.Box.new(Gtk.Orientation.VERTICAL, StockEms.MEDIUM) self.content_right = Gtk.Box.new(Gtk.Orientation.VERTICAL, 1) self.box.pack_start(self.content_left, False, False, 0) self.box.pack_start(self.content_right, False, False, 0) self.image = Gtk.Image() _update_icon(self.image, icon, icon_size) self.content_left.pack_start(self.image, False, False, 0) self.title = Gtk.Label.new(self._MARKUP % GObject.markup_escape_text(label)) self.title.set_alignment(0.0, 0.5) self.title.set_use_markup(True) self.title.set_tooltip_text(label) self.title.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.title, False, False, 0) categories = helper.get_categories(doc) if categories is not None: self.category = Gtk.Label.new( '<span font_desc="%i">%s</span>' % (em(0.6), GObject.markup_escape_text(categories))) self.category.set_use_markup(True) self.category.set_alignment(0.0, 0.5) self.category.set_ellipsize(Pango.EllipsizeMode.END) self.content_right.pack_start(self.category, False, False, 4) stats_a11y = None if stats is not None: self.stars = Star(size=StarSize.SMALL) self.stars.render_outline = True self.stars.set_rating(stats.ratings_average) self.rating_box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, StockEms.SMALL) self.rating_box.pack_start(self.stars, False, False, 0) self.n_ratings = Gtk.Label.new( '<span font_desc="%i"> (%i)</span>' % (em(0.45), stats.ratings_total)) self.n_ratings.set_use_markup(True) self.n_ratings.set_name("subtle-label") self.n_ratings.set_alignment(0.0, 0.5) self.rating_box.pack_start(self.n_ratings, False, False, 0) self.content_right.pack_start(self.rating_box, False, False, 0) # TRANSLATORS: this is an accessibility description for eg orca and # is not visible in the ui stats_a11y = _('%(stars)d stars - %(reviews)d reviews') % { 'stars': stats.ratings_average, 'reviews': stats.ratings_total } # work out width tile needs to be to ensure ratings text is all # visible req_width = (self.stars.size_request().width + self.image.size_request().width + self.n_ratings.size_request().width + StockEms.MEDIUM * 3) global _global_featured_tile_width _global_featured_tile_width = max(_global_featured_tile_width, req_width) details = AppDetails(db=helper.db, doc=doc) # TRANSLATORS: Free here means Gratis price = details.price or _("Free") if price == '0.00': # TRANSLATORS: Free here means Gratis price = _("Free") # TRANSLATORS: Free here means Gratis if price != _("Free"): price = 'US$ ' + price self.price = Gtk.Label.new('<span font_desc="%i">%s</span>' % (em(0.6), price)) self.price.set_use_markup(True) self.price.set_name("subtle-label") self.price.set_alignment(0.0, 0.5) self.content_right.pack_start(self.price, False, False, 0) self.set_name("featured-tile") a11y_name = '. '.join( [t for t in [label, categories, stats_a11y, price] if t]) self.get_accessible().set_name(a11y_name) backend = get_install_backend() backend.connect("transaction-finished", self.on_transaction_finished, helper, doc) self.connect("enter-notify-event", self.on_enter) self.connect("leave-notify-event", self.on_leave) self.connect("button-press-event", self.on_press) self.connect("button-release-event", self.on_release) def _on_needs_refresh(self, helper, pkgname, doc, icon_size): icon = helper.get_icon_at_size(doc, icon_size, icon_size) _update_icon(self.image, icon, icon_size) def do_get_preferred_width(self): w = _global_featured_tile_width return w, w def do_draw(self, cr): cr.save() A = self.get_allocation() if self._pressed: cr.translate(1, 1) if self.has_focus(): Gtk.render_focus(self.get_style_context(), cr, 3, 3, A.width - 6, A.height - 6) for child in self: self.propagate_draw(child, cr) if self.is_installed: # paint installed tick overlay if self.get_direction() != Gtk.TextDirection.RTL: x = y = 36 else: x = A.width - 56 y = 36 Gdk.cairo_set_source_pixbuf(cr, self._overlay, x, y) cr.paint() cr.restore() def on_transaction_finished(self, backend, result, helper, doc): trans_pkgname = str(result.pkgname) pkgname = helper.get_pkgname(doc) if trans_pkgname != pkgname: return # update installed state helper.update_availability(doc) self.is_installed = helper.is_installed(doc) self.queue_draw() def on_enter(self, widget, event): window = self.get_window() window.set_cursor(_HAND) return True def on_leave(self, widget, event): window = self.get_window() window.set_cursor(None) self._pressed = False return True def on_press(self, widget, event): self._pressed = True def on_release(self, widget, event): if not self._pressed: return self.emit("clicked") self._pressed = False