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

Side by Side Diff: chrome/browser/views/page_info_bubble_view.cc

Issue 3136027: First pass at convert the SSL dialogs into InfoBubbles.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 4 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/views/page_info_bubble_view.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/views/page_info_bubble_view.h"
6
7 #include "app/resource_bundle.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/views/frame/browser_view.h"
10 #include "chrome/browser/views/info_bubble.h"
11 #include "chrome/browser/views/toolbar_view.h"
12 #include "grit/locale_settings.h"
13 #include "grit/theme_resources.h"
14 #include "views/controls/image_view.h"
15 #include "views/controls/label.h"
16 #include "views/controls/separator.h"
17 #include "views/grid_layout.h"
18 #include "views/widget/widget_win.h"
19 #include "views/window/window.h"
20
21 // Layout constants.
22 const int kHGapToBorder = 11;
23 const int kVGapToImage = 10;
24 const int kVGapToHeadline = 7;
25 const int kHGapImageToDescription = 6;
26 const int kTextPaddingRight = 10;
27 const int kPaddingBelowSeparator = 4;
28 const int kPaddingAboveSeparator = 13;
29 const int kIconOffset = 28;
30
31 // A section contains an image that shows a status (good or bad), a title, an
32 // optional head-line (in bold) and a description.
33 class Section : public views::View {
34 public:
35 Section(bool state,
36 const string16& headline,
37 const string16& description);
38 virtual ~Section();
39
40 virtual int GetHeightForWidth(int w);
41 virtual void Layout();
42
43 private:
44 // Calculate the layout if |compute_bounds_only|, otherwise does Layout also.
45 gfx::Size LayoutItems(bool compute_bounds_only, int width);
46
47 // Whether to show the good/bad icon.
48 bool state_;
49
50 // The first line of the description, show in bold.
51 string16 headline_;
52
53 // The description, displayed below the head line.
54 string16 description_;
55
56 static SkBitmap* good_state_icon_;
57 static SkBitmap* bad_state_icon_;
58
59 views::ImageView* status_image_;
60 views::Label* headline_label_;
61 views::Label* description_label_;
62
63 DISALLOW_COPY_AND_ASSIGN(Section);
64 };
65
66 // static
67 SkBitmap* Section::good_state_icon_ = NULL;
68 SkBitmap* Section::bad_state_icon_ = NULL;
69
70 ////////////////////////////////////////////////////////////////////////////////
71 // PageInfoBubbleView
72
73 PageInfoBubbleView::PageInfoBubbleView(Profile* profile,
74 const GURL& url,
75 const NavigationEntry::SSLStatus& ssl,
76 bool show_history)
77 : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl,
78 show_history, this)),
79 cert_id_(ssl.cert_id()),
80 info_bubble_(NULL) {
81 LayoutSections();
82 }
83
84 PageInfoBubbleView::~PageInfoBubbleView() {
85 }
86
87 void PageInfoBubbleView::LayoutSections() {
88 // Remove all the existing sections.
89 RemoveAllChildViews(true);
90
91 views::GridLayout* layout = new views::GridLayout(this);
92 SetLayoutManager(layout);
93 views::ColumnSet* columns = layout->AddColumnSet(0);
94 columns->AddColumn(views::GridLayout::FILL, // Horizontal resize.
95 views::GridLayout::FILL, // Vertical resize.
96 1, // Resize weight.
97 views::GridLayout::USE_PREF, // Size type.
98 0, // Ignored for USE_PREF.
99 0); // Minimum size.
100
101 int count = model_.GetSectionCount();
102 for (int i = 0; i < count; ++i) {
103 PageInfoModel::SectionInfo info = model_.GetSectionInfo(i);
104 layout->StartRow(0, 0);
105 // TODO(finnur): Remove title from the info struct, since it is
106 // not used anymore.
107 layout->AddView(new Section(info.state, info.head_line, info.description));
108
109 // Add separator after all sections except the last.
110 if (i < count - 1) {
111 layout->AddPaddingRow(0, kPaddingAboveSeparator);
112 layout->StartRow(0, 0);
113 layout->AddView(new views::Separator());
114 layout->AddPaddingRow(0, kPaddingBelowSeparator);
115 }
116 }
117 }
118
119 gfx::Size PageInfoBubbleView::GetPreferredSize() {
120 gfx::Size size(views::Window::GetLocalizedContentsSize(
121 IDS_PAGEINFOBUBBLE_WIDTH_CHARS, IDS_PAGEINFOBUBBLE_HEIGHT_LINES));
122 size.set_height(0);
123
124 int count = model_.GetSectionCount();
125 for (int i = 0; i < count; ++i) {
126 PageInfoModel::SectionInfo info = model_.GetSectionInfo(i);
127 Section section(info.state, info.head_line, info.description);
128 size.Enlarge(0, section.GetHeightForWidth(size.width()));
129 }
130
131 // Account for the separators and padding.
132 views::Separator separator;
133 gfx::Size separator_size = separator.GetPreferredSize();
134 size.Enlarge(0, (count - 1) * (separator_size.height() +
135 kPaddingAboveSeparator +
136 kPaddingBelowSeparator));
137 return size;
138 }
139
140 void PageInfoBubbleView::ModelChanged() {
141 LayoutSections();
142 info_bubble_->SizeToContents();
143 }
144
145 ////////////////////////////////////////////////////////////////////////////////
146 // Section
147
148 Section::Section(bool state,
149 const string16& headline,
150 const string16& description)
151 : state_(state),
152 headline_(headline),
153 description_(description) {
154 if (!good_state_icon_) {
155 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
156 good_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_GOOD);
157 bad_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_BAD);
158 }
159
160 status_image_ = new views::ImageView();
161 status_image_->SetImage(state ? good_state_icon_ : bad_state_icon_);
162 AddChildView(status_image_);
163
164 headline_label_ = new views::Label(UTF16ToWideHack(headline));
165 headline_label_->SetFont(
166 headline_label_->font().DeriveFont(0, gfx::Font::BOLD));
167 headline_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
168 AddChildView(headline_label_);
169
170 description_label_ = new views::Label(UTF16ToWideHack(description));
171 description_label_->SetMultiLine(true);
172 description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
173 // Allow linebreaking in the middle of words if necessary, so that extremely
174 // long hostnames (longer than one line) will still be completely shown.
175 description_label_->SetAllowCharacterBreak(true);
176 AddChildView(description_label_);
177 }
178
179 Section::~Section() {
180 }
181
182 int Section::GetHeightForWidth(int width) {
183 return LayoutItems(true, width).height();
184 }
185
186 void Section::Layout() {
187 LayoutItems(false, width());
188 }
189
190 gfx::Size Section::LayoutItems(bool compute_bounds_only, int width) {
191 int x = kHGapToBorder;
192 int y = kVGapToImage;
193
194 // Layout the image, head-line and description.
195 gfx::Size size = status_image_->GetPreferredSize();
196 if (!compute_bounds_only)
197 status_image_->SetBounds(x, y, size.width(), size.height());
198 int image_height = y + size.height();
199 x += size.width() + kHGapImageToDescription;
200 int w = width - x - kTextPaddingRight;
201 y = kVGapToHeadline;
202 if (!headline_label_->GetText().empty()) {
203 size = headline_label_->GetPreferredSize();
204 if (!compute_bounds_only)
205 headline_label_->SetBounds(x, y, w > 0 ? w : 0, size.height());
206 y += size.height();
207 } else {
208 if (!compute_bounds_only)
209 headline_label_->SetBounds(x, y, 0, 0);
210 }
211 if (w > 0) {
212 int height = description_label_->GetHeightForWidth(w);
213 if (!compute_bounds_only)
214 description_label_->SetBounds(x, y, w, height);
215 y += height;
216 } else {
217 if (!compute_bounds_only)
218 description_label_->SetBounds(x, y, 0, 0);
219 }
220
221 // Make sure the image is not truncated if the text doesn't contain much.
222 y = std::max(y, image_height);
223 return gfx::Size(width, y);
224 }
225
226 namespace browser {
227
228 void ShowPageInfoBubble(gfx::NativeWindow parent,
229 Profile* profile,
230 const GURL& url,
231 const NavigationEntry::SSLStatus& ssl,
232 bool show_history) {
233 // Find where to point the bubble at.
234 BrowserView* browser_view =
235 BrowserView::GetBrowserViewForNativeWindow(parent);
236 gfx::Rect bounds = browser_view->toolbar()->location_bar()->bounds();
237 gfx::Point point;
238 views::View::ConvertPointToScreen(browser_view->toolbar()->location_bar(),
239 &point);
240 bounds.set_origin(point);
241 bounds.set_width(kIconOffset);
242
243 // Show the bubble.
244 PageInfoBubbleView* page_info_bubble =
245 new PageInfoBubbleView(profile, url, ssl, show_history);
246 InfoBubble* info_bubble =
247 InfoBubble::Show(browser_view->GetWidget(), bounds,
248 BubbleBorder::TOP_LEFT,
249 page_info_bubble, page_info_bubble);
250 page_info_bubble->set_info_bubble(info_bubble);
251 }
252
253 }
OLDNEW
« no previous file with comments | « chrome/browser/views/page_info_bubble_view.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698