[bitbake-devel] [PATCH 12/12] Hob: per UI design add refresh icon for building log
Joshua Lock
josh at linux.intel.com
Tue Mar 20 18:29:15 UTC 2012
On 20/03/12 06:04, An, LimingX L wrote:
>
> On 16/03/12 08:10, Shane Wang wrote:
>> From: Liming An<limingx.l.an at intel.com>
>>
>> To add the HobCellRendererPixbuf object which has the same feather as the gtk.CellRendererPixbuf and added the task-refresh stock icon which is an animation icon function.
>>
>> Signed-off-by: Liming An<limingx.l.an at intel.com>
>> Signed-off-by: Shane Wang<shane.wang at intel.com>
>> ---
>> bitbake/lib/bb/ui/crumbs/hobwidget.py | 193 ++++++++++++++++++++++++++++++
>> bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 +++-
>> 2 files changed, 208 insertions(+), 5 deletions(-)
>>
>> diff --git a/bitbake/lib/bb/ui/crumbs/hobwidget.py
>> b/bitbake/lib/bb/ui/crumbs/hobwidget.py
>> index d4ee94e..fee9935 100644
>> --- a/bitbake/lib/bb/ui/crumbs/hobwidget.py
>> +++ b/bitbake/lib/bb/ui/crumbs/hobwidget.py
>> @@ -53,6 +53,7 @@ class hic:
>> ICON_INFO_HOVER_FILE = os.path.join(HOB_ICON_BASE_DIR, ('info/info_hover.png'))
>> ICON_INDI_CONFIRM_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/confirmation.png'))
>> ICON_INDI_ERROR_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/error.png'))
>> + ICON_INDI_REFERENCE_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/refresh.png'))
Should this not be ICON_INDI_REFRESH_FILE ?
>>
>> class hcc:
>>
>> @@ -687,3 +688,195 @@ class HobNotebook(gtk.VBox):
>> search.set_style(style)
>> search.set_text(self.search_name)
>> search.set_editable(False)
>> +
>> +class RefreshRuningController(gobject.GObject):
>> + __gsignals__ = {
>> + # emit when it completed a cycle
>> + "refresh-cycle-completed":(gobject.SIGNAL_RUN_LAST,
>> + gobject.TYPE_NONE,
>> + ()),
>> + }
>> + def __init__(self, widget=None, iter=None):
>> + gobject.GObject.__init__(self)
>> + self.timeout_id = None
>> + self.current_angle_pos = 0.0
>> + self.step_angle = 0.0
>> + self.alpha = 1.0
>> + self.tree_headers_height = 0
>> + self.running_cell_areas = []
>> +
>> + def is_active(self):
>> + if self.timeout_id:
>> + return True
>> + else:
>> + return False
>> +
>> + def reset(self):
>> + self.force_stop(True)
>> + self.current_angle_pos = 0.0
>> + self.timeout_id = None
>> + self.step_angle = 0.0
>> +
>> + ''' time_iterval: (1~1000)ms, which will be as the basic interval count for timer
>> + init_usrdata: the current data which related the progress-bar will be at
>> + min_usrdata: the range of min of user data
>> + max_usrdata: the range of max of user data
>> + step: each step which you want to progress
>> + Note: the init_usrdata should in the range of from min to max, and max should> min
>> + step should< (max - min)
>> + '''
>> + def start_run(self, time_iterval, init_usrdata, min_usrdata, max_usrdata, step, tree):
>> + if (not time_iterval) or (not max_usrdata):
>> + return
>> + usr_range = (max_usrdata - min_usrdata) * 1.0
>> + self.current_angle_pos = (init_usrdata * 1.0) / usr_range
>> + self.step_angle = (step * 1) / usr_range
>> + self.timeout_id = gobject.timeout_add(int(time_iterval),
>> + self.make_image_on_progressing_cb, tree)
>> + self.tree_headers_height =
>> + self.get_treeview_headers_height(tree)
>> +
>> + def force_stop(self, after_hide_or_not=False):
>> + if self.timeout_id:
>> + gobject.source_remove(self.timeout_id)
>> + self.timeout_id = None
>> + if self.running_cell_areas:
>> + self.running_cell_areas = []
>> +
>> + def on_draw_cb(self, pixbuf, cr, x, y, img_width, img_height, do_refresh=True):
>> + if pixbuf:
>> + r = max(img_width/2, img_height/2)
>> + cr.translate(x + r, y + r)
>> + if do_refresh:
>> + cr.rotate(2 * math.pi * self.current_angle_pos)
>> + cr.set_source_pixbuf(pixbuf, -img_width/2, -img_height/2)
>> + # you can use the cr.paint() to replace cr.paint_with_alpha() when no need alpha
>> + # we needed to change the alpha with the speed of running,
>> + if self.current_angle_pos< 0.3:
>> + self.alpha = 1.0 - self.step_angle
>> + else:
>> + self.alpha = self.current_angle_pos
>> + cr.paint_with_alpha(self.alpha)
>> + else:
>> + cr.set_source_pixbuf(pixbuf, -img_width/2, -img_height/2)
>> + cr.paint()
>> +
>> + def get_treeview_headers_height(self, tree):
>> + if tree and (tree.get_property("headers-visible") == True):
>> + height = tree.get_allocation().height - tree.get_bin_window().get_size()[1]
>> + return height
>> +
>> + return 0
>> +
>> + def make_image_on_progressing_cb(self, tree):
>> + self.current_angle_pos += self.step_angle
>> + if (self.current_angle_pos>= 1):
>> + self.current_angle_pos = self.step_angle
>> + self.emit("refresh-cycle-completed")
>> +
>> + for rect in self.running_cell_areas:
>> + tree.queue_draw_area(rect.x, rect.y +
>> + self.tree_headers_height, rect.width, rect.height)
>> +
>> + return True
>> +
>> + def append_running_cell_area(self, cell_area):
>> + if cell_area and (cell_area not in self.running_cell_areas):
>> + self.running_cell_areas.append(cell_area)
>> +
>> + def remove_running_cell_area(self, cell_area):
>> + if cell_area in self.running_cell_areas:
>> + self.running_cell_areas.remove(cell_area)
>> + if not self.running_cell_areas:
>> + self.reset()
>> +
>> +gobject.type_register(RefreshRuningController)
>> +
>> +class HobCellRendererPixbuf(gtk.GenericCellRenderer):
>> + __gproperties__ = {
>> + "icon-name": (gobject.TYPE_STRING, "setPixbufByStockName",
>> + "set icon by specified stock name, and add the refresh animation icon 'task-refresh'", "", gobject.PARAM_READWRITE),
>> + "stock-size": (gobject.TYPE_STRING, "setTheStockSize",
>> + "set ICON_SIZE as 'DIALOG','BUTTON', 'MENU', 'DND', 'LARGE_TOOLBAR','SMALL_TOOL_BAR'", "", gobject.PARAM_READWRITE),
>> + }
>> + def __init__(self):
>> + gtk.GenericCellRenderer.__init__(self)
>> + self.control = RefreshRuningController()
>> + self.cell_attr = {"icon-name":"", "stock-size":gtk.ICON_SIZE_DND}
>> + # create default refrensh stock icon
>> + self.set_pixbuf_to_stock_icon(self.create_default_pixbuf())
>
> This is a very heavyweight way to implement this functionality and very specific to the specific use for the build log.
>
> I have a patch which I've not yet submitted which adds a similar widget that's more generic and fewer lines of code:
> http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h=josh/hob&id=3926d93f1fd04b476d5810d347d38e0dfc247c3d
>
> class CellRendererPixbufActivatable(gtk.CellRendererPixbuf):
> """
> A custom CellRenderer implementation which is activatable
> so that we can handle user clicks
> """
> __gsignals__ = { 'clicked' : (gobject.SIGNAL_RUN_LAST,
> gobject.TYPE_NONE,
> (gobject.TYPE_STRING,)), }
>
> def __init__(self):
> gtk.CellRendererPixbuf.__init__(self)
> self.set_property('mode',
> gtk.CELL_RENDERER_MODE_ACTIVATABLE)
>
> """
> Respond to a user click on a cell
> """
> def do_activate(self, even, widget, path, background_area, cell_area,
> flags):
> self.emit('clicked', path)
>
> Would you be willing to hold this patch until I've submitted the generic implementation and then build atop that?
> Hi Josh,
>
> Sorry, the refresh icon is animation icon, it's not static pixbuf icon.
Ah yes, so I see. Whilst we can't share the same class I implemented for
clickable cells here I'm surprised you need to subclass the
GenericCellRenderer rather than the CellRendererPixbuf.
I would have expected similar functionality could have been achieved in
less code by just using a CellRendererPixbuf and a timeout which sets
the pixbuf property of the CellRendererPixbuf periodically to a rotated one.
Have you tried such an approach?
Cheers,
Joshua
--
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology Centre
More information about the bitbake-devel
mailing list