Commit c44c6a9a authored by tapted's avatar tapted Committed by Commit bot

MacViews: TouchBar integration for toolkit-views dialogs.

Native Mac NSAlert dialogs show the dialog buttons on the TouchBar, we
want similar behaviour for Chrome dialogs.

If a Widget's delegate implements views::DialogDelegate, add buttons to
the touchbar for the "OK" and "Cancel" buttons. Note the labels might
not necessarily be labeled "OK" and "Cancel".

Nearly all dialogs and bubbles work correctly with the TouchBar this
way. One exception is the Add Bookmark bubble -
LocationBarBubbleDelegateView::GetDialogButtons() returns
ui::DIALOG_BUTTON_NONE. That makes sense for the ZoomBubble.
SaveCardBubbleViews overrides again to return both buttons and works.
The translate bubble has "TODO: This should be using GetDialogButtons."

Screenshot: http://crbug.com/660126#c13

BUG=661581

Review-Url: https://codereview.chromium.org/2469213002
Cr-Commit-Position: refs/heads/master@{#430209}
parent be675544
...@@ -289,6 +289,20 @@ BASE_EXPORT extern NSString* const NSAppearanceNameVibrantLight; ...@@ -289,6 +289,20 @@ BASE_EXPORT extern NSString* const NSAppearanceNameVibrantLight;
#endif // MAC_OS_X_VERSION_10_12 #endif // MAC_OS_X_VERSION_10_12
// Once Chrome no longer supports OSX 10.12.0, everything within this
// preprocessor block can be removed.
#if !defined(MAC_OS_X_VERSION_10_12_1) || \
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_1
@interface NSButton (SierraPointOneSDK)
@property(copy) NSColor* bezelColor;
+ (instancetype)buttonWithTitle:(NSString*)title
target:(id)target
action:(SEL)action;
@end
#endif // MAC_OS_X_VERSION_10_12_1
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// The symbol for kCWSSIDDidChangeNotification is available in the // The symbol for kCWSSIDDidChangeNotification is available in the
// CoreWLAN.framework for OSX versions 10.6 through 10.10. The symbol is not // CoreWLAN.framework for OSX versions 10.6 through 10.10. The symbol is not
......
...@@ -130,6 +130,7 @@ component("base") { ...@@ -130,6 +130,7 @@ component("base") {
"cocoa/three_part_image.mm", "cocoa/three_part_image.mm",
"cocoa/tool_tip_base_view.h", "cocoa/tool_tip_base_view.h",
"cocoa/tool_tip_base_view.mm", "cocoa/tool_tip_base_view.mm",
"cocoa/touch_bar_forward_declarations.h",
"cocoa/tracking_area.h", "cocoa/tracking_area.h",
"cocoa/tracking_area.mm", "cocoa/tracking_area.mm",
"cocoa/underlay_opengl_hosting_window.h", "cocoa/underlay_opengl_hosting_window.h",
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_COCOA_TOUCH_BAR_FORWARD_DECLARATIONS_H_
#define UI_BASE_COCOA_TOUCH_BAR_FORWARD_DECLARATIONS_H_
// Once Chrome no longer supports OSX 10.12.0, this file can be deleted.
#import <Foundation/Foundation.h>
#if !defined(MAC_OS_X_VERSION_10_12_1)
// The TouchBar classes do not exist at all without the 10.12.1 SDK. When
// compiling with older SDKs, pretend they are NSObject and add categories to
// NSObject to expose the methods.
// To alloc one of these classes, use -[NSClassFromString(@"..") alloc].
// Incomplete. Add more as necessary.
typedef NSObject NSCustomTouchBarItem;
typedef NSObject NSGroupTouchBarItem;
typedef NSObject NSTouchBar;
typedef NSObject NSTouchBarItem;
typedef NSString* NSTouchBarItemIdentifier;
@protocol NSTouchBarDelegate<NSObject>
@end
@interface NSObject (FakeNSCustomTouchBarItem)
@property(readwrite, strong) NSView* view;
@end
@interface NSObject (FakeNSGroupTouchBarItem)
+ (NSGroupTouchBarItem*)groupItemWithIdentifier:
(NSTouchBarItemIdentifier)identifier
items:(NSArray*)items;
@end
@interface NSObject (FakeNSTouchBar)
@property(copy) NSArray* defaultItemIdentifiers;
@property(copy) NSTouchBarItemIdentifier principalItemIdentifier;
@property(weak) id<NSTouchBarDelegate> delegate;
@end
#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12_1
// When compiling against the 10.12.1 SDK or later, just provide forward
// declarations to suppress the partial availability warnings.
@class NSCustomTouchBarItem;
@class NSGroupTouchBarItem;
@class NSTouchBar;
@protocol NSTouchBarDelegate;
@class NSTouchBarItem;
#endif // MAC_OS_X_VERSION_10_12_1
#endif // UI_BASE_COCOA_TOUCH_BAR_FORWARD_DECLARATIONS_H_
...@@ -62,6 +62,7 @@ component("views") { ...@@ -62,6 +62,7 @@ component("views") {
"button_drag_utils.h", "button_drag_utils.h",
"cocoa/bridged_content_view.h", "cocoa/bridged_content_view.h",
"cocoa/bridged_content_view.mm", "cocoa/bridged_content_view.mm",
"cocoa/bridged_content_view_touch_bar.mm",
"cocoa/bridged_native_widget.h", "cocoa/bridged_native_widget.h",
"cocoa/bridged_native_widget.mm", "cocoa/bridged_native_widget.mm",
"cocoa/bridged_native_widget_owner.h", "cocoa/bridged_native_widget_owner.h",
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "base/mac/scoped_nsobject.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/strings/sys_string_conversions.h"
#import "ui/base/cocoa/touch_bar_forward_declarations.h"
#include "ui/base/models/dialog_model.h"
#import "ui/views/cocoa/bridged_content_view.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/views/window/dialog_client_view.h"
#include "ui/views/window/dialog_delegate.h"
namespace {
NSString* const kTouchBarDialogButtonsGroupId =
@"com.google.chrome-DIALOG-BUTTONS-GROUP";
NSString* const kTouchBarOKId = @"com.google.chrome-OK";
NSString* const kTouchBarCancelId = @"com.google.chrome-CANCEL";
} // namespace
@interface BridgedContentView (TouchBarAdditions)<NSTouchBarDelegate>
- (void)touchBarButtonAction:(id)sender;
@end
@implementation BridgedContentView (TouchBarAdditions)
- (void)touchBarButtonAction:(id)sender {
if (!hostedView_)
return;
views::DialogDelegate* dialog =
hostedView_->GetWidget()->widget_delegate()->AsDialogDelegate();
DCHECK(dialog);
views::DialogClientView* client = dialog->GetDialogClientView();
if ([sender tag] == ui::DIALOG_BUTTON_OK) {
client->AcceptWindow();
return;
}
DCHECK_EQ([sender tag], ui::DIALOG_BUTTON_CANCEL);
client->CancelWindow();
}
// NSTouchBarDelegate protocol implementation.
- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
if (!hostedView_)
return nil;
if ([identifier isEqualToString:kTouchBarDialogButtonsGroupId]) {
NSMutableArray* items = [NSMutableArray arrayWithCapacity:2];
for (NSTouchBarItemIdentifier i in @[ kTouchBarCancelId, kTouchBarOKId ]) {
NSTouchBarItem* item = [self touchBar:touchBar makeItemForIdentifier:i];
if (item)
[items addObject:item];
}
if ([items count] == 0)
return nil;
return [NSGroupTouchBarItem groupItemWithIdentifier:identifier items:items];
}
ui::DialogButton type = ui::DIALOG_BUTTON_NONE;
if ([identifier isEqualToString:kTouchBarOKId])
type = ui::DIALOG_BUTTON_OK;
else if ([identifier isEqualToString:kTouchBarCancelId])
type = ui::DIALOG_BUTTON_CANCEL;
else
return nil;
ui::DialogModel* model =
hostedView_->GetWidget()->widget_delegate()->AsDialogDelegate();
if (!model || !(model->GetDialogButtons() & type))
return nil;
base::scoped_nsobject<NSCustomTouchBarItem> item([[NSClassFromString(
@"NSCustomTouchBarItem") alloc] initWithIdentifier:identifier]);
NSString* title = base::SysUTF16ToNSString(model->GetDialogButtonLabel(type));
NSButton* button =
[NSButton buttonWithTitle:title
target:self
action:@selector(touchBarButtonAction:)];
if (type == model->GetDefaultDialogButton()) {
// NSAlert uses a private NSButton subclass (_NSTouchBarGroupButton) with
// more bells and whistles. It doesn't use -setBezelColor: directly, but
// this gives an appearance matching the default _NSTouchBarGroupButton.
[button setBezelColor:[NSColor colorWithSRGBRed:0.168
green:0.51
blue:0.843
alpha:1.0]];
}
[button setEnabled:model->IsDialogButtonEnabled(type)];
[button setTag:type];
[item setView:button];
return item.autorelease();
}
// NSTouchBarProvider protocol implementation (via NSResponder category).
- (NSTouchBar*)makeTouchBar {
if (!hostedView_)
return nil;
ui::DialogModel* model =
hostedView_->GetWidget()->widget_delegate()->AsDialogDelegate();
if (!model || !model->GetDialogButtons())
return nil;
base::scoped_nsobject<NSTouchBar> bar(
[[NSClassFromString(@"NSTouchBar") alloc] init]);
[bar setDelegate:self];
// Use a group rather than individual items so they can be centered together.
[bar setDefaultItemIdentifiers:@[ kTouchBarDialogButtonsGroupId ]];
// Setting the group as principal will center it in the TouchBar.
[bar setPrincipalItemIdentifier:kTouchBarDialogButtonsGroupId];
return bar.autorelease();
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment