Hob Notebook Implementation and Others
v3 cover Hob Notebook Implementation and Others
This patchset is
- to implement Hob self-defined notebook, and use it in the build details page.
- to clean up the code per the comments from the community.
(In order to make it readable, we did them in separate patches)
- to improve the build log with the animation of the refresh icon.
- to add proxy support in the Settings dialog.
The following changes since commit 87ef82dead665ea8805ccbab8ef871dc20008701:
bitbake/fetch: Fix uri_replace (2012-03-15 22:56:16 +0000)
are available in the git repository at:
git://git.pokylinux.org/poky-contrib shane/hob2-v0.69
http://git.pokylinux.org/cgit.cgi/poky-contrib/log/?h=shane/hob2-v0.69
Liming An (6):
Hob: remove the invalid code in hobwidget.py
Hob: change the range dance in hobwidget make it like a pythonista
Hob: fix static variable "self.search" to parameter "search" in
signal callback function
Hob: add auto adjust background area function for long issue text
Hob: change HobNoteBook tab edge color from green to gray
Hob: per UI design add refresh icon for building log
Shane Wang (6):
Hob: implement a self-defined notebook visual component for Hob
Hob: use HobNotebook to implement a notebook in build details page
Hob: show indicators on the tabs of the Hob notebook
Hob: change the code style to enumerate a list in a for-loop
Hob: fix '!= None' and '== None' in the code
Hob: allow users to setup the proxies
bitbake/lib/bb/ui/crumbs/builddetailspage.py | 40 +- bitbake/lib/bb/ui/crumbs/builder.py | 41 ++ bitbake/lib/bb/ui/crumbs/hig.py | 82 +++- bitbake/lib/bb/ui/crumbs/hobcolor.py | 3 + bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 4 +- bitbake/lib/bb/ui/crumbs/hoblistmodel.py | 2 +- bitbake/lib/bb/ui/crumbs/hobpages.py | 4 +- bitbake/lib/bb/ui/crumbs/hobwidget.py | 720 +++++++++++++++++++--- bitbake/lib/bb/ui/crumbs/imagedetailspage.py | 12 +- bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 27 +- bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 29 +- bitbake/lib/bb/ui/crumbs/runningbuild.py | 87 +++- 12 files changed, 884 insertions(+), 167 deletions(-)
Signature · 1 line
1.7.6
PATCH v3 1/12 Hob: implement a self-defined notebook visual component for Hob
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video. We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward. But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Regarding those, we give up gtk.Notebook and use our own.
--- bitbake/lib/bb/ui/crumbs/hobcolor.py | 1 + bitbake/lib/bb/ui/crumbs/hobwidget.py | 468 ++++++++++++++++++---- bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 17 +- bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 19 +- 4 files changed, 394 insertions(+), 111 deletions(-)
bitbake/lib/bb/ui/crumbs/hobcolor.py +1 -0
@@ -28,6 +28,7 @@ class HobColors: DARK = "#3c3b37" BLACK = "#000000" LIGHT_ORANGE = "#f7a787" + YELLOW = "#ffff00" OK = WHITE RUNNING = PALE_GREEN
bitbake/lib/bb/ui/crumbs/hobwidget.py +383 -85
487 lines not on this page · raw message
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +5 -12
@@ -23,7 +23,7 @@ import gtk import glib from bb.ui.crumbs.hobcolor import HobColors -from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable +from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook from bb.ui.crumbs.hoblistmodel import PackageListModel from bb.ui.crumbs.hobpages import HobPage
@@ -102,11 +102,7 @@ class PackageSelectionPage (HobPage): self.pack_start(self.group_align, expand=True, fill=True) # set visiable members - self.grid = gtk.Table(10, 1, True) - self.grid.set_col_spacings(3) - - self.ins = gtk.Notebook() - self.ins.set_show_tabs(False) + self.ins = HobNotebook() self.tables = [] # we need to modify table when the dialog is shown # append the tab for i in range(len(self.pages)):
@@ -122,16 +118,13 @@ class PackageSelectionPage (HobPage): self.ins.append_page(tab, label) self.tables.append(tab) - self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1) - # a black bar associated with the notebook - self.topbar = HobViewBar(self.ins) - self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1) + self.ins.set_entry("Search packages:") # set the search entry for each table for tab in self.tables: - tab.set_search_entry(0, self.topbar.search) + tab.set_search_entry(0, self.ins.search) # add all into the dialog - self.box_group_area.add(self.grid) + self.box_group_area.pack_start(self.ins, expand=True, fill=True) button_box = gtk.HBox(False, 6) self.box_group_area.pack_start(button_box, expand=False, fill=False)
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5 -14
@@ -23,7 +23,7 @@ import gtk import glib from bb.ui.crumbs.hobcolor import HobColors -from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable +from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook from bb.ui.crumbs.hoblistmodel import RecipeListModel from bb.ui.crumbs.hobpages import HobPage
@@ -124,13 +124,7 @@ class RecipeSelectionPage (HobPage): self.pack_start(self.group_align, expand=True, fill=True) # set visiable members - self.grid = gtk.Table(10, 1, True) - self.grid.set_col_spacings(3) - - # draw the left part of the window - # a notebook - self.ins = gtk.Notebook() - self.ins.set_show_tabs(False) + self.ins = HobNotebook() self.tables = [] # we need modify table when the dialog is shown # append the tabs in order for i in range(len(self.pages)):
@@ -146,16 +140,13 @@ class RecipeSelectionPage (HobPage): self.ins.append_page(tab, label) self.tables.append(tab) - self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) - # a black bar associated with the notebook - self.topbar = HobViewBar(self.ins) - self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) + self.ins.set_entry("Search recipes:") # set the search entry for each table for tab in self.tables: - tab.set_search_entry(0, self.topbar.search) + tab.set_search_entry(0, self.ins.search) # add all into the window - self.box_group_area.add(self.grid) + self.box_group_area.pack_start(self.ins, expand=True, fill=True) button_box = gtk.HBox(False, 6) self.box_group_area.pack_end(button_box, expand=False, fill=False)
Signature · 1 line
1.7.6
PATCH v3 2/12 Hob: use HobNotebook to implement a notebook in build details page
This patch is to use HobNotebook we defined to implement the notebook in the build details page.
--- bitbake/lib/bb/ui/crumbs/builddetailspage.py | 30 ++++++++++-- bitbake/lib/bb/ui/crumbs/runningbuild.py | 65 ++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/builddetailspage.py +25 -5
@@ -22,8 +22,10 @@ import gtk from bb.ui.crumbs.progressbar import HobProgressBar -from bb.ui.crumbs.hobwidget import hic +from bb.ui.crumbs.hobwidget import hic, HobNotebook from bb.ui.crumbs.runningbuild import RunningBuildTreeView +from bb.ui.crumbs.runningbuild import BuildConfigurationTreeView +from bb.ui.crumbs.runningbuild import BuildFailureTreeView from bb.ui.crumbs.hobpages import HobPage #
@@ -49,11 +51,29 @@ class BuildDetailsPage (HobPage): self.stop_button.connect("clicked", self.stop_button_clicked_cb) self.progress_box.pack_end(self.stop_button, expand=False, fill=False) + self.notebook = HobNotebook() + self.config_tv = BuildConfigurationTreeView() + self.config_model = self.builder.handler.build.model.config_model() + self.config_tv.set_model(self.config_model) + self.scrolled_view_config = gtk.ScrolledWindow () + self.scrolled_view_config.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_config.add(self.config_tv) + self.notebook.append_page(self.scrolled_view_config, gtk.Label("Build Configuration")) + + self.failure_tv = BuildFailureTreeView() + self.failure_model = self.builder.handler.build.model.failure_model() + self.failure_tv.set_model(self.failure_model) + self.scrolled_view_failure = gtk.ScrolledWindow () + self.scrolled_view_failure.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_failure.add(self.failure_tv) + self.notebook.append_page(self.scrolled_view_failure, gtk.Label("Issues")) + self.build_tv = RunningBuildTreeView(readonly=True) self.build_tv.set_model(self.builder.handler.build.model) - self.scrolled_view = gtk.ScrolledWindow () - self.scrolled_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.scrolled_view.add(self.build_tv) + self.scrolled_view_build = gtk.ScrolledWindow () + self.scrolled_view_build.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_build.add(self.build_tv) + self.notebook.append_page(self.scrolled_view_build, gtk.Label("Log")) self.button_box = gtk.HBox(False, 6) self.back_button = gtk.LinkButton("Go back to Image Configuration screen", "<< Back to image configuration")
@@ -86,7 +106,7 @@ class BuildDetailsPage (HobPage): self.progress_bar.reset() self.vbox.pack_start(self.progress_box, expand=False, fill=False) - self.vbox.pack_start(self.scrolled_view, expand=True, fill=True) + self.vbox.pack_start(self.notebook, expand=True, fill=True) self.box_group_area.pack_end(self.button_box, expand=False, fill=False) self.show_all()
bitbake/lib/bb/ui/crumbs/runningbuild.py +65 -0
80 lines not on this page · raw message
Signature · 1 line
1.7.6
Re: [PATCH 02/12] Hob: use HobNotebook to implement a notebook in build details page
Quoted 80 lines · Shane Wang
This patch is to use HobNotebook we defined to implement the notebook in the build details page.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/builddetailspage.py | 30 ++++++++++-- bitbake/lib/bb/ui/crumbs/runningbuild.py | 65 ++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-)bitbake/lib/bb/ui/crumbs/builddetailspage.py +25
-5@@ -22,8 +22,10 @@ import gtk from bb.ui.crumbs.progressbar import HobProgressBar -from bb.ui.crumbs.hobwidget import hic +from bb.ui.crumbs.hobwidget import hic, HobNotebook from bb.ui.crumbs.runningbuild import RunningBuildTreeView +from bb.ui.crumbs.runningbuild import BuildConfigurationTreeView +from bb.ui.crumbs.runningbuild import BuildFailureTreeView from bb.ui.crumbs.hobpages import HobPage #@@ -49,11 +51,29 @@ class BuildDetailsPage (HobPage): self.stop_button.connect("clicked", self.stop_button_clicked_cb) self.progress_box.pack_end(self.stop_button, expand=False, fill=False) + self.notebook = HobNotebook() + self.config_tv = BuildConfigurationTreeView() + self.config_model = self.builder.handler.build.model.config_model() + self.config_tv.set_model(self.config_model) + self.scrolled_view_config = gtk.ScrolledWindow () + self.scrolled_view_config.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_config.add(self.config_tv) + self.notebook.append_page(self.scrolled_view_config, gtk.Label("Build Configuration")) + + self.failure_tv = BuildFailureTreeView() + self.failure_model = self.builder.handler.build.model.failure_model() + self.failure_tv.set_model(self.failure_model) + self.scrolled_view_failure = gtk.ScrolledWindow () + self.scrolled_view_failure.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_failure.add(self.failure_tv) + self.notebook.append_page(self.scrolled_view_failure, gtk.Label("Issues")) + self.build_tv = RunningBuildTreeView(readonly=True) self.build_tv.set_model(self.builder.handler.build.model) - self.scrolled_view = gtk.ScrolledWindow () - self.scrolled_view.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.scrolled_view.add(self.build_tv) + self.scrolled_view_build = gtk.ScrolledWindow () + self.scrolled_view_build.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.scrolled_view_build.add(self.build_tv) + self.notebook.append_page(self.scrolled_view_build, gtk.Label("Log")) self.button_box = gtk.HBox(False, 6) self.back_button = gtk.LinkButton("Go back to Image Configuration screen", "<< Back to image configuration")@@ -86,7 +106,7 @@ class BuildDetailsPage (HobPage): self.progress_bar.reset() self.vbox.pack_start(self.progress_box, expand=False, fill=False) - self.vbox.pack_start(self.scrolled_view, expand=True, fill=True) + self.vbox.pack_start(self.notebook, expand=True, fill=True) self.box_group_area.pack_end(self.button_box, expand=False, fill=False) self.show_all()bitbake/lib/bb/ui/crumbs/runningbuild.py +1
-0@@ -25,6 +25,7 @@ import logging import time import urllib import urllib2 +import pango from bb.ui.crumbs.hobcolor import HobColors class RunningBuildModel (gtk.TreeStore):
bitbake/lib/bb/ui/crumbs/runningbuild.py class RunningBuildModel (gtk.TreeStore): · line 50
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py +7
-0@@ -40,6 +41,32 @@ class RunningBuildModel (gtk.TreeStore): gobject.TYPE_STRING, gobject.TYPE_INT) + def config_model_filter(self, model, it): + msg = model.get(it, self.COL_MESSAGE)[0] + if msg == None or type(msg) != str: + return False + if msg.startswith("\nOE Build Configuration:\n"): + return True + return False
I think I commented on this before, this seems like a heavy way to achieve this functionality. Is there not another way we can display the Build Configuration to the user without having to filter every message emitted?
Further, if we're going to display this information in a separate page of the notebook would it not make sense to not show it in the build log page?
Cheers,
Joshua
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentreRe: [PATCH 02/12] Hob: use HobNotebook to implement a notebook in build details page
Joshua Lock wrote on 2012-03-20:
Quoted 9 lines · Shane Wang
Quoted 8 lines
class RunningBuildModel (gtk.TreeStore):
bitbake/lib/bb/ui/crumbs/runningbuild.py +4
-0@@ -40,6 +41,32 @@ class RunningBuildModel (gtk.TreeStore): gobject.TYPE_STRING, gobject.TYPE_INT) + def config_model_filter(self, model, it): + msg = model.get(it, self.COL_MESSAGE)[0] + if msg == None or type(msg) != str: + return False
Quoted 8 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py class RunningBuildModel (gtk.TreeStore): · line 50
Quoted 3 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py +3
-0+ if msg.startswith("\nOE Build Configuration:\n"): + return True + return FalseI think I commented on this before, this seems like a heavy way to achieve this functionality. Is there not another way we can display the Build Configuration to the user without having to filter every message emitted?
I am going to submit a bug in bugzilla to address it later, since the series of patches block a lot of patch submissions.
Quoted 4 lines
Further, if we're going to display this information in a separate page of the notebook would it not make sense to not show it in the build log page?
OK, if you want I can remove it. But I suggest to keep it because of your above comment. That is the configuration information in Configuration Tab comes from different sources.
--
Shane
Quoted 3 lines
Cheers,
Joshua
Re: [PATCH 02/12] Hob: use HobNotebook to implement a notebook in build details page
In reply to Joshua Lockhttps://bugzilla.yoctoproject.org/show_bug.cgi?id=2144
for this.
--
Shane
Wang, Shane wrote on 2012-03-20:
Quoted 31 lines
Joshua Lock wrote on 2012-03-20:
Quoted 9 lines · Shane Wang
Quoted 8 lines
class RunningBuildModel (gtk.TreeStore):
bitbake/lib/bb/ui/crumbs/runningbuild.py +4
-0@@ -40,6 +41,32 @@ class RunningBuildModel (gtk.TreeStore): gobject.TYPE_STRING, gobject.TYPE_INT) + def config_model_filter(self, model, it): + msg = model.get(it, self.COL_MESSAGE)[0] + if msg == None or type(msg) != str: + return FalseQuoted 8 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py class RunningBuildModel (gtk.TreeStore): · line 50
Quoted 3 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py +3
-0+ if msg.startswith("\nOE Build Configuration:\n"): + return True + return FalseI think I commented on this before, this seems like a heavy way to achieve this functionality. Is there not another way we can display the Build Configuration to the user without having to filter every message emitted?
I am going to submit a bug in bugzilla to address it later, since the series of patches block a lot of patch submissions.
Quoted 4 lines
Further, if we're going to display this information in a separate page of the notebook would it not make sense to not show it in the build log page?
OK, if you want I can remove it. But I suggest to keep it because of your above comment.
That is the configuration information in Configuration Tab comes from different sources.
PATCH v3 3/12 Hob: show indicators on the tabs of the Hob notebook
In reply to Shane WangThis patch is to show the indicators (e.g., the number of the issues) in the build details page to highlight.
--- bitbake/lib/bb/ui/crumbs/builddetailspage.py | 10 ++++++++++ bitbake/lib/bb/ui/crumbs/builder.py | 5 +++++ bitbake/lib/bb/ui/crumbs/hobwidget.py | 14 ++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 4 ++++ 4 files changed, 33 insertions(+), 0 deletions(-)
bitbake/lib/bb/ui/crumbs/builddetailspage.py +10 -0
@@ -37,6 +37,8 @@ class BuildDetailsPage (HobPage): def __init__(self, builder): super(BuildDetailsPage, self).__init__(builder, "Building ...") + self.num_of_issues = 0 + # create visual elements self.create_visual_elements()
@@ -80,6 +82,14 @@ class BuildDetailsPage (HobPage): self.back_button.connect("clicked", self.back_button_clicked_cb) self.button_box.pack_start(self.back_button, expand=False, fill=False) + def show_issues(self): + self.num_of_issues += 1 + self.notebook.show_indicator_icon("Issues", self.num_of_issues) + + def reset_issues(self): + self.num_of_issues = 0 + self.notebook.hide_indicator_icon("Issues") + def _remove_all_widget(self): children = self.vbox.get_children() or [] for child in children:
bitbake/lib/bb/ui/crumbs/builder.py +5 -0
@@ -212,6 +212,7 @@ class Builder(gtk.Window): self.handler.build.connect("build-succeeded", self.handler_build_succeeded_cb) self.handler.build.connect("build-failed", self.handler_build_failed_cb) self.handler.build.connect("task-started", self.handler_task_started_cb) + self.handler.build.connect("log-error", self.handler_build_failure_cb) self.handler.connect("generating-data", self.handler_generating_data_cb) self.handler.connect("data-generated", self.handler_data_generated_cb) self.handler.connect("command-succeeded", self.handler_command_succeeded_cb)
@@ -533,6 +534,7 @@ class Builder(gtk.Window): elif self.current_step == self.PACKAGE_GENERATING: fraction = 0 self.build_details_page.update_progress_bar("Build Started: ", fraction) + self.build_details_page.reset_issues() def build_succeeded(self): if self.current_step == self.FAST_IMAGE_GENERATING:
@@ -600,6 +602,9 @@ class Builder(gtk.Window): fraction = 0.2 + 0.8 * fraction self.build_details_page.update_progress_bar(title + ": ", fraction) + def handler_build_failure_cb(self, running_build): + self.build_details_page.show_issues() + def destroy_window_cb(self, widget, event): lbl = "<b>Do you really want to exit the Hob image creator?</b>" dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)
bitbake/lib/bb/ui/crumbs/hobwidget.py +14 -0
@@ -619,6 +619,20 @@ class HobNotebook(gtk.VBox): self.tb.show() + def show_indicator_icon(self, title, number): + for i, child in enumerate(self.tabbar.children): + if child["toggled_page"] == -1: + continue + if child["title"] == title: + self.tabbar.show_indicator_icon(i, number) + + def hide_indicator_icon(self, title): + for i, child in enumerate(self.tabbar.children): + if child["toggled_page"] == -1: + continue + if child["title"] == title: + self.tabbar.hide_indicator_icon(i) + def tab_switched_cb(self, widget, page): self.notebook.set_current_page(page)
bitbake/lib/bb/ui/crumbs/runningbuild.py +4 -0
@@ -84,6 +84,9 @@ class RunningBuild (gobject.GObject): 'task-started' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), + 'log-error' : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + ()), } pids_to_task = {} tasks_to_iter = {}
@@ -134,6 +137,7 @@ class RunningBuild (gobject.GObject): if event.levelno >= logging.ERROR: icon = "dialog-error" color = HobColors.ERROR + self.emit("log-error") elif event.levelno >= logging.WARNING: icon = "dialog-warning" color = HobColors.WARNING
Signature · 1 line
1.7.6
Re: [PATCH 03/12] Hob: show indicators on the tabs of the Hob notebook
Quoted 4 lines · Shane Wang
This patch is to show the indicators (e.g., the number of the issues) in the build details page to highlight.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
Quoted 112 lines
--- bitbake/lib/bb/ui/crumbs/builddetailspage.py | 10 ++++++++++ bitbake/lib/bb/ui/crumbs/builder.py | 5 +++++ bitbake/lib/bb/ui/crumbs/hobwidget.py | 14 ++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 4 ++++ 4 files changed, 33 insertions(+), 0 deletions(-)bitbake/lib/bb/ui/crumbs/builddetailspage.py +10
-0@@ -37,6 +37,8 @@ class BuildDetailsPage (HobPage): def __init__(self, builder): super(BuildDetailsPage, self).__init__(builder, "Building ...") + self.num_of_issues = 0 + # create visual elements self.create_visual_elements()@@ -80,6 +82,14 @@ class BuildDetailsPage (HobPage): self.back_button.connect("clicked", self.back_button_clicked_cb) self.button_box.pack_start(self.back_button, expand=False, fill=False) + def show_issues(self): + self.num_of_issues += 1 + self.notebook.show_indicator_icon("Issues", self.num_of_issues) + + def reset_issues(self): + self.num_of_issues = 0 + self.notebook.hide_indicator_icon("Issues") + def _remove_all_widget(self): children = self.vbox.get_children() or [] for child in children:bitbake/lib/bb/ui/crumbs/builder.py +5
-0@@ -212,6 +212,7 @@ class Builder(gtk.Window): self.handler.build.connect("build-succeeded", self.handler_build_succeeded_cb) self.handler.build.connect("build-failed", self.handler_build_failed_cb) self.handler.build.connect("task-started", self.handler_task_started_cb) + self.handler.build.connect("log-error", self.handler_build_failure_cb) self.handler.connect("generating-data", self.handler_generating_data_cb) self.handler.connect("data-generated", self.handler_data_generated_cb) self.handler.connect("command-succeeded", self.handler_command_succeeded_cb)@@ -533,6 +534,7 @@ class Builder(gtk.Window): elif self.current_step == self.PACKAGE_GENERATING: fraction = 0 self.build_details_page.update_progress_bar("Build Started: ", fraction) + self.build_details_page.reset_issues() def build_succeeded(self): if self.current_step == self.FAST_IMAGE_GENERATING:@@ -600,6 +602,9 @@ class Builder(gtk.Window): fraction = 0.2 + 0.8 * fraction self.build_details_page.update_progress_bar(title + ": ", fraction) + def handler_build_failure_cb(self, running_build): + self.build_details_page.show_issues() + def destroy_window_cb(self, widget, event): lbl = "<b>Do you really want to exit the Hob image creator?</b>" dialog = CrumbsMessageDialog(self, lbl, gtk.STOCK_DIALOG_INFO)bitbake/lib/bb/ui/crumbs/hobwidget.py +14
-0@@ -619,6 +619,20 @@ class HobNotebook(gtk.VBox): self.tb.show() + def show_indicator_icon(self, title, number): + for i, child in enumerate(self.tabbar.children): + if child["toggled_page"] == -1: + continue + if child["title"] == title: + self.tabbar.show_indicator_icon(i, number) + + def hide_indicator_icon(self, title): + for i, child in enumerate(self.tabbar.children): + if child["toggled_page"] == -1: + continue + if child["title"] == title: + self.tabbar.hide_indicator_icon(i) + def tab_switched_cb(self, widget, page): self.notebook.set_current_page(page)bitbake/lib/bb/ui/crumbs/runningbuild.py +4
-0@@ -84,6 +84,9 @@ class RunningBuild (gobject.GObject): 'task-started' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)), + 'log-error' : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + ()), } pids_to_task = {} tasks_to_iter = {}@@ -134,6 +137,7 @@ class RunningBuild (gobject.GObject): if event.levelno>= logging.ERROR: icon = "dialog-error" color = HobColors.ERROR + self.emit("log-error") elif event.levelno>= logging.WARNING: icon = "dialog-warning" color = HobColors.WARNING
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 4/12 Hob: change the code style to enumerate a list in a for-loop
In reply to Shane WangWe use the more common style to enumerate a list in a for-loop
(http://docs.python.org/library/functions.html#enumerate), that is:
try to use
for item in mylist,
and try to use
for i, item in enumerate(list)
rather than
for i in range(len(mylist))
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 30 +++++++++++----------- bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 10 +++--- bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 10 +++--- 3 files changed, 25 insertions(+), 25 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +15 -15
@@ -109,38 +109,38 @@ class HobViewTable (gtk.VBox): self.toggle_columns = [] self.table_tree.connect("row-activated", self.row_activated_cb) - for i in range(len(columns)): - col = gtk.TreeViewColumn(columns[i]['col_name']) + for i, column in enumerate(columns): + col = gtk.TreeViewColumn(column['col_name']) col.set_clickable(True) col.set_resizable(True) - col.set_sort_column_id(columns[i]['col_id']) - if 'col_min' in columns[i].keys(): - col.set_min_width(columns[i]['col_min']) - if 'col_max' in columns[i].keys(): - col.set_max_width(columns[i]['col_max']) + col.set_sort_column_id(column['col_id']) + if 'col_min' in column.keys(): + col.set_min_width(column['col_min']) + if 'col_max' in column.keys(): + col.set_max_width(column['col_max']) self.table_tree.append_column(col) - if (not 'col_style' in columns[i].keys()) or columns[i]['col_style'] == 'text': + if (not 'col_style' in column.keys()) or column['col_style'] == 'text': cell = gtk.CellRendererText() col.pack_start(cell, True) - col.set_attributes(cell, text=columns[i]['col_id']) - elif columns[i]['col_style'] == 'check toggle': + col.set_attributes(cell, text=column['col_id']) + elif column['col_style'] == 'check toggle': cell = gtk.CellRendererToggle() cell.set_property('activatable', True) cell.connect("toggled", self.toggled_cb, i, self.table_tree) self.toggle_id = i col.pack_end(cell, True) - col.set_attributes(cell, active=columns[i]['col_id']) - self.toggle_columns.append(columns[i]['col_name']) - elif columns[i]['col_style'] == 'radio toggle': + col.set_attributes(cell, active=column['col_id']) + self.toggle_columns.append(column['col_name']) + elif column['col_style'] == 'radio toggle': cell = gtk.CellRendererToggle() cell.set_property('activatable', True) cell.set_radio(True) cell.connect("toggled", self.toggled_cb, i, self.table_tree) self.toggle_id = i col.pack_end(cell, True) - col.set_attributes(cell, active=columns[i]['col_id']) - self.toggle_columns.append(columns[i]['col_name']) + col.set_attributes(cell, active=column['col_id']) + self.toggle_columns.append(column['col_name']) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
bitbake/lib/bb/ui/crumbs/packageselectionpage.py +5 -5
@@ -105,16 +105,16 @@ class PackageSelectionPage (HobPage): self.ins = HobNotebook() self.tables = [] # we need to modify table when the dialog is shown # append the tab - for i in range(len(self.pages)): - columns = self.pages[i]['columns'] + for page in self.pages: + columns = page['columns'] tab = HobViewTable(columns) - filter = self.pages[i]['filter'] + filter = page['filter'] tab.set_model(self.package_model.tree_model(filter)) tab.connect("toggled", self.table_toggled_cb) - if self.pages[i]['name'] == "Included": + if page['name'] == "Included": tab.connect("row-activated", self.tree_row_activated_cb) - label = gtk.Label(self.pages[i]['name']) + label = gtk.Label(page['name']) self.ins.append_page(tab, label) self.tables.append(tab)
bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5 -5
@@ -127,16 +127,16 @@ class RecipeSelectionPage (HobPage): self.ins = HobNotebook() self.tables = [] # we need modify table when the dialog is shown # append the tabs in order - for i in range(len(self.pages)): - columns = self.pages[i]['columns'] + for page in self.pages: + columns = page['columns'] tab = HobViewTable(columns) - filter = self.pages[i]['filter'] + filter = page['filter'] tab.set_model(self.recipe_model.tree_model(filter)) tab.connect("toggled", self.table_toggled_cb) - if self.pages[i]['name'] == "Included": + if page['name'] == "Included": tab.connect("row-activated", self.tree_row_activated_cb) - label = gtk.Label(self.pages[i]['name']) + label = gtk.Label(page['name']) self.ins.append_page(tab, label) self.tables.append(tab)
Signature · 1 line
1.7.6
Re: [PATCH 04/12] Hob: change the code style to enumerate a list in a for-loop
Quoted 6 lines · Shane Wang
We use the more common style to enumerate a list in a for-loop
(http://docs.python.org/library/functions.html#enumerate), that is:try to use
for item in mylist,
Quoted 6 lines
and try to use
for i, item in enumerate(list)
rather than
for i in range(len(mylist))Signed-off-by Shane Wang<[email protected]>
Thanks!
Quoted 116 lines
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 30 +++++++++++----------- bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 10 +++--- bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 10 +++--- 3 files changed, 25 insertions(+), 25 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +15
-15@@ -109,38 +109,38 @@ class HobViewTable (gtk.VBox): self.toggle_columns = [] self.table_tree.connect("row-activated", self.row_activated_cb) - for i in range(len(columns)): - col = gtk.TreeViewColumn(columns[i]['col_name']) + for i, column in enumerate(columns): + col = gtk.TreeViewColumn(column['col_name']) col.set_clickable(True) col.set_resizable(True) - col.set_sort_column_id(columns[i]['col_id']) - if 'col_min' in columns[i].keys(): - col.set_min_width(columns[i]['col_min']) - if 'col_max' in columns[i].keys(): - col.set_max_width(columns[i]['col_max']) + col.set_sort_column_id(column['col_id']) + if 'col_min' in column.keys(): + col.set_min_width(column['col_min']) + if 'col_max' in column.keys(): + col.set_max_width(column['col_max']) self.table_tree.append_column(col) - if (not 'col_style' in columns[i].keys()) or columns[i]['col_style'] == 'text': + if (not 'col_style' in column.keys()) or column['col_style'] == 'text': cell = gtk.CellRendererText() col.pack_start(cell, True) - col.set_attributes(cell, text=columns[i]['col_id']) - elif columns[i]['col_style'] == 'check toggle': + col.set_attributes(cell, text=column['col_id']) + elif column['col_style'] == 'check toggle': cell = gtk.CellRendererToggle() cell.set_property('activatable', True) cell.connect("toggled", self.toggled_cb, i, self.table_tree) self.toggle_id = i col.pack_end(cell, True) - col.set_attributes(cell, active=columns[i]['col_id']) - self.toggle_columns.append(columns[i]['col_name']) - elif columns[i]['col_style'] == 'radio toggle': + col.set_attributes(cell, active=column['col_id']) + self.toggle_columns.append(column['col_name']) + elif column['col_style'] == 'radio toggle': cell = gtk.CellRendererToggle() cell.set_property('activatable', True) cell.set_radio(True) cell.connect("toggled", self.toggled_cb, i, self.table_tree) self.toggle_id = i col.pack_end(cell, True) - col.set_attributes(cell, active=columns[i]['col_id']) - self.toggle_columns.append(columns[i]['col_name']) + col.set_attributes(cell, active=column['col_id']) + self.toggle_columns.append(column['col_name']) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)bitbake/lib/bb/ui/crumbs/packageselectionpage.py +5
-5@@ -105,16 +105,16 @@ class PackageSelectionPage (HobPage): self.ins = HobNotebook() self.tables = [] # we need to modify table when the dialog is shown # append the tab - for i in range(len(self.pages)): - columns = self.pages[i]['columns'] + for page in self.pages: + columns = page['columns'] tab = HobViewTable(columns) - filter = self.pages[i]['filter'] + filter = page['filter'] tab.set_model(self.package_model.tree_model(filter)) tab.connect("toggled", self.table_toggled_cb) - if self.pages[i]['name'] == "Included": + if page['name'] == "Included": tab.connect("row-activated", self.tree_row_activated_cb) - label = gtk.Label(self.pages[i]['name']) + label = gtk.Label(page['name']) self.ins.append_page(tab, label) self.tables.append(tab)bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5
-5@@ -127,16 +127,16 @@ class RecipeSelectionPage (HobPage): self.ins = HobNotebook() self.tables = [] # we need modify table when the dialog is shown # append the tabs in order - for i in range(len(self.pages)): - columns = self.pages[i]['columns'] + for page in self.pages: + columns = page['columns'] tab = HobViewTable(columns) - filter = self.pages[i]['filter'] + filter = page['filter'] tab.set_model(self.recipe_model.tree_model(filter)) tab.connect("toggled", self.table_toggled_cb) - if self.pages[i]['name'] == "Included": + if page['name'] == "Included": tab.connect("row-activated", self.tree_row_activated_cb) - label = gtk.Label(self.pages[i]['name']) + label = gtk.Label(page['name']) self.ins.append_page(tab, label) self.tables.append(tab)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 5/12 Hob: fix '!= None' and '== None' in the code
In reply to Shane WangThis patch is to fix the following:
if foo != None -----> if foo
if foo == None -----> if not foo
--- bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 4 ++-- bitbake/lib/bb/ui/crumbs/hoblistmodel.py | 2 +- bitbake/lib/bb/ui/crumbs/hobpages.py | 4 ++-- bitbake/lib/bb/ui/crumbs/hobwidget.py | 6 +++--- bitbake/lib/bb/ui/crumbs/imagedetailspage.py | 12 ++++++------ bitbake/lib/bb/ui/crumbs/runningbuild.py | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-)
bitbake/lib/bb/ui/crumbs/hobeventhandler.py +2 -2
@@ -119,7 +119,7 @@ class HobHandler(gobject.GObject): self.generating = False def run_next_command(self, initcmd=None): - if initcmd != None: + if initcmd: self.initcmd = initcmd if self.commands_async:
@@ -127,7 +127,7 @@ class HobHandler(gobject.GObject): next_command = self.commands_async.pop(0) else: self.clear_busy() - if self.initcmd != None: + if self.initcmd: self.emit("command-succeeded", self.initcmd) return
bitbake/lib/bb/ui/crumbs/hoblistmodel.py +1 -1
@@ -713,7 +713,7 @@ class RecipeListModel(gtk.ListStore): return None def set_selected_image(self, img): - if img == None: + if not img: return path = self.find_path_for_item(img) self.include_item(item_path=path,
bitbake/lib/bb/ui/crumbs/hobpages.py +2 -2
@@ -34,7 +34,7 @@ class HobPage (gtk.VBox): self.builder = builder self.builder_width, self.builder_height = self.builder.size_request() - if title == None: + if not title: self.title = "HOB -- Image Creator" else: self.title = title
@@ -62,7 +62,7 @@ class HobPage (gtk.VBox): label.set_markup("<span font_desc=\'14\'>%s</span>" % self.title) hbox.pack_start(label, expand=False, fill=False, padding=20) - if widget != None: + if widget: # add the widget in the event box hbox.pack_end(widget, expand=False, fill=False, padding=padding) eventbox.add(hbox)
bitbake/lib/bb/ui/crumbs/hobwidget.py +3 -3
@@ -366,7 +366,7 @@ class HobTabBar(gtk.DrawingArea): child["x"] = self.tab_x + i * self.tab_width child["y"] = self.tab_y - if self.blank_rectangle != None: + if self.blank_rectangle: self.resize_blank_rectangle() def resize_blank_rectangle(self):
@@ -553,7 +553,7 @@ class HobTabBar(gtk.DrawingArea): self.queue_draw() def set_blank_size(self, x, y, w, h): - if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + if not self.blank_rectangle or self.blank_rectangle.x != x or self.blank_rectangle.width != w: self.emit("blank-area-changed", x, y, w, h) return gtk.gdk.Rectangle(x, y, w, h)
@@ -640,7 +640,7 @@ class HobNotebook(gtk.VBox): if not notebook: return title = notebook.get_tab_label_text(notebook_child) - if title == None: + if not title: return for child in self.tabbar.children: if child["title"] == title:
bitbake/lib/bb/ui/crumbs/imagedetailspage.py +6 -6
@@ -64,9 +64,9 @@ class ImageDetailsPage (HobPage): self.hbox.set_border_width(15) self.add(self.hbox) - if widget != None: + if widget: row = 1 - elif varlist != None and vallist != None: + elif varlist and vallist: # pack the icon and the text on the left row = len(varlist) self.table = gtk.Table(row, 20, True)
@@ -75,18 +75,18 @@ class ImageDetailsPage (HobPage): colid = 0 self.line_widgets = {} - if icon != None: + if icon: self.table.attach(icon, colid, colid + 2, 0, 1) colid = colid + 2 - if widget != None: + if widget: self.table.attach(widget, colid, 20, 0, 1) - elif varlist != None and vallist != None: + elif varlist and vallist: for line in range(0, row): self.line_widgets[varlist[line]] = self.text2label(varlist[line], vallist[line]) self.table.attach(self.line_widgets[varlist[line]], colid, 20, line, line + 1) # pack the button on the right - if button != None: + if button: self.hbox.pack_end(button, expand=False, fill=False) def update_line_widgets(self, variable, value):
bitbake/lib/bb/ui/crumbs/runningbuild.py +2 -2
@@ -43,7 +43,7 @@ class RunningBuildModel (gtk.TreeStore): def config_model_filter(self, model, it): msg = model.get(it, self.COL_MESSAGE)[0] - if msg == None or type(msg) != str: + if not msg or type(msg) != str: return False if msg.startswith("\nOE Build Configuration:\n"): return True
@@ -51,7 +51,7 @@ class RunningBuildModel (gtk.TreeStore): def failure_model_filter(self, model, it): color = model.get(it, self.COL_COLOR)[0] - if color == None: + if not color: return False if color == HobColors.ERROR: return True
Signature · 1 line
1.7.6
Re: [PATCH 05/12] Hob: fix '!= None' and '== None' in the code
Quoted 6 lines · Shane Wang
This patch is to fix the following:
if foo != None -----> if foo
if foo == None -----> if not fooSigned-off-by Shane Wang<[email protected]>
Thanks!
Quoted 158 lines
--- bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 4 ++-- bitbake/lib/bb/ui/crumbs/hoblistmodel.py | 2 +- bitbake/lib/bb/ui/crumbs/hobpages.py | 4 ++-- bitbake/lib/bb/ui/crumbs/hobwidget.py | 6 +++--- bitbake/lib/bb/ui/crumbs/imagedetailspage.py | 12 ++++++------ bitbake/lib/bb/ui/crumbs/runningbuild.py | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-)bitbake/lib/bb/ui/crumbs/hobeventhandler.py +2
-2@@ -119,7 +119,7 @@ class HobHandler(gobject.GObject): self.generating = False def run_next_command(self, initcmd=None): - if initcmd != None: + if initcmd: self.initcmd = initcmd if self.commands_async:@@ -127,7 +127,7 @@ class HobHandler(gobject.GObject): next_command = self.commands_async.pop(0) else: self.clear_busy() - if self.initcmd != None: + if self.initcmd: self.emit("command-succeeded", self.initcmd) returnbitbake/lib/bb/ui/crumbs/hoblistmodel.py +1
-1@@ -713,7 +713,7 @@ class RecipeListModel(gtk.ListStore): return None def set_selected_image(self, img): - if img == None: + if not img: return path = self.find_path_for_item(img) self.include_item(item_path=path,bitbake/lib/bb/ui/crumbs/hobpages.py +2
-2@@ -34,7 +34,7 @@ class HobPage (gtk.VBox): self.builder = builder self.builder_width, self.builder_height = self.builder.size_request() - if title == None: + if not title: self.title = "HOB -- Image Creator" else: self.title = title@@ -62,7 +62,7 @@ class HobPage (gtk.VBox): label.set_markup("<span font_desc=\'14\'>%s</span>" % self.title) hbox.pack_start(label, expand=False, fill=False, padding=20) - if widget != None: + if widget: # add the widget in the event box hbox.pack_end(widget, expand=False, fill=False, padding=padding) eventbox.add(hbox)bitbake/lib/bb/ui/crumbs/hobwidget.py +3
-3@@ -366,7 +366,7 @@ class HobTabBar(gtk.DrawingArea): child["x"] = self.tab_x + i * self.tab_width child["y"] = self.tab_y - if self.blank_rectangle != None: + if self.blank_rectangle: self.resize_blank_rectangle() def resize_blank_rectangle(self):@@ -553,7 +553,7 @@ class HobTabBar(gtk.DrawingArea): self.queue_draw() def set_blank_size(self, x, y, w, h): - if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + if not self.blank_rectangle or self.blank_rectangle.x != x or self.blank_rectangle.width != w: self.emit("blank-area-changed", x, y, w, h) return gtk.gdk.Rectangle(x, y, w, h)@@ -640,7 +640,7 @@ class HobNotebook(gtk.VBox): if not notebook: return title = notebook.get_tab_label_text(notebook_child) - if title == None: + if not title: return for child in self.tabbar.children: if child["title"] == title:bitbake/lib/bb/ui/crumbs/imagedetailspage.py +6
-6@@ -64,9 +64,9 @@ class ImageDetailsPage (HobPage): self.hbox.set_border_width(15) self.add(self.hbox) - if widget != None: + if widget: row = 1 - elif varlist != None and vallist != None: + elif varlist and vallist: # pack the icon and the text on the left row = len(varlist) self.table = gtk.Table(row, 20, True)@@ -75,18 +75,18 @@ class ImageDetailsPage (HobPage): colid = 0 self.line_widgets = {} - if icon != None: + if icon: self.table.attach(icon, colid, colid + 2, 0, 1) colid = colid + 2 - if widget != None: + if widget: self.table.attach(widget, colid, 20, 0, 1) - elif varlist != None and vallist != None: + elif varlist and vallist: for line in range(0, row): self.line_widgets[varlist[line]] = self.text2label(varlist[line], vallist[line]) self.table.attach(self.line_widgets[varlist[line]], colid, 20, line, line + 1) # pack the button on the right - if button != None: + if button: self.hbox.pack_end(button, expand=False, fill=False) def update_line_widgets(self, variable, value):bitbake/lib/bb/ui/crumbs/runningbuild.py +2
-2@@ -43,7 +43,7 @@ class RunningBuildModel (gtk.TreeStore): def config_model_filter(self, model, it): msg = model.get(it, self.COL_MESSAGE)[0] - if msg == None or type(msg) != str: + if not msg or type(msg) != str: return False if msg.startswith("\nOE Build Configuration:\n"): return True@@ -51,7 +51,7 @@ class RunningBuildModel (gtk.TreeStore): def failure_model_filter(self, model, it): color = model.get(it, self.COL_COLOR)[0] - if color == None: + if not color: return False if color == HobColors.ERROR: return True
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 6/12 Hob: allow users to setup the proxies
In reply to Shane WangThis patch is to set os.environ to allow users to set the environment variables for http_proxy, https_proxy and ftp_proxy.
--- bitbake/lib/bb/ui/crumbs/builder.py | 36 +++++++++++++++ bitbake/lib/bb/ui/crumbs/hig.py | 82 ++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 11 deletions(-)
bitbake/lib/bb/ui/crumbs/builder.py +36 -0
@@ -116,6 +116,7 @@ class Configuration: class Parameters: '''Represents other variables like available machines, etc.''' + __dummy_proxy__ = "myproxy.example.com:8010" def __init__(self, params): # Variables
@@ -129,6 +130,8 @@ class Parameters: self.image_names = [] self.image_addr = params["image_addr"] self.image_types = params["image_types"].split() + self.http_proxy = self.https_proxy = self.ftp_proxy = self.__dummy_proxy__ + self.enable_proxy = False class Builder(gtk.Window):
@@ -734,6 +737,28 @@ class Builder(gtk.Window): dialog.destroy() + def _setup_proxy(self): + if (self.parameters.http_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.http_proxy.lstrip() == "") \ + and "http_proxy" in os.environ.keys(): + del os.environ["http_proxy"] + else: + os.environ["http_proxy"] = self.parameters.http_proxy + + if (self.parameters.https_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.https_proxy.lstrip() == "") \ + and "https_proxy" in os.environ.keys(): + del os.environ["https_proxy"] + else: + os.environ["https_proxy"] = self.parameters.https_proxy + + if (self.parameters.ftp_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.ftp_proxy.lstrip() == "") \ + and "ftp_proxy" in os.environ.keys(): + del os.environ["ftp_proxy"] + else: + os.environ["ftp_proxy"] = self.parameters.ftp_proxy + def show_adv_settings_dialog(self): dialog = AdvancedSettingDialog(title = "Settings", configuration = copy.deepcopy(self.configuration),
@@ -742,6 +767,10 @@ class Builder(gtk.Window): all_distros = self.parameters.all_distros, all_sdk_machines = self.parameters.all_sdk_machines, max_threads = self.parameters.max_threads, + http_proxy = self.parameters.http_proxy, + https_proxy = self.parameters.https_proxy, + ftp_proxy = self.parameters.ftp_proxy, + enable_proxy = self.parameters.enable_proxy, split_model = self.get_split_model(), parent = self, flags = gtk.DIALOG_MODAL
@@ -752,6 +781,13 @@ class Builder(gtk.Window): response = dialog.run() if response == gtk.RESPONSE_YES: self.configuration = dialog.configuration + # setup the proxy + self.parameters.enable_proxy = dialog.enable_proxy + if self.parameters.enable_proxy == True: + self.parameters.http_proxy = dialog.http_proxy + self.parameters.https_proxy = dialog.https_proxy + self.parameters.ftp_proxy = dialog.ftp_proxy + self._setup_proxy() # DO reparse recipes if dialog.settings_changed: if self.configuration.curr_mach == "":
bitbake/lib/bb/ui/crumbs/hig.py +71 -11
130 lines not on this page · raw message
Signature · 1 line
1.7.6
Re: [PATCH 06/12] Hob: allow users to setup the proxies
Quoted 1 line · Shane Wang
This patch is to set os.environ to allow users to set the environment variables for
http_proxy,https_proxyandftp_proxy.
I think we need to be careful about implementing this functionality, so I have two suggestions
1) As far as I can tell the proxy settings will not be remembered between runs of the Hob, I think they probably should be.
2) If the user already has some or all of the proxy settings set in their environment we should probably detect those and display them appropriately in the GUI.
Are their any design documents for this dialogue?
Cheers,
Joshua
Quoted 224 lines
Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/builder.py | 36 +++++++++++++++ bitbake/lib/bb/ui/crumbs/hig.py | 82 ++++++++++++++++++++++++++++++----- 2 files changed, 107 insertions(+), 11 deletions(-)bitbake/lib/bb/ui/crumbs/builder.py +36
-0@@ -116,6 +116,7 @@ class Configuration: class Parameters: '''Represents other variables like available machines, etc.''' + __dummy_proxy__ = "myproxy.example.com:8010" def __init__(self, params): # Variables@@ -129,6 +130,8 @@ class Parameters: self.image_names = [] self.image_addr = params["image_addr"] self.image_types = params["image_types"].split() + self.http_proxy = self.https_proxy = self.ftp_proxy = self.__dummy_proxy__ + self.enable_proxy = False class Builder(gtk.Window):@@ -734,6 +737,28 @@ class Builder(gtk.Window): dialog.destroy() + def _setup_proxy(self): + if (self.parameters.http_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.http_proxy.lstrip() == "") \ + and "http_proxy" in os.environ.keys(): + del os.environ["http_proxy"] + else: + os.environ["http_proxy"] = self.parameters.http_proxy + + if (self.parameters.https_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.https_proxy.lstrip() == "") \ + and "https_proxy" in os.environ.keys(): + del os.environ["https_proxy"] + else: + os.environ["https_proxy"] = self.parameters.https_proxy + + if (self.parameters.ftp_proxy == Parameters.__dummy_proxy__ \ + or self.parameters.ftp_proxy.lstrip() == "") \ + and "ftp_proxy" in os.environ.keys(): + del os.environ["ftp_proxy"] + else: + os.environ["ftp_proxy"] = self.parameters.ftp_proxy + def show_adv_settings_dialog(self): dialog = AdvancedSettingDialog(title = "Settings", configuration = copy.deepcopy(self.configuration),@@ -742,6 +767,10 @@ class Builder(gtk.Window): all_distros = self.parameters.all_distros, all_sdk_machines = self.parameters.all_sdk_machines, max_threads = self.parameters.max_threads, + http_proxy = self.parameters.http_proxy, + https_proxy = self.parameters.https_proxy, + ftp_proxy = self.parameters.ftp_proxy, + enable_proxy = self.parameters.enable_proxy, split_model = self.get_split_model(), parent = self, flags = gtk.DIALOG_MODAL@@ -752,6 +781,13 @@ class Builder(gtk.Window): response = dialog.run() if response == gtk.RESPONSE_YES: self.configuration = dialog.configuration + # setup the proxy + self.parameters.enable_proxy = dialog.enable_proxy + if self.parameters.enable_proxy == True: + self.parameters.http_proxy = dialog.http_proxy + self.parameters.https_proxy = dialog.https_proxy + self.parameters.ftp_proxy = dialog.ftp_proxy + self._setup_proxy() # DO reparse recipes if dialog.settings_changed: if self.configuration.curr_mach == "":bitbake/lib/bb/ui/crumbs/hig.py +71
-11@@ -170,7 +170,7 @@ class AdvancedSettingDialog (CrumbsDialog): dialog.destroy() - def gen_entry_widget(self, split_model, content, parent, tooltip=""): + def gen_entry_widget(self, split_model, content, parent, tooltip="", need_button=True): hbox = gtk.HBox(False, 12) entry = gtk.Entry() entry.set_text(content)@@ -178,15 +178,18 @@ class AdvancedSettingDialog (CrumbsDialog): if split_model: hbox.pack_start(entry, expand=True, fill=True) else: - table = gtk.Table(1, 10, True) - hbox.pack_start(table, expand=True, fill=True) - table.attach(entry, 0, 9, 0, 1) - image = gtk.Image() - image.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON) - open_button = gtk.Button() - open_button.set_image(image) - open_button.connect("clicked", self.entry_widget_select_path_cb, parent, entry) - table.attach(open_button, 9, 10, 0, 1) + if need_button: + table = gtk.Table(1, 10, True) + hbox.pack_start(table, expand=True, fill=True) + table.attach(entry, 0, 9, 0, 1) + image = gtk.Image() + image.set_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON) + open_button = gtk.Button() + open_button.set_image(image) + open_button.connect("clicked", self.entry_widget_select_path_cb, parent, entry) + table.attach(open_button, 9, 10, 0, 1) + else: + hbox.pack_start(entry, expand=True, fill=True) info = HobInfoButton(tooltip, self) hbox.pack_start(info, expand=False, fill=False)@@ -421,7 +424,8 @@ class AdvancedSettingDialog (CrumbsDialog): def __init__(self, title, configuration, all_image_types, all_package_formats, all_distros, all_sdk_machines, - max_threads, split_model, parent, flags, buttons): + max_threads, http_proxy, https_proxy, ftp_proxy, + enable_proxy, split_model, parent, flags, buttons): super(AdvancedSettingDialog, self).__init__(title, parent, flags, buttons) # class members from other objects@@ -432,6 +436,10 @@ class AdvancedSettingDialog (CrumbsDialog): self.all_distros = all_distros self.all_sdk_machines = all_sdk_machines self.max_threads = max_threads + self.http_proxy = http_proxy + self.https_proxy = https_proxy + self.ftp_proxy = ftp_proxy + self.enable_proxy = enable_proxy self.split_model = split_model # class members for internal use@@ -466,6 +474,7 @@ class AdvancedSettingDialog (CrumbsDialog): self.nb.append_page(self.create_image_types_page(), gtk.Label("Image types")) self.nb.append_page(self.create_output_page(), gtk.Label("Output")) self.nb.append_page(self.create_build_environment_page(), gtk.Label("Build environment")) + self.nb.append_page(self.create_proxy_page(), gtk.Label("Proxies")) self.nb.append_page(self.create_others_page(), gtk.Label("Others")) self.nb.set_current_page(0) self.vbox.pack_start(self.nb, expand=True, fill=True)@@ -606,6 +615,44 @@ class AdvancedSettingDialog (CrumbsDialog): return advanced_vbox + def create_proxy_page(self): + advanced_vbox = gtk.VBox(False, 6) + advanced_vbox.set_border_width(6) + + sub_vbox = gtk.VBox(False, 6) + advanced_vbox.pack_start(sub_vbox, expand=False, fill=False) + self.proxy_checkbox = gtk.CheckButton("Enable Proxy") + self.proxy_checkbox.set_tooltip_text("Check this box to setup the proxy you specified") + self.proxy_checkbox.set_active(self.enable_proxy) + self.proxy_checkbox.connect("toggled", self.proxy_checkbox_toggled_cb) + sub_vbox.pack_start(self.proxy_checkbox, expand=False, fill=False) + + label = self.gen_label_widget("<span weight=\"bold\">Select HTTP Proxy:</span>") + tooltip = "Select the HTTP proxy that will be used in do_fetch() source code" + proxy_widget, self.http_proxy_text = self.gen_entry_widget(self.split_model, self.http_proxy, self, tooltip, False) + self.http_proxy_text.set_editable(self.enable_proxy) + self.http_proxy_text.set_sensitive(self.enable_proxy) + sub_vbox.pack_start(label, expand=False, fill=False) + sub_vbox.pack_start(proxy_widget, expand=False, fill=False) + + label = self.gen_label_widget("<span weight=\"bold\">Select HTTPS Proxy:</span>") + tooltip = "Select the HTTPS proxy that will be used in do_fetch() source code" + proxy_widget, self.https_proxy_text = self.gen_entry_widget(self.split_model, self.https_proxy, self, tooltip, False) + self.https_proxy_text.set_editable(self.enable_proxy) + self.https_proxy_text.set_sensitive(self.enable_proxy) + sub_vbox.pack_start(label, expand=False, fill=False) + sub_vbox.pack_start(proxy_widget, expand=False, fill=False) + + label = self.gen_label_widget("<span weight=\"bold\">Select FTP Proxy:</span>") + tooltip = "Select the FTP proxy that will be used in do_fetch() source code" + proxy_widget, self.ftp_proxy_text = self.gen_entry_widget(self.split_model, self.ftp_proxy, self, tooltip, False) + self.ftp_proxy_text.set_editable(self.enable_proxy) + self.ftp_proxy_text.set_sensitive(self.enable_proxy) + sub_vbox.pack_start(label, expand=False, fill=False) + sub_vbox.pack_start(proxy_widget, expand=False, fill=False) + + return advanced_vbox + def create_others_page(self): advanced_vbox = gtk.VBox(False, 6) advanced_vbox.set_border_width(6)@@ -620,6 +667,15 @@ class AdvancedSettingDialog (CrumbsDialog): return advanced_vbox + def proxy_checkbox_toggled_cb(self, button): + self.enable_proxy = self.proxy_checkbox.get_active() + self.http_proxy_text.set_editable(self.enable_proxy) + self.http_proxy_text.set_sensitive(self.enable_proxy) + self.https_proxy_text.set_editable(self.enable_proxy) + self.https_proxy_text.set_sensitive(self.enable_proxy) + self.ftp_proxy_text.set_editable(self.enable_proxy) + self.ftp_proxy_text.set_sensitive(self.enable_proxy) + def response_cb(self, dialog, response_id): self.variables = {}@@ -669,6 +725,10 @@ class AdvancedSettingDialog (CrumbsDialog): self.variables[key] = value it = self.setting_store.iter_next(it) + self.http_proxy = self.http_proxy_text.get_text() + self.https_proxy = self.https_proxy_text.get_text() + self.ftp_proxy = self.ftp_proxy_text.get_text() + md5 = hashlib.md5(str(sorted(self.variables.items()))).hexdigest() self.settings_changed = (self.md5 != md5)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentreRe: [PATCH 06/12] Hob: allow users to setup the proxies
Joshua Lock wrote on 2012-03-20:
Quoted 10 lines · Shane Wang
Quoted 1 line
This patch is to set os.environ to allow users to set the environment
variables for
http_proxy,https_proxyandftp_proxy.I think we need to be careful about implementing this functionality, so I have two suggestions
1) As far as I can tell the proxy settings will not be remembered between runs of the Hob, I think they probably should be.
Yes.
Quoted 3 lines
2) If the user already has some or all of the proxy settings set in their environment we should probably detect those and display them appropriately in the GUI.
OK, will investigate and have a try.
Quoted 2 lines
Are their any design documents for this dialogue?
No.
Quoted 3 lines
Cheers,
Joshua
Re: [PATCH 06/12] Hob: allow users to setup the proxies
Hi all,
Sorry for the delay in commenting on this.
I've checked our discussions about the proxy functionality, and it looks like we never reached an agreement on how to implement this feature. It was suggested to configure the proxy through sites.conf, and then Scott Garman replied pointing out that the "the proxy situation is a mess under Linux. This is likely to be a non-trivial problem
(http://www.yoctoproject.org/blogs/sgarman/2011/proxy-problem)". After that, the discussion died out.
We could review the implementation and provide some suggestions. Would that be useful?
Cheers
Belen
Quoted 24 lines · Shane
Joshua Lock wrote on 2012-03-20:
Quoted 10 lines · Shane Wang
Quoted 1 line
This patch is to set os.environ to allow users to set the environment
variables for
http_proxy,https_proxyandftp_proxy.I think we need to be careful about implementing this functionality, so I have two suggestions
1) As far as I can tell the proxy settings will not be remembered between runs of the Hob, I think they probably should be.Yes.
Quoted 3 lines
2) If the user already has some or all of the proxy settings set in their environment we should probably detect those and display them appropriately in the GUI.
OK, will investigate and have a try.
Quoted 2 lines
Are their any design documents for this dialogue?
No.
Quoted 1 line
Quoted 6 lines
Quoted 2 lines
Cheers,
Joshua_______________________________________________
bitbake-devel mailing list
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/bitbake-devel
---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.
PATCH v3 7/12 Hob: remove the invalid code in hobwidget.py
In reply to Shane WangFrom: Liming An <[email protected]>
To delete some code which is not used
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +0 -2
@@ -516,7 +516,6 @@ class HobTabBar(gtk.DrawingArea): cr.fill() def draw_indicator(self, cr, i): - style = self.get_style() tab_x = self.children[i]["x"] tab_y = self.children[i]["y"] number = self.children[i]["indicator_number"]
@@ -528,7 +527,6 @@ class HobTabBar(gtk.DrawingArea): # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x) x = tab_x + self.tab_width * 3/4 - dest_w/2 y = tab_y + self.tab_height/2 - dest_h/2 - cr.move_to(tab_x, tab_y) r = min(dest_w, dest_h)/2 color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE)) cr.arc(x + r, y + r, r, 0, 2*math.pi)
Signature · 1 line
1.7.6
Re: [PATCH 07/12] Hob: remove the invalid code in hobwidget.py
Quoted 6 lines · Shane Wang
From: Liming An<[email protected]>
To delete some code which is not used
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
Quoted 24 lines
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +0
-2@@ -516,7 +516,6 @@ class HobTabBar(gtk.DrawingArea): cr.fill() def draw_indicator(self, cr, i): - style = self.get_style() tab_x = self.children[i]["x"] tab_y = self.children[i]["y"] number = self.children[i]["indicator_number"]@@ -528,7 +527,6 @@ class HobTabBar(gtk.DrawingArea): # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x) x = tab_x + self.tab_width * 3/4 - dest_w/2 y = tab_y + self.tab_height/2 - dest_h/2 - cr.move_to(tab_x, tab_y) r = min(dest_w, dest_h)/2 color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE)) cr.arc(x + r, y + r, r, 0, 2*math.pi)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 8/12 Hob: change the range dance in hobwidget make it like a pythonista
In reply to Shane WangFrom: Liming An <[email protected]>
To fix the for..in.. range dance code, and make it like pythonista, as the required.
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 67 +++++++++++++++++--------------- 1 files changed, 36 insertions(+), 31 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +36 -31
@@ -309,7 +309,7 @@ class HobTabBar(gtk.DrawingArea): self.tab_h_ratio = 52 * 1.0/53 self.set_size_request(self.width, self.height) - self.current_child = 0 + self.current_child = None self.font = self.get_style().font_desc self.font.set_size(pango.SCALE * 13) self.update_children_text_layout_and_bg_color()
@@ -339,10 +339,10 @@ class HobTabBar(gtk.DrawingArea): if self.is_focus() or event.type == gtk.gdk.BUTTON_PRESS: x, y = event.get_coords() # check which tab be clicked - for i, child in enumerate(self.children): + for child in self.children: if (child["x"] < x) and (x < child["x"] + self.tab_width) \ and (child["y"] < y) and (y < child["y"] + self.tab_height): - self.current_child = i + self.current_child = child result = True break
@@ -353,7 +353,7 @@ class HobTabBar(gtk.DrawingArea): self.grab_focus() if result == True: - page = self.children[self.current_child]["toggled_page"] + page = self.current_child["toggled_page"] self.emit("tab-switched", page) self.tab_pressed = True self.queue_draw()
@@ -366,7 +366,7 @@ class HobTabBar(gtk.DrawingArea): child["x"] = self.tab_x + i * self.tab_width child["y"] = self.tab_y - if self.blank_rectangle: + if self.blank_rectangle != None: self.resize_blank_rectangle() def resize_blank_rectangle(self):
@@ -383,16 +383,16 @@ class HobTabBar(gtk.DrawingArea): pangolayout = self.create_pango_layout(child["title"]) pangolayout.set_font_description(self.font) child["title_layout"] = pangolayout - child[i]["r"] = color.red - child[i]["g"] = color.green - child[i]["b"] = color.blue + child["r"] = color.red + child["g"] = color.green + child["b"] = color.blue def append_tab_child(self, title, page): num = len(self.children) + 1 self.tab_width = self.tab_width * len(self.children) / num i = 0 - for child in self.children: + for i, child in enumerate(self.children): child["x"] = self.tab_x + i * self.tab_width i += 1
@@ -414,6 +414,9 @@ class HobTabBar(gtk.DrawingArea): "indicator_number" : 0, } self.children.append(new_one) + # set the default current child + if not self.current_child: + self.current_child = new_one def on_draw(self, widget, event): cr = widget.window.cairo_create()
@@ -425,11 +428,12 @@ class HobTabBar(gtk.DrawingArea): self.draw_background(cr) self.draw_toggled_tab(cr) - self.draw_tab_text(cr) - for i, child in enumerate(self.children): + for child in self.children: if child["indicator_show"] == True: - self.draw_indicator(cr, i) + self.draw_indicator(cr, child) + + self.draw_tab_text(cr) def draw_background(self, cr): style = self.get_style()
@@ -476,14 +480,15 @@ class HobTabBar(gtk.DrawingArea): # center pos off_x = (self.tab_width - fontw) / 2 off_y = (self.tab_height - fonth) / 2 - x = child[i]["x"] + off_x - y = child[i]["y"] + off_y + x = child["x"] + off_x + y = child["y"] + off_y self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), pangolayout) def draw_toggled_tab(self, cr): - i = self.current_child - x = self.children[i]["x"] - y = self.children[i]["y"] + if not self.current_child: + return + x = self.current_child["x"] + y = self.current_child["y"] width = self.tab_width height = self.tab_height style = self.get_style()
@@ -515,10 +520,10 @@ class HobTabBar(gtk.DrawingArea): cr.arc(x + r, y + r, r, math.pi, 1.5*math.pi) cr.fill() - def draw_indicator(self, cr, i): - tab_x = self.children[i]["x"] - tab_y = self.children[i]["y"] - number = self.children[i]["indicator_number"] + def draw_indicator(self, cr, child): + tab_x = child["x"] + tab_y = child["y"] + number = child["indicator_number"] dest_w = int(32 * self.tab_w_ratio) dest_h = int(32 * self.tab_h_ratio) if dest_h < self.tab_height:
@@ -541,17 +546,17 @@ class HobTabBar(gtk.DrawingArea): cr.move_to(x, y) self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), layout) - def show_indicator_icon(self, i, number): - self.children[i]["indicator_show"] = True - self.children[i]["indicator_number"] = number + def show_indicator_icon(self, child, number): + child["indicator_show"] = True + child["indicator_number"] = number self.queue_draw() - def hide_indicator_icon(self, i): - self.children[i]["indicator_show"] = False + def hide_indicator_icon(self, child): + child["indicator_show"] = False self.queue_draw() def set_blank_size(self, x, y, w, h): - if not self.blank_rectangle or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w: self.emit("blank-area-changed", x, y, w, h) return gtk.gdk.Rectangle(x, y, w, h)
@@ -618,18 +623,18 @@ class HobNotebook(gtk.VBox): self.tb.show() def show_indicator_icon(self, title, number): - for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.show_indicator_icon(i, number) + self.tabbar.show_indicator_icon(child, number) def hide_indicator_icon(self, title): - for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.hide_indicator_icon(i) + self.tabbar.hide_indicator_icon(child) def tab_switched_cb(self, widget, page): self.notebook.set_current_page(page)
Signature · 1 line
1.7.6
Re: [PATCH 08/12] Hob: change the range dance in hobwidget make it like a pythonista
Quoted 3 lines · Shane Wang
From: Liming An<[email protected]>
To fix the for..in.. range dance code, and make it like pythonista, as the required.
This commit message doesn't match the patch contents.
Quoted 43 lines
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 67 +++++++++++++++++--------------- 1 files changed, 36 insertions(+), 31 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +4
-4@@ -309,7 +309,7 @@ class HobTabBar(gtk.DrawingArea): self.tab_h_ratio = 52 * 1.0/53 self.set_size_request(self.width, self.height) - self.current_child = 0 + self.current_child = None self.font = self.get_style().font_desc self.font.set_size(pango.SCALE * 13) self.update_children_text_layout_and_bg_color()@@ -339,10 +339,10 @@ class HobTabBar(gtk.DrawingArea): if self.is_focus() or event.type == gtk.gdk.BUTTON_PRESS: x, y = event.get_coords() # check which tab be clicked - for i, child in enumerate(self.children): + for child in self.children: if (child["x"]< x) and (x< child["x"] + self.tab_width) \ and (child["y"]< y) and (y< child["y"] + self.tab_height): - self.current_child = i + self.current_child = child result = True break@@ -353,7 +353,7 @@ class HobTabBar(gtk.DrawingArea): self.grab_focus() if result == True: - page = self.children[self.current_child]["toggled_page"] + page = self.current_child["toggled_page"] self.emit("tab-switched", page) self.tab_pressed = True self.queue_draw()
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobTabBar(gtk.DrawingArea): · line 369
Quoted 5 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +1
-1@@ -366,7 +366,7 @@ class HobTabBar(gtk.DrawingArea): child["x"] = self.tab_x + i * self.tab_width child["y"] = self.tab_y - if self.blank_rectangle: + if self.blank_rectangle != None:
This seems redundant?
Quoted 97 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +24
-19self.resize_blank_rectangle() def resize_blank_rectangle(self):@@ -383,16 +383,16 @@ class HobTabBar(gtk.DrawingArea): pangolayout = self.create_pango_layout(child["title"]) pangolayout.set_font_description(self.font) child["title_layout"] = pangolayout - child[i]["r"] = color.red - child[i]["g"] = color.green - child[i]["b"] = color.blue + child["r"] = color.red + child["g"] = color.green + child["b"] = color.blue def append_tab_child(self, title, page): num = len(self.children) + 1 self.tab_width = self.tab_width * len(self.children) / num i = 0 - for child in self.children: + for i, child in enumerate(self.children): child["x"] = self.tab_x + i * self.tab_width i += 1@@ -414,6 +414,9 @@ class HobTabBar(gtk.DrawingArea): "indicator_number" : 0, } self.children.append(new_one) + # set the default current child + if not self.current_child: + self.current_child = new_one def on_draw(self, widget, event): cr = widget.window.cairo_create()@@ -425,11 +428,12 @@ class HobTabBar(gtk.DrawingArea): self.draw_background(cr) self.draw_toggled_tab(cr) - self.draw_tab_text(cr) - for i, child in enumerate(self.children): + for child in self.children: if child["indicator_show"] == True: - self.draw_indicator(cr, i) + self.draw_indicator(cr, child) + + self.draw_tab_text(cr) def draw_background(self, cr): style = self.get_style()@@ -476,14 +480,15 @@ class HobTabBar(gtk.DrawingArea): # center pos off_x = (self.tab_width - fontw) / 2 off_y = (self.tab_height - fonth) / 2 - x = child[i]["x"] + off_x - y = child[i]["y"] + off_y + x = child["x"] + off_x + y = child["y"] + off_y self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), pangolayout) def draw_toggled_tab(self, cr): - i = self.current_child - x = self.children[i]["x"] - y = self.children[i]["y"] + if not self.current_child: + return + x = self.current_child["x"] + y = self.current_child["y"] width = self.tab_width height = self.tab_height style = self.get_style()@@ -515,10 +520,10 @@ class HobTabBar(gtk.DrawingArea): cr.arc(x + r, y + r, r, math.pi, 1.5*math.pi) cr.fill() - def draw_indicator(self, cr, i): - tab_x = self.children[i]["x"] - tab_y = self.children[i]["y"] - number = self.children[i]["indicator_number"] + def draw_indicator(self, cr, child): + tab_x = child["x"] + tab_y = child["y"] + number = child["indicator_number"] dest_w = int(32 * self.tab_w_ratio) dest_h = int(32 * self.tab_h_ratio) if dest_h< self.tab_height:@@ -541,17 +546,17 @@ class HobTabBar(gtk.DrawingArea): cr.move_to(x, y) self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), layout) - def show_indicator_icon(self, i, number): - self.children[i]["indicator_show"] = True - self.children[i]["indicator_number"] = number + def show_indicator_icon(self, child, number): + child["indicator_show"] = True + child["indicator_number"] = number self.queue_draw()
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobTabBar(gtk.DrawingArea): · line 559
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +3
-3- def hide_indicator_icon(self, i): - self.children[i]["indicator_show"] = False + def hide_indicator_icon(self, child): + child["indicator_show"] = False self.queue_draw() def set_blank_size(self, x, y, w, h): - if not self.blank_rectangle or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w:
This change seems redundant.
Quoted 26 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +4
-4self.emit("blank-area-changed", x, y, w, h) return gtk.gdk.Rectangle(x, y, w, h)@@ -618,18 +623,18 @@ class HobNotebook(gtk.VBox): self.tb.show() def show_indicator_icon(self, title, number): - for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.show_indicator_icon(i, number) + self.tabbar.show_indicator_icon(child, number) def hide_indicator_icon(self, title): - for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.hide_indicator_icon(i) + self.tabbar.hide_indicator_icon(child) def tab_switched_cb(self, widget, page): self.notebook.set_current_page(page)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentreRe: [PATCH 08/12] Hob: change the range dance in hobwidget make it like a pythonista
-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Joshua Lock
Sent: Tuesday, March 20, 2012 7:58 AM
To: [email protected]
Subject: Re: [bitbake-devel] [PATCH 08/12] Hob: change the range dance in hobwidget make it like a pythonista
Quoted 3 lines · Shane Wang
From: Liming An<[email protected]>
To fix the for..in.. range dance code, and make it like pythonista, as the required.
This commit message doesn't match the patch contents.
Quoted 44 lines
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 67 +++++++++++++++++--------------- 1 files changed, 36 insertions(+), 31 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +4
-4@@ -309,7 +309,7 @@ class HobTabBar(gtk.DrawingArea): self.tab_h_ratio = 52 * 1.0/53 self.set_size_request(self.width, self.height) - self.current_child = 0 + self.current_child = None self.font = self.get_style().font_desc self.font.set_size(pango.SCALE * 13) self.update_children_text_layout_and_bg_color()@@ -339,10 +339,10 @@ class HobTabBar(gtk.DrawingArea): if self.is_focus() or event.type == gtk.gdk.BUTTON_PRESS: x, y = event.get_coords() # check which tab be clicked - for i, child in enumerate(self.children): + for child in self.children: if (child["x"]< x) and (x< child["x"] + self.tab_width) \ and (child["y"]< y) and (y< child["y"] + self.tab_height): - self.current_child = i + self.current_child = child result = True break@@ -353,7 +353,7 @@ class HobTabBar(gtk.DrawingArea): self.grab_focus() if result == True: - page = self.children[self.current_child]["toggled_page"] + page = self.current_child["toggled_page"] self.emit("tab-switched", page) self.tab_pressed = True self.queue_draw()
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobTabBar(gtk.DrawingArea): · line 369
Quoted 5 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +1
-1@@ -366,7 +366,7 @@ class HobTabBar(gtk.DrawingArea): child["x"] = self.tab_x + i * self.tab_width child["y"] = self.tab_y - if self.blank_rectangle: + if self.blank_rectangle != None:
This seems redundant?
Quoted 100 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +7
-4self.resize_blank_rectangle() def resize_blank_rectangle(self):@@ -383,16 +383,16 @@ class HobTabBar(gtk.DrawingArea): pangolayout = self.create_pango_layout(child["title"]) pangolayout.set_font_description(self.font) child["title_layout"] = pangolayout - child[i]["r"] = color.red - child[i]["g"] = color.green - child[i]["b"] = color.blue + child["r"] = color.red + child["g"] = color.green + child["b"] = color.blue def append_tab_child(self, title, page): num = len(self.children) + 1 self.tab_width = self.tab_width * len(self.children) / num i = 0 - for child in self.children: + for i, child in enumerate(self.children): child["x"] = self.tab_x + i * self.tab_width i += 1@@ -414,6 +414,9 @@ class HobTabBar(gtk.DrawingArea): "indicator_number" : 0, } self.children.append(new_one) + # set the default current child + if not self.current_child: + self.current_child = new_one def on_draw(self, widget, event): cr = widget.window.cairo_create() @@ -425,11 +428,12 @@class HobTabBar(gtk.DrawingArea):
self.draw_background(cr)
self.draw_toggled_tab(cr)bitbake/lib/bb/ui/crumbs/hobwidget.py +10
-8- self.draw_tab_text(cr) - for i, child in enumerate(self.children): + for child in self.children: if child["indicator_show"] == True: - self.draw_indicator(cr, i) + self.draw_indicator(cr, child) + + self.draw_tab_text(cr) def draw_background(self, cr): style = self.get_style()@@ -476,14 +480,15 @@ class HobTabBar(gtk.DrawingArea): # center pos off_x = (self.tab_width - fontw) / 2 off_y = (self.tab_height - fonth) / 2 - x = child[i]["x"] + off_x - y = child[i]["y"] + off_y + x = child["x"] + off_x + y = child["y"] + off_y self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), pangolayout) def draw_toggled_tab(self, cr): - i = self.current_child - x = self.children[i]["x"] - y = self.children[i]["y"] + if not self.current_child: + return + x = self.current_child["x"] + y = self.current_child["y"] width = self.tab_widthheight = self.tab_height
style =self.get_style()bitbake/lib/bb/ui/crumbs/hobwidget.py +7
-7@@ -515,10 +520,10 @@ class HobTabBar(gtk.DrawingArea): cr.arc(x + r, y + r, r, math.pi, 1.5*math.pi) cr.fill() - def draw_indicator(self, cr, i): - tab_x = self.children[i]["x"] - tab_y = self.children[i]["y"] - number = self.children[i]["indicator_number"] + def draw_indicator(self, cr, child): + tab_x = child["x"] + tab_y = child["y"] + number = child["indicator_number"] dest_w = int(32 * self.tab_w_ratio) dest_h = int(32 * self.tab_h_ratio) if dest_h< self.tab_height:@@ -541,17 +546,17 @@ class HobTabBar(gtk.DrawingArea): cr.move_to(x, y) self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), layout) - def show_indicator_icon(self, i, number): - self.children[i]["indicator_show"] = True - self.children[i]["indicator_number"] = number + def show_indicator_icon(self, child, number): + child["indicator_show"] = True + child["indicator_number"] = number self.queue_draw()
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobTabBar(gtk.DrawingArea): · line 560
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +3
-3- def hide_indicator_icon(self, i): - self.children[i]["indicator_show"] = False + def hide_indicator_icon(self, child): + child["indicator_show"] = False self.queue_draw() def set_blank_size(self, x, y, w, h): - if not self.blank_rectangle or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w:
This change seems redundant.
Quoted 16 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +0
-0self.emit("blank-area-changed", x, y, w, h)return gtk.gdk.Rectangle(x, y, w, h) @@ -618,18 +623,18 @@class HobNotebook(gtk.VBox):
self.tb.show()def
show_indicator_icon(self, title, number):bitbake/lib/bb/ui/crumbs/hobwidget.py +2
-2- for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.show_indicator_icon(i, number) + self.tabbar.show_indicator_icon(child, number) def hide_indicator_icon(self, title):
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobNotebook(gtk.VBox): · line 640
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +2
-2- for i, child in enumerate(self.tabbar.children): + for child in self.tabbar.children: if child["toggled_page"] == -1: continue if child["title"] == title: - self.tabbar.hide_indicator_icon(i) + self.tabbar.hide_indicator_icon(child) def tab_switched_cb(self, widget, page): self.notebook.set_current_page(page)
--
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology Centre
Hi Josh,
This commend is be fixed please to review in limx/hob2-v0.69, Thanks! --
Regards
Liming
_______________________________________________
bitbake-devel mailing list [email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/bitbake-devel
PATCH v3 9/12 Hob: fix static variable "self.search" to parameter "search" in signal callback function
In reply to Shane WangFrom: Liming An <[email protected]>
To fix the signal callback function code, and make the temp parameter to replaced the static global variable, as required.
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 31 ++++++++++++++----------------- 1 files changed, 14 insertions(+), 17 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +14 -17
@@ -658,20 +658,17 @@ class HobNotebook(gtk.VBox): def blank_area_resize_cb(self, widget, request_x, request_y, request_width, request_height): self.search.set_size_request(request_width, request_height) - widget.modify_bg(gtk.STATE_SELECTED, gtk.gdk.color_parse(HobColors.YELLOW)) - - def set_search_entry_editable_cb(self, widget, event): - if self.search: - self.search.set_editable(True) - self.search.set_text("") - style = self.search.get_style() - style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) - self.search.set_style(style) - - def set_search_entry_reset_cb(self, widget, event): - if self.search: - style = self.search.get_style() - style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) - self.search.set_style(style) - self.search.set_text(self.search_name) - self.search.set_editable(False) + + def set_search_entry_editable_cb(self, search, event): + search.set_editable(True) + search.set_text("") + style = self.search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) + search.set_style(style) + + def set_search_entry_reset_cb(self, search, event): + style = search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) + search.set_style(style) + search.set_text(self.search_name) + search.set_editable(False)
Signature · 1 line
1.7.6
Re: [PATCH 09/12] Hob: fix static variable "self.search" to parameter "search" in signal callback function
Quoted 6 lines · Shane Wang
From: Liming An<[email protected]>
To fix the signal callback function code, and make the temp parameter to replaced the static global variable, as required.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
Quoted 43 lines
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 31 ++++++++++++++----------------- 1 files changed, 14 insertions(+), 17 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +14
-17@@ -658,20 +658,17 @@ class HobNotebook(gtk.VBox): def blank_area_resize_cb(self, widget, request_x, request_y, request_width, request_height): self.search.set_size_request(request_width, request_height) - widget.modify_bg(gtk.STATE_SELECTED, gtk.gdk.color_parse(HobColors.YELLOW)) - - def set_search_entry_editable_cb(self, widget, event): - if self.search: - self.search.set_editable(True) - self.search.set_text("") - style = self.search.get_style() - style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) - self.search.set_style(style) - - def set_search_entry_reset_cb(self, widget, event): - if self.search: - style = self.search.get_style() - style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) - self.search.set_style(style) - self.search.set_text(self.search_name) - self.search.set_editable(False) + + def set_search_entry_editable_cb(self, search, event): + search.set_editable(True) + search.set_text("") + style = self.search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) + search.set_style(style) + + def set_search_entry_reset_cb(self, search, event): + style = search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) + search.set_style(style) + search.set_text(self.search_name) + search.set_editable(False)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 10/12 Hob: add auto adjust background area function for long issue text
In reply to Shane WangFrom: Liming An <[email protected]>
To add auto expand the background area function for long issue text input.
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +21 -9
@@ -521,26 +521,38 @@ class HobTabBar(gtk.DrawingArea): cr.fill() def draw_indicator(self, cr, child): + text = ("%d" % child["indicator_number"]) + layout = self.create_pango_layout(text) + layout.set_font_description(self.font) + textw, texth = layout.get_pixel_size() + # draw the back round area tab_x = child["x"] tab_y = child["y"] - number = child["indicator_number"] dest_w = int(32 * self.tab_w_ratio) dest_h = int(32 * self.tab_h_ratio) if dest_h < self.tab_height: dest_w = dest_h - # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x) x = tab_x + self.tab_width * 3/4 - dest_w/2 y = tab_y + self.tab_height/2 - dest_h/2 + r = min(dest_w, dest_h)/2 color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE)) - cr.arc(x + r, y + r, r, 0, 2*math.pi) - cr.fill() - - text = ("%d" % number) - layout = self.create_pango_layout(text) - layout.set_font_description(self.font) - textw, texth = layout.get_pixel_size() + # check round back area can contain the text or not + back_round_can_contain_width = float(2 * r * 0.707) + if float(textw) > back_round_can_contain_width: + xoff = (textw - int(back_round_can_contain_width)) / 2 + cr.move_to(x + r - xoff, y + r + r) + cr.arc((x + r - xoff), (y + r), r, 0.5*math.pi, 1.5*math.pi) + cr.fill() # left half round + cr.rectangle((x + r - xoff), y, 2 * xoff, 2 * r) + cr.fill() # center rectangle + cr.arc((x + r + xoff), (y + r), r, 1.5*math.pi, 0.5*math.pi) + cr.fill() # right half round + else: + cr.arc((x + r), (y + r), r, 0, 2*math.pi) + cr.fill() + # draw the number text x = x + (dest_w/2)-(textw/2) y = y + (dest_h/2) - (texth/2) cr.move_to(x, y)
Signature · 1 line
1.7.6
Re: [PATCH 10/12] Hob: add auto adjust background area function for long issue text
Quoted 6 lines · Shane Wang
From: Liming An<[email protected]>
To add auto expand the background area function for long issue text input.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
Quoted 56 lines
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +21
-9@@ -521,26 +521,38 @@ class HobTabBar(gtk.DrawingArea): cr.fill() def draw_indicator(self, cr, child): + text = ("%d" % child["indicator_number"]) + layout = self.create_pango_layout(text) + layout.set_font_description(self.font) + textw, texth = layout.get_pixel_size() + # draw the back round area tab_x = child["x"] tab_y = child["y"] - number = child["indicator_number"] dest_w = int(32 * self.tab_w_ratio) dest_h = int(32 * self.tab_h_ratio) if dest_h< self.tab_height: dest_w = dest_h - # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x) x = tab_x + self.tab_width * 3/4 - dest_w/2 y = tab_y + self.tab_height/2 - dest_h/2 + r = min(dest_w, dest_h)/2 color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE)) - cr.arc(x + r, y + r, r, 0, 2*math.pi) - cr.fill() - - text = ("%d" % number) - layout = self.create_pango_layout(text) - layout.set_font_description(self.font) - textw, texth = layout.get_pixel_size() + # check round back area can contain the text or not + back_round_can_contain_width = float(2 * r * 0.707) + if float(textw)> back_round_can_contain_width: + xoff = (textw - int(back_round_can_contain_width)) / 2 + cr.move_to(x + r - xoff, y + r + r) + cr.arc((x + r - xoff), (y + r), r, 0.5*math.pi, 1.5*math.pi) + cr.fill() # left half round + cr.rectangle((x + r - xoff), y, 2 * xoff, 2 * r) + cr.fill() # center rectangle + cr.arc((x + r + xoff), (y + r), r, 1.5*math.pi, 0.5*math.pi) + cr.fill() # right half round + else: + cr.arc((x + r), (y + r), r, 0, 2*math.pi) + cr.fill() + # draw the number text x = x + (dest_w/2)-(textw/2) y = y + (dest_h/2) - (texth/2) cr.move_to(x, y)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 11/12 Hob: change HobNoteBook tab edge color from green to gray
In reply to Shane WangFrom: Liming An <[email protected]>
To change the notebook tab pressed edge color from green to gray.
--- bitbake/lib/bb/ui/crumbs/hobcolor.py | 2 ++ bitbake/lib/bb/ui/crumbs/hobwidget.py | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/hobcolor.py +2 -0
@@ -25,6 +25,8 @@ class HobColors: PALE_RED = "#ffaaaa" GRAY = "#aaaaaa" LIGHT_GRAY = "#dddddd" + DEEP_GRAY = "#7c7c77" + SLIGHT_DARK = "#5f5f5f" DARK = "#3c3b37" BLACK = "#000000" LIGHT_ORANGE = "#f7a787"
bitbake/lib/bb/ui/crumbs/hobwidget.py +8 -5
@@ -496,16 +496,19 @@ class HobTabBar(gtk.DrawingArea): r = height / 10 if self.tab_pressed == True: - for xoff, yoff in [(1, 0), (2, 0)]: - cr.set_source_color(gtk.gdk.color_parse(HobColors.PALE_GREEN)) + for xoff, yoff, c1, c2 in [(1, 0, HobColors.SLIGHT_DARK, HobColors.DARK), (2, 0, HobColors.GRAY, HobColors.LIGHT_GRAY)]: + cr.set_source_color(gtk.gdk.color_parse(c1)) + cr.move_to(x + xoff, y + height + yoff) + cr.line_to(x + xoff, r + yoff) + cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi) cr.move_to(x + r + xoff, y + yoff) cr.line_to(x + width - r + xoff, y + yoff) - cr.arc(x + width - r+ xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi) + cr.arc(x + width - r + xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi) + cr.stroke() + cr.set_source_color(gtk.gdk.color_parse(c2)) cr.move_to(x + width + xoff, r + yoff) cr.line_to(x + width + xoff, y + height + yoff) cr.line_to(x + xoff, y + height + yoff) - cr.line_to(x + xoff, r + yoff) - cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi) cr.stroke() x = x + 2 y = y + 2
Signature · 1 line
1.7.6
Re: [PATCH 11/12] Hob: change HobNoteBook tab edge color from green to gray
Quoted 6 lines · Shane Wang
From: Liming An<[email protected]>
To change the notebook tab pressed edge color from green to gray.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
Quoted 47 lines
--- bitbake/lib/bb/ui/crumbs/hobcolor.py | 2 ++ bitbake/lib/bb/ui/crumbs/hobwidget.py | 13 ++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-)bitbake/lib/bb/ui/crumbs/hobcolor.py +2
-0@@ -25,6 +25,8 @@ class HobColors: PALE_RED = "#ffaaaa" GRAY = "#aaaaaa" LIGHT_GRAY = "#dddddd" + DEEP_GRAY = "#7c7c77" + SLIGHT_DARK = "#5f5f5f" DARK = "#3c3b37" BLACK = "#000000" LIGHT_ORANGE = "#f7a787"bitbake/lib/bb/ui/crumbs/hobwidget.py +8
-5@@ -496,16 +496,19 @@ class HobTabBar(gtk.DrawingArea): r = height / 10 if self.tab_pressed == True: - for xoff, yoff in [(1, 0), (2, 0)]: - cr.set_source_color(gtk.gdk.color_parse(HobColors.PALE_GREEN)) + for xoff, yoff, c1, c2 in [(1, 0, HobColors.SLIGHT_DARK, HobColors.DARK), (2, 0, HobColors.GRAY, HobColors.LIGHT_GRAY)]: + cr.set_source_color(gtk.gdk.color_parse(c1)) + cr.move_to(x + xoff, y + height + yoff) + cr.line_to(x + xoff, r + yoff) + cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi) cr.move_to(x + r + xoff, y + yoff) cr.line_to(x + width - r + xoff, y + yoff) - cr.arc(x + width - r+ xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi) + cr.arc(x + width - r + xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi) + cr.stroke() + cr.set_source_color(gtk.gdk.color_parse(c2)) cr.move_to(x + width + xoff, r + yoff) cr.line_to(x + width + xoff, y + height + yoff) cr.line_to(x + xoff, y + height + yoff) - cr.line_to(x + xoff, r + yoff) - cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi) cr.stroke() x = x + 2 y = y + 2
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentrePATCH v3 12/12 Hob: per UI design add refresh icon for building log
In reply to Shane WangFrom: Liming An <[email protected]>
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.
--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 193 ++++++++++++++++++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 +++- 2 files changed, 208 insertions(+), 5 deletions(-)
bitbake/lib/bb/ui/crumbs/hobwidget.py +193 -0
@@ -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')) 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()) + + '''set property for exactly cell + ''' + def do_set_property(self, pspec, value): + self.cell_attr[pspec.name] = value + if (pspec.name == "stock-size") and (value in [gtk.ICON_SIZE_BUTTON, gtk.ICON_SIZE_DND, \ + gtk.ICON_SIZE_DIALOG, gtk.ICON_SIZE_LARGE_TOOLBAR, \ + gtk.ICON_SIZE_MENU, gtk.ICON_SIZE_SMALL_TOOLBAR]): + self.cell_attr["stock-size"] = value + + def do_get_property(self, pspec): + return self.cell_attr[pspec.name] + + def reset(self): + pass + + def create_default_pixbuf(self): + try: + pixbuf = gtk.gdk.pixbuf_new_from_file( + hic.ICON_INDI_REFERENCE_FILE + ) + except Exception, e: + print e.message + self.reset() + return None + return pixbuf + + def set_pixbuf_to_stock_icon(self, pixbuf=None, stock_id="task-refresh"): + if pixbuf and stock_id and (gtk.icon_factory_lookup_default(stock_id) == None): + icon_factory = gtk.IconFactory() + icon_factory.add_default() + icon_factory.add('task-refresh',gtk.IconSet(pixbuf)) + gtk.stock_add([('task-refresh', '_label', 0, 0, '')]) + + return icon_factory.lookup(stock_id) + + return None + + def get_pixbuf_from_stock_icon(self, widget, stock_id="", size=gtk.ICON_SIZE_DIALOG): + if widget and stock_id and gtk.icon_factory_lookup_default(stock_id): + return widget.render_icon(stock_id, size) + + return None + + ''' render cell exactly, "icon-name" is priority + if use the 'task-refresh' will make the pix animation + if 'pix' will change the pixbuf for it from the pixbuf or image. + ''' + def on_render(self, window, tree, background_area,cell_area, expose_area, flags): + if (not self.control) or (not tree): + return + x, y, w, h = self.on_get_size(tree, cell_area) + x += cell_area.x + y += cell_area.y + w -= 2 * self.get_property("xpad") + h -= 2 * self.get_property("ypad") + + cairo_context = window.cairo_create() + + stock_id = self.cell_attr["icon-name"] + pix = self.get_pixbuf_from_stock_icon(tree, stock_id, self.cell_attr["stock-size"]) + if stock_id == 'task-refresh': + self.control.append_running_cell_area(cell_area) + if self.control.is_active(): + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, True) + else: + self.control.start_run(100, 0, 0, 1000, 80, tree) + else: + self.control.remove_running_cell_area(cell_area) + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, False) + + def on_get_size(self, widget, cell_area): + if self.cell_attr["icon-name"]: + w, h = gtk.icon_size_lookup(self.cell_attr["stock-size"]) + return 0, 0, w, h + + return 0, 0, 0, 0
bitbake/lib/bb/ui/crumbs/runningbuild.py +15 -5
@@ -1,4 +1,3 @@ - # # BitBake Graphical GTK User Interface #
@@ -27,6 +26,7 @@ import urllib import urllib2 import pango from bb.ui.crumbs.hobcolor import HobColors +from bb.ui.crumbs.hobwidget import HobCellRendererPixbuf class RunningBuildModel (gtk.TreeStore): (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_COLOR, COL_NUM_ACTIVE) = range(7)
@@ -67,6 +67,13 @@ class RunningBuildModel (gtk.TreeStore): model.set_visible_func(self.failure_model_filter) return model + def foreach_cell_func(self, model, path, iter, usr_data=None): + if model.get_value(iter, self.COL_ICON) == "task-refresh": + model.set(iter, self.COL_ICON, "") + + def close_task_refresh(self): + self.foreach(self.foreach_cell_func, None) + class RunningBuild (gobject.GObject): __gsignals__ = { 'build-started' : (gobject.SIGNAL_RUN_LAST,
@@ -188,7 +195,7 @@ class RunningBuild (gobject.GObject): # Because this parent package now has an active child mark it as # such. # @todo if parent is already in error, don't mark it green - self.model.set(parent, self.model.COL_ICON, "gtk-execute", + self.model.set(parent, self.model.COL_ICON, "task-refresh", self.model.COL_COLOR, HobColors.RUNNING) # Add an entry in the model for this task
@@ -196,7 +203,7 @@ class RunningBuild (gobject.GObject): package, task, "Task: %s" % (task), - "gtk-execute", + "task-refresh", HobColors.RUNNING, 0))
@@ -283,6 +290,8 @@ class RunningBuild (gobject.GObject): # Emit a generic "build-complete" signal for things wishing to # handle when the build is finished self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() if pbar: pbar.set_text(event.msg)
@@ -291,6 +300,8 @@ class RunningBuild (gobject.GObject): # If the command fails with an exit code we're done, emit the # generic signal for the UI to notify the user self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() elif isinstance(event, bb.event.CacheLoadStarted) and pbar: pbar.set_title("Loading cache")
@@ -344,7 +355,7 @@ class RunningBuildTreeView (gtk.TreeView): self.readonly = readonly # The icon that indicates whether we're building or failed. - renderer = gtk.CellRendererPixbuf () + renderer = HobCellRendererPixbuf () col = gtk.TreeViewColumn ("Status", renderer) col.add_attribute (renderer, "icon-name", 4) self.append_column (col)
@@ -426,7 +437,6 @@ class BuildConfigurationTreeView(gtk.TreeView): self.message_renderer.set_property('font-desc', font) self.append_column (self.message_column) - class BuildFailureTreeView(gtk.TreeView): def __init__ (self):
Signature · 1 line
1.7.6
Re: [PATCH 12/12] Hob: per UI design add refresh icon for building log
Quoted 132 lines · Shane Wang
From: Liming An<[email protected]>
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<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 193 ++++++++++++++++++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 +++- 2 files changed, 208 insertions(+), 5 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +106
-0@@ -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')) 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",
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobNotebook(gtk.VBox): · line 805
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10
-0+ "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?
Quoted 161 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +77
-0+ + '''set property for exactly cell + ''' + def do_set_property(self, pspec, value): + self.cell_attr[pspec.name] = value + if (pspec.name == "stock-size") and (value in [gtk.ICON_SIZE_BUTTON, gtk.ICON_SIZE_DND, \ + gtk.ICON_SIZE_DIALOG, gtk.ICON_SIZE_LARGE_TOOLBAR, \ + gtk.ICON_SIZE_MENU, gtk.ICON_SIZE_SMALL_TOOLBAR]): + self.cell_attr["stock-size"] = value + + def do_get_property(self, pspec): + return self.cell_attr[pspec.name] + + def reset(self): + pass + + def create_default_pixbuf(self): + try: + pixbuf = gtk.gdk.pixbuf_new_from_file( + hic.ICON_INDI_REFERENCE_FILE + ) + except Exception, e: + print e.message + self.reset() + return None + return pixbuf + + def set_pixbuf_to_stock_icon(self, pixbuf=None, stock_id="task-refresh"): + if pixbuf and stock_id and (gtk.icon_factory_lookup_default(stock_id) == None): + icon_factory = gtk.IconFactory() + icon_factory.add_default() + icon_factory.add('task-refresh',gtk.IconSet(pixbuf)) + gtk.stock_add([('task-refresh', '_label', 0, 0, '')]) + + return icon_factory.lookup(stock_id) + + return None + + def get_pixbuf_from_stock_icon(self, widget, stock_id="", size=gtk.ICON_SIZE_DIALOG): + if widget and stock_id and gtk.icon_factory_lookup_default(stock_id): + return widget.render_icon(stock_id, size) + + return None + + ''' render cell exactly, "icon-name" is priority + if use the 'task-refresh' will make the pix animation + if 'pix' will change the pixbuf for it from the pixbuf or image. + ''' + def on_render(self, window, tree, background_area,cell_area, expose_area, flags): + if (not self.control) or (not tree): + return + x, y, w, h = self.on_get_size(tree, cell_area) + x += cell_area.x + y += cell_area.y + w -= 2 * self.get_property("xpad") + h -= 2 * self.get_property("ypad") + + cairo_context = window.cairo_create() + + stock_id = self.cell_attr["icon-name"] + pix = self.get_pixbuf_from_stock_icon(tree, stock_id, self.cell_attr["stock-size"]) + if stock_id == 'task-refresh': + self.control.append_running_cell_area(cell_area) + if self.control.is_active(): + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, True) + else: + self.control.start_run(100, 0, 0, 1000, 80, tree) + else: + self.control.remove_running_cell_area(cell_area) + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, False) + + def on_get_size(self, widget, cell_area): + if self.cell_attr["icon-name"]: + w, h = gtk.icon_size_lookup(self.cell_attr["stock-size"]) + return 0, 0, w, h + + return 0, 0, 0, 0bitbake/lib/bb/ui/crumbs/runningbuild.py +15
-5@@ -1,4 +1,3 @@ - # # BitBake Graphical GTK User Interface #@@ -27,6 +26,7 @@ import urllib import urllib2 import pango from bb.ui.crumbs.hobcolor import HobColors +from bb.ui.crumbs.hobwidget import HobCellRendererPixbuf class RunningBuildModel (gtk.TreeStore): (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_COLOR, COL_NUM_ACTIVE) = range(7)@@ -67,6 +67,13 @@ class RunningBuildModel (gtk.TreeStore): model.set_visible_func(self.failure_model_filter) return model + def foreach_cell_func(self, model, path, iter, usr_data=None): + if model.get_value(iter, self.COL_ICON) == "task-refresh": + model.set(iter, self.COL_ICON, "") + + def close_task_refresh(self): + self.foreach(self.foreach_cell_func, None) + class RunningBuild (gobject.GObject): __gsignals__ = { 'build-started' : (gobject.SIGNAL_RUN_LAST,@@ -188,7 +195,7 @@ class RunningBuild (gobject.GObject): # Because this parent package now has an active child mark it as # such. # @todo if parent is already in error, don't mark it green - self.model.set(parent, self.model.COL_ICON, "gtk-execute", + self.model.set(parent, self.model.COL_ICON, "task-refresh", self.model.COL_COLOR, HobColors.RUNNING) # Add an entry in the model for this task@@ -196,7 +203,7 @@ class RunningBuild (gobject.GObject): package, task, "Task: %s" % (task), - "gtk-execute", + "task-refresh", HobColors.RUNNING, 0))@@ -283,6 +290,8 @@ class RunningBuild (gobject.GObject): # Emit a generic "build-complete" signal for things wishing to # handle when the build is finished self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() if pbar: pbar.set_text(event.msg)@@ -291,6 +300,8 @@ class RunningBuild (gobject.GObject): # If the command fails with an exit code we're done, emit the # generic signal for the UI to notify the user self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() elif isinstance(event, bb.event.CacheLoadStarted) and pbar: pbar.set_title("Loading cache")@@ -344,7 +355,7 @@ class RunningBuildTreeView (gtk.TreeView): self.readonly = readonly # The icon that indicates whether we're building or failed. - renderer = gtk.CellRendererPixbuf () + renderer = HobCellRendererPixbuf () col = gtk.TreeViewColumn ("Status", renderer) col.add_attribute (renderer, "icon-name", 4) self.append_column (col)@@ -426,7 +437,6 @@ class BuildConfigurationTreeView(gtk.TreeView): self.message_renderer.set_property('font-desc', font) self.append_column (self.message_column) - class BuildFailureTreeView(gtk.TreeView): def __init__ (self):
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentreRe: [PATCH 12/12] Hob: per UI design add refresh icon for building log
Quoted 135 lines · Shane Wang
From: Liming An<[email protected]>
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<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 193 ++++++++++++++++++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 +++- 2 files changed, 208 insertions(+), 5 deletions(-)bitbake/lib/bb/ui/crumbs/hobwidget.py +108
-0@@ -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')) 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",
bitbake/lib/bb/ui/crumbs/hobwidget.py class HobNotebook(gtk.VBox): · line 807
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10
-0+ "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?
Quoted 157 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +78
-0+ + '''set property for exactly cell + ''' + def do_set_property(self, pspec, value): + self.cell_attr[pspec.name] = value + if (pspec.name == "stock-size") and (value in [gtk.ICON_SIZE_BUTTON, gtk.ICON_SIZE_DND, \ + gtk.ICON_SIZE_DIALOG, gtk.ICON_SIZE_LARGE_TOOLBAR, \ + gtk.ICON_SIZE_MENU, gtk.ICON_SIZE_SMALL_TOOLBAR]): + self.cell_attr["stock-size"] = value + + def do_get_property(self, pspec): + return self.cell_attr[pspec.name] + + def reset(self): + pass + + def create_default_pixbuf(self): + try: + pixbuf = gtk.gdk.pixbuf_new_from_file( + hic.ICON_INDI_REFERENCE_FILE + ) + except Exception, e: + print e.message + self.reset() + return None + return pixbuf + + def set_pixbuf_to_stock_icon(self, pixbuf=None, stock_id="task-refresh"): + if pixbuf and stock_id and (gtk.icon_factory_lookup_default(stock_id) == None): + icon_factory = gtk.IconFactory() + icon_factory.add_default() + icon_factory.add('task-refresh',gtk.IconSet(pixbuf)) + gtk.stock_add([('task-refresh', '_label', 0, 0, '')]) + + return icon_factory.lookup(stock_id) + + return None + + def get_pixbuf_from_stock_icon(self, widget, stock_id="", size=gtk.ICON_SIZE_DIALOG): + if widget and stock_id and gtk.icon_factory_lookup_default(stock_id): + return widget.render_icon(stock_id, size) + + return None + + ''' render cell exactly, "icon-name" is priority + if use the 'task-refresh' will make the pix animation + if 'pix' will change the pixbuf for it from the pixbuf or image. + ''' + def on_render(self, window, tree, background_area,cell_area, expose_area, flags): + if (not self.control) or (not tree): + return + x, y, w, h = self.on_get_size(tree, cell_area) + x += cell_area.x + y += cell_area.y + w -= 2 * self.get_property("xpad") + h -= 2 * self.get_property("ypad") + + cairo_context = window.cairo_create() + + stock_id = self.cell_attr["icon-name"] + pix = self.get_pixbuf_from_stock_icon(tree, stock_id, self.cell_attr["stock-size"]) + if stock_id == 'task-refresh': + self.control.append_running_cell_area(cell_area) + if self.control.is_active(): + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, True) + else: + self.control.start_run(100, 0, 0, 1000, 80, tree) + else: + self.control.remove_running_cell_area(cell_area) + self.control.on_draw_cb(pix, cairo_context, x, y, w, h, + False) + + def on_get_size(self, widget, cell_area): + if self.cell_attr["icon-name"]: + w, h = gtk.icon_size_lookup(self.cell_attr["stock-size"]) + return 0, 0, w, h + + return 0, 0, 0, 0bitbake/lib/bb/ui/crumbs/runningbuild.py +1
-1@@ -1,4 +1,3 @@ - # # BitBake Graphical GTK User Interface #@@ -27,6 +26,7 @@ import urllib import urllib2 import pango from bb.ui.crumbs.hobcolor import HobColors +from bb.ui.crumbs.hobwidget import HobCellRendererPixbuf class RunningBuildModel (gtk.TreeStore): (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON,
COL_COLOR,COL_NUM_ACTIVE) = range(7) @@ -67,6 +67,13 @@ class RunningBuildModel (gtk.TreeStore):
model.set_visible_func(self.failure_model_filter)
return modelbitbake/lib/bb/ui/crumbs/runningbuild.py +16
-2+ def foreach_cell_func(self, model, path, iter, usr_data=None): + if model.get_value(iter, self.COL_ICON) == "task-refresh": + model.set(iter, self.COL_ICON, "") + + def close_task_refresh(self): + self.foreach(self.foreach_cell_func, None) + class RunningBuild (gobject.GObject): __gsignals__ = { 'build-started' : (gobject.SIGNAL_RUN_LAST, @@ -188,7 +195,7 @@ class RunningBuild (gobject.GObject): # Because this parent package now has an active child mark it as # such. # @todo if parent is already in error, don't mark it green - self.model.set(parent, self.model.COL_ICON, "gtk-execute", + self.model.set(parent, self.model.COL_ICON, + "task-refresh", self.model.COL_COLOR, HobColors.RUNNING) # Add an entry in the model for this task @@ -196,7 +203,7 @@ class RunningBuild (gobject.GObject): package, task, "Task: %s" % (task), - "gtk-execute", + "task-refresh", HobColors.RUNNING, 0))@@ -283,6 +290,8 @@ class RunningBuild (gobject.GObject): # Emit a generic "build-complete" signal for things wishing to # handle when the build is finished self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() if pbar: pbar.set_text(event.msg)@@ -291,6 +300,8 @@ class RunningBuild (gobject.GObject): # If the command fails with an exit code we're done, emit the # generic signal for the UI to notify the user self.emit("build-complete") + # reset the all cell's icon indicator + self.model.close_task_refresh() elif isinstance(event, bb.event.CacheLoadStarted) and pbar: pbar.set_title("Loading cache") @@ -344,7 +355,7 @@class RunningBuildTreeView (gtk.TreeView):
self.readonly = readonly# The icon that indicates whether we're building or failed.
bitbake/lib/bb/ui/crumbs/runningbuild.py +1
-1- renderer = gtk.CellRendererPixbuf () + renderer = HobCellRendererPixbuf () col = gtk.TreeViewColumn ("Status", renderer) col.add_attribute (renderer, "icon-name", 4) self.append_column (col)
bitbake/lib/bb/ui/crumbs/runningbuild.py class BuildConfigurationTreeView(gtk.TreeView): · line 442
Quoted 7 lines
bitbake/lib/bb/ui/crumbs/runningbuild.py +0
-1@@ -426,7 +437,6 @@ class BuildConfigurationTreeView(gtk.TreeView): self.message_renderer.set_property('font-desc', font) self.append_column (self.message_column) - class BuildFailureTreeView(gtk.TreeView): def __init__ (self):
--
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology Centre
Hi Josh,
Sorry, the refresh icon is animation icon, it's not static pixbuf icon.
we added it as previous 'hob 1.2 ui design', that has an refresh icon request, not my willing, if UI design team agree to delete it, we no problem. I agree with you that it will add some burden of build performance, and we had realized that and do some steps to reduce effect of building when add it and do corresponding test
1) use the one timer, and start or reset with refresh icon need or not, and can adjust the timer interval count to reduce the render times
2) use one list to recorder the performed refresh cells, and only render this cells, other cell will be rendered by needed
3)do some test to confirm how often and which case about the gtk core to call the 'on render', and fixed the code to avoid to no means call action.
Regards
Liming
_______________________________________________
bitbake-devel mailing list
[email protected]
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/bitbake-devel
Re: [PATCH 12/12] Hob: per UI design add refresh icon for building log
Quoted 13 lines · LimingX L
Quoted 11 lines · Shane Wang
From: Liming An<[email protected]>
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<[email protected]>Signed-off-by Shane Wang<[email protected]>--- bitbake/lib/bb/ui/crumbs/hobwidget.py | 193 ++++++++++++++++++++++++++++++ bitbake/lib/bb/ui/crumbs/runningbuild.py | 20 +++- 2 files changed, 208 insertions(+), 5 deletions(-)
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py class hic: · line 56
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +1
-0@@ -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 ?
Quoted 148 lines
Quoted 114 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +107
-0class 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",bitbake/lib/bb/ui/crumbs/hobwidget.py class HobNotebook(gtk.VBox): · line 807
Quoted 10 lines
bitbake/lib/bb/ui/crumbs/hobwidget.py +10
-0+ "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=3926d93f1fd04b476d5810d347d38e0dfc247c3dclass 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,
Quoted 7 lines
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
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology CentreRe: [PATCH 01/12] Hob: implement a self-defined notebook visual component for Hob
In reply to Shane WangQuoted 8 lines · Shane Wang
In recipe selection page, package selection page, and build details page, etc, there is a notebook component which is not gtk.Notebook in the design video. We implement the visual component with a drawing area, and use it to replace the old notebook in recipe selection page and package selection page. The reasons why we do it are:
1) General speaking, gtk.Notebook doesn't look like the designer worked out. (see https://wiki.yoctoproject.org/wiki/File:Hob1.2-screencast2.mov)
2) And the designer version looks better, for example, there is an indicator to show how many recipes or packages are included, and how many issues happened when building? Very straightforward. But technically, gtk.Notebook can't implement that, as far as we know.
3) Moreover, there is an entry for "search recipes", and "search packages". How to make it horizontal to the tabs is a problem to us.
Quoted 4 lines
Regarding those, we give up gtk.Notebook and use our own.
Signed-off-by Liming An<[email protected]>Signed-off-by Shane Wang<[email protected]>
This implementation still has the problem of the search entry retaining focus when the user has clicked off it.
Other than that, so far as I can tell, most of my former suggestions have been addressed - I'd be fine with merging this as is and fixing focus in a follow on patch. If we take this approach, however, please file a bug to track that issue.
I'd also like to see a clear button added to the search entry, as is the norm in Gtk+ based applications.
Thanks,
Joshua
Quoted 607 lines
--- bitbake/lib/bb/ui/crumbs/hobcolor.py | 1 + bitbake/lib/bb/ui/crumbs/hobwidget.py | 468 ++++++++++++++++++---- bitbake/lib/bb/ui/crumbs/packageselectionpage.py | 17 +- bitbake/lib/bb/ui/crumbs/recipeselectionpage.py | 19 +- 4 files changed, 394 insertions(+), 111 deletions(-)bitbake/lib/bb/ui/crumbs/hobcolor.py +1
-0@@ -28,6 +28,7 @@ class HobColors: DARK = "#3c3b37" BLACK = "#000000" LIGHT_ORANGE = "#f7a787" + YELLOW = "#ffff00" OK = WHITE RUNNING = PALE_GREENbitbake/lib/bb/ui/crumbs/hobwidget.py +383
-85@@ -17,11 +17,14 @@ # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - import gtk import gobject import os import os.path +import sys +import pango, pangocairo +import math + from bb.ui.crumbs.hobcolor import HobColors from bb.ui.crumbs.persistenttooltip import PersistentTooltip@@ -168,90 +171,6 @@ class HobViewTable (gtk.VBox): if not view_column.get_title() in self.toggle_columns: self.emit("row-activated", tree.get_model(), path) -class HobViewBar (gtk.EventBox): - """ - A EventBox with the specified gray background color is associated with a notebook. - And the toolbar to simulate the tabs. - """ - - def __init__(self, notebook): - if not notebook: - return - self.notebook = notebook - - # setup an event box - gtk.EventBox.__init__(self) - self.set_border_width(2) - style = self.get_style().copy() - style.bg[gtk.STATE_NORMAL] = self.get_colormap().alloc_color (HobColors.GRAY, False, False) - self.set_style(style) - - hbox = gtk.HBox() - self.add(hbox) - - # setup a tool bar in the event box - self.toolbar = gtk.Toolbar() - self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL) - self.toolbar.set_style(gtk.TOOLBAR_TEXT) - self.toolbar.set_border_width(5) - - self.toolbuttons = [] - for index in range(self.notebook.get_n_pages()): - child = self.notebook.get_nth_page(index) - label = self.notebook.get_tab_label_text(child) - tip_text = 'switch to ' + label + ' page' - toolbutton = self.toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None, - label, tip_text, "Private text", None, - self.toolbutton_cb, index) - toolbutton.set_size_request(200, 100) - self.toolbuttons.append(toolbutton) - - # set the default current page - self.modify_toolbuttons_bg(0) - self.notebook.set_current_page(0) - - self.toolbar.append_space() - - # add the tool bar into the event box - hbox.pack_start(self.toolbar, expand=False, fill=False) - - self.search = gtk.Entry() - self.align = gtk.Alignment(xalign=0.5, yalign=0.5) - self.align.add(self.search) - hbox.pack_end(self.align, expand=False, fill=False) - - self.label = gtk.Label(" Search: ") - self.label.set_alignment(0.5, 0.5) - hbox.pack_end(self.label, expand=False, fill=False) - - def toolbutton_cb(self, widget, index): - if index>= self.notebook.get_n_pages(): - return - self.notebook.set_current_page(index) - self.modify_toolbuttons_bg(index) - - def modify_toolbuttons_bg(self, index): - if index>= len(self.toolbuttons): - return - for i in range(0, len(self.toolbuttons)): - toolbutton = self.toolbuttons[i] - if i == index: - self.modify_toolbutton_bg(toolbutton, True) - else: - self.modify_toolbutton_bg(toolbutton) - - def modify_toolbutton_bg(self, toolbutton, active=False): - if active: - toolbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.WHITE)) - toolbutton.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(HobColors.WHITE)) - toolbutton.modify_bg(gtk.STATE_SELECTED, gtk.gdk.Color(HobColors.WHITE)) - toolbutton.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(HobColors.WHITE)) - else: - toolbutton.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(HobColors.GRAY)) - toolbutton.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color(HobColors.GRAY)) - toolbutton.modify_bg(gtk.STATE_SELECTED, gtk.gdk.Color(HobColors.GRAY)) - toolbutton.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color(HobColors.GRAY)) - class HobXpmLabelButtonBox(gtk.EventBox): """ label: name of buttonbox description: the simple description@@ -360,3 +279,382 @@ class HobInfoButton(gtk.EventBox): """ def mouse_out_cb(self, widget, event): self.image.set_from_file(hic.ICON_INFO_DISPLAY_FILE) + +class HobTabBar(gtk.DrawingArea): + __gsignals__ = { + "blank-area-changed" : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_INT, + gobject.TYPE_INT, + gobject.TYPE_INT, + gobject.TYPE_INT,)), + + "tab-switched" : (gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_INT,)), + } + + def __init__(self): + gtk.DrawingArea.__init__(self) + self.children = [] + + self.tab_width = 140 + self.tab_height = 52 + self.tab_x = 10 + self.tab_y = 0 + + self.width = 500 + self.height = 53 + self.tab_w_ratio = 140 * 1.0/500 + self.tab_h_ratio = 52 * 1.0/53 + self.set_size_request(self.width, self.height) + + self.current_child = 0 + self.font = self.get_style().font_desc + self.font.set_size(pango.SCALE * 13) + self.update_children_text_layout_and_bg_color() + + self.blank_rectangle = None + self.tab_pressed = False + + self.set_property('can-focus', True) + self.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.POINTER_MOTION_MASK | + gtk.gdk.BUTTON1_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | + gtk.gdk.BUTTON_RELEASE_MASK) + + self.connect("expose-event", self.on_draw) + self.connect("button-press-event", self.button_pressed_cb) + self.connect("button-release-event", self.button_released_cb) + self.show_all() + + def button_released_cb(self, widget, event): + self.tab_pressed = False + self.queue_draw() + + def button_pressed_cb(self, widget, event): + if event.type == gtk.gdk._2BUTTON_PRESS: + return + + result = False + if self.is_focus() or event.type == gtk.gdk.BUTTON_PRESS: + x, y = event.get_coords() + # check which tab be clicked + for i, child in enumerate(self.children): + if (child["x"]< x) and (x< child["x"] + self.tab_width) \ + and (child["y"]< y) and (y< child["y"] + self.tab_height): + self.current_child = i + result = True + break + + # check the blank area is focus in or not + if (self.blank_rectangle) and (self.blank_rectangle.x> 0) and (self.blank_rectangle.y> 0): + if (self.blank_rectangle.x< x) and (x< self.blank_rectangle.x + self.blank_rectangle.width) \ + and (self.blank_rectangle.y< y) and (y< self.blank_rectangle.y + self.blank_rectangle.height): + self.grab_focus() + + if result == True: + page = self.children[self.current_child]["toggled_page"] + self.emit("tab-switched", page) + self.tab_pressed = True + self.queue_draw() + + def update_children_size(self): + # calculate the size of tabs + self.tab_width = int(self.width * self.tab_w_ratio) + self.tab_height = int(self.height * self.tab_h_ratio) + for i, child in enumerate(self.children): + child["x"] = self.tab_x + i * self.tab_width + child["y"] = self.tab_y + + if self.blank_rectangle != None: + self.resize_blank_rectangle() + + def resize_blank_rectangle(self): + width = self.width - self.tab_width * len(self.children) - self.tab_x + x = self.tab_x + self.tab_width * len(self.children) + hpadding = vpadding = 5 + self.blank_rectangle = self.set_blank_size(x + hpadding, self.tab_y + vpadding, + width - 2 * hpadding, self.tab_height - 2 * vpadding) + + def update_children_text_layout_and_bg_color(self): + style = self.get_style().copy() + color = style.base[gtk.STATE_NORMAL] + for child in self.children: + pangolayout = self.create_pango_layout(child["title"]) + pangolayout.set_font_description(self.font) + child["title_layout"] = pangolayout + child[i]["r"] = color.red + child[i]["g"] = color.green + child[i]["b"] = color.blue + + def append_tab_child(self, title, page): + num = len(self.children) + 1 + self.tab_width = self.tab_width * len(self.children) / num + + i = 0 + for child in self.children: + child["x"] = self.tab_x + i * self.tab_width + i += 1 + + x = self.tab_x + i * self.tab_width + y = self.tab_y + pangolayout = self.create_pango_layout(title) + pangolayout.set_font_description(self.font) + color = self.style.base[gtk.STATE_NORMAL] + new_one = { + "x" : x, + "y" : y, + "r" : color.red, + "g" : color.green, + "b" : color.blue, + "title_layout" : pangolayout, + "toggled_page" : page, + "title" : title, + "indicator_show" : False, + "indicator_number" : 0, + } + self.children.append(new_one) + + def on_draw(self, widget, event): + cr = widget.window.cairo_create() + + self.width = self.allocation.width + self.height = self.allocation.height + + self.update_children_size() + + self.draw_background(cr) + self.draw_toggled_tab(cr) + self.draw_tab_text(cr) + + for i, child in enumerate(self.children): + if child["indicator_show"] == True: + self.draw_indicator(cr, i) + + def draw_background(self, cr): + style = self.get_style() + + if self.is_focus(): + cr.set_source_color(style.base[gtk.STATE_SELECTED]) + else: + cr.set_source_color(style.base[gtk.STATE_NORMAL]) + + y = 6 + h = self.height - 6 - 1 + gap = 1 + + w = self.children[0]["x"] + cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY)) + cr.rectangle(0, y, w - gap, h) # start rectangle + cr.fill() + + cr.set_source_color(style.base[gtk.STATE_NORMAL]) + cr.rectangle(w - gap, y, w, h) #first gap + cr.fill() + + w = self.tab_width + for child in self.children: + x = child["x"] + cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY)) + cr.rectangle(x, y, w - gap, h) # tab rectangle + cr.fill() + cr.set_source_color(style.base[gtk.STATE_NORMAL]) + cr.rectangle(x + w - gap, y, w, h) # gap + cr.fill() + + cr.set_source_color(gtk.gdk.color_parse(HobColors.GRAY)) + cr.rectangle(x + w, y, self.width - x - w, h) # last rectangle + cr.fill() + + def draw_tab_text(self, cr): + style = self.get_style() + + for child in self.children: + pangolayout = child["title_layout"] + if pangolayout: + fontw, fonth = pangolayout.get_pixel_size() + # center pos + off_x = (self.tab_width - fontw) / 2 + off_y = (self.tab_height - fonth) / 2 + x = child[i]["x"] + off_x + y = child[i]["y"] + off_y + self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), pangolayout) + + def draw_toggled_tab(self, cr): + i = self.current_child + x = self.children[i]["x"] + y = self.children[i]["y"] + width = self.tab_width + height = self.tab_height + style = self.get_style() + color = style.base[gtk.STATE_NORMAL] + + r = height / 10 + if self.tab_pressed == True: + for xoff, yoff in [(1, 0), (2, 0)]: + cr.set_source_color(gtk.gdk.color_parse(HobColors.PALE_GREEN)) + cr.move_to(x + r + xoff, y + yoff) + cr.line_to(x + width - r + xoff, y + yoff) + cr.arc(x + width - r+ xoff, y + r + yoff, r, 1.5*math.pi, 2*math.pi) + cr.move_to(x + width + xoff, r + yoff) + cr.line_to(x + width + xoff, y + height + yoff) + cr.line_to(x + xoff, y + height + yoff) + cr.line_to(x + xoff, r + yoff) + cr.arc(x + r + xoff, y + r + yoff, r, math.pi, 1.5*math.pi) + cr.stroke() + x = x + 2 + y = y + 2 + cr.set_source_rgba(color.red, color.green, color.blue, 1) + cr.move_to(x + r, y) + cr.line_to(x + width - r , y) + cr.arc(x + width - r, y + r, r, 1.5*math.pi, 2*math.pi) + cr.move_to(x + width, r) + cr.line_to(x + width, y + height) + cr.line_to(x, y + height) + cr.line_to(x, r) + cr.arc(x + r, y + r, r, math.pi, 1.5*math.pi) + cr.fill() + + def draw_indicator(self, cr, i): + style = self.get_style() + tab_x = self.children[i]["x"] + tab_y = self.children[i]["y"] + number = self.children[i]["indicator_number"] + dest_w = int(32 * self.tab_w_ratio) + dest_h = int(32 * self.tab_h_ratio) + if dest_h< self.tab_height: + dest_w = dest_h + + # x position is offset(tab_width*3/4 - icon_width/2) + start_pos(tab_x) + x = tab_x + self.tab_width * 3/4 - dest_w/2 + y = tab_y + self.tab_height/2 - dest_h/2 + cr.move_to(tab_x, tab_y) + r = min(dest_w, dest_h)/2 + color = cr.set_source_color(gtk.gdk.color_parse(HobColors.ORANGE)) + cr.arc(x + r, y + r, r, 0, 2*math.pi) + cr.fill() + + text = ("%d" % number) + layout = self.create_pango_layout(text) + layout.set_font_description(self.font) + textw, texth = layout.get_pixel_size() + x = x + (dest_w/2)-(textw/2) + y = y + (dest_h/2) - (texth/2) + cr.move_to(x, y) + self.window.draw_layout(self.style.fg_gc[gtk.STATE_NORMAL], int(x), int(y), layout) + + def show_indicator_icon(self, i, number): + self.children[i]["indicator_show"] = True + self.children[i]["indicator_number"] = number + self.queue_draw() + + def hide_indicator_icon(self, i): + self.children[i]["indicator_show"] = False + self.queue_draw() + + def set_blank_size(self, x, y, w, h): + if self.blank_rectangle == None or self.blank_rectangle.x != x or self.blank_rectangle.width != w: + self.emit("blank-area-changed", x, y, w, h) + + return gtk.gdk.Rectangle(x, y, w, h) + +class HobNotebook(gtk.VBox): + + def __init__(self): + gtk.VBox.__init__(self, False, 0) + + self.notebook = gtk.Notebook() + self.notebook.set_property('homogeneous', True) + self.notebook.set_property('show-tabs', False) + + self.tabbar = HobTabBar() + self.tabbar.connect("tab-switched", self.tab_switched_cb) + self.notebook.connect("page-added", self.page_added_cb) + self.notebook.connect("page-removed", self.page_removed_cb) + + self.search = None + self.search_name = "" + + self.tb = gtk.Table(1, 100, False) + self.hbox= gtk.HBox(False, 0) + self.hbox.pack_start(self.tabbar, True, True) + self.tb.attach(self.hbox, 0, 100, 0, 1) + + self.pack_start(self.tb, False, False) + self.pack_start(self.notebook) + + self.show_all() + + def append_page(self, child, tab_label): + self.notebook.set_current_page(self.notebook.append_page(child, tab_label)) + + def set_entry(self, name="Search:"): + for child in self.tb.get_children(): + if child: + self.tb.remove(child) + + hbox_entry = gtk.HBox(False, 0) + hbox_entry.show() + + self.search = gtk.Entry() + self.search_name = name + style = self.search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) + self.search.set_style(style) + self.search.set_text(name) + self.search.set_editable(False) + self.search.show() + self.align = gtk.Alignment(xalign=1.0, yalign=0.7) + self.align.add(self.search) + self.align.show() + hbox_entry.pack_end(self.align, False, False) + self.tabbar.resize_blank_rectangle() + + self.tb.attach(hbox_entry, 75, 100, 0, 1, xpadding=5) + self.tb.attach(self.hbox, 0, 100, 0, 1) + + self.tabbar.connect("blank-area-changed", self.blank_area_resize_cb) + self.search.connect("focus-in-event", self.set_search_entry_editable_cb) + self.search.connect("focus-out-event", self.set_search_entry_reset_cb) + + self.tb.show() + + def tab_switched_cb(self, widget, page): + self.notebook.set_current_page(page) + + def page_added_cb(self, notebook, notebook_child, page): + if not notebook: + return + title = notebook.get_tab_label_text(notebook_child) + if title == None: + return + for child in self.tabbar.children: + if child["title"] == title: + child["toggled_page"] = page + return + self.tabbar.append_tab_child(title, page) + + def page_removed_cb(self, notebook, notebook_child, page, title=""): + for child in self.tabbar.children: + if child["title"] == title: + child["toggled_page"] = -1 + + def blank_area_resize_cb(self, widget, request_x, request_y, request_width, request_height): + self.search.set_size_request(request_width, request_height) + widget.modify_bg(gtk.STATE_SELECTED, gtk.gdk.color_parse(HobColors.YELLOW)) + + def set_search_entry_editable_cb(self, widget, event): + if self.search: + self.search.set_editable(True) + self.search.set_text("") + style = self.search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False) + self.search.set_style(style) + + def set_search_entry_reset_cb(self, widget, event): + if self.search: + style = self.search.get_style() + style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False) + self.search.set_style(style) + self.search.set_text(self.search_name) + self.search.set_editable(False)bitbake/lib/bb/ui/crumbs/packageselectionpage.py +5
-12@@ -23,7 +23,7 @@ import gtk import glib from bb.ui.crumbs.hobcolor import HobColors -from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable +from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook from bb.ui.crumbs.hoblistmodel import PackageListModel from bb.ui.crumbs.hobpages import HobPage@@ -102,11 +102,7 @@ class PackageSelectionPage (HobPage): self.pack_start(self.group_align, expand=True, fill=True) # set visiable members - self.grid = gtk.Table(10, 1, True) - self.grid.set_col_spacings(3) - - self.ins = gtk.Notebook() - self.ins.set_show_tabs(False) + self.ins = HobNotebook() self.tables = [] # we need to modify table when the dialog is shown # append the tab for i in range(len(self.pages)):@@ -122,16 +118,13 @@ class PackageSelectionPage (HobPage): self.ins.append_page(tab, label) self.tables.append(tab) - self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1) - # a black bar associated with the notebook - self.topbar = HobViewBar(self.ins) - self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 1, 1) + self.ins.set_entry("Search packages:") # set the search entry for each table for tab in self.tables: - tab.set_search_entry(0, self.topbar.search) + tab.set_search_entry(0, self.ins.search) # add all into the dialog - self.box_group_area.add(self.grid) + self.box_group_area.pack_start(self.ins, expand=True, fill=True) button_box = gtk.HBox(False, 6) self.box_group_area.pack_start(button_box, expand=False, fill=False)bitbake/lib/bb/ui/crumbs/recipeselectionpage.py +5
-14@@ -23,7 +23,7 @@ import gtk import glib from bb.ui.crumbs.hobcolor import HobColors -from bb.ui.crumbs.hobwidget import HobViewBar, HobViewTable +from bb.ui.crumbs.hobwidget import HobViewTable, HobNotebook from bb.ui.crumbs.hoblistmodel import RecipeListModel from bb.ui.crumbs.hobpages import HobPage@@ -124,13 +124,7 @@ class RecipeSelectionPage (HobPage): self.pack_start(self.group_align, expand=True, fill=True) # set visiable members - self.grid = gtk.Table(10, 1, True) - self.grid.set_col_spacings(3) - - # draw the left part of the window - # a notebook - self.ins = gtk.Notebook() - self.ins.set_show_tabs(False) + self.ins = HobNotebook() self.tables = [] # we need modify table when the dialog is shown # append the tabs in order for i in range(len(self.pages)):@@ -146,16 +140,13 @@ class RecipeSelectionPage (HobPage): self.ins.append_page(tab, label) self.tables.append(tab) - self.grid.attach(self.ins, 0, 1, 1, 10, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) - # a black bar associated with the notebook - self.topbar = HobViewBar(self.ins) - self.grid.attach(self.topbar, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) + self.ins.set_entry("Search recipes:") # set the search entry for each table for tab in self.tables: - tab.set_search_entry(0, self.topbar.search) + tab.set_search_entry(0, self.ins.search) # add all into the window - self.box_group_area.add(self.grid) + self.box_group_area.pack_start(self.ins, expand=True, fill=True) button_box = gtk.HBox(False, 6) self.box_group_area.pack_end(button_box, expand=False, fill=False)
Signature · 3 lines
Joshua '贾詡' Lock
Yocto Project "Johannes factotum"
Intel Open Source Technology Centre