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

Side by Side Diff: chrome/browser/ui/views/chooser_content_view.cc

Issue 2595083002: Change ChooserContentView[Cocoa] class name to be DeviceChooserContentView[Cocoa] (Closed)
Patch Set: merge master Created 3 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
OLDNEW
(Empty)
1 // Copyright 2016 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/ui/views/chooser_content_view.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "chrome/grit/generated_resources.h"
10 #include "ui/base/l10n/l10n_util.h"
11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/gfx/color_palette.h"
13 #include "ui/gfx/geometry/point.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/image/image_skia.h"
16 #include "ui/gfx/paint_vector_icon.h"
17 #include "ui/gfx/vector_icons_public.h"
18 #include "ui/resources/grit/ui_resources.h"
19 #include "ui/views/controls/styled_label.h"
20 #include "ui/views/controls/table/table_view.h"
21 #include "ui/views/controls/throbber.h"
22 #include "ui/views/widget/widget.h"
23
24 namespace {
25
26 const int kChooserWidth = 370;
27
28 const int kChooserHeight = 260;
29
30 const int kThrobberDiameter = 24;
31
32 const int kAdapterOffHelpLinkPadding = 5;
33
34 // The lookup table for signal strength level image.
35 const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR,
36 IDR_SIGNAL_2_BAR, IDR_SIGNAL_3_BAR,
37 IDR_SIGNAL_4_BAR};
38
39 } // namespace
40
41 ChooserContentView::ChooserContentView(
42 views::TableViewObserver* table_view_observer,
43 std::unique_ptr<ChooserController> chooser_controller)
44 : chooser_controller_(std::move(chooser_controller)),
45 help_text_(l10n_util::GetStringFUTF16(
46 IDS_DEVICE_CHOOSER_GET_HELP_LINK_WITH_SCANNING_STATUS,
47 base::string16())),
48 help_and_scanning_text_(l10n_util::GetStringFUTF16(
49 IDS_DEVICE_CHOOSER_GET_HELP_LINK_WITH_SCANNING_STATUS,
50 l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING))) {
51 base::string16 re_scan_text =
52 l10n_util::GetStringUTF16(IDS_BLUETOOTH_DEVICE_CHOOSER_RE_SCAN);
53 std::vector<size_t> offsets;
54 help_and_re_scan_text_ = l10n_util::GetStringFUTF16(
55 IDS_DEVICE_CHOOSER_GET_HELP_LINK_WITH_RE_SCAN_LINK, help_text_,
56 re_scan_text, &offsets);
57 help_text_range_ = gfx::Range(offsets[0], offsets[0] + help_text_.size());
58 re_scan_text_range_ =
59 gfx::Range(offsets[1], offsets[1] + re_scan_text.size());
60 chooser_controller_->set_view(this);
61 std::vector<ui::TableColumn> table_columns;
62 table_columns.push_back(ui::TableColumn());
63 table_view_ = new views::TableView(
64 this, table_columns,
65 chooser_controller_->ShouldShowIconBeforeText() ? views::ICON_AND_TEXT
66 : views::TEXT_ONLY,
67 !chooser_controller_->AllowMultipleSelection() /* single_selection */);
68 table_view_->set_select_on_remove(false);
69 table_view_->set_observer(table_view_observer);
70 table_view_->SetEnabled(chooser_controller_->NumOptions() > 0);
71
72 table_parent_ = table_view_->CreateParentIfNecessary();
73 AddChildView(table_parent_);
74
75 throbber_ = new views::Throbber();
76 throbber_->SetVisible(false);
77 AddChildView(throbber_);
78
79 base::string16 link_text = l10n_util::GetStringUTF16(
80 IDS_BLUETOOTH_DEVICE_CHOOSER_TURN_ON_BLUETOOTH_LINK_TEXT);
81 size_t offset = 0;
82 base::string16 text = l10n_util::GetStringFUTF16(
83 IDS_BLUETOOTH_DEVICE_CHOOSER_TURN_ADAPTER_OFF, link_text, &offset);
84 turn_adapter_off_help_ = new views::StyledLabel(text, this);
85 turn_adapter_off_help_->AddStyleRange(
86 gfx::Range(0, link_text.size()),
87 views::StyledLabel::RangeStyleInfo::CreateForLink());
88 turn_adapter_off_help_->SetVisible(false);
89 AddChildView(turn_adapter_off_help_);
90 }
91
92 ChooserContentView::~ChooserContentView() {
93 chooser_controller_->set_view(nullptr);
94 table_view_->set_observer(nullptr);
95 table_view_->SetModel(nullptr);
96 }
97
98 gfx::Size ChooserContentView::GetPreferredSize() const {
99 return gfx::Size(kChooserWidth, kChooserHeight);
100 }
101
102 void ChooserContentView::Layout() {
103 gfx::Rect rect(GetContentsBounds());
104 table_parent_->SetBoundsRect(rect);
105 // Set the throbber in the center of the chooser.
106 throbber_->SetBounds((rect.width() - kThrobberDiameter) / 2,
107 (rect.height() - kThrobberDiameter) / 2,
108 kThrobberDiameter, kThrobberDiameter);
109 turn_adapter_off_help_->SetPosition(
110 gfx::Point(kAdapterOffHelpLinkPadding, kAdapterOffHelpLinkPadding));
111 turn_adapter_off_help_->SizeToFit(rect.width() -
112 2 * kAdapterOffHelpLinkPadding);
113 views::View::Layout();
114 }
115
116 int ChooserContentView::RowCount() {
117 // When there are no devices, the table contains a message saying there
118 // are no devices, so the number of rows is always at least 1.
119 return std::max(base::checked_cast<int>(chooser_controller_->NumOptions()),
120 1);
121 }
122
123 base::string16 ChooserContentView::GetText(int row, int column_id) {
124 int num_options = base::checked_cast<int>(chooser_controller_->NumOptions());
125 if (num_options == 0) {
126 DCHECK_EQ(0, row);
127 return chooser_controller_->GetNoOptionsText();
128 }
129
130 DCHECK_GE(row, 0);
131 DCHECK_LT(row, num_options);
132 base::string16 text =
133 chooser_controller_->GetOption(static_cast<size_t>(row));
134 return chooser_controller_->IsPaired(row)
135 ? l10n_util::GetStringFUTF16(
136 IDS_DEVICE_CHOOSER_DEVICE_NAME_AND_PAIRED_STATUS_TEXT, text)
137 : text;
138 }
139
140 void ChooserContentView::SetObserver(ui::TableModelObserver* observer) {}
141
142 gfx::ImageSkia ChooserContentView::GetIcon(int row) {
143 DCHECK(chooser_controller_->ShouldShowIconBeforeText());
144
145 size_t num_options = chooser_controller_->NumOptions();
146 if (num_options == 0) {
147 DCHECK_EQ(0, row);
148 return gfx::ImageSkia();
149 }
150
151 DCHECK_GE(row, 0);
152 DCHECK_LT(row, base::checked_cast<int>(num_options));
153
154 if (chooser_controller_->IsConnected(row)) {
155 return gfx::CreateVectorIcon(gfx::VectorIconId::BLUETOOTH_CONNECTED,
156 gfx::kChromeIconGrey);
157 }
158
159 int level = chooser_controller_->GetSignalStrengthLevel(row);
160
161 if (level == -1)
162 return gfx::ImageSkia();
163
164 DCHECK_GE(level, 0);
165 DCHECK_LT(level, static_cast<int>(arraysize(kSignalStrengthLevelImageIds)));
166
167 return *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
168 kSignalStrengthLevelImageIds[level]);
169 }
170
171 void ChooserContentView::OnOptionsInitialized() {
172 table_view_->OnModelChanged();
173 UpdateTableView();
174 }
175
176 void ChooserContentView::OnOptionAdded(size_t index) {
177 table_view_->OnItemsAdded(base::checked_cast<int>(index), 1);
178 UpdateTableView();
179 table_view_->SetVisible(true);
180 throbber_->SetVisible(false);
181 throbber_->Stop();
182 }
183
184 void ChooserContentView::OnOptionRemoved(size_t index) {
185 table_view_->OnItemsRemoved(base::checked_cast<int>(index), 1);
186 UpdateTableView();
187 }
188
189 void ChooserContentView::OnOptionUpdated(size_t index) {
190 table_view_->OnItemsChanged(base::checked_cast<int>(index), 1);
191 UpdateTableView();
192 }
193
194 void ChooserContentView::OnAdapterEnabledChanged(bool enabled) {
195 // No row is selected since the adapter status has changed.
196 // This will also disable the OK button if it was enabled because
197 // of a previously selected row.
198 table_view_->Select(-1);
199 UpdateTableView();
200 table_view_->SetVisible(enabled);
201 turn_adapter_off_help_->SetVisible(!enabled);
202
203 throbber_->Stop();
204 throbber_->SetVisible(false);
205
206 if (enabled) {
207 SetGetHelpAndReScanLink();
208 } else {
209 DCHECK(footnote_link_);
210 footnote_link_->SetText(help_text_);
211 footnote_link_->AddStyleRange(
212 help_text_range_, views::StyledLabel::RangeStyleInfo::CreateForLink());
213 }
214
215 if (GetWidget() && GetWidget()->GetRootView())
216 GetWidget()->GetRootView()->Layout();
217 }
218
219 void ChooserContentView::OnRefreshStateChanged(bool refreshing) {
220 if (refreshing) {
221 // No row is selected since the chooser is refreshing. This will also
222 // disable the OK button if it was enabled because of a previously
223 // selected row.
224 table_view_->Select(-1);
225 UpdateTableView();
226 }
227
228 // When refreshing and no option available yet, hide |table_view_| and show
229 // |throbber_|. Otherwise show |table_view_| and hide |throbber_|.
230 bool throbber_visible =
231 refreshing && (chooser_controller_->NumOptions() == 0);
232 table_view_->SetVisible(!throbber_visible);
233 throbber_->SetVisible(throbber_visible);
234 if (throbber_visible)
235 throbber_->Start();
236 else
237 throbber_->Stop();
238
239 if (refreshing) {
240 DCHECK(footnote_link_);
241 footnote_link_->SetText(help_and_scanning_text_);
242 footnote_link_->AddStyleRange(
243 help_text_range_, views::StyledLabel::RangeStyleInfo::CreateForLink());
244 } else {
245 SetGetHelpAndReScanLink();
246 }
247
248 if (GetWidget() && GetWidget()->GetRootView())
249 GetWidget()->GetRootView()->Layout();
250 }
251
252 void ChooserContentView::StyledLabelLinkClicked(views::StyledLabel* label,
253 const gfx::Range& range,
254 int event_flags) {
255 if (label == turn_adapter_off_help_) {
256 chooser_controller_->OpenAdapterOffHelpUrl();
257 } else if (label == footnote_link_.get()) {
258 if (range == help_text_range_)
259 chooser_controller_->OpenHelpCenterUrl();
260 else if (range == re_scan_text_range_)
261 chooser_controller_->RefreshOptions();
262 else
263 NOTREACHED();
264 } else {
265 NOTREACHED();
266 }
267 }
268
269 base::string16 ChooserContentView::GetWindowTitle() const {
270 return chooser_controller_->GetTitle();
271 }
272
273 base::string16 ChooserContentView::GetDialogButtonLabel(
274 ui::DialogButton button) const {
275 return button == ui::DIALOG_BUTTON_OK
276 ? chooser_controller_->GetOkButtonLabel()
277 : l10n_util::GetStringUTF16(IDS_DEVICE_CHOOSER_CANCEL_BUTTON_TEXT);
278 }
279
280 bool ChooserContentView::IsDialogButtonEnabled(ui::DialogButton button) const {
281 return button != ui::DIALOG_BUTTON_OK ||
282 !table_view_->selection_model().empty();
283 }
284
285 views::StyledLabel* ChooserContentView::footnote_link() {
286 if (chooser_controller_->ShouldShowFootnoteView()) {
287 footnote_link_ = base::MakeUnique<views::StyledLabel>(help_text_, this);
288 footnote_link_->set_owned_by_client();
289 footnote_link_->AddStyleRange(
290 help_text_range_, views::StyledLabel::RangeStyleInfo::CreateForLink());
291 }
292
293 return footnote_link_.get();
294 }
295
296 void ChooserContentView::Accept() {
297 std::vector<size_t> indices(
298 table_view_->selection_model().selected_indices().begin(),
299 table_view_->selection_model().selected_indices().end());
300 chooser_controller_->Select(indices);
301 }
302
303 void ChooserContentView::Cancel() {
304 chooser_controller_->Cancel();
305 }
306
307 void ChooserContentView::Close() {
308 chooser_controller_->Close();
309 }
310
311 void ChooserContentView::UpdateTableView() {
312 if (chooser_controller_->NumOptions() == 0) {
313 table_view_->OnModelChanged();
314 table_view_->SetEnabled(false);
315 } else {
316 table_view_->SetEnabled(true);
317 }
318 }
319
320 void ChooserContentView::SetGetHelpAndReScanLink() {
321 DCHECK(footnote_link_);
322 footnote_link_->SetText(help_and_re_scan_text_);
323 footnote_link_->AddStyleRange(
324 help_text_range_, views::StyledLabel::RangeStyleInfo::CreateForLink());
325 footnote_link_->AddStyleRange(
326 re_scan_text_range_, views::StyledLabel::RangeStyleInfo::CreateForLink());
327 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/chooser_content_view.h ('k') | chrome/browser/ui/views/chooser_content_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698