Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: chrome/browser/ui/gtk/first_run_bubble.cc

Issue 9016036: Implement the new first run bubble, clean up old bubbles. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync and merge. Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/gtk/first_run_bubble.h ('k') | chrome/browser/ui/gtk/location_bar_view_gtk.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/gtk/first_run_bubble.h" 5 #include "chrome/browser/ui/gtk/first_run_bubble.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "base/command_line.h"
10 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
11 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/search_engines/util.h" 11 #include "chrome/browser/search_engines/util.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_list.h" 12 #include "chrome/browser/ui/browser_list.h"
15 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 13 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
16 #include "chrome/browser/ui/gtk/gtk_util.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h" 14 #include "grit/generated_resources.h"
19 #include "grit/locale_settings.h"
20 #include "ui/base/gtk/gtk_hig_constants.h" 15 #include "ui/base/gtk/gtk_hig_constants.h"
21 #include "ui/base/l10n/l10n_util.h" 16 #include "ui/base/l10n/l10n_util.h"
22 17
23 namespace { 18 namespace {
24 // Markup for the text of the Omnibox search label 19 // Markup for the text of the Omnibox search label
25 const char kSearchLabelMarkup[] = "<big><b>%s</b></big>"; 20 const char kSearchLabelMarkup[] = "<big><b>%s</b></big>";
26 21
27 // Padding for the buttons on first run bubble.
28 const int kButtonPadding = 4;
29
30 // Padding between content and edge of bubble. 22 // Padding between content and edge of bubble.
31 const int kContentBorder = 7; 23 const int kContentBorder = 7;
32 24
33 // Vertical spacing between labels. 25 // Vertical spacing between labels.
34 const int kInterLineSpacing = 5; 26 const int kInterLineSpacing = 5;
35 27
36 } // namespace 28 } // namespace
37 29
38 // static 30 // static
39 void FirstRunBubble::Show(Profile* profile, 31 void FirstRunBubble::Show(Profile* profile,
40 GtkWidget* anchor, 32 GtkWidget* anchor,
41 const gfx::Rect& rect, 33 const gfx::Rect& rect) {
42 FirstRun::BubbleType bubble_type) { 34 new FirstRunBubble(profile, anchor, rect);
43 new FirstRunBubble(profile, anchor, rect, bubble_type);
44 } 35 }
45 36
46 void FirstRunBubble::BubbleClosing(BubbleGtk* bubble, 37 void FirstRunBubble::BubbleClosing(BubbleGtk* bubble, bool closed_by_escape) {
47 bool closed_by_escape) {
48 // TODO(port): Enable parent window 38 // TODO(port): Enable parent window
49 } 39 }
50 40
51 FirstRunBubble::FirstRunBubble(Profile* profile, 41 FirstRunBubble::FirstRunBubble(Profile* profile,
52 GtkWidget* anchor, 42 GtkWidget* anchor,
53 const gfx::Rect& rect, 43 const gfx::Rect& rect)
54 FirstRun::BubbleType bubble_type)
55 : profile_(profile), 44 : profile_(profile),
56 theme_service_(GtkThemeService::GetFrom(profile_)),
57 anchor_(anchor),
58 content_(NULL),
59 bubble_(NULL) { 45 bubble_(NULL) {
60 content_ = gtk_vbox_new(FALSE, kInterLineSpacing); 46 GtkThemeService* theme_service = GtkThemeService::GetFrom(profile_);
61 gtk_container_set_border_width(GTK_CONTAINER(content_), kContentBorder); 47 GtkWidget* title = theme_service->BuildLabel("", ui::kGdkBlack);
62 g_signal_connect(content_, "destroy", 48 char* markup = g_markup_printf_escaped(kSearchLabelMarkup,
63 G_CALLBACK(&HandleDestroyThunk), this); 49 l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_TITLE,
50 GetDefaultSearchEngineName(profile_)).c_str());
51 gtk_label_set_markup(GTK_LABEL(title), markup);
52 g_free(markup);
64 53
65 int width_resource = 0; 54 GtkWidget* change = theme_service->BuildChromeLinkButton(
66 std::vector<GtkWidget*> labels; 55 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_CHANGE));
67 if (bubble_type == FirstRun::LARGE_BUBBLE) { 56 g_signal_connect(change, "clicked", G_CALLBACK(&HandleChangeLinkThunk), this);
68 width_resource = IDS_FIRSTRUNBUBBLE_DIALOG_WIDTH_CHARS;
69 InitializeContentForLarge(&labels);
70 } else if (bubble_type == FirstRun::OEM_BUBBLE) {
71 width_resource = IDS_FIRSTRUNOEMBUBBLE_DIALOG_WIDTH_CHARS;
72 InitializeContentForOEM(&labels);
73 } else if (bubble_type == FirstRun::MINIMAL_BUBBLE) {
74 width_resource = IDS_FIRSTRUN_MINIMAL_BUBBLE_DIALOG_WIDTH_CHARS;
75 InitializeContentForMinimal(&labels);
76 } else {
77 NOTREACHED();
78 }
79 57
80 InitializeLabels(width_resource, &labels); 58 GtkWidget* subtext = theme_service->BuildLabel(
59 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT), ui::kGdkBlack);
81 60
82 BubbleGtk::ArrowLocationGtk arrow_location = 61 GtkWidget* top_line = gtk_hbox_new(FALSE, kContentBorder);
83 !base::i18n::IsRTL() ? 62 gtk_box_pack_start(GTK_BOX(top_line), title, FALSE, FALSE, 0);
84 BubbleGtk::ARROW_LOCATION_TOP_LEFT : 63 gtk_box_pack_start(GTK_BOX(top_line), change, FALSE, FALSE, 0);
85 BubbleGtk::ARROW_LOCATION_TOP_RIGHT; 64
86 bubble_ = BubbleGtk::Show(anchor_, 65 GtkWidget* content = gtk_vbox_new(FALSE, kInterLineSpacing);
87 &rect, 66 gtk_container_set_border_width(GTK_CONTAINER(content), kContentBorder);
88 content_, 67 g_signal_connect(content, "destroy", G_CALLBACK(&HandleDestroyThunk), this);
89 arrow_location, 68 gtk_box_pack_start(GTK_BOX(content), top_line, FALSE, FALSE, 0);
90 true, // match_system_theme 69 gtk_box_pack_start(GTK_BOX(content), subtext, FALSE, FALSE, 0);
91 true, // grab_input 70
92 theme_service_, 71 BubbleGtk::ArrowLocationGtk arrow_location = !base::i18n::IsRTL() ?
93 this); // delegate 72 BubbleGtk::ARROW_LOCATION_TOP_LEFT : BubbleGtk::ARROW_LOCATION_TOP_RIGHT;
94 if (!bubble_) { 73 bubble_ = BubbleGtk::Show(anchor, &rect, content, arrow_location,
95 NOTREACHED(); 74 true /*match_system_theme*/, true /*grab_input*/, theme_service, this);
96 return; 75 DCHECK(bubble_);
97 }
98 } 76 }
99 77
100 FirstRunBubble::~FirstRunBubble() { 78 FirstRunBubble::~FirstRunBubble() {
101 } 79 }
102 80
103 void FirstRunBubble::InitializeContentForLarge(
104 std::vector<GtkWidget*>* labels) {
105 GtkWidget* label1 = theme_service_->BuildLabel("", ui::kGdkBlack);
106 labels->push_back(label1);
107 char* markup = g_markup_printf_escaped(kSearchLabelMarkup,
108 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_TITLE).c_str());
109 gtk_label_set_markup(GTK_LABEL(label1), markup);
110 g_free(markup);
111
112 GtkWidget* label2 = theme_service_->BuildLabel(
113 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT), ui::kGdkBlack);
114 labels->push_back(label2);
115
116 string16 search_engine = GetDefaultSearchEngineName(profile_);
117 GtkWidget* label3 = theme_service_->BuildLabel(
118 l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_QUESTION, search_engine),
119 ui::kGdkBlack);
120 labels->push_back(label3);
121
122 GtkWidget* keep_button = gtk_button_new_with_label(
123 l10n_util::GetStringFUTF8(IDS_FR_BUBBLE_OK, search_engine).c_str());
124 GtkWidget* change_button = gtk_button_new_with_label(
125 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_CHANGE).c_str());
126
127 gtk_box_pack_start(GTK_BOX(content_), label1, FALSE, FALSE, 0);
128 gtk_box_pack_start(GTK_BOX(content_), label2, FALSE, FALSE, 0);
129 // Leave an empty line.
130 gtk_box_pack_start(GTK_BOX(content_), gtk_label_new(NULL), FALSE, FALSE, 0);
131 gtk_box_pack_start(GTK_BOX(content_), label3, FALSE, FALSE, 0);
132
133 GtkWidget* bottom = gtk_hbox_new(FALSE, 0);
134 // We want the buttons on the right, so just use an expanding label to fill
135 // all of the extra space on the left.
136 gtk_box_pack_start(GTK_BOX(bottom), gtk_label_new(NULL), TRUE, TRUE, 0);
137 gtk_box_pack_start(GTK_BOX(bottom), keep_button, FALSE, FALSE,
138 kButtonPadding);
139 gtk_box_pack_start(GTK_BOX(bottom), change_button, FALSE, FALSE, 0);
140
141 gtk_box_pack_start(GTK_BOX(content_), bottom, FALSE, FALSE, 0);
142 // We want the focus to start on the keep entry, not on the change button.
143 gtk_widget_grab_focus(keep_button);
144
145 g_signal_connect(keep_button, "clicked",
146 G_CALLBACK(&HandleKeepButtonThunk), this);
147 g_signal_connect(change_button, "clicked",
148 G_CALLBACK(&HandleChangeButtonThunk), this);
149 }
150
151 void FirstRunBubble::InitializeContentForOEM(std::vector<GtkWidget*>* labels) {
152 NOTIMPLEMENTED() << "Falling back to minimal bubble";
153 InitializeContentForMinimal(labels);
154 }
155
156 void FirstRunBubble::InitializeContentForMinimal(
157 std::vector<GtkWidget*>* labels) {
158 GtkWidget* label1 = theme_service_->BuildLabel("", ui::kGdkBlack);
159 labels->push_back(label1);
160 char* markup = g_markup_printf_escaped(kSearchLabelMarkup,
161 l10n_util::GetStringFUTF8(
162 IDS_FR_SE_BUBBLE_TITLE,
163 GetDefaultSearchEngineName(profile_)).c_str());
164 gtk_label_set_markup(GTK_LABEL(label1), markup);
165 g_free(markup);
166
167 GtkWidget* label2 = theme_service_->BuildLabel(
168 l10n_util::GetStringUTF8(IDS_FR_BUBBLE_SUBTEXT), ui::kGdkBlack);
169 labels->push_back(label2);
170
171 gtk_box_pack_start(GTK_BOX(content_), label1, FALSE, FALSE, 0);
172 gtk_box_pack_start(GTK_BOX(content_), label2, FALSE, FALSE, 0);
173 }
174
175 void FirstRunBubble::InitializeLabels(int width_resource,
176 std::vector<GtkWidget*>* labels) {
177 int width = -1;
178
179 gtk_util::GetWidgetSizeFromResources(
180 anchor_, width_resource, 0, &width, NULL);
181
182 for (size_t i = 0; i < labels->size(); ++i) {
183 // Resize the labels so that they don't wrap more than necessary. We leave
184 // |content_| unsized so that it'll expand as needed to hold the other
185 // widgets -- the buttons may be wider than |width| on high-DPI displays.
186 gtk_util::SetLabelWidth((*labels)[i], width);
187 }
188 }
189
190 void FirstRunBubble::HandleDestroy(GtkWidget* sender) { 81 void FirstRunBubble::HandleDestroy(GtkWidget* sender) {
191 content_ = NULL;
192 delete this; 82 delete this;
193 } 83 }
194 84
195 void FirstRunBubble::HandleKeepButton(GtkWidget* sender) { 85 void FirstRunBubble::HandleChangeLink(GtkWidget* sender) {
86 // Get |profile_|'s browser before closing the bubble, which deletes |this|.
87 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
196 bubble_->Close(); 88 bubble_->Close();
89 if (browser)
90 browser->OpenSearchEngineOptionsDialog();
197 } 91 }
198
199 void FirstRunBubble::HandleChangeButton(GtkWidget* sender) {
200 bubble_->Close();
201 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
202 DCHECK(browser);
203 browser->OpenSearchEngineOptionsDialog();
204 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/first_run_bubble.h ('k') | chrome/browser/ui/gtk/location_bar_view_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698