diff options
-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) |