4
4
PI_OVER_180 = PI / 180
5
5
import softwarecenter.paths
7
from gi.repository import Gtk, Gdk
7
from gi.repository import Gtk, Gdk, GObject
9
9
from buttons import MoreLink
10
10
from softwarecenter.ui.gtk3.em import StockEms
11
11
from softwarecenter.ui.gtk3.drawing import rounded_rect
12
from softwarecenter.ui.gtk3.widgets.spinner import SpinnerNotebook
12
from softwarecenter.ui.gtk3.widgets.spinner import (SpinnerView,
14
from softwarecenter.ui.gtk3.widgets.buttons import FeaturedTile
15
17
class FlowableGrid(Gtk.Fixed):
82
84
def do_get_request_mode(self):
83
return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH
85
return Gtk.SizeRequestMode.WIDTH_FOR_HEIGHT
85
87
def do_get_preferred_height_for_width(self, width):
86
88
old = self.get_allocation()
175
177
self.column_spacing = value
176
178
self._layout_children(self.get_allocation())
178
def remove_all(self):
180
def remove_all(self, destroy=True):
179
181
self._cell_size = None
180
182
for child in self:
181
183
self.remove(child)
184
# meh, this should not really be necessary, but e.g. the
185
# TileButtons have pretty high refcounts even after remove (~10)
187
#print child.__grefcount__
192
class TileGrid(FlowableGrid):
193
''' a flowable layout widget that holds a collection of TileButtons
196
"application-activated": (GObject.SignalFlags.RUN_LAST,
198
(GObject.TYPE_PYOBJECT, ),
202
def add_tiles(self, properties_helper, docs, amount):
203
'''Adds application tiles to an ApplicationTileGrid:
204
properties_help -- an instance of the PropertiesHelper object
205
docs -- xapian documents (apps)
206
amount -- number of tiles to add from start of doc range
208
amount = min(len(docs), amount)
209
for doc in docs[0:amount]:
210
tile = FeaturedTile(properties_helper, doc)
211
tile.connect('clicked', self._on_app_clicked,
212
properties_helper.get_application(doc))
216
def _on_app_clicked(self, btn, app):
217
"""emit signal when a tile is clicked"""
219
self.emit("application-activated", app)
222
GObject.timeout_add(50, timeout_emit)
184
225
# first tier of caching, cache component assets from which frames are
196
237
def __init__(self, padding=0):
197
238
Gtk.Alignment.__init__(self)
198
# set padding + some additional padding in the bottom, left and
199
# right edges to factor in the dropshadow width, and ensure even
201
self.set_padding(padding, padding + 2, padding + 1, padding + 1)
239
# set padding + some additional padding to factor in the
240
# dropshadow+border width
241
# padding is (top, bottom, left, right)
242
self.set_padding(padding, padding + 2, padding + 3, padding + 3)
203
244
self._cache_art_assets()
204
245
# second tier of caching, cache resultant surface of
207
248
self._allocation = Gdk.Rectangle()
208
249
self.connect("size-allocate", self.on_size_allocate)
209
250
self.connect("style-updated", self.on_style_updated)
251
# workaround broken engines (LP: #1021308)
252
self.emit("style-updated")
211
254
def on_style_updated(self, widget):
212
255
self._frame_surface_cache = None
450
493
self.content_box = Gtk.Box.new(orientation, spacing)
451
494
self.content_box.show()
452
495
# finally, a notebook for the spinner and the content box to share
453
self.spinner_notebook = SpinnerNotebook(self.content_box)
496
self.spinner_notebook = SpinnerNotebook(self.content_box,
497
spinner_size=SpinnerView.SMALL)
454
498
self.box.add(self.spinner_notebook)
499
# make the "More" button, but don't add it to the header unless/until
500
# we get a header_implements_more_button
501
self.more = MoreLink()
456
503
def on_draw(self, cr):
457
504
a = self.get_allocation()
471
518
def pack_end(self, *args, **kwargs):
472
519
return self.content_box.pack_end(*args, **kwargs)
474
# XXX: non-functional with current code...
475
#~ def set_header_expand(self, expand):
476
#~ alignment = self.header_alignment
481
#~ alignment.set(alignment.get_property("xalign"),
482
#~ alignment.get_property("yalign"),
485
521
def set_header_position(self, position):
486
522
alignment = self.header_alignment
487
523
alignment.set(position, 0.5,
500
536
self.title.set_markup(self.MARKUP % label)
502
538
def header_implements_more_button(self):
503
if not hasattr(self, "more"):
504
self.more = MoreLink()
539
if self.more not in self.header:
505
540
self.header.pack_end(self.more, False, False, 0)
507
542
def remove_more_button(self):
508
if hasattr(self, "more"):
543
if self.more in self.header:
509
544
self.header.remove(self.more)
512
546
def render_header(self, cr, a, border_radius, assets):
514
if hasattr(self, "more"):
548
if self.more in self.header:
515
549
context = self.get_style_context()
517
551
# set the arrow fill color