diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-28 00:24:50 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-28 00:24:50 +0000 |
commit | 450028dd67e33563e5ccd2057e8412d5e341def3 (patch) | |
tree | c8529240dad16b1350aef26f48b3a28fef9df854 /chrome | |
parent | a3ab1726197c051d92a1d1ee26abf2140c3c3607 (diff) | |
download | chromium_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.cc | 6 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.h | 6 | ||||
-rw-r--r-- | chrome/browser/gtk/first_run_bubble.cc | 141 | ||||
-rw-r--r-- | chrome/browser/gtk/first_run_bubble.h | 14 | ||||
-rw-r--r-- | chrome/browser/views/first_run_bubble.cc | 6 |
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: |