summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-28 00:24:50 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-28 00:24:50 +0000
commit450028dd67e33563e5ccd2057e8412d5e341def3 (patch)
treec8529240dad16b1350aef26f48b3a28fef9df854 /chrome
parenta3ab1726197c051d92a1d1ee26abf2140c3c3607 (diff)
downloadchromium_src-450028dd67e33563e5ccd2057e8412d5e341def3.zip
chromium_src-450028dd67e33563e5ccd2057e8412d5e341def3.tar.gz
chromium_src-450028dd67e33563e5ccd2057e8412d5e341def3.tar.bz2
[GTK] implement minimal first run bubble.
This is the type of bubble now used in organic installs, i.e. all Linux installs. BUG=49705 TEST=run with --first-run Review URL: http://codereview.chromium.org/3203013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57755 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser.cc6
-rw-r--r--chrome/browser/first_run/first_run.h6
-rw-r--r--chrome/browser/gtk/first_run_bubble.cc141
-rw-r--r--chrome/browser/gtk/first_run_bubble.h14
-rw-r--r--chrome/browser/views/first_run_bubble.cc6
5 files changed, 113 insertions, 60 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index dad49e7..53f367c 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -380,15 +380,15 @@ void Browser::CreateBrowserWindow() {
return;
if (local_state->FindPreference(prefs::kShouldShowFirstRunBubble) &&
local_state->GetBoolean(prefs::kShouldShowFirstRunBubble)) {
- FirstRun::BubbleType bubble_type = FirstRun::LARGEBUBBLE;
+ FirstRun::BubbleType bubble_type = FirstRun::LARGE_BUBBLE;
if (local_state->
FindPreference(prefs::kShouldUseOEMFirstRunBubble) &&
local_state->GetBoolean(prefs::kShouldUseOEMFirstRunBubble)) {
- bubble_type = FirstRun::OEMBUBBLE;
+ bubble_type = FirstRun::OEM_BUBBLE;
} else if (local_state->
FindPreference(prefs::kShouldUseMinimalFirstRunBubble) &&
local_state->GetBoolean(prefs::kShouldUseMinimalFirstRunBubble)) {
- bubble_type = FirstRun::MINIMALBUBBLE;
+ bubble_type = FirstRun::MINIMAL_BUBBLE;
}
// Reset the preference so we don't show the bubble for subsequent windows.
local_state->ClearPref(prefs::kShouldShowFirstRunBubble);
diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h
index d4dcf5e..15c5866 100644
--- a/chrome/browser/first_run/first_run.h
+++ b/chrome/browser/first_run/first_run.h
@@ -33,9 +33,9 @@ class FirstRun {
public:
// There are three types of possible first run bubbles:
typedef enum {
- LARGEBUBBLE = 0, // The normal bubble, with search engine choice
- OEMBUBBLE, // Smaller bubble for OEM builds
- MINIMALBUBBLE // Minimal bubble shown after search engine dialog
+ LARGE_BUBBLE, // The normal bubble, with search engine choice
+ OEM_BUBBLE, // Smaller bubble for OEM builds
+ MINIMAL_BUBBLE // Minimal bubble shown after search engine dialog
} BubbleType;
// See ProcessMasterPreferences for more info about this structure.
struct MasterPrefs {
diff --git a/chrome/browser/gtk/first_run_bubble.cc b/chrome/browser/gtk/first_run_bubble.cc
index c652a39..1a728c8 100644
--- a/chrome/browser/gtk/first_run_bubble.cc
+++ b/chrome/browser/gtk/first_run_bubble.cc
@@ -30,6 +30,10 @@ const int kButtonPadding = 4;
// Padding between content and edge of info bubble.
const int kContentBorder = 7;
+
+// Vertical spacing between labels.
+const int kInterLineSpacing = 5;
+
} // namespace
// static
@@ -37,7 +41,7 @@ void FirstRunBubble::Show(Profile* profile,
GtkWidget* anchor,
const gfx::Rect& rect,
FirstRun::BubbleType bubble_type) {
- new FirstRunBubble(profile, anchor, rect);
+ new FirstRunBubble(profile, anchor, rect, bubble_type);
}
void FirstRunBubble::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
@@ -65,60 +69,83 @@ void FirstRunBubble::Observe(NotificationType type,
FirstRunBubble::FirstRunBubble(Profile* profile,
GtkWidget* anchor,
- const gfx::Rect& rect)
+ const gfx::Rect& rect,
+ FirstRun::BubbleType bubble_type)
: profile_(profile),
theme_provider_(GtkThemeProvider::GetFrom(profile_)),
anchor_(anchor),
content_(NULL),
bubble_(NULL) {
+ content_ = gtk_vbox_new(FALSE, kInterLineSpacing);
+ gtk_container_set_border_width(GTK_CONTAINER(content_), kContentBorder);
+ g_signal_connect(content_, "destroy",
+ G_CALLBACK(&HandleDestroyThunk), this);
+
+ int width_resource = 0;
+ if (bubble_type == FirstRun::LARGE_BUBBLE) {
+ width_resource = IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS;
+ InitializeContentForLarge();
+ } else if (bubble_type == FirstRun::OEM_BUBBLE) {
+ width_resource = IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS;
+ InitializeContentForOEM();
+ } else if (bubble_type == FirstRun::MINIMAL_BUBBLE) {
+ width_resource = IDS_FIRSTRUN_MINIMAL_BUBBLE_DIALOG_WIDTH_CHARS;
+ InitializeContentForMinimal();
+ } else {
+ NOTREACHED();
+ }
+
+ InitializeLabels(width_resource);
+
+ InfoBubbleGtk::ArrowLocationGtk arrow_location =
+ !base::i18n::IsRTL() ?
+ InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT :
+ InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT;
+ bubble_ = InfoBubbleGtk::Show(anchor_,
+ &rect,
+ content_,
+ arrow_location,
+ true, // match_system_theme
+ true, // grab_input
+ theme_provider_,
+ this); // delegate
+ if (!bubble_) {
+ NOTREACHED();
+ return;
+ }
+
+ registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
+ NotificationService::AllSources());
+ theme_provider_->InitThemesFor(this);
+}
+
+FirstRunBubble::~FirstRunBubble() {
+}
+
+void FirstRunBubble::InitializeContentForLarge() {
GtkWidget* label1 = gtk_label_new(NULL);
labels_.push_back(label1);
char* markup = g_markup_printf_escaped(kSearchLabelMarkup,
l10n_util::GetStringUTF8(IDS_FR_BUBBLE_TITLE).c_str());
gtk_label_set_markup(GTK_LABEL(label1), markup);
g_free(markup);
- gtk_misc_set_alignment(GTK_MISC(label1), 0, .5);
- // TODO(erg): Theme these colors.
- gtk_widget_modify_fg(label1, GTK_STATE_NORMAL, &gfx::kGdkBlack);
GtkWidget* label2 = gtk_label_new(
l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT).c_str());
labels_.push_back(label2);
- gtk_misc_set_alignment(GTK_MISC(label2), 0, .5);
gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE);
- gtk_widget_modify_fg(label2, GTK_STATE_NORMAL, &gfx::kGdkBlack);
string16 search_engine = GetDefaultSearchEngineName(profile_);
GtkWidget* label3 = gtk_label_new(
l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_QUESTION, search_engine).c_str());
labels_.push_back(label3);
- gtk_misc_set_alignment(GTK_MISC(label3), 0, .5);
gtk_label_set_line_wrap(GTK_LABEL(label3), TRUE);
- gtk_widget_modify_fg(label3, GTK_STATE_NORMAL, &gfx::kGdkBlack);
GtkWidget* keep_button = gtk_button_new_with_label(
l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_OK, search_engine).c_str());
GtkWidget* change_button = gtk_button_new_with_label(
l10n_util::GetStringUTF8(IDS_FR_BUBBLE_CHANGE).c_str());
- content_ = gtk_vbox_new(FALSE, 5);
- gtk_container_set_border_width(GTK_CONTAINER(content_), kContentBorder);
-
- // We compute the widget's size using the anchor widget -- |content_| is
- // unrealized at this point.
- int width = -1, height = -1;
- gtk_util::GetWidgetSizeFromResources(
- anchor_,
- IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS,
- IDS_FIRSTRUNBUBBLE_DIALOG_HEIGHT_LINES,
- &width, &height);
- // Resize the labels so that they don't wrap more than necessary. We leave
- // |content_| unsized so that it'll expand as needed to hold the other
- // widgets -- the buttons may be wider than |width| on high-DPI displays.
- gtk_widget_set_size_request(label1, width, -1);
- gtk_widget_set_size_request(label2, width, -1);
- gtk_widget_set_size_request(label3, width, -1);
-
gtk_box_pack_start(GTK_BOX(content_), label1, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(content_), label2, FALSE, FALSE, 0);
// Leave an empty line.
@@ -137,33 +164,49 @@ FirstRunBubble::FirstRunBubble(Profile* profile,
// We want the focus to start on the keep entry, not on the change button.
gtk_widget_grab_focus(keep_button);
- InfoBubbleGtk::ArrowLocationGtk arrow_location =
- !base::i18n::IsRTL() ?
- InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT :
- InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT;
- bubble_ = InfoBubbleGtk::Show(anchor_,
- &rect,
- content_,
- arrow_location,
- true, // match_system_theme
- true, // grab_input
- theme_provider_,
- this); // delegate
- if (!bubble_) {
- NOTREACHED();
- return;
- }
-
- g_signal_connect(content_, "destroy",
- G_CALLBACK(&HandleDestroyThunk), this);
g_signal_connect(keep_button, "clicked",
G_CALLBACK(&HandleKeepButtonThunk), this);
g_signal_connect(change_button, "clicked",
G_CALLBACK(&HandleChangeButtonThunk), this);
+}
- registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
- NotificationService::AllSources());
- theme_provider_->InitThemesFor(this);
+void FirstRunBubble::InitializeContentForOEM() {
+ NOTIMPLEMENTED() << "Falling back to minimal bubble";
+ InitializeContentForMinimal();
+}
+
+void FirstRunBubble::InitializeContentForMinimal() {
+ GtkWidget* label1 = gtk_label_new(NULL);
+ labels_.push_back(label1);
+ char* markup = g_markup_printf_escaped(kSearchLabelMarkup,
+ l10n_util::GetStringFUTF8(
+ IDS_FR_SE_BUBBLE_TITLE,
+ GetDefaultSearchEngineName(profile_)).c_str());
+ gtk_label_set_markup(GTK_LABEL(label1), markup);
+ g_free(markup);
+
+ GtkWidget* label2 =
+ gtk_label_new(l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT).c_str());
+ labels_.push_back(label2);
+ gtk_label_set_line_wrap(GTK_LABEL(label2), TRUE);
+
+ gtk_box_pack_start(GTK_BOX(content_), label1, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(content_), label2, FALSE, FALSE, 0);
+}
+
+void FirstRunBubble::InitializeLabels(int width_resource) {
+ int width = -1;
+
+ gtk_util::GetWidgetSizeFromResources(
+ anchor_, width_resource, 0, &width, NULL);
+
+ for (size_t i = 0; i < labels_.size(); ++i) {
+ // Resize the labels so that they don't wrap more than necessary. We leave
+ // |content_| unsized so that it'll expand as needed to hold the other
+ // widgets -- the buttons may be wider than |width| on high-DPI displays.
+ gtk_widget_set_size_request(labels_[i], width, -1);
+ gtk_misc_set_alignment(GTK_MISC(labels_[i]), 0, .5);
+ }
}
void FirstRunBubble::HandleDestroy(GtkWidget* sender) {
diff --git a/chrome/browser/gtk/first_run_bubble.h b/chrome/browser/gtk/first_run_bubble.h
index e319518..211ae68 100644
--- a/chrome/browser/gtk/first_run_bubble.h
+++ b/chrome/browser/gtk/first_run_bubble.h
@@ -44,8 +44,18 @@ class FirstRunBubble : public InfoBubbleGtkDelegate,
private:
FirstRunBubble(Profile* profile,
GtkWidget* anchor,
- const gfx::Rect& rect);
- ~FirstRunBubble() { }
+ const gfx::Rect& rect,
+ FirstRun::BubbleType bubble_type);
+ virtual ~FirstRunBubble();
+
+ // Create and pack widgets for different bubble types.
+ void InitializeContentForLarge();
+ void InitializeContentForOEM();
+ void InitializeContentForMinimal();
+
+ // Contains some common set up for the labels in the bubble. |width| is a
+ // resource that holds the desired width for the labels.
+ void InitializeLabels(int width_resource);
CHROMEGTK_CALLBACK_0(FirstRunBubble, void, HandleDestroy);
CHROMEGTK_CALLBACK_0(FirstRunBubble, void, HandleKeepButton);
diff --git a/chrome/browser/views/first_run_bubble.cc b/chrome/browser/views/first_run_bubble.cc
index 0fa0893..fae2cfa 100644
--- a/chrome/browser/views/first_run_bubble.cc
+++ b/chrome/browser/views/first_run_bubble.cc
@@ -467,13 +467,13 @@ FirstRunBubble* FirstRunBubble::Show(Profile* profile,
FirstRunBubbleViewBase* view = NULL;
switch (bubble_type) {
- case FirstRun::OEMBUBBLE:
+ case FirstRun::OEM_BUBBLE:
view = new FirstRunOEMBubbleView(window, profile);
break;
- case FirstRun::LARGEBUBBLE:
+ case FirstRun::LARGE_BUBBLE:
view = new FirstRunBubbleView(window, profile);
break;
- case FirstRun::MINIMALBUBBLE:
+ case FirstRun::MINIMAL_BUBBLE:
view = new FirstRunMinimalBubbleView(window, profile);
break;
default: