diff options
author | Liming An <limingx.l.an@intel.com> | 2012-03-23 22:29:46 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2012-03-28 16:49:18 +0100 |
commit | 673a8f44c55c503a6f4e68c2586685641ca7d74e (patch) | |
tree | 1ac475f5c5ec9984471d387c347cbae30c08b623 /bitbake/lib/bb/ui/crumbs | |
parent | ceee95efb1590b63a397bc680f1391d4c494fdd9 (diff) | |
download | poky-673a8f44c55c503a6f4e68c2586685641ca7d74e.tar.gz |
Hob: add refresh icon as ui request in building log
add a refresh icon to indicator the running task, for avoid add more heavy to bitbake building process, increased the timer interval counter, and decreased the refresh icon render size.
(From Poky rev: cf76d2cef0905a442e61769560173b2e6a58fb62)
(Bitbake rev: d5923a484f80bc1577f78035152c2d0728e4a1f3)
Signed-off-by: Liming An <limingx.l.an@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs')
-rw-r--r-- | bitbake/lib/bb/ui/crumbs/hobwidget.py | 169 | ||||
-rw-r--r-- | bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 |
2 files changed, 185 insertions, 4 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hobwidget.py b/bitbake/lib/bb/ui/crumbs/hobwidget.py index 8936f0a42a..e2247622fa 100644 --- a/bitbake/lib/bb/ui/crumbs/hobwidget.py +++ b/bitbake/lib/bb/ui/crumbs/hobwidget.py | |||
@@ -57,6 +57,7 @@ class hic: | |||
57 | ICON_INDI_REMOVE_HOVER_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/remove-hover.png')) | 57 | ICON_INDI_REMOVE_HOVER_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/remove-hover.png')) |
58 | ICON_INDI_ADD_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/add.png')) | 58 | ICON_INDI_ADD_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/add.png')) |
59 | ICON_INDI_ADD_HOVER_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/add-hover.png')) | 59 | ICON_INDI_ADD_HOVER_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/add-hover.png')) |
60 | ICON_INDI_REFRESH_FILE = os.path.join(HOB_ICON_BASE_DIR, ('indicators/refresh.png')) | ||
60 | 61 | ||
61 | class hcc: | 62 | class hcc: |
62 | 63 | ||
@@ -793,3 +794,171 @@ class HobWarpCellRendererText(gtk.CellRendererText): | |||
793 | return adjwidth | 794 | return adjwidth |
794 | 795 | ||
795 | gobject.type_register(HobWarpCellRendererText) | 796 | gobject.type_register(HobWarpCellRendererText) |
797 | |||
798 | class RefreshRuningController(gobject.GObject): | ||
799 | def __init__(self, widget=None, iter=None): | ||
800 | gobject.GObject.__init__(self) | ||
801 | self.timeout_id = None | ||
802 | self.current_angle_pos = 0.0 | ||
803 | self.step_angle = 0.0 | ||
804 | self.tree_headers_height = 0 | ||
805 | self.running_cell_areas = [] | ||
806 | |||
807 | def is_active(self): | ||
808 | if self.timeout_id: | ||
809 | return True | ||
810 | else: | ||
811 | return False | ||
812 | |||
813 | def reset(self): | ||
814 | self.force_stop(True) | ||
815 | self.current_angle_pos = 0.0 | ||
816 | self.timeout_id = None | ||
817 | self.step_angle = 0.0 | ||
818 | |||
819 | ''' time_iterval: (1~1000)ms, which will be as the basic interval count for timer | ||
820 | init_usrdata: the current data which related the progress-bar will be at | ||
821 | min_usrdata: the range of min of user data | ||
822 | max_usrdata: the range of max of user data | ||
823 | step: each step which you want to progress | ||
824 | Note: the init_usrdata should in the range of from min to max, and max should > min | ||
825 | step should < (max - min) | ||
826 | ''' | ||
827 | def start_run(self, time_iterval, init_usrdata, min_usrdata, max_usrdata, step, tree): | ||
828 | if (not time_iterval) or (not max_usrdata): | ||
829 | return | ||
830 | usr_range = (max_usrdata - min_usrdata) * 1.0 | ||
831 | self.current_angle_pos = (init_usrdata * 1.0) / usr_range | ||
832 | self.step_angle = (step * 1) / usr_range | ||
833 | self.timeout_id = gobject.timeout_add(int(time_iterval), | ||
834 | self.make_image_on_progressing_cb, tree) | ||
835 | self.tree_headers_height = self.get_treeview_headers_height(tree) | ||
836 | |||
837 | def force_stop(self, after_hide_or_not=False): | ||
838 | if self.timeout_id: | ||
839 | gobject.source_remove(self.timeout_id) | ||
840 | self.timeout_id = None | ||
841 | if self.running_cell_areas: | ||
842 | self.running_cell_areas = [] | ||
843 | |||
844 | def on_draw_cb(self, pixbuf, cr, x, y, img_width, img_height, do_refresh=True): | ||
845 | if pixbuf: | ||
846 | r = max(img_width/2, img_height/2) | ||
847 | cr.translate(x + r, y + r) | ||
848 | if do_refresh: | ||
849 | cr.rotate(2 * math.pi * self.current_angle_pos) | ||
850 | |||
851 | cr.set_source_pixbuf(pixbuf, -img_width/2, -img_height/2) | ||
852 | cr.paint() | ||
853 | |||
854 | def get_treeview_headers_height(self, tree): | ||
855 | if tree and (tree.get_property("headers-visible") == True): | ||
856 | height = tree.get_allocation().height - tree.get_bin_window().get_size()[1] | ||
857 | return height | ||
858 | |||
859 | return 0 | ||
860 | |||
861 | def make_image_on_progressing_cb(self, tree): | ||
862 | self.current_angle_pos += self.step_angle | ||
863 | if (self.current_angle_pos >= 1): | ||
864 | self.current_angle_pos = self.step_angle | ||
865 | |||
866 | for rect in self.running_cell_areas: | ||
867 | tree.queue_draw_area(rect.x, rect.y + self.tree_headers_height, rect.width, rect.height) | ||
868 | |||
869 | return True | ||
870 | |||
871 | def append_running_cell_area(self, cell_area): | ||
872 | if cell_area and (cell_area not in self.running_cell_areas): | ||
873 | self.running_cell_areas.append(cell_area) | ||
874 | |||
875 | def remove_running_cell_area(self, cell_area): | ||
876 | if cell_area in self.running_cell_areas: | ||
877 | self.running_cell_areas.remove(cell_area) | ||
878 | if not self.running_cell_areas: | ||
879 | self.reset() | ||
880 | |||
881 | gobject.type_register(RefreshRuningController) | ||
882 | |||
883 | class HobCellRendererPixbuf(gtk.CellRendererPixbuf): | ||
884 | def __init__(self): | ||
885 | gtk.CellRendererPixbuf.__init__(self) | ||
886 | self.control = RefreshRuningController() | ||
887 | # create default refrensh stock icon | ||
888 | self.set_hob_icon_to_stock_icon(hic.ICON_INDI_REFRESH_FILE, "task-refresh") | ||
889 | |||
890 | def set_hob_icon_to_stock_icon(self, file_path, stock_id=""): | ||
891 | try: | ||
892 | pixbuf = gtk.gdk.pixbuf_new_from_file(file_path) | ||
893 | except Exception, e: | ||
894 | return None | ||
895 | |||
896 | if pixbuf and stock_id and (gtk.icon_factory_lookup_default(stock_id) == None): | ||
897 | icon_factory = gtk.IconFactory() | ||
898 | icon_factory.add_default() | ||
899 | icon_factory.add(stock_id, gtk.IconSet(pixbuf)) | ||
900 | gtk.stock_add([(stock_id, '_label', 0, 0, '')]) | ||
901 | |||
902 | return icon_factory.lookup(stock_id) | ||
903 | |||
904 | return None | ||
905 | |||
906 | def get_pixbuf_from_stock_icon(self, widget, stock_id="", size=gtk.ICON_SIZE_DIALOG): | ||
907 | if widget and stock_id and gtk.icon_factory_lookup_default(stock_id): | ||
908 | return widget.render_icon(stock_id, size) | ||
909 | |||
910 | return None | ||
911 | |||
912 | def set_icon_name_to_id(self, name): | ||
913 | if name and type(name) == str: | ||
914 | if name.startswith("gtk") or name == "task-refresh": | ||
915 | stock_id = name | ||
916 | else: | ||
917 | stock_id = 'gtk-' + name | ||
918 | |||
919 | return stock_id | ||
920 | |||
921 | ''' render cell exactly, "icon-name" is priority | ||
922 | if use the 'task-refresh' will make the pix animation | ||
923 | if 'pix' will change the pixbuf for it from the pixbuf or image. | ||
924 | ''' | ||
925 | def do_render(self, window, tree, background_area,cell_area, expose_area, flags): | ||
926 | if (not self.control) or (not tree): | ||
927 | return | ||
928 | |||
929 | x, y, w, h = self.on_get_size(tree, cell_area) | ||
930 | x += cell_area.x | ||
931 | y += cell_area.y | ||
932 | w -= 2 * self.get_property("xpad") | ||
933 | h -= 2 * self.get_property("ypad") | ||
934 | |||
935 | stock_id = "" | ||
936 | if self.props.icon_name: | ||
937 | stock_id = self.set_icon_name_to_id(self.props.icon_name) | ||
938 | elif self.props.stock_id: | ||
939 | stock_id = self.props.stock_id | ||
940 | elif self.props.pixbuf: | ||
941 | pix = self.props.pixbuf | ||
942 | else: | ||
943 | return | ||
944 | |||
945 | if stock_id: | ||
946 | pix = self.get_pixbuf_from_stock_icon(tree, stock_id, self.props.stock_size) | ||
947 | if stock_id == 'task-refresh': | ||
948 | self.control.append_running_cell_area(cell_area) | ||
949 | if self.control.is_active(): | ||
950 | self.control.on_draw_cb(pix, window.cairo_create(), x, y, w, h, True) | ||
951 | else: | ||
952 | self.control.start_run(200, 0, 0, 1000, 200, tree) | ||
953 | else: | ||
954 | self.control.remove_running_cell_area(cell_area) | ||
955 | self.control.on_draw_cb(pix, window.cairo_create(), x, y, w, h, False) | ||
956 | |||
957 | def on_get_size(self, widget, cell_area): | ||
958 | if self.props.icon_name or self.props.pixbuf or self.props.stock_id: | ||
959 | w, h = gtk.icon_size_lookup(self.props.stock_size) | ||
960 | return 0, 0, w, h | ||
961 | |||
962 | return 0, 0, 0, 0 | ||
963 | |||
964 | gobject.type_register(HobCellRendererPixbuf) | ||
diff --git a/bitbake/lib/bb/ui/crumbs/runningbuild.py b/bitbake/lib/bb/ui/crumbs/runningbuild.py index 0f58e4e678..aecfadfb34 100644 --- a/bitbake/lib/bb/ui/crumbs/runningbuild.py +++ b/bitbake/lib/bb/ui/crumbs/runningbuild.py | |||
@@ -27,7 +27,7 @@ import urllib | |||
27 | import urllib2 | 27 | import urllib2 |
28 | import pango | 28 | import pango |
29 | from bb.ui.crumbs.hobcolor import HobColors | 29 | from bb.ui.crumbs.hobcolor import HobColors |
30 | from bb.ui.crumbs.hobwidget import HobWarpCellRendererText | 30 | from bb.ui.crumbs.hobwidget import HobWarpCellRendererText, HobCellRendererPixbuf |
31 | 31 | ||
32 | class RunningBuildModel (gtk.TreeStore): | 32 | class RunningBuildModel (gtk.TreeStore): |
33 | (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_COLOR, COL_NUM_ACTIVE) = range(7) | 33 | (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_COLOR, COL_NUM_ACTIVE) = range(7) |
@@ -68,6 +68,14 @@ class RunningBuildModel (gtk.TreeStore): | |||
68 | model.set_visible_func(self.failure_model_filter) | 68 | model.set_visible_func(self.failure_model_filter) |
69 | return model | 69 | return model |
70 | 70 | ||
71 | def foreach_cell_func(self, model, path, iter, usr_data=None): | ||
72 | if model.get_value(iter, self.COL_ICON) == "task-refresh": | ||
73 | model.set(iter, self.COL_ICON, "") | ||
74 | |||
75 | def close_task_refresh(self): | ||
76 | self.foreach(self.foreach_cell_func, None) | ||
77 | |||
78 | |||
71 | class RunningBuild (gobject.GObject): | 79 | class RunningBuild (gobject.GObject): |
72 | __gsignals__ = { | 80 | __gsignals__ = { |
73 | 'build-started' : (gobject.SIGNAL_RUN_LAST, | 81 | 'build-started' : (gobject.SIGNAL_RUN_LAST, |
@@ -189,7 +197,7 @@ class RunningBuild (gobject.GObject): | |||
189 | # Because this parent package now has an active child mark it as | 197 | # Because this parent package now has an active child mark it as |
190 | # such. | 198 | # such. |
191 | # @todo if parent is already in error, don't mark it green | 199 | # @todo if parent is already in error, don't mark it green |
192 | self.model.set(parent, self.model.COL_ICON, "gtk-execute", | 200 | self.model.set(parent, self.model.COL_ICON, "task-refresh", |
193 | self.model.COL_COLOR, HobColors.RUNNING) | 201 | self.model.COL_COLOR, HobColors.RUNNING) |
194 | 202 | ||
195 | # Add an entry in the model for this task | 203 | # Add an entry in the model for this task |
@@ -197,7 +205,7 @@ class RunningBuild (gobject.GObject): | |||
197 | package, | 205 | package, |
198 | task, | 206 | task, |
199 | "Task: %s" % (task), | 207 | "Task: %s" % (task), |
200 | "gtk-execute", | 208 | "task-refresh", |
201 | HobColors.RUNNING, | 209 | HobColors.RUNNING, |
202 | 0)) | 210 | 0)) |
203 | 211 | ||
@@ -284,6 +292,8 @@ class RunningBuild (gobject.GObject): | |||
284 | # Emit a generic "build-complete" signal for things wishing to | 292 | # Emit a generic "build-complete" signal for things wishing to |
285 | # handle when the build is finished | 293 | # handle when the build is finished |
286 | self.emit("build-complete") | 294 | self.emit("build-complete") |
295 | # reset the all cell's icon indicator | ||
296 | self.model.close_task_refresh() | ||
287 | if pbar: | 297 | if pbar: |
288 | pbar.set_text(event.msg) | 298 | pbar.set_text(event.msg) |
289 | 299 | ||
@@ -292,6 +302,8 @@ class RunningBuild (gobject.GObject): | |||
292 | # If the command fails with an exit code we're done, emit the | 302 | # If the command fails with an exit code we're done, emit the |
293 | # generic signal for the UI to notify the user | 303 | # generic signal for the UI to notify the user |
294 | self.emit("build-complete") | 304 | self.emit("build-complete") |
305 | # reset the all cell's icon indicator | ||
306 | self.model.close_task_refresh() | ||
295 | 307 | ||
296 | elif isinstance(event, bb.event.CacheLoadStarted) and pbar: | 308 | elif isinstance(event, bb.event.CacheLoadStarted) and pbar: |
297 | pbar.set_title("Loading cache") | 309 | pbar.set_title("Loading cache") |
@@ -346,7 +358,7 @@ class RunningBuildTreeView (gtk.TreeView): | |||
346 | self.readonly = readonly | 358 | self.readonly = readonly |
347 | 359 | ||
348 | # The icon that indicates whether we're building or failed. | 360 | # The icon that indicates whether we're building or failed. |
349 | renderer = gtk.CellRendererPixbuf () | 361 | renderer = HobCellRendererPixbuf () |
350 | col = gtk.TreeViewColumn ("Status", renderer) | 362 | col = gtk.TreeViewColumn ("Status", renderer) |
351 | col.add_attribute (renderer, "icon-name", 4) | 363 | col.add_attribute (renderer, "icon-name", 4) |
352 | self.append_column (col) | 364 | self.append_column (col) |