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

Unified Diff: chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm

Issue 2304213002: Show device connection and paired status in chooser on Mac (Closed)
Patch Set: use vector icons Created 4 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm
diff --git a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm b/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm
index ba6990f50c09c09857a3e7404e918c992c21d06d..3217403d8e9d9b19197824b7aad47f0cb31260f6 100644
--- a/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/chooser_content_view_cocoa.mm
@@ -12,10 +12,15 @@
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
#include "chrome/browser/ui/cocoa/spinner_view.h"
#include "chrome/grit/generated_resources.h"
+#include "skia/ext/skia_utils_mac.h"
#import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#import "ui/base/cocoa/controls/hyperlink_button_cell.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/color_palette.h"
+#include "ui/gfx/image/image_skia_util_mac.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/gfx/vector_icons_public.h"
#include "ui/resources/grit/ui_resources.h"
namespace {
@@ -26,11 +31,12 @@ const CGFloat kChooserWidth = 350.0f;
// Chooser height.
const CGFloat kChooserHeight = 300.0f;
-// Signal strength level image size.
-const CGFloat kSignalStrengthLevelImageSize = 20.0f;
+// Row view image size.
+const CGFloat kRowViewImageSize = 20.0f;
// Table row view height.
-const CGFloat kTableRowViewHeight = 23.0f;
+const CGFloat kTableRowViewOneLineHeight = 23.0f;
+const CGFloat kTableRowViewTwoLinesHeight = 39.0f;
// Spinner size.
const CGFloat kSpinnerSize = 24.0f;
@@ -50,11 +56,29 @@ const CGFloat kSeparatorAlphaValue = 0.6f;
// Separator height.
const CGFloat kSeparatorHeight = 1.0f;
+// Distance between two views inside the table row view.
+const CGFloat kTableRowViewHorizontalPadding = 5.0f;
+const CGFloat kTableRowViewVerticalPadding = 1.0f;
+
// The lookup table for signal strength level image.
const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR,
IDR_SIGNAL_2_BAR, IDR_SIGNAL_3_BAR,
IDR_SIGNAL_4_BAR};
+// Creates a text field with |text|.
Jeffrey Yasskin 2016/09/07 02:01:47 I think this is a label, rather than a general tex
juncai 2016/09/09 20:06:15 Done.
+base::scoped_nsobject<NSTextField> CreateTextField(NSString* text) {
+ base::scoped_nsobject<NSTextField> text_field(
+ [[NSTextField alloc] initWithFrame:NSZeroRect]);
+ [text_field setDrawsBackground:NO];
Jeffrey Yasskin 2016/09/07 02:01:47 I hate that we need this long list of setters in o
juncai 2016/09/09 20:06:15 Acknowledged.
+ [text_field setBezeled:NO];
+ [text_field setEditable:NO];
+ [text_field setSelectable:NO];
+ [text_field setStringValue:text];
+ [text_field setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
+ [text_field sizeToFit];
+ return text_field;
+}
+
} // namespace
// A table row view that contains one line of text, and optionally contains an
@@ -63,11 +87,18 @@ const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR,
@private
base::scoped_nsobject<NSImageView> image_;
base::scoped_nsobject<NSTextField> text_;
+ base::scoped_nsobject<NSTextField> pairedStatus_;
}
// Designated initializer.
+// |horizontalPaddingOffset| is used to adjust the origin x of |text_|
+// when the chooser needs to show no devices found message.
- (instancetype)initWithText:(NSString*)text
- signalStrengthLevel:(NSInteger)level;
+ signalStrengthLevel:(NSInteger)level
+ isConnected:(bool)isConnected
+ isPaired:(bool)isPaired
+ rowHeight:(CGFloat)rowHeight
+ horizontalPaddingOffset:(CGFloat)horizontalPaddingOffset;
// Gets the image in front of the text.
- (NSImageView*)image;
@@ -75,46 +106,89 @@ const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR,
// Gets the text.
- (NSTextField*)text;
+// Gets the paired status.
+- (NSTextField*)pairedStatus;
+
@end
@implementation ChooserContentTableRowView
- (instancetype)initWithText:(NSString*)text
- signalStrengthLevel:(NSInteger)level {
+ signalStrengthLevel:(NSInteger)level
+ isConnected:(bool)isConnected
+ isPaired:(bool)isPaired
+ rowHeight:(CGFloat)rowHeight
+ horizontalPaddingOffset:(CGFloat)horizontalPaddingOffset {
if ((self = [super initWithFrame:NSZeroRect])) {
- if (level != -1) {
+ // Create the views.
+ // Image.
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ NSImage* image = nullptr;
+ if (isConnected) {
+ image = gfx::NSImageFromImageSkia(gfx::CreateVectorIcon(
+ gfx::VectorIconId::BLUETOOTH_CONNECTED, SK_ColorBLACK));
Evan Stade 2016/09/07 16:41:42 are you sure you want black and not kChromeIconGre
juncai 2016/09/09 20:06:15 Done.
+ } else if (level != -1) {
DCHECK_GE(level, 0);
DCHECK_LT(level, base::checked_cast<NSInteger>(
arraysize(kSignalStrengthLevelImageIds)));
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- NSImage* signalStrengthLevelImage =
- rb.GetNativeImageNamed(kSignalStrengthLevelImageIds[level])
- .ToNSImage();
+ image = rb.GetNativeImageNamed(kSignalStrengthLevelImageIds[level])
+ .ToNSImage();
+ }
+ CGFloat imageOriginX = kTableRowViewHorizontalPadding;
+ CGFloat imageOriginY = (rowHeight - kRowViewImageSize) / 2;
+ if (image) {
image_.reset([[NSImageView alloc]
- initWithFrame:NSMakeRect(0, (kTableRowViewHeight -
- kSignalStrengthLevelImageSize) /
- 2,
- kSignalStrengthLevelImageSize,
- kSignalStrengthLevelImageSize)]);
- [image_ setImage:signalStrengthLevelImage];
+ initWithFrame:NSMakeRect(imageOriginX, imageOriginY,
+ kRowViewImageSize, kRowViewImageSize)]);
+ [image_ setImage:image];
[self addSubview:image_];
}
- text_.reset([[NSTextField alloc] initWithFrame:NSZeroRect]);
- [text_ setDrawsBackground:NO];
- [text_ setBezeled:NO];
- [text_ setEditable:NO];
- [text_ setSelectable:NO];
- [text_ setStringValue:text];
- [text_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
- [text_ sizeToFit];
+ // Text.
+ text_ = CreateTextField(text);
CGFloat textHeight = NSHeight([text_ frame]);
- [text_ setFrameOrigin:NSMakePoint(
- level == -1 ? 0 : kSignalStrengthLevelImageSize +
- kHorizontalPadding,
- (kTableRowViewHeight - textHeight) / 2)];
+
+ // Paired status.
+ CGFloat pairedStatusHeight = 0.0f;
+ if (isPaired) {
+ pairedStatus_ = CreateTextField(
+ l10n_util::GetNSString(IDS_DEVICE_CHOOSER_PAIRED_STATUS_TEXT));
+ [pairedStatus_
+ setTextColor:skia::SkColorToCalibratedNSColor(gfx::kGoogleGreen700)];
+ pairedStatusHeight = NSHeight([pairedStatus_ frame]);
+ }
+
+ // Lay out the views.
+ // Text.
+ CGFloat textOriginX = imageOriginX + kRowViewImageSize +
+ kTableRowViewHorizontalPadding +
+ horizontalPaddingOffset;
+ CGFloat textOriginY;
+ if (isPaired) {
+ textOriginY = pairedStatusHeight +
+ (rowHeight - textHeight - pairedStatusHeight -
+ kTableRowViewVerticalPadding) /
+ 2 +
+ kTableRowViewVerticalPadding;
+ } else {
+ textOriginY = (rowHeight - textHeight) / 2;
+ }
+
+ [text_ setFrameOrigin:NSMakePoint(textOriginX, textOriginY)];
[self addSubview:text_];
+
+ // Paired status.
+ if (isPaired) {
+ CGFloat pairedStatusOriginX = textOriginX;
+ CGFloat pairedStatusOriginY =
+ (rowHeight - textHeight - pairedStatusHeight -
+ kTableRowViewVerticalPadding) /
+ 2;
+ [pairedStatus_
+ setFrameOrigin:NSMakePoint(pairedStatusOriginX, pairedStatusOriginY)];
+ [self addSubview:pairedStatus_];
+ }
}
return self;
@@ -128,6 +202,10 @@ const int kSignalStrengthLevelImageIds[5] = {IDR_SIGNAL_0_BAR, IDR_SIGNAL_1_BAR,
return text_.get();
}
+- (NSTextField*)pairedStatus {
+ return pairedStatus_.get();
+}
+
@end
class ChooserContentViewController : public ChooserController::View {
@@ -310,8 +388,8 @@ void ChooserContentViewController::UpdateTableView() {
titleHeight_ = NSHeight([titleView_ frame]);
// Status.
- status_ = [self createTextField:l10n_util::GetNSString(
- IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING)];
+ status_ = CreateTextField(
+ l10n_util::GetNSString(IDS_BLUETOOTH_DEVICE_CHOOSER_SCANNING));
CGFloat statusWidth = kChooserWidth / 2 - kMarginX;
// The height is arbitrary as it will be adjusted later.
[status_ setFrameSize:NSMakeSize(statusWidth, 0.0f)];
@@ -341,9 +419,8 @@ void ChooserContentViewController::UpdateTableView() {
separator_ = [self createSeparator];
// Message.
- message_ = [self createTextField:l10n_util::GetNSStringF(
- IDS_DEVICE_CHOOSER_FOOTNOTE_TEXT,
- base::string16())];
+ message_ = CreateTextField(l10n_util::GetNSStringF(
+ IDS_DEVICE_CHOOSER_FOOTNOTE_TEXT, base::string16()));
CGFloat messageWidth = NSWidth([message_ frame]);
messageHeight_ = NSHeight([message_ frame]);
@@ -489,25 +566,54 @@ void ChooserContentViewController::UpdateTableView() {
return titleView;
}
-- (base::scoped_nsobject<NSView>)createTableRowView:(NSInteger)rowIndex {
+- (base::scoped_nsobject<NSView>)createTableRowView:(NSInteger)row {
NSInteger level = -1;
+ bool isConnected = false;
+ bool isPaired = false;
+ CGFloat horizontalPaddingOffset = 0.0f;
size_t numOptions = chooserController_->NumOptions();
- if (chooserController_->ShouldShowIconBeforeText() && numOptions > 0) {
- DCHECK_GE(rowIndex, 0);
- DCHECK_LT(rowIndex, base::checked_cast<NSInteger>(numOptions));
- level = base::checked_cast<NSInteger>(
- chooserController_->GetSignalStrengthLevel(
- base::checked_cast<size_t>(rowIndex)));
+ if (numOptions == 0) {
Jeffrey Yasskin 2016/09/07 02:01:47 There are enough special cases for numOptions==0 h
juncai 2016/09/09 20:06:15 If using a different view, it will make the test c
+ DCHECK_EQ(0, row);
+ // Here since the chooser needs to show no devices found message,
+ // the text's origin x needs to be adjusted.
+ horizontalPaddingOffset =
+ -(kRowViewImageSize + kTableRowViewHorizontalPadding);
+ } else {
+ DCHECK_GE(row, 0);
+ DCHECK_LT(row, base::checked_cast<NSInteger>(numOptions));
+ size_t rowIndex = base::checked_cast<size_t>(row);
+ if (chooserController_->ShouldShowIconBeforeText()) {
+ level = base::checked_cast<NSInteger>(
+ chooserController_->GetSignalStrengthLevel(rowIndex));
+ }
+ isConnected = chooserController_->IsConnected(rowIndex);
+ isPaired = chooserController_->IsPaired(rowIndex);
}
base::scoped_nsobject<NSView> tableRowView([[ChooserContentTableRowView alloc]
- initWithText:[self optionAtIndex:rowIndex]
- signalStrengthLevel:level]);
+ initWithText:[self optionAtIndex:row]
+ signalStrengthLevel:level
+ isConnected:isConnected
+ isPaired:isPaired
+ rowHeight:[self tableRowViewHeight:row]
+ horizontalPaddingOffset:horizontalPaddingOffset]);
return tableRowView;
}
- (CGFloat)tableRowViewHeight:(NSInteger)row {
- return kTableRowViewHeight;
+ size_t numOptions = chooserController_->NumOptions();
+ if (numOptions == 0) {
+ DCHECK_EQ(0, row);
+ return kTableRowViewOneLineHeight;
+ }
+
+ DCHECK_GE(row, 0);
+ DCHECK_LT(row, base::checked_cast<NSInteger>(numOptions));
+ size_t rowIndex = base::checked_cast<size_t>(row);
+ if (chooserController_->IsPaired(rowIndex))
Jeffrey Yasskin 2016/09/07 02:01:47 This part of the calculation should be done inside
juncai 2016/09/09 20:06:15 Since https://cs.chromium.org/chromium/src/chrome/
Jeffrey Yasskin 2016/09/14 20:08:36 Yep, oh well.
+ return kTableRowViewTwoLinesHeight;
+ else
+ return kTableRowViewOneLineHeight;
}
- (base::scoped_nsobject<NSButton>)createButtonWithTitle:(NSString*)title {
@@ -540,19 +646,6 @@ void ChooserContentViewController::UpdateTableView() {
return spacer;
}
-- (base::scoped_nsobject<NSTextField>)createTextField:(NSString*)text {
- base::scoped_nsobject<NSTextField> textField(
- [[NSTextField alloc] initWithFrame:NSZeroRect]);
- [textField setDrawsBackground:NO];
- [textField setBezeled:NO];
- [textField setEditable:NO];
- [textField setSelectable:NO];
- [textField setStringValue:text];
- [textField setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]];
- [textField sizeToFit];
- return textField;
-}
-
- (base::scoped_nsobject<NSButton>)createHyperlinkButtonWithText:
(NSString*)text {
base::scoped_nsobject<NSButton> button(
@@ -704,4 +797,10 @@ void ChooserContentViewController::UpdateTableView() {
return [tableRowView text];
}
+- (NSTextField*)tableRowViewPairedStatus:(NSInteger)row {
+ ChooserContentTableRowView* tableRowView =
+ [tableView_ viewAtColumn:0 row:row makeIfNecessary:YES];
+ return [tableRowView pairedStatus];
+}
+
@end

Powered by Google App Engine
This is Rietveld 408576698