Commit 96c5cd3d authored by Nico Weber's avatar Nico Weber Committed by Commit Bot

mac: Remove unused cocoa SadTab and HoverImageMenuButton code.

Bug: 832676
Change-Id: I12724b2c0bd76aa86b598f5a23b8c20decf3ba92
Reviewed-on: https://chromium-review.googlesource.com/1239639
Commit-Queue: Nico Weber <thakis@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593460}
parent c635c06e
...@@ -286,9 +286,6 @@ jumbo_split_static_library("ui") { ...@@ -286,9 +286,6 @@ jumbo_split_static_library("ui") {
"cocoa/tab_contents/favicon_util_mac.mm", "cocoa/tab_contents/favicon_util_mac.mm",
"cocoa/tab_contents/overlayable_contents_controller.h", "cocoa/tab_contents/overlayable_contents_controller.h",
"cocoa/tab_contents/overlayable_contents_controller.mm", "cocoa/tab_contents/overlayable_contents_controller.mm",
"cocoa/tab_contents/sad_tab_mac.mm",
"cocoa/tab_contents/sad_tab_view_cocoa.h",
"cocoa/tab_contents/sad_tab_view_cocoa.mm",
"cocoa/tab_contents/tab_contents_controller.h", "cocoa/tab_contents/tab_contents_controller.h",
"cocoa/tab_contents/tab_contents_controller.mm", "cocoa/tab_contents/tab_contents_controller.mm",
"cocoa/tab_modal_confirm_dialog_mac.h", "cocoa/tab_modal_confirm_dialog_mac.h",
......
// Copyright (c) 2011 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 "chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h"
#include "chrome/browser/ui/sad_tab.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/ui_features.h"
namespace {
class SadTabCocoa : public SadTab {
public:
SadTabCocoa(content::WebContents* web_contents, SadTabKind kind)
: SadTab(web_contents, kind) {
NSView* web_contents_view = web_contents->GetNativeView();
sad_tab_view_ =
[[SadTabViewCocoa alloc] initWithFrame:web_contents_view.bounds
sadTab:this];
[web_contents_view addSubview:sad_tab_view_];
[sad_tab_view_ release];
}
~SadTabCocoa() override { [sad_tab_view_ removeFromSuperview]; }
private:
// Owned by web_contents
SadTabViewCocoa* sad_tab_view_;
};
} // namespace
SadTab* SadTab::CreateCocoa(content::WebContents* web_contents,
SadTabKind kind) {
return new SadTabCocoa(web_contents, kind);
}
#if !BUILDFLAG(MAC_VIEWS_BROWSER)
SadTab* SadTab::Create(content::WebContents* web_contents, SadTabKind kind) {
return CreateCocoa(web_contents, kind);
}
#endif
// Copyright (c) 2012 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 "chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h"
#import "base/mac/foundation_util.h"
#include "base/mac/scoped_nsobject.h"
#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "ui/base/cocoa/controls/hyperlink_text_view.h"
namespace {
template <typename T>
T* FindSadTabSubview(NSView* sadTabView) {
NSView* containerView = sadTabView.subviews.firstObject;
for (NSView* view in [containerView subviews]) {
if (auto subview = base::mac::ObjCCast<T>(view))
return subview;
}
return nil;
}
class SadTabViewTest : public CocoaTest {
public:
SadTabViewTest() {
base::scoped_nsobject<SadTabViewCocoa> view([SadTabViewCocoa new]);
view_ = view;
[[test_window() contentView] addSubview:view_];
}
SadTabViewCocoa* view_; // Weak. Owned by the view hierarchy.
};
TEST_VIEW(SadTabViewTest, view_);
TEST(SadTabViewBehaviorTest, ClickOnLinks) {
using Action = SadTab::Action;
class MockSadTab : public SadTab {
public:
MockSadTab() : SadTab(nullptr, SAD_TAB_KIND_CRASHED) {}
MOCK_METHOD0(RecordFirstPaint, void());
MOCK_METHOD1(PerformAction, void(Action));
};
MockSadTab sadTab;
base::scoped_nsobject<SadTabViewCocoa> view(
[[SadTabViewCocoa alloc] initWithFrame:NSZeroRect sadTab:&sadTab]);
EXPECT_CALL(sadTab, RecordFirstPaint());
EXPECT_CALL(sadTab, PerformAction(testing::TypedEq<Action>(Action::BUTTON)));
EXPECT_CALL(sadTab,
PerformAction(testing::TypedEq<Action>(Action::HELP_LINK)));
[view displayIfNeeded];
[FindSadTabSubview<NSButton>(view) performClick:nil];
[FindSadTabSubview<HyperlinkTextView>(view) clickedOnLink:[NSNull null]
atIndex:0];
}
} // namespace
// Copyright (c) 2012 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 CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_COCOA_H_
#define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_COCOA_H_
#import <Cocoa/Cocoa.h>
#include "chrome/browser/ui/sad_tab.h"
// A view that displays the "sad tab" (aka crash page).
@interface SadTabViewCocoa : NSView
- (instancetype)initWithFrame:(NSRect)frame sadTab:(SadTab*)sadTab;
@end
#endif // CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_COCOA_H_
// Copyright (c) 2012 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.
#include "chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h"
#include <vector>
#import "base/mac/foundation_util.h"
#include "components/grit/components_scaled_resources.h"
#import "ui/base/cocoa/controls/blue_label_button.h"
#import "ui/base/cocoa/controls/hyperlink_text_view.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "ui/base/resource/resource_bundle.h"
namespace {
// Maximum width used by page contents.
const CGFloat kMaxContainerWidth = 600;
// Padding between icon and title.
const CGFloat kIconTitleSpacing = 40;
// Space between lines of the title.
const CGFloat kTitleLineSpacing = 6;
// Padding between title and message.
const CGFloat kTitleMessageSpacing = 18;
// Padding between message and link.
const CGFloat kMessageLinkSpacing = 50;
// Padding between message and button.
const CGFloat kMessageButtonSpacing = 44;
// Minimum margins on all sides.
const CGFloat kTabMargin = 13;
// Maximum margin on top.
const CGFloat kMaxTopMargin = 130;
} // namespace
@interface SadTabContainerView : NSView
@end
@implementation SadTabContainerView
- (BOOL)isFlipped {
return YES;
}
@end
@interface SadTabViewCocoa ()<NSTextViewDelegate>
@end
@implementation SadTabViewCocoa {
NSView* container_;
NSTextView* message_;
HyperlinkTextView* help_;
NSButton* button_;
SadTab* sadTab_;
BOOL recordedFirstPaint_;
}
- (instancetype)initWithFrame:(NSRect)frame sadTab:(SadTab*)sadTab {
if ((self = [super initWithFrame:frame])) {
sadTab_ = sadTab;
recordedFirstPaint_ = NO;
self.wantsLayer = YES;
self.layer.backgroundColor =
[NSColor colorWithCalibratedWhite:245.0f / 255.0f alpha:1.0].CGColor;
container_ = [[SadTabContainerView new] autorelease];
NSImage* iconImage = ui::ResourceBundle::GetSharedInstance()
.GetNativeImageNamed(IDR_CRASH_SAD_TAB)
.ToNSImage();
NSImageView* icon = [[NSImageView new] autorelease];
icon.image = iconImage;
icon.frameSize = iconImage.size;
[container_ addSubview:icon];
message_ = [[[NSTextView alloc]
initWithFrame:NSMakeRect(0, NSMaxY(icon.frame) + kIconTitleSpacing,
NSWidth(container_.bounds), 0)] autorelease];
message_.editable = NO;
message_.drawsBackground = NO;
message_.autoresizingMask = NSViewWidthSizable;
NSMutableParagraphStyle* titleParagraphStyle =
[[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
titleParagraphStyle.lineSpacing = kTitleLineSpacing;
titleParagraphStyle.paragraphSpacing =
kTitleMessageSpacing - kTitleLineSpacing;
[message_.textStorage
appendAttributedString:
[[[NSAttributedString alloc]
initWithString:[NSString
stringWithFormat:@"%@\n",
l10n_util::GetNSString(
sadTab->GetTitle())]
attributes:@{
NSParagraphStyleAttributeName : titleParagraphStyle,
NSFontAttributeName : [NSFont systemFontOfSize:24],
NSForegroundColorAttributeName :
[NSColor colorWithCalibratedWhite:38.0f / 255.0f
alpha:1.0],
}] autorelease]];
NSFont* messageFont = [NSFont systemFontOfSize:14];
NSColor* messageColor =
[NSColor colorWithCalibratedWhite:81.0f / 255.0f alpha:1.0];
[message_.textStorage
appendAttributedString:[[[NSAttributedString alloc]
initWithString:l10n_util::GetNSString(
sadTab->GetInfoMessage())
attributes:@{
NSFontAttributeName : messageFont,
NSForegroundColorAttributeName :
messageColor,
}] autorelease]];
std::vector<int> subMessages = sadTab->GetSubMessages();
if (!subMessages.empty()) {
NSTextList* textList =
[[[NSTextList alloc] initWithMarkerFormat:@"{disc}" options:0]
autorelease];
NSMutableParagraphStyle* paragraphStyle =
[[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
paragraphStyle.textLists = @[ textList ];
paragraphStyle.paragraphSpacingBefore = messageFont.capHeight;
paragraphStyle.headIndent =
static_cast<NSTextTab*>(paragraphStyle.tabStops[1]).location;
NSMutableString* subMessageString = [NSMutableString string];
for (int subMessage : subMessages) {
// All markers are disc so pass 0 here for item number.
[subMessageString appendFormat:@"\n\t%@\t%@",
[textList markerForItemNumber:0],
l10n_util::GetNSString(subMessage)];
}
[message_.textStorage
appendAttributedString:[[[NSAttributedString alloc]
initWithString:subMessageString
attributes:@{
NSParagraphStyleAttributeName :
paragraphStyle,
NSFontAttributeName : messageFont,
NSForegroundColorAttributeName :
messageColor,
}] autorelease]];
}
[message_ sizeToFit];
[container_ addSubview:message_];
NSString* helpLinkTitle =
l10n_util::GetNSString(sadTab->GetHelpLinkTitle());
help_ = [[[HyperlinkTextView alloc]
initWithFrame:NSMakeRect(0, 0, 1, message_.font.pointSize + 4)]
autorelease];
help_.delegate = self;
help_.autoresizingMask = NSViewWidthSizable;
help_.textContainer.lineFragmentPadding = 2; // To align with message_.
[help_ setMessage:helpLinkTitle
withFont:messageFont
messageColor:messageColor];
[help_ addLinkRange:NSMakeRange(0, helpLinkTitle.length)
withURL:@(sadTab->GetHelpLinkURL())
linkColor:messageColor];
[help_ sizeToFit];
[container_ addSubview:help_];
button_ = [[BlueLabelButton new] autorelease];
button_.target = self;
button_.action = @selector(buttonClicked);
button_.title = l10n_util::GetNSString(sadTab->GetButtonTitle());
[button_ sizeToFit];
[container_ addSubview:button_];
[self addSubview:container_];
[self resizeSubviewsWithOldSize:self.bounds.size];
}
return self;
}
- (BOOL)isOpaque {
return YES;
}
- (BOOL)isFlipped {
return YES;
}
- (void)updateLayer {
// updateLayer seems to be called whenever NSBackingLayerDisplayIfNeeded is
// called by AppKit, which could be multiple times - at least twice has been
// observed. Guard against repeated recordings of first paint.
if (!recordedFirstPaint_) {
sadTab_->RecordFirstPaint();
recordedFirstPaint_ = YES;
}
}
- (void)resizeSubviewsWithOldSize:(NSSize)oldSize {
[super resizeSubviewsWithOldSize:oldSize];
NSSize size = self.bounds.size;
NSSize containerSize = NSMakeSize(
std::min(size.width - 2 * kTabMargin, kMaxContainerWidth), size.height);
// Set the container's size first because text wrapping depends on its width.
container_.frameSize = containerSize;
help_.frameOrigin =
NSMakePoint(0, NSMaxY(message_.frame) + kMessageLinkSpacing);
button_.frameOrigin =
NSMakePoint(containerSize.width - NSWidth(button_.bounds),
NSMaxY(message_.frame) + kMessageButtonSpacing);
containerSize.height = NSMaxY(button_.frame);
container_.frameSize = containerSize;
// Center. Top margin is must be between kTabMargin and kMaxTopMargin.
container_.frameOrigin = NSMakePoint(
floor((size.width - containerSize.width) / 2),
std::min(kMaxTopMargin,
std::max(kTabMargin,
size.height - containerSize.height - kTabMargin)));
}
- (void)buttonClicked {
sadTab_->PerformAction(SadTab::Action::BUTTON);
}
// Called when someone clicks on the embedded link.
- (BOOL)textView:(NSTextView*)textView
clickedOnLink:(id)link
atIndex:(NSUInteger)charIndex {
sadTab_->PerformAction(SadTab::Action::HELP_LINK);
return YES;
}
@end
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/chrome_typography.h"
#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views_mode_controller.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -226,9 +225,5 @@ void SadTabView::RemovedFromWidget() { ...@@ -226,9 +225,5 @@ void SadTabView::RemovedFromWidget() {
SadTab* SadTab::Create(content::WebContents* web_contents, SadTab* SadTab::Create(content::WebContents* web_contents,
SadTabKind kind) { SadTabKind kind) {
#if defined(OS_MACOSX)
if (views_mode_controller::IsViewsBrowserCocoa())
return CreateCocoa(web_contents, kind);
#endif
return new SadTabView(web_contents, kind); return new SadTabView(web_contents, kind);
} }
...@@ -4200,7 +4200,6 @@ test("unit_tests") { ...@@ -4200,7 +4200,6 @@ test("unit_tests") {
"../browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm", "../browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm",
"../browser/ui/cocoa/styled_text_field_cell_unittest.mm", "../browser/ui/cocoa/styled_text_field_cell_unittest.mm",
"../browser/ui/cocoa/styled_text_field_unittest.mm", "../browser/ui/cocoa/styled_text_field_unittest.mm",
"../browser/ui/cocoa/tab_contents/sad_tab_mac_unittest.mm",
"../browser/ui/cocoa/tabbed_browser_window_unittest.mm", "../browser/ui/cocoa/tabbed_browser_window_unittest.mm",
"../browser/ui/cocoa/tabs/alert_indicator_button_cocoa_unittest.mm", "../browser/ui/cocoa/tabs/alert_indicator_button_cocoa_unittest.mm",
"../browser/ui/cocoa/tabs/tab_controller_unittest.mm", "../browser/ui/cocoa/tabs/tab_controller_unittest.mm",
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<grit-part> <grit-part>
<structure type="chrome_scaled_image" name="IDR_CRASH_SAD_FAVICON" file="crash/favicon_sad_tab.png" /> <structure type="chrome_scaled_image" name="IDR_CRASH_SAD_FAVICON" file="crash/favicon_sad_tab.png" />
<if expr="is_macosx or is_ios"> <if expr="is_ios">
<structure type="chrome_scaled_image" name="IDR_CRASH_SAD_TAB" file="crash/legacy/sadtab.png" /> <structure type="chrome_scaled_image" name="IDR_CRASH_SAD_TAB" file="crash/legacy/sadtab.png" />
</if> </if>
</grit-part> </grit-part>
...@@ -103,14 +103,8 @@ jumbo_component("base") { ...@@ -103,14 +103,8 @@ jumbo_component("base") {
"cocoa/command_dispatcher.mm", "cocoa/command_dispatcher.mm",
"cocoa/constrained_window/constrained_window_animation.h", "cocoa/constrained_window/constrained_window_animation.h",
"cocoa/constrained_window/constrained_window_animation.mm", "cocoa/constrained_window/constrained_window_animation.mm",
"cocoa/controls/blue_label_button.h",
"cocoa/controls/blue_label_button.mm",
"cocoa/controls/button_utils.h", "cocoa/controls/button_utils.h",
"cocoa/controls/button_utils.mm", "cocoa/controls/button_utils.mm",
"cocoa/controls/hover_image_menu_button.h",
"cocoa/controls/hover_image_menu_button.mm",
"cocoa/controls/hover_image_menu_button_cell.h",
"cocoa/controls/hover_image_menu_button_cell.mm",
"cocoa/controls/hyperlink_button_cell.h", "cocoa/controls/hyperlink_button_cell.h",
"cocoa/controls/hyperlink_button_cell.mm", "cocoa/controls/hyperlink_button_cell.mm",
"cocoa/controls/hyperlink_text_view.h", "cocoa/controls/hyperlink_text_view.h",
...@@ -873,8 +867,6 @@ test("ui_base_unittests") { ...@@ -873,8 +867,6 @@ test("ui_base_unittests") {
"cocoa/bubble_closer_unittest.mm", "cocoa/bubble_closer_unittest.mm",
"cocoa/cocoa_base_utils_unittest.mm", "cocoa/cocoa_base_utils_unittest.mm",
"cocoa/constrained_window/constrained_window_animation_unittest.mm", "cocoa/constrained_window/constrained_window_animation_unittest.mm",
"cocoa/controls/blue_label_button_unittest.mm",
"cocoa/controls/hover_image_menu_button_unittest.mm",
"cocoa/controls/hyperlink_button_cell_unittest.mm", "cocoa/controls/hyperlink_button_cell_unittest.mm",
"cocoa/controls/hyperlink_text_view_unittest.mm", "cocoa/controls/hyperlink_text_view_unittest.mm",
"cocoa/focus_tracker_unittest.mm", "cocoa/focus_tracker_unittest.mm",
......
// Copyright 2013 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_CONTROLS_BLUE_LABEL_BUTTON_H_
#define UI_BASE_COCOA_CONTROLS_BLUE_LABEL_BUTTON_H_
#import <Cocoa/Cocoa.h>
#import "ui/base/cocoa/hover_button.h"
#include "ui/base/ui_base_export.h"
// A rectangular blue NSButton that reacts to hover, focus and lit states. It
// can contain an arbitrary single-line text label, and will be sized to fit the
// font height and label width.
UI_BASE_EXPORT
@interface BlueLabelButton : HoverButtonCocoa
@end
#endif // UI_BASE_COCOA_CONTROLS_BLUE_LABEL_BUTTON_H_
// Copyright 2013 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 "ui/base/cocoa/controls/blue_label_button.h"
#include "base/mac/foundation_util.h"
#include "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/cocoa/scoped_cg_context_smooth_fonts.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
const CGFloat kCornerRadius = 2;
const CGFloat kTopBottomTextPadding = 7;
const CGFloat kLeftRightTextPadding = 15;
const SkColor kTextShadowColor = SkColorSetRGB(0x53, 0x8c, 0xea);
const SkColor kShadowColor = SkColorSetRGB(0xe9, 0xe9, 0xe9);
const SkColor kDefaultColor = SkColorSetRGB(0x5a, 0x97, 0xff);
const SkColor kHoverColor = SkColorSetRGB(0x55, 0x8f, 0xf3);
const SkColor kPressedColor = SkColorSetRGB(0x42, 0x79, 0xd8);
const SkColor kInnerRingColor = SkColorSetRGB(0x64, 0x9e, 0xff);
const SkColor kFocusInnerRingColor = SkColorSetRGB(0xad, 0xcc, 0xff);
const SkColor kPressInnerRingColor = SkColorSetRGB(0x3f, 0x73, 0xcd);
const SkColor kOuterRingColor = SkColorSetRGB(0x2b, 0x67, 0xce);
const SkColor kPressOuterRingColor = SkColorSetRGB(0x23, 0x52, 0xa2);
const int kFontSizeDelta = ui::ResourceBundle::kSmallFontDelta;
@interface BlueLabelButtonCell : NSButtonCell
+ (NSAttributedString*)generateAttributedString:(NSString*)buttonText;
@end
@implementation BlueLabelButton
+ (Class)cellClass {
return [BlueLabelButtonCell class];
}
- (id)initWithFrame:(NSRect)frameRect {
if ((self = [super initWithFrame:frameRect])) {
[self setBezelStyle:NSSmallSquareBezelStyle];
}
return self;
}
@end
@implementation BlueLabelButtonCell
+ (NSAttributedString*)generateAttributedString:(NSString*)buttonText {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
NSFont* buttonFont = rb.GetFontWithDelta(kFontSizeDelta).GetNativeFont();
base::scoped_nsobject<NSMutableParagraphStyle> buttonTextParagraphStyle(
[[NSMutableParagraphStyle alloc] init]);
[buttonTextParagraphStyle setAlignment:NSCenterTextAlignment];
base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
[shadow setShadowOffset:NSMakeSize(0, -1)];
[shadow setShadowBlurRadius:0];
[shadow setShadowColor:skia::SkColorToSRGBNSColor(kTextShadowColor)];
NSDictionary* buttonTextAttributes = @{
NSParagraphStyleAttributeName : buttonTextParagraphStyle,
NSFontAttributeName : buttonFont,
NSForegroundColorAttributeName : [NSColor whiteColor],
NSShadowAttributeName : shadow.get()
};
base::scoped_nsobject<NSAttributedString> attributedButtonText(
[[NSAttributedString alloc] initWithString:buttonText
attributes:buttonTextAttributes]);
return attributedButtonText.autorelease();
}
- (NSSize)cellSize {
NSAttributedString* attributedTitle =
[[self class] generateAttributedString:[self title]];
NSSize textSize = [attributedTitle size];
// Add 1 to maintain identical height w/ previous drawing code.
textSize.height += 2 * kTopBottomTextPadding + 1;
textSize.width += 2 * kLeftRightTextPadding;
return textSize;
}
- (NSRect)drawTitle:(NSAttributedString*)title
withFrame:(NSRect)frame
inView:(NSView*)controlView {
// Fuzz factor to adjust for the drop shadow. Based on visual inspection.
frame.origin.y -= 1;
ui::ScopedCGContextSmoothFonts fontSmoothing;
NSAttributedString* attributedTitle =
[[self class] generateAttributedString:[self title]];
[attributedTitle drawInRect:frame];
return frame;
}
- (void)drawBezelWithFrame:(NSRect)frame
inView:(NSView*)controlView {
NSColor* centerColor;
NSColor* innerColor;
NSColor* outerColor;
CloseButtonHoverState hoverState =
[base::mac::ObjCCastStrict<HoverButtonCocoa>(controlView) hoverState];
// Leave a sliver of height 1 for the button drop shadow.
frame.size.height -= 1;
if (hoverState == kHoverStateMouseDown && [self isHighlighted]) {
centerColor = skia::SkColorToSRGBNSColor(kPressedColor);
innerColor = skia::SkColorToSRGBNSColor(kPressInnerRingColor);
outerColor = skia::SkColorToSRGBNSColor(kPressOuterRingColor);
} else {
centerColor = hoverState == kHoverStateMouseOver ?
skia::SkColorToSRGBNSColor(kHoverColor) :
skia::SkColorToSRGBNSColor(kDefaultColor);
innerColor = [self showsFirstResponder] ?
skia::SkColorToSRGBNSColor(kFocusInnerRingColor) :
skia::SkColorToSRGBNSColor(kInnerRingColor);
outerColor = skia::SkColorToSRGBNSColor(kOuterRingColor);
}
{
gfx::ScopedNSGraphicsContextSaveGState context;
base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
[shadow setShadowOffset:NSMakeSize(0, -1)];
[shadow setShadowBlurRadius:1.0];
[shadow setShadowColor:skia::SkColorToSRGBNSColor(kShadowColor)];
[shadow set];
[outerColor set];
[[NSBezierPath bezierPathWithRoundedRect:frame
xRadius:kCornerRadius
yRadius:kCornerRadius] fill];
}
[innerColor set];
[[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1, 1)
xRadius:kCornerRadius
yRadius:kCornerRadius] fill];
[centerColor set];
[[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2, 2)
xRadius:kCornerRadius
yRadius:kCornerRadius] fill];
}
@end
// Copyright 2013 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 "ui/base/cocoa/controls/blue_label_button.h"
#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#import "testing/gtest_mac.h"
#import "ui/base/test/cocoa_helper.h"
namespace ui {
namespace test {
class BlueLabelButtonTest : public ui::CocoaTest {
public:
BlueLabelButtonTest() {}
// ui::CocoaTest override:
void SetUp() override;
protected:
base::scoped_nsobject<BlueLabelButton> blue_label_button_;
private:
DISALLOW_COPY_AND_ASSIGN(BlueLabelButtonTest);
};
void BlueLabelButtonTest::SetUp() {
blue_label_button_.reset([[BlueLabelButton alloc] initWithFrame:NSZeroRect]);
[blue_label_button_ setTitle:@"Test Title"];
[blue_label_button_ sizeToFit];
ui::CocoaTest::SetUp();
[[test_window() contentView] addSubview:blue_label_button_];
}
TEST_VIEW(BlueLabelButtonTest, blue_label_button_);
} // namespace test
} // namespace ui
// Copyright 2013 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_CONTROLS_HOVER_IMAGE_MENU_BUTTON_H_
#define UI_BASE_COCOA_CONTROLS_HOVER_IMAGE_MENU_BUTTON_H_
#import <Cocoa/Cocoa.h>
#import "ui/base/cocoa/tracking_area.h"
#include "ui/base/ui_base_export.h"
@class HoverImageMenuButtonCell;
// An NSPopUpButton that additionally tracks mouseover state and calls
// [[self cell] setHovered:flag] when the hover state changes. Uses
// HoverImageMenuButtonCell as the default cellClass. Note that the menu item at
// index 0 is ignored and client code should populate it with a dummy item.
UI_BASE_EXPORT
@interface HoverImageMenuButton : NSPopUpButton {
@private
ui::ScopedCrTrackingArea trackingArea_;
}
- (HoverImageMenuButtonCell*)hoverImageMenuButtonCell;
@end
#endif // UI_BASE_COCOA_CONTROLS_HOVER_IMAGE_MENU_BUTTON_H_
// Copyright 2013 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 "ui/base/cocoa/controls/hover_image_menu_button.h"
#include "base/mac/foundation_util.h"
#import "ui/base/cocoa/controls/hover_image_menu_button_cell.h"
@implementation HoverImageMenuButton
+ (Class)cellClass {
return [HoverImageMenuButtonCell class];
}
- (id)initWithFrame:(NSRect)frameRect
pullsDown:(BOOL)flag {
if ((self = [super initWithFrame:frameRect
pullsDown:flag])) {
trackingArea_.reset(
[[CrTrackingArea alloc] initWithRect:NSZeroRect
options:NSTrackingInVisibleRect |
NSTrackingMouseEnteredAndExited |
NSTrackingActiveInKeyWindow
owner:self
userInfo:nil]);
[self addTrackingArea:trackingArea_.get()];
}
return self;
}
- (HoverImageMenuButtonCell*)hoverImageMenuButtonCell {
return base::mac::ObjCCastStrict<HoverImageMenuButtonCell>([self cell]);
}
- (void)mouseEntered:(NSEvent*)theEvent {
[[self cell] setHovered:YES];
}
- (void)mouseExited:(NSEvent*)theEvent {
[[self cell] setHovered:NO];
}
@end
// Copyright 2013 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_CONTROLS_HOVER_IMAGE_MENU_BUTTON_CELL_H_
#define UI_BASE_COCOA_CONTROLS_HOVER_IMAGE_MENU_BUTTON_CELL_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#include "ui/base/ui_base_export.h"
// A custom NSPopUpButtonCell that permits a hover image, and draws only an
// image in its frame; no border, bezel or drop-down arrow. Use setDefaultImage:
// to set the default image, setAlternateImage: to set the button shown while
// the menu is active, and setHoverImage: for the mouseover hover image.
UI_BASE_EXPORT
@interface HoverImageMenuButtonCell : NSPopUpButtonCell {
@private
base::scoped_nsobject<NSImage> hoverImage_;
BOOL hovered_;
}
@property(retain, nonatomic) NSImage* hoverImage;
@property(assign, nonatomic, getter=isHovered) BOOL hovered;
// Return the image that would be drawn based on the current state flags.
- (NSImage*)imageToDraw;
// Set the default image to show on the menu button.
- (void)setDefaultImage:(NSImage*)defaultImage;
@end
#endif // UI_BASE_COCOA_CONTROLS_HOVER_IMAGE_MENU_BUTTON_CELL_H_
// Copyright 2013 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 "ui/base/cocoa/controls/hover_image_menu_button_cell.h"
@implementation HoverImageMenuButtonCell
@synthesize hovered = hovered_;
- (id)initTextCell:(NSString*)stringValue
pullsDown:(BOOL)pullDown {
if ((self = [super initTextCell:stringValue
pullsDown:pullDown])) {
[self setUsesItemFromMenu:NO];
}
return self;
}
- (void)setHoverImage:(NSImage*)newImage {
if ([hoverImage_ isEqual:newImage])
return;
hoverImage_.reset([newImage retain]);
if (hovered_)
[[self controlView] setNeedsDisplay:YES];
}
- (NSImage*)hoverImage {
return hoverImage_;
}
- (void)setHovered:(BOOL)hovered {
if (hovered_ == hovered)
return;
hovered_ = hovered;
[[self controlView] setNeedsDisplay:YES];
}
- (NSImage*)imageToDraw {
if ([self isHighlighted] && [self alternateImage])
return [self alternateImage];
if ([self isHovered] && [self hoverImage])
return [self hoverImage];
// Note that NSPopUpButtonCell updates the cell image when the [self menuItem]
// changes.
return [self image];
}
- (void)setDefaultImage:(NSImage*)defaultImage {
base::scoped_nsobject<NSMenuItem> buttonMenuItem([[NSMenuItem alloc] init]);
[buttonMenuItem setImage:defaultImage];
[self setMenuItem:buttonMenuItem];
}
- (void)drawWithFrame:(NSRect)cellFrame
inView:(NSView*)controlView {
[[self imageToDraw] drawInRect:cellFrame
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0
respectFlipped:YES
hints:nil];
}
@end
// Copyright 2013 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 "ui/base/cocoa/controls/hover_image_menu_button.h"
#include "base/mac/foundation_util.h"
#include "base/macros.h"
#import "testing/gtest_mac.h"
#import "ui/base/cocoa/controls/hover_image_menu_button_cell.h"
#import "ui/base/test/cocoa_helper.h"
#include "ui/events/test/cocoa_test_event_utils.h"
namespace ui {
namespace {
// Test initialization and display of the NSPopUpButton that shows the drop-
// down menu. Don't try to show the menu, since it will block the thread.
class HoverImageMenuButtonTest : public CocoaTest {
public:
HoverImageMenuButtonTest() {}
// CocoaTest override:
void SetUp() override;
protected:
base::scoped_nsobject<HoverImageMenuButton> menu_button_;
base::scoped_nsobject<NSImage> normal_;
base::scoped_nsobject<NSImage> pressed_;
base::scoped_nsobject<NSImage> hovered_;
DISALLOW_COPY_AND_ASSIGN(HoverImageMenuButtonTest);
};
void HoverImageMenuButtonTest::SetUp() {
menu_button_.reset(
[[HoverImageMenuButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 30)
pullsDown:YES]);
normal_.reset([base::mac::ObjCCastStrict<NSImage>(
[NSImage imageNamed:NSImageNameStatusAvailable]) retain]);
pressed_.reset([base::mac::ObjCCastStrict<NSImage>(
[NSImage imageNamed:NSImageNameStatusUnavailable]) retain]);
hovered_.reset([base::mac::ObjCCastStrict<NSImage>(
[NSImage imageNamed:NSImageNameStatusPartiallyAvailable]) retain]);
[[menu_button_ hoverImageMenuButtonCell] setDefaultImage:normal_];
[[menu_button_ hoverImageMenuButtonCell] setAlternateImage:pressed_];
[[menu_button_ hoverImageMenuButtonCell] setHoverImage:hovered_];
CocoaTest::SetUp();
[[test_window() contentView] addSubview:menu_button_];
}
} // namespace
TEST_VIEW(HoverImageMenuButtonTest, menu_button_);
// Tests that the correct image is chosen, depending on the cell's state flags.
TEST_F(HoverImageMenuButtonTest, CheckImagesForState) {
EXPECT_FALSE([[menu_button_ cell] isHovered]);
EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
[[menu_button_ cell] setHovered:YES];
EXPECT_TRUE([[menu_button_ cell] isHovered]);
EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
EXPECT_NSEQ(hovered_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
// Highlighted takes precendece over hover.
[[menu_button_ cell] setHighlighted:YES];
EXPECT_TRUE([[menu_button_ cell] isHovered]);
EXPECT_TRUE([[menu_button_ cell] isHighlighted]);
EXPECT_NSEQ(pressed_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
[[menu_button_ cell] setHovered:NO];
EXPECT_FALSE([[menu_button_ cell] isHovered]);
EXPECT_TRUE([[menu_button_ cell] isHighlighted]);
EXPECT_NSEQ(pressed_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
[[menu_button_ cell] setHighlighted:NO];
EXPECT_FALSE([[menu_button_ cell] isHovered]);
EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
}
// Tests that calling the various setXImage functions calls setNeedsDisplay.
TEST_F(HoverImageMenuButtonTest, NewImageCausesDisplay) {
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Uses setDefaultImage rather than setImage to ensure the image goes into the
// NSPopUpButtonCell's menuItem. It is then accessible using [NSCell image].
EXPECT_NSEQ(normal_, [[menu_button_ cell] image]);
[[menu_button_ cell] setDefaultImage:pressed_];
EXPECT_NSEQ(pressed_, [[menu_button_ cell] image]);
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Highlighting the cell requires a redisplay.
[[menu_button_ cell] setHighlighted:YES];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// setAlternateImage comes from NSButtonCell. Ensure the added setHover*
// behaviour matches.
[[menu_button_ cell] setAlternateImage:normal_];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Setting the same image should not cause a redisplay.
[[menu_button_ cell] setAlternateImage:normal_];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Unhighlighting requires a redisplay.
[[menu_button_ cell] setHighlighted:NO];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Changing hover state requires a redisplay.
[[menu_button_ cell] setHovered:YES];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// setHoverImage comes directly from storage in HoverImageMenuButtonCell.
[[menu_button_ cell] setHoverImage:normal_];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Setting the same image should not cause a redisplay.
[[menu_button_ cell] setHoverImage:normal_];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Unhover requires a redisplay.
[[menu_button_ cell] setHovered:NO];
EXPECT_TRUE([menu_button_ needsDisplay]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
// Changing the image while not hovered should not require a redisplay.
[[menu_button_ cell] setHoverImage:pressed_];
EXPECT_FALSE([menu_button_ needsDisplay]);
}
// Test that the mouse enter and exit is properly handled, to set hover state.
TEST_F(HoverImageMenuButtonTest, SimulateMouseEnterExit) {
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
[menu_button_ mouseEntered:cocoa_test_event_utils::EnterEvent()];
EXPECT_TRUE([menu_button_ needsDisplay]);
EXPECT_NSEQ(hovered_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
[menu_button_ mouseExited:cocoa_test_event_utils::ExitEvent()];
EXPECT_TRUE([menu_button_ needsDisplay]);
EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
[menu_button_ display];
EXPECT_FALSE([menu_button_ needsDisplay]);
}
} // namespace ui
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