summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui')
-rw-r--r--bitbake/lib/bb/ui/crumbs/hoblistmodel.py22
-rw-r--r--bitbake/lib/bb/ui/crumbs/hobwidget.py129
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/recipeselectionpage.py50
3 files changed, 166 insertions, 35 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hoblistmodel.py b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
index 4934ba8ed8..523a591620 100644
--- a/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
+++ b/bitbake/lib/bb/ui/crumbs/hoblistmodel.py
@@ -34,7 +34,7 @@ class PackageListModel(gtk.TreeStore):
34 providing convenience functions to access gtk.TreeModel subclasses which 34 providing convenience functions to access gtk.TreeModel subclasses which
35 provide filtered views of the data. 35 provide filtered views of the data.
36 """ 36 """
37 (COL_NAME, COL_VER, COL_REV, COL_RNM, COL_SEC, COL_SUM, COL_RDEP, COL_RPROV, COL_SIZE, COL_BINB, COL_INC) = range(11) 37 (COL_NAME, COL_VER, COL_REV, COL_RNM, COL_SEC, COL_SUM, COL_RDEP, COL_RPROV, COL_SIZE, COL_BINB, COL_INC, COL_FADE_INC) = range(12)
38 38
39 __gsignals__ = { 39 __gsignals__ = {
40 "package-selection-changed" : (gobject.SIGNAL_RUN_LAST, 40 "package-selection-changed" : (gobject.SIGNAL_RUN_LAST,
@@ -62,6 +62,7 @@ class PackageListModel(gtk.TreeStore):
62 gobject.TYPE_STRING, 62 gobject.TYPE_STRING,
63 gobject.TYPE_STRING, 63 gobject.TYPE_STRING,
64 gobject.TYPE_STRING, 64 gobject.TYPE_STRING,
65 gobject.TYPE_BOOLEAN,
65 gobject.TYPE_BOOLEAN) 66 gobject.TYPE_BOOLEAN)
66 67
67 68
@@ -437,7 +438,7 @@ class RecipeListModel(gtk.ListStore):
437 providing convenience functions to access gtk.TreeModel subclasses which 438 providing convenience functions to access gtk.TreeModel subclasses which
438 provide filtered views of the data. 439 provide filtered views of the data.
439 """ 440 """
440 (COL_NAME, COL_DESC, COL_LIC, COL_GROUP, COL_DEPS, COL_BINB, COL_TYPE, COL_INC, COL_IMG, COL_INSTALL, COL_PN) = range(11) 441 (COL_NAME, COL_DESC, COL_LIC, COL_GROUP, COL_DEPS, COL_BINB, COL_TYPE, COL_INC, COL_IMG, COL_INSTALL, COL_PN, COL_FADE_INC) = range(12)
441 442
442 __dummy_image__ = "Create your own image" 443 __dummy_image__ = "Create your own image"
443 444
@@ -461,7 +462,8 @@ class RecipeListModel(gtk.ListStore):
461 gobject.TYPE_BOOLEAN, 462 gobject.TYPE_BOOLEAN,
462 gobject.TYPE_BOOLEAN, 463 gobject.TYPE_BOOLEAN,
463 gobject.TYPE_STRING, 464 gobject.TYPE_STRING,
464 gobject.TYPE_STRING) 465 gobject.TYPE_STRING,
466 gobject.TYPE_BOOLEAN)
465 467
466 """ 468 """
467 Find the model path for the item_name 469 Find the model path for the item_name
@@ -498,17 +500,25 @@ class RecipeListModel(gtk.ListStore):
498 500
499 return True 501 return True
500 502
503 def exclude_item_sort_func(self, model, iter1, iter2):
504 val1 = model.get_value(iter1, RecipeListModel.COL_FADE_INC)
505 val2 = model.get_value(iter2, RecipeListModel.COL_INC)
506 return ((val1 == True) and (val2 == False))
507
501 """ 508 """
502 Create, if required, and return a filtered gtk.TreeModelSort 509 Create, if required, and return a filtered gtk.TreeModelSort
503 containing only the items which are items specified by filter 510 containing only the items which are items specified by filter
504 """ 511 """
505 def tree_model(self, filter): 512 def tree_model(self, filter, excluded_items_head=False):
506 model = self.filter_new() 513 model = self.filter_new()
507 model.set_visible_func(self.tree_model_filter, filter) 514 model.set_visible_func(self.tree_model_filter, filter)
508 515
509 sort = gtk.TreeModelSort(model) 516 sort = gtk.TreeModelSort(model)
510 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING) 517 if excluded_items_head:
511 sort.set_default_sort_func(None) 518 sort.set_default_sort_func(self.exclude_item_sort_func)
519 else:
520 sort.set_sort_column_id(RecipeListModel.COL_NAME, gtk.SORT_ASCENDING)
521 sort.set_default_sort_func(None)
512 return sort 522 return sort
513 523
514 def convert_vpath_to_path(self, view_model, view_path): 524 def convert_vpath_to_path(self, view_model, view_path):
diff --git a/bitbake/lib/bb/ui/crumbs/hobwidget.py b/bitbake/lib/bb/ui/crumbs/hobwidget.py
index 96894bf01c..c6e3bb1ae6 100644
--- a/bitbake/lib/bb/ui/crumbs/hobwidget.py
+++ b/bitbake/lib/bb/ui/crumbs/hobwidget.py
@@ -105,6 +105,11 @@ class HobViewTable (gtk.VBox):
105 gobject.TYPE_NONE, 105 gobject.TYPE_NONE,
106 (gobject.TYPE_PYOBJECT, 106 (gobject.TYPE_PYOBJECT,
107 gobject.TYPE_PYOBJECT,)), 107 gobject.TYPE_PYOBJECT,)),
108 "cell-fadeinout-stopped" : (gobject.SIGNAL_RUN_LAST,
109 gobject.TYPE_NONE,
110 (gobject.TYPE_PYOBJECT,
111 gobject.TYPE_PYOBJECT,
112 gobject.TYPE_PYOBJECT,)),
108 } 113 }
109 114
110 def __init__(self, columns): 115 def __init__(self, columns):
@@ -136,9 +141,10 @@ class HobViewTable (gtk.VBox):
136 col.pack_start(cell, True) 141 col.pack_start(cell, True)
137 col.set_attributes(cell, text=column['col_id']) 142 col.set_attributes(cell, text=column['col_id'])
138 elif column['col_style'] == 'check toggle': 143 elif column['col_style'] == 'check toggle':
139 cell = gtk.CellRendererToggle() 144 cell = HobCellRendererToggle()
140 cell.set_property('activatable', True) 145 cell.set_property('activatable', True)
141 cell.connect("toggled", self.toggled_cb, i, self.table_tree) 146 cell.connect("toggled", self.toggled_cb, i, self.table_tree)
147 cell.connect_render_state_changed(self.stop_cell_fadeinout_cb, self.table_tree)
142 self.toggle_id = i 148 self.toggle_id = i
143 col.pack_end(cell, True) 149 col.pack_end(cell, True)
144 col.set_attributes(cell, active=column['col_id']) 150 col.set_attributes(cell, active=column['col_id'])
@@ -195,6 +201,9 @@ class HobViewTable (gtk.VBox):
195 if not view_column.get_title() in self.toggle_columns: 201 if not view_column.get_title() in self.toggle_columns:
196 self.emit("row-activated", tree.get_model(), path) 202 self.emit("row-activated", tree.get_model(), path)
197 203
204 def stop_cell_fadeinout_cb(self, ctrl, cell, tree):
205 self.emit("cell-fadeinout-stopped", ctrl, cell, tree)
206
198""" 207"""
199A method to calculate a softened value for the colour of widget when in the 208A method to calculate a softened value for the colour of widget when in the
200provided state. 209provided state.
@@ -858,14 +867,23 @@ class HobIconChecker(hic):
858 867
859 return valid_stock_id 868 return valid_stock_id
860 869
861class RefreshRuningController(gobject.GObject): 870class HobCellRendererController(gobject.GObject):
862 def __init__(self, widget=None, iter=None): 871 (MODE_CYCLE_RUNNING, MODE_ONE_SHORT) = range(2)
872 __gsignals__ = {
873 "run-timer-stopped" : (gobject.SIGNAL_RUN_LAST,
874 gobject.TYPE_NONE,
875 ()),
876 }
877 def __init__(self, runningmode=MODE_CYCLE_RUNNING, is_draw_row=False):
863 gobject.GObject.__init__(self) 878 gobject.GObject.__init__(self)
864 self.timeout_id = None 879 self.timeout_id = None
865 self.current_angle_pos = 0.0 880 self.current_angle_pos = 0.0
866 self.step_angle = 0.0 881 self.step_angle = 0.0
867 self.tree_headers_height = 0 882 self.tree_headers_height = 0
868 self.running_cell_areas = [] 883 self.running_cell_areas = []
884 self.running_mode = runningmode
885 self.is_queue_draw_row_area = is_draw_row
886 self.force_stop_enable = False
869 887
870 def is_active(self): 888 def is_active(self):
871 if self.timeout_id: 889 if self.timeout_id:
@@ -873,10 +891,10 @@ class RefreshRuningController(gobject.GObject):
873 else: 891 else:
874 return False 892 return False
875 893
876 def reset(self): 894 def reset_run(self):
877 self.force_stop(True) 895 self.force_stop()
896 self.running_cell_areas = []
878 self.current_angle_pos = 0.0 897 self.current_angle_pos = 0.0
879 self.timeout_id = None
880 self.step_angle = 0.0 898 self.step_angle = 0.0
881 899
882 ''' time_iterval: (1~1000)ms, which will be as the basic interval count for timer 900 ''' time_iterval: (1~1000)ms, which will be as the basic interval count for timer
@@ -896,15 +914,16 @@ class RefreshRuningController(gobject.GObject):
896 self.timeout_id = gobject.timeout_add(int(time_iterval), 914 self.timeout_id = gobject.timeout_add(int(time_iterval),
897 self.make_image_on_progressing_cb, tree) 915 self.make_image_on_progressing_cb, tree)
898 self.tree_headers_height = self.get_treeview_headers_height(tree) 916 self.tree_headers_height = self.get_treeview_headers_height(tree)
917 self.force_stop_enable = False
899 918
900 def force_stop(self, after_hide_or_not=False): 919 def force_stop(self):
920 self.emit("run-timer-stopped")
921 self.force_stop_enable = True
901 if self.timeout_id: 922 if self.timeout_id:
902 gobject.source_remove(self.timeout_id) 923 if gobject.source_remove(self.timeout_id):
903 self.timeout_id = None 924 self.timeout_id = None
904 if self.running_cell_areas:
905 self.running_cell_areas = []
906 925
907 def on_draw_cb(self, pixbuf, cr, x, y, img_width, img_height, do_refresh=True): 926 def on_draw_pixbuf_cb(self, pixbuf, cr, x, y, img_width, img_height, do_refresh=True):
908 if pixbuf: 927 if pixbuf:
909 r = max(img_width/2, img_height/2) 928 r = max(img_width/2, img_height/2)
910 cr.translate(x + r, y + r) 929 cr.translate(x + r, y + r)
@@ -914,6 +933,16 @@ class RefreshRuningController(gobject.GObject):
914 cr.set_source_pixbuf(pixbuf, -img_width/2, -img_height/2) 933 cr.set_source_pixbuf(pixbuf, -img_width/2, -img_height/2)
915 cr.paint() 934 cr.paint()
916 935
936 def on_draw_fadeinout_cb(self, cr, color, x, y, width, height, do_fadeout=True):
937 if do_fadeout:
938 alpha = self.current_angle_pos * 0.8
939 else:
940 alpha = (1.0 - self.current_angle_pos) * 0.8
941
942 cr.set_source_rgba(color.red, color.green, color.blue, alpha)
943 cr.rectangle(x, y, width, height)
944 cr.fill()
945
917 def get_treeview_headers_height(self, tree): 946 def get_treeview_headers_height(self, tree):
918 if tree and (tree.get_property("headers-visible") == True): 947 if tree and (tree.get_property("headers-visible") == True):
919 height = tree.get_allocation().height - tree.get_bin_window().get_size()[1] 948 height = tree.get_allocation().height - tree.get_bin_window().get_size()[1]
@@ -923,13 +952,24 @@ class RefreshRuningController(gobject.GObject):
923 952
924 def make_image_on_progressing_cb(self, tree): 953 def make_image_on_progressing_cb(self, tree):
925 self.current_angle_pos += self.step_angle 954 self.current_angle_pos += self.step_angle
926 if (self.current_angle_pos >= 1): 955 if self.running_mode == self.MODE_CYCLE_RUNNING:
927 self.current_angle_pos = self.step_angle 956 if (self.current_angle_pos >= 1):
928 957 self.current_angle_pos = self.step_angle
929 for rect in self.running_cell_areas: 958 else:
930 tree.queue_draw_area(rect.x, rect.y + self.tree_headers_height, rect.width, rect.height) 959 if self.current_angle_pos > 1:
960 self.force_stop()
961 return False
962
963 if self.is_queue_draw_row_area:
964 for path in self.running_cell_areas:
965 rect = tree.get_cell_area(path, tree.get_column(0))
966 row_x, _, row_width, _ = tree.get_visible_rect()
967 tree.queue_draw_area(row_x, rect.y + self.tree_headers_height, row_width, rect.height)
968 else:
969 for rect in self.running_cell_areas:
970 tree.queue_draw_area(rect.x, rect.y + self.tree_headers_height, rect.width, rect.height)
931 971
932 return True 972 return (not self.force_stop_enable)
933 973
934 def append_running_cell_area(self, cell_area): 974 def append_running_cell_area(self, cell_area):
935 if cell_area and (cell_area not in self.running_cell_areas): 975 if cell_area and (cell_area not in self.running_cell_areas):
@@ -939,14 +979,14 @@ class RefreshRuningController(gobject.GObject):
939 if cell_area in self.running_cell_areas: 979 if cell_area in self.running_cell_areas:
940 self.running_cell_areas.remove(cell_area) 980 self.running_cell_areas.remove(cell_area)
941 if not self.running_cell_areas: 981 if not self.running_cell_areas:
942 self.reset() 982 self.reset_run()
943 983
944gobject.type_register(RefreshRuningController) 984gobject.type_register(HobCellRendererController)
945 985
946class HobCellRendererPixbuf(gtk.CellRendererPixbuf): 986class HobCellRendererPixbuf(gtk.CellRendererPixbuf):
947 def __init__(self): 987 def __init__(self):
948 gtk.CellRendererPixbuf.__init__(self) 988 gtk.CellRendererPixbuf.__init__(self)
949 self.control = RefreshRuningController() 989 self.control = HobCellRendererController()
950 # add icon checker for make the gtk-icon transfer to hob-icon 990 # add icon checker for make the gtk-icon transfer to hob-icon
951 self.checker = HobIconChecker() 991 self.checker = HobIconChecker()
952 self.set_property("stock-size", gtk.ICON_SIZE_DND) 992 self.set_property("stock-size", gtk.ICON_SIZE_DND)
@@ -997,12 +1037,12 @@ class HobCellRendererPixbuf(gtk.CellRendererPixbuf):
997 if stock_id == 'hic-task-refresh': 1037 if stock_id == 'hic-task-refresh':
998 self.control.append_running_cell_area(cell_area) 1038 self.control.append_running_cell_area(cell_area)
999 if self.control.is_active(): 1039 if self.control.is_active():
1000 self.control.on_draw_cb(pix, window.cairo_create(), x, y, w, h, True) 1040 self.control.on_draw_pixbuf_cb(pix, window.cairo_create(), x, y, w, h, True)
1001 else: 1041 else:
1002 self.control.start_run(200, 0, 0, 1000, 200, tree) 1042 self.control.start_run(200, 0, 0, 1000, 200, tree)
1003 else: 1043 else:
1004 self.control.remove_running_cell_area(cell_area) 1044 self.control.remove_running_cell_area(cell_area)
1005 self.control.on_draw_cb(pix, window.cairo_create(), x, y, w, h, False) 1045 self.control.on_draw_pixbuf_cb(pix, window.cairo_create(), x, y, w, h, False)
1006 1046
1007 def on_get_size(self, widget, cell_area): 1047 def on_get_size(self, widget, cell_area):
1008 if self.props.icon_name or self.props.pixbuf or self.props.stock_id: 1048 if self.props.icon_name or self.props.pixbuf or self.props.stock_id:
@@ -1020,3 +1060,46 @@ class HobCellRendererPixbuf(gtk.CellRendererPixbuf):
1020 return 0, 0, 0, 0 1060 return 0, 0, 0, 0
1021 1061
1022gobject.type_register(HobCellRendererPixbuf) 1062gobject.type_register(HobCellRendererPixbuf)
1063
1064class HobCellRendererToggle(gtk.CellRendererToggle):
1065 def __init__(self):
1066 gtk.CellRendererToggle.__init__(self)
1067 self.ctrl = HobCellRendererController(is_draw_row=True)
1068 self.ctrl.running_mode = self.ctrl.MODE_ONE_SHORT
1069 self.cell_attr = {"fadeout": False}
1070
1071 def do_render(self, window, widget, background_area, cell_area, expose_area, flags):
1072 if (not self.ctrl) or (not widget):
1073 return
1074 if self.ctrl.is_active():
1075 path = widget.get_path_at_pos(cell_area.x + cell_area.width/2, cell_area.y + cell_area.height/2)[0]
1076 if path in self.ctrl.running_cell_areas:
1077 cr = window.cairo_create()
1078 color = gtk.gdk.Color(HobColors.WHITE)
1079
1080 row_x, _, row_width, _ = widget.get_visible_rect()
1081 border_y = self.get_property("ypad")
1082 self.ctrl.on_draw_fadeinout_cb(cr, color, row_x, cell_area.y - border_y, row_width, \
1083 cell_area.height + border_y * 2, self.cell_attr["fadeout"])
1084
1085 return gtk.CellRendererToggle.do_render(self, window, widget, background_area, cell_area, expose_area, flags)
1086
1087 '''delay: normally delay time is 1000ms
1088 cell_list: whilch cells need to be render
1089 '''
1090 def fadeout(self, tree, delay, cell_list=None):
1091 if (delay < 200) or (not tree):
1092 return
1093 self.cell_attr["fadeout"] = True
1094 self.ctrl.running_cell_areas = cell_list
1095 self.ctrl.start_run(200, 0, 0, delay, (delay * 200 / 1000), tree)
1096
1097 def connect_render_state_changed(self, func, usrdata=None):
1098 if not func:
1099 return
1100 if usrdata:
1101 self.ctrl.connect("run-timer-stopped", func, self, usrdata)
1102 else:
1103 self.ctrl.connect("run-timer-stopped", func, self)
1104
1105gobject.type_register(HobCellRendererToggle)
diff --git a/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py b/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
index bcd7b9c42d..b2d2db9d76 100755
--- a/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
+++ b/bitbake/lib/bb/ui/crumbs/recipeselectionpage.py
@@ -146,10 +146,10 @@ class RecipeSelectionPage (HobPage):
146 tab = HobViewTable(columns) 146 tab = HobViewTable(columns)
147 filter = page['filter'] 147 filter = page['filter']
148 tab.set_model(self.recipe_model.tree_model(filter)) 148 tab.set_model(self.recipe_model.tree_model(filter))
149 tab.connect("toggled", self.table_toggled_cb) 149 tab.connect("toggled", self.table_toggled_cb, page['name'])
150 if page['name'] == "Included": 150 if page['name'] == "Included":
151 tab.connect("button-release-event", self.button_click_cb) 151 tab.connect("button-release-event", self.button_click_cb)
152 152 tab.connect("cell-fadeinout-stopped", self.after_fadeout_checkin_include)
153 label = gtk.Label(page['name']) 153 label = gtk.Label(page['name'])
154 self.ins.append_page(tab, label) 154 self.ins.append_page(tab, label)
155 self.tables.append(tab) 155 self.tables.append(tab)
@@ -197,11 +197,16 @@ class RecipeSelectionPage (HobPage):
197 self.label.set_text("Recipes included: %s" % len(self.builder.configuration.selected_recipes)) 197 self.label.set_text("Recipes included: %s" % len(self.builder.configuration.selected_recipes))
198 self.ins.show_indicator_icon("Included", len(self.builder.configuration.selected_recipes)) 198 self.ins.show_indicator_icon("Included", len(self.builder.configuration.selected_recipes))
199 199
200 def toggle_item_idle_cb(self, path): 200 def toggle_item_idle_cb(self, path, view_tree, cell, pagename):
201 if not self.recipe_model.path_included(path): 201 if not self.recipe_model.path_included(path):
202 self.recipe_model.include_item(item_path=path, binb="User Selected", image_contents=False) 202 self.recipe_model.include_item(item_path=path, binb="User Selected", image_contents=False)
203 else: 203 else:
204 self.recipe_model.exclude_item(item_path=path) 204 if pagename == "Included":
205 self.pre_fadeout_checkout_include(view_tree)
206 self.recipe_model.exclude_item(item_path=path)
207 self.render_fadeout(view_tree, cell)
208 else:
209 self.recipe_model.exclude_item(item_path=path)
205 210
206 self.refresh_selection() 211 self.refresh_selection()
207 if not self.builder.customized: 212 if not self.builder.customized:
@@ -211,9 +216,42 @@ class RecipeSelectionPage (HobPage):
211 216
212 self.builder.window_sensitive(True) 217 self.builder.window_sensitive(True)
213 218
214 def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree): 219 def table_toggled_cb(self, table, cell, view_path, toggled_columnid, view_tree, pagename):
215 # Click to include a recipe 220 # Click to include a recipe
216 self.builder.window_sensitive(False) 221 self.builder.window_sensitive(False)
217 view_model = view_tree.get_model() 222 view_model = view_tree.get_model()
218 path = self.recipe_model.convert_vpath_to_path(view_model, view_path) 223 path = self.recipe_model.convert_vpath_to_path(view_model, view_path)
219 glib.idle_add(self.toggle_item_idle_cb, path) 224 glib.idle_add(self.toggle_item_idle_cb, path, view_tree, cell, pagename)
225
226 def pre_fadeout_checkout_include(self, tree):
227 #resync the included items to a backup fade include column
228 it = self.recipe_model.get_iter_first()
229 while it:
230 active = self.recipe_model.get_value(it, self.recipe_model.COL_INC)
231 self.recipe_model.set(it, self.recipe_model.COL_FADE_INC, active)
232 it = self.recipe_model.iter_next(it)
233 # Check out a model which base on the column COL_FADE_INC,
234 # it's save the prev state of column COL_INC before do exclude_item
235 filter = { RecipeListModel.COL_FADE_INC : [True],
236 RecipeListModel.COL_TYPE : ['recipe', 'task'] }
237 new_model = self.recipe_model.tree_model(filter, excluded_items_head=True)
238 tree.set_model(new_model)
239
240 def render_fadeout(self, tree, cell):
241 if (not cell) or (not tree):
242 return
243 to_render_cells = []
244 model = tree.get_model()
245 it = model.get_iter_first()
246 while it:
247 path = model.get_path(it)
248 prev_cell_is_active = model.get_value(it, RecipeListModel.COL_FADE_INC)
249 curr_cell_is_active = model.get_value(it, RecipeListModel.COL_INC)
250 if (prev_cell_is_active == True) and (curr_cell_is_active == False):
251 to_render_cells.append(path)
252 it = model.iter_next(it)
253
254 cell.fadeout(tree, 1000, to_render_cells)
255
256 def after_fadeout_checkin_include(self, table, ctrl, cell, tree):
257 tree.set_model(self.recipe_model.tree_model(self.pages[0]['filter']))