mac: Remove some unused bits of constrained_windows, and molokocacao.
Bug: 832676 Change-Id: Iac4e3e7c9e959f65a5f113653af8122b1a212519 Reviewed-on: https://chromium-review.googlesource.com/1244020 Reviewed-by: Robert Sesek <rsesek@chromium.org> Commit-Queue: Nico Weber <thakis@chromium.org> Cr-Commit-Position: refs/heads/master@{#594073}
This commit is contained in:
1
BUILD.gn
1
BUILD.gn
@ -546,7 +546,6 @@ group("gn_all") {
|
||||
deps += [
|
||||
"//third_party/breakpad:crash_inspector",
|
||||
"//third_party/breakpad:dump_syms",
|
||||
"//third_party/molokocacao",
|
||||
]
|
||||
deps -= [
|
||||
# Mojo in GN contains some things which are never compiled in GYP on Mac,
|
||||
|
@ -85,10 +85,6 @@ jumbo_split_static_library("ui") {
|
||||
"cocoa/clickhold_button_cell.mm",
|
||||
"cocoa/cocoa_util.h",
|
||||
"cocoa/cocoa_util.mm",
|
||||
"cocoa/constrained_window/constrained_window_alert.h",
|
||||
"cocoa/constrained_window/constrained_window_alert.mm",
|
||||
"cocoa/constrained_window/constrained_window_button.h",
|
||||
"cocoa/constrained_window/constrained_window_button.mm",
|
||||
"cocoa/constrained_window/constrained_window_control_utils.h",
|
||||
"cocoa/constrained_window/constrained_window_control_utils.mm",
|
||||
"cocoa/constrained_window/constrained_window_custom_sheet.h",
|
||||
@ -2233,7 +2229,6 @@ jumbo_split_static_library("ui") {
|
||||
"//chrome/browser/apps/app_shim",
|
||||
"//extensions/components/native_app_window",
|
||||
"//third_party/google_toolbox_for_mac",
|
||||
"//third_party/molokocacao",
|
||||
"//third_party/mozilla",
|
||||
"//ui/accelerated_widget_mac:accelerated_widget_mac",
|
||||
]
|
||||
|
@ -1,5 +1,4 @@
|
||||
include_rules = [
|
||||
"+chrome/browser/ui/views",
|
||||
"+third_party/molokocacao", # For NSBezierPath additions.
|
||||
"+third_party/ocmock", # For unit tests.
|
||||
]
|
||||
|
@ -1,60 +0,0 @@
|
||||
// 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_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_ALERT_H_
|
||||
#define CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_ALERT_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
|
||||
// This class implements an alert that has a constrained window look and feel
|
||||
// (close button on top right, WebUI style buttons, etc...). The alert can be
|
||||
// shown by using the window accessor and calling -[window orderFont:]. Normally
|
||||
// this would be done by ConstrainedWindowSheetController.
|
||||
@interface ConstrainedWindowAlert : NSObject {
|
||||
@private
|
||||
base::scoped_nsobject<NSTextField> informativeTextField_;
|
||||
base::scoped_nsobject<NSTextField> messageTextField_;
|
||||
base::scoped_nsobject<NSButton> linkView_;
|
||||
base::scoped_nsobject<NSView> accessoryView_;
|
||||
base::scoped_nsobject<NSMutableArray> buttons_;
|
||||
base::scoped_nsobject<NSButton> closeButton_;
|
||||
base::scoped_nsobject<NSWindow> window_;
|
||||
}
|
||||
|
||||
@property(nonatomic, copy) NSString* informativeText;
|
||||
@property(nonatomic, copy) NSString* messageText;
|
||||
@property(nonatomic, retain) NSView* accessoryView;
|
||||
@property(nonatomic, readonly) NSArray* buttons;
|
||||
@property(nonatomic, readonly) NSButton* closeButton;
|
||||
@property(nonatomic, readonly) NSWindow* window;
|
||||
|
||||
// Default initializer.
|
||||
- (id)init;
|
||||
|
||||
// Adds a button with the given |title|. Newly added buttons are positioned in
|
||||
// order from right to left.
|
||||
- (void)addButtonWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)keyEquivalent
|
||||
target:(id)target
|
||||
action:(SEL)action;
|
||||
|
||||
// Sets the |text|, the |target| and the |action| of a left-aligned link
|
||||
// positioned above the buttons. If |text| is empty, no link is displayed.
|
||||
- (void)setLinkText:(NSString*)text
|
||||
target:(id)target
|
||||
action:(SEL)action;
|
||||
|
||||
// Lays out the controls in the alert. This should be called before the window
|
||||
// is displayed.
|
||||
- (void)layout;
|
||||
|
||||
@end
|
||||
|
||||
@interface ConstrainedWindowAlert (ExposedForTesting)
|
||||
@property(nonatomic, readonly) NSButton* linkView;
|
||||
@end
|
||||
|
||||
#endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_ALERT_H_
|
@ -1,291 +0,0 @@
|
||||
// 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/constrained_window/constrained_window_alert.h"
|
||||
|
||||
#import "base/logging.h"
|
||||
#import "chrome/browser/ui/cocoa/chrome_style.h"
|
||||
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
|
||||
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_utils.h"
|
||||
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
|
||||
#import "chrome/browser/ui/cocoa/hover_close_button.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h"
|
||||
#include "ui/base/cocoa/controls/hyperlink_button_cell.h"
|
||||
#include "ui/base/cocoa/window_size_constants.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const CGFloat kConstrainedWindowMinWidth = 500;
|
||||
const CGFloat kConstrainedWindowButtonGap = 6;
|
||||
|
||||
} // namespace
|
||||
|
||||
@interface ConstrainedWindowAlert ()
|
||||
// Position the alert buttons within the given window width.
|
||||
- (void)layoutButtonsWithWindowWidth:(CGFloat)windowWidth;
|
||||
// Resize the given text field to fit within the window and position it starting
|
||||
// at |yPos|. Returns the new value of yPos.
|
||||
- (CGFloat)layoutTextField:(NSTextField*)textField
|
||||
yPos:(CGFloat)yPos
|
||||
windowWidth:(CGFloat)windowWidth;
|
||||
// If a link has been set, resizes the link to fit within the window and
|
||||
// position it starting at |yPos|. Returns the new value of yPos.
|
||||
- (CGFloat)layoutLinkAtYPos:(CGFloat)yPos
|
||||
windowWidth:(CGFloat)windowWidth;
|
||||
// Positions the accessory view starting at yPos. Returns the new value of yPos.
|
||||
- (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos;
|
||||
// Update the position of the close button.
|
||||
- (void)layoutCloseButtonWithWindowWidth:(CGFloat)windowWidth
|
||||
windowHeight:(CGFloat)windowHeight;
|
||||
@end
|
||||
|
||||
@implementation ConstrainedWindowAlert
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
window_.reset([[ConstrainedWindowCustomWindow alloc]
|
||||
initWithContentRect:ui::kWindowSizeDeterminedLater]);
|
||||
NSView* contentView = [window_ contentView];
|
||||
|
||||
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
||||
|
||||
informativeTextField_.reset([constrained_window::CreateLabel() retain]);
|
||||
[informativeTextField_ setSelectable:YES];
|
||||
[informativeTextField_ setAlignment:NSNaturalTextAlignment];
|
||||
if (@available(macOS 10.10, *)) {
|
||||
[informativeTextField_ setLineBreakMode:NSLineBreakByWordWrapping];
|
||||
} else {
|
||||
[[informativeTextField_ cell] setLineBreakMode:NSLineBreakByWordWrapping];
|
||||
}
|
||||
[informativeTextField_
|
||||
setFont:rb.GetFont(chrome_style::kTextFontStyle).GetNativeFont()];
|
||||
[contentView addSubview:informativeTextField_];
|
||||
|
||||
messageTextField_.reset([constrained_window::CreateLabel() retain]);
|
||||
[messageTextField_ setSelectable:YES];
|
||||
[messageTextField_ setAlignment:NSNaturalTextAlignment];
|
||||
if (@available(macOS 10.10, *)) {
|
||||
[messageTextField_ setLineBreakMode:NSLineBreakByWordWrapping];
|
||||
} else {
|
||||
[[messageTextField_ cell] setLineBreakMode:NSLineBreakByWordWrapping];
|
||||
}
|
||||
[messageTextField_
|
||||
setFont:rb.GetFont(chrome_style::kTitleFontStyle).GetNativeFont()];
|
||||
[contentView addSubview:messageTextField_];
|
||||
|
||||
closeButton_.reset(
|
||||
[[WebUIHoverCloseButton alloc] initWithFrame:NSZeroRect]);
|
||||
[contentView addSubview:closeButton_];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString*)informativeText {
|
||||
return [informativeTextField_ stringValue];
|
||||
}
|
||||
|
||||
- (void)setInformativeText:(NSString*)string {
|
||||
[informativeTextField_ setStringValue:string];
|
||||
}
|
||||
|
||||
- (NSString*)messageText {
|
||||
return [messageTextField_ stringValue];
|
||||
}
|
||||
|
||||
- (void)setMessageText:(NSString*)string {
|
||||
[messageTextField_ setStringValue:string];
|
||||
}
|
||||
|
||||
- (void)setLinkText:(NSString*)text target:(id)target action:(SEL)action {
|
||||
if (![text length]) {
|
||||
[linkView_ removeFromSuperview];
|
||||
linkView_.reset(nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!linkView_.get()) {
|
||||
linkView_.reset(
|
||||
[[HyperlinkButtonCell buttonWithString:[NSString string]] retain]);
|
||||
[[window_ contentView] addSubview:linkView_];
|
||||
}
|
||||
|
||||
[linkView_ setTitle:text];
|
||||
[linkView_ setTarget:target];
|
||||
[linkView_ setAction:action];
|
||||
}
|
||||
|
||||
- (NSView*)accessoryView {
|
||||
return accessoryView_;
|
||||
}
|
||||
|
||||
- (void)setAccessoryView:(NSView*)accessoryView {
|
||||
[accessoryView_ removeFromSuperview];
|
||||
accessoryView_.reset([accessoryView retain]);
|
||||
[[window_ contentView] addSubview:accessoryView_];
|
||||
}
|
||||
|
||||
- (NSArray*)buttons {
|
||||
return buttons_;
|
||||
}
|
||||
|
||||
- (NSButton*)closeButton {
|
||||
return closeButton_;
|
||||
}
|
||||
|
||||
- (NSWindow*)window {
|
||||
return window_;
|
||||
}
|
||||
|
||||
- (void)addButtonWithTitle:(NSString*)title
|
||||
keyEquivalent:(NSString*)keyEquivalent
|
||||
target:(id)target
|
||||
action:(SEL)action {
|
||||
if (!buttons_.get())
|
||||
buttons_.reset([[NSMutableArray alloc] init]);
|
||||
base::scoped_nsobject<NSButton> button(
|
||||
[[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
|
||||
[button setTitle:title];
|
||||
[button setKeyEquivalent:keyEquivalent];
|
||||
[button setTarget:target];
|
||||
[button setAction:action];
|
||||
[buttons_ addObject:button];
|
||||
[[window_ contentView] addSubview:button];
|
||||
}
|
||||
|
||||
- (void)layout {
|
||||
// Button width.
|
||||
CGFloat buttonWidth = 0;
|
||||
for (NSButton* button in buttons_.get()) {
|
||||
[button sizeToFit];
|
||||
NSSize size = [button frame].size;
|
||||
buttonWidth += size.width;
|
||||
}
|
||||
if ([buttons_ count])
|
||||
buttonWidth += ([buttons_ count] - 1) * kConstrainedWindowButtonGap;
|
||||
|
||||
// Window width.
|
||||
CGFloat windowWidth = buttonWidth;
|
||||
if (accessoryView_.get())
|
||||
windowWidth = std::max(windowWidth, NSWidth([accessoryView_ frame]));
|
||||
windowWidth += chrome_style::kHorizontalPadding * 2;
|
||||
windowWidth = std::max(windowWidth, kConstrainedWindowMinWidth);
|
||||
|
||||
// Layout controls.
|
||||
[self layoutButtonsWithWindowWidth:windowWidth];
|
||||
CGFloat curY = [buttons_ count] ? NSMaxY([[buttons_ lastObject] frame])
|
||||
: chrome_style::kClientBottomPadding;
|
||||
CGFloat availableMessageWidth = windowWidth -
|
||||
chrome_style::GetCloseButtonSize() -
|
||||
kConstrainedWindowButtonGap;
|
||||
curY = [self layoutLinkAtYPos:curY
|
||||
windowWidth:availableMessageWidth];
|
||||
curY = [self layoutAccessoryViewAtYPos:curY];
|
||||
curY = [self layoutTextField:informativeTextField_
|
||||
yPos:curY
|
||||
windowWidth:windowWidth];
|
||||
curY = [self layoutTextField:messageTextField_
|
||||
yPos:curY
|
||||
windowWidth:availableMessageWidth];
|
||||
|
||||
CGFloat windowHeight = curY + chrome_style::kTitleTopPadding;
|
||||
[self layoutCloseButtonWithWindowWidth:windowWidth
|
||||
windowHeight:windowHeight];
|
||||
|
||||
// Update window frame.
|
||||
NSRect windowFrame = NSMakeRect(0, 0, windowWidth, windowHeight);
|
||||
windowFrame = [window_ frameRectForContentRect:windowFrame];
|
||||
[window_ setFrame:windowFrame display:NO];
|
||||
}
|
||||
|
||||
- (void)layoutButtonsWithWindowWidth:(CGFloat)windowWidth {
|
||||
// Layout first 2 button right to left.
|
||||
CGFloat curX = windowWidth - chrome_style::kHorizontalPadding;
|
||||
const int buttonCount = [buttons_ count];
|
||||
for (int i = 0; i < std::min(2, buttonCount); ++i) {
|
||||
NSButton* button = [buttons_ objectAtIndex:i];
|
||||
NSRect rect = [button frame];
|
||||
rect.origin.x = curX - NSWidth(rect);
|
||||
rect.origin.y = chrome_style::kClientBottomPadding;
|
||||
[button setFrameOrigin:rect.origin];
|
||||
curX = NSMinX(rect) - kConstrainedWindowButtonGap;
|
||||
}
|
||||
|
||||
// Layout remaining buttons left to right.
|
||||
curX = chrome_style::kHorizontalPadding;
|
||||
for (int i = buttonCount - 1; i >= 2; --i) {
|
||||
NSButton* button = [buttons_ objectAtIndex:i];
|
||||
[button setFrameOrigin:
|
||||
NSMakePoint(curX, chrome_style::kClientBottomPadding)];
|
||||
curX += NSMaxX([button frame]) + kConstrainedWindowButtonGap;
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)layoutTextField:(NSTextField*)textField
|
||||
yPos:(CGFloat)yPos
|
||||
windowWidth:(CGFloat)windowWidth {
|
||||
if (![[textField stringValue] length]) {
|
||||
[textField setHidden:YES];
|
||||
return yPos;
|
||||
}
|
||||
|
||||
[textField setHidden:NO];
|
||||
NSRect rect;
|
||||
rect.origin.y = yPos + chrome_style::kRowPadding;
|
||||
rect.origin.x = chrome_style::kHorizontalPadding;
|
||||
rect.size.width = windowWidth -
|
||||
chrome_style::kHorizontalPadding * 2;
|
||||
rect.size.height = 1;
|
||||
[textField setFrame:rect];
|
||||
[GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:textField];
|
||||
return NSMaxY([textField frame]);
|
||||
}
|
||||
|
||||
- (CGFloat)layoutLinkAtYPos:(CGFloat)yPos
|
||||
windowWidth:(CGFloat)windowWidth {
|
||||
if (!linkView_.get())
|
||||
return yPos;
|
||||
|
||||
NSRect availableBounds = NSMakeRect(
|
||||
0,
|
||||
0,
|
||||
windowWidth - chrome_style::kHorizontalPadding * 2,
|
||||
CGFLOAT_MAX);
|
||||
NSSize size = [[linkView_ cell] cellSizeForBounds:availableBounds];
|
||||
|
||||
NSRect rect;
|
||||
rect.origin.y = yPos + chrome_style::kRowPadding;
|
||||
rect.origin.x = chrome_style::kHorizontalPadding;
|
||||
rect.size = size;
|
||||
[linkView_ setFrame:rect];
|
||||
return NSMaxY([linkView_ frame]);
|
||||
}
|
||||
|
||||
- (CGFloat)layoutAccessoryViewAtYPos:(CGFloat)yPos {
|
||||
if (!accessoryView_.get())
|
||||
return yPos;
|
||||
NSRect frame = [accessoryView_ frame];
|
||||
frame.origin.y = yPos + chrome_style::kRowPadding;
|
||||
frame.origin.x = chrome_style::kHorizontalPadding;
|
||||
[accessoryView_ setFrameOrigin:frame.origin];
|
||||
return NSMaxY(frame);
|
||||
}
|
||||
|
||||
- (void)layoutCloseButtonWithWindowWidth:(CGFloat)windowWidth
|
||||
windowHeight:(CGFloat)windowHeight {
|
||||
NSRect frame;
|
||||
frame.size.width = chrome_style::GetCloseButtonSize();
|
||||
frame.size.height = chrome_style::GetCloseButtonSize();
|
||||
frame.origin.x = windowWidth -
|
||||
chrome_style::kCloseButtonPadding - NSWidth(frame);
|
||||
frame.origin.y = windowHeight -
|
||||
chrome_style::kCloseButtonPadding - NSHeight(frame);
|
||||
[closeButton_ setFrame:frame];
|
||||
}
|
||||
|
||||
- (NSButton*)linkView {
|
||||
return linkView_;
|
||||
}
|
||||
|
||||
@end
|
@ -1,103 +0,0 @@
|
||||
// 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/constrained_window/constrained_window_alert.h"
|
||||
|
||||
#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h"
|
||||
#import "testing/gtest_mac.h"
|
||||
|
||||
class ConstrainedWindowAlertTest : public CocoaTest {
|
||||
};
|
||||
|
||||
@interface ConstrainedWindowAlertTestTarget : NSObject {
|
||||
@private
|
||||
int linkClickedCount_;
|
||||
}
|
||||
@property(nonatomic, readonly) int linkClickedCount;
|
||||
|
||||
- (void)onLinkClicked:(id)sender;
|
||||
@end
|
||||
|
||||
@implementation ConstrainedWindowAlertTestTarget
|
||||
|
||||
@synthesize linkClickedCount = linkClickedCount_;
|
||||
|
||||
- (void)onLinkClicked:(id)sender {
|
||||
++linkClickedCount_;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Test showing the alert.
|
||||
TEST_F(ConstrainedWindowAlertTest, Show) {
|
||||
base::scoped_nsobject<ConstrainedWindowAlert> alert(
|
||||
[[ConstrainedWindowAlert alloc] init]);
|
||||
EXPECT_TRUE([alert window]);
|
||||
EXPECT_TRUE([alert closeButton]);
|
||||
|
||||
[alert setMessageText:@"Message text"];
|
||||
[alert setInformativeText:@"Informative text"];
|
||||
[alert addButtonWithTitle:@"OK" keyEquivalent:@"" target:nil action:NULL];
|
||||
[alert addButtonWithTitle:@"Cancel" keyEquivalent:@"" target:nil action:NULL];
|
||||
|
||||
[alert layout];
|
||||
[[alert window] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
// Test showing the alert with no buttons.
|
||||
TEST_F(ConstrainedWindowAlertTest, NoButtons) {
|
||||
base::scoped_nsobject<ConstrainedWindowAlert> alert(
|
||||
[[ConstrainedWindowAlert alloc] init]);
|
||||
[alert layout];
|
||||
[[alert window] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
// Test adding an accessory view to an alert.
|
||||
TEST_F(ConstrainedWindowAlertTest, AccessoryView) {
|
||||
base::scoped_nsobject<ConstrainedWindowAlert> alert(
|
||||
[[ConstrainedWindowAlert alloc] init]);
|
||||
[alert addButtonWithTitle:@"OK" keyEquivalent:@"" target:nil action:NULL];
|
||||
[alert addButtonWithTitle:@"Cancel" keyEquivalent:@"" target:nil action:NULL];
|
||||
|
||||
NSRect view_rect = NSMakeRect(0, 0, 700, 300);
|
||||
base::scoped_nsobject<NSView> view([[NSView alloc] initWithFrame:view_rect]);
|
||||
EXPECT_FALSE([alert accessoryView]);
|
||||
[alert setAccessoryView:view];
|
||||
EXPECT_NSEQ([alert accessoryView], view);
|
||||
|
||||
[alert layout];
|
||||
NSRect window_rect = [[alert window] frame];
|
||||
EXPECT_GT(NSWidth(window_rect), NSWidth(view_rect));
|
||||
EXPECT_GT(NSHeight(window_rect), NSHeight(view_rect));
|
||||
|
||||
[[alert window] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
// Test adding a link to an alert.
|
||||
TEST_F(ConstrainedWindowAlertTest, LinkView) {
|
||||
base::scoped_nsobject<ConstrainedWindowAlert> alert(
|
||||
[[ConstrainedWindowAlert alloc] init]);
|
||||
base::scoped_nsobject<ConstrainedWindowAlertTestTarget> target(
|
||||
[[ConstrainedWindowAlertTestTarget alloc] init]);
|
||||
|
||||
[alert layout];
|
||||
NSRect initial_window_rect = [[alert window] frame];
|
||||
|
||||
EXPECT_EQ(nil, [alert linkView]);
|
||||
NSString* linkText = @"Text of the link";
|
||||
[alert setLinkText:linkText
|
||||
target:target.get()
|
||||
action:@selector(onLinkClicked:)];
|
||||
EXPECT_EQ([linkText length], [[[alert linkView] title] length]);
|
||||
|
||||
[alert layout];
|
||||
NSRect window_rect = [[alert window] frame];
|
||||
|
||||
EXPECT_GT(NSHeight(window_rect), NSHeight(initial_window_rect));
|
||||
|
||||
[[alert window] makeKeyAndOrderFront:nil];
|
||||
|
||||
[[alert linkView] performClick:nil];
|
||||
EXPECT_EQ(1, [target linkClickedCount]);
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
// 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_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_BUTTON_H_
|
||||
#define CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_BUTTON_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "ui/base/cocoa/tracking_area.h"
|
||||
|
||||
namespace constrained_window_button {
|
||||
const CGFloat kButtonMinWidth = 72;
|
||||
}
|
||||
|
||||
@protocol ConstrainedWindowButtonDrawableCell
|
||||
@property (nonatomic, assign) BOOL isMouseInside;
|
||||
- (BOOL)isEnabled;
|
||||
- (BOOL)isHighlighted;
|
||||
@end
|
||||
|
||||
// A push button for use in a constrained window. Specialized constrained
|
||||
// windows that need a push button should use this class instead of NSButton.
|
||||
@interface ConstrainedWindowButton : NSButton {
|
||||
@private
|
||||
ui::ScopedCrTrackingArea trackingArea_;
|
||||
}
|
||||
|
||||
extern const CGFloat buttonMinWidth_;
|
||||
|
||||
// Draws the background and shadow inside |path| with the appropriate
|
||||
// colors for |buttonState|, onto |view|.
|
||||
+ (void)DrawBackgroundAndShadowForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view;
|
||||
|
||||
// Draws the highlight inside |path|, with the color for |buttonState|,
|
||||
// onto |view|.
|
||||
+ (void)DrawInnerHighlightForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view;
|
||||
|
||||
// Draws the border along |path|, with a color according to |buttonState|,
|
||||
// onto |view|.
|
||||
+ (void)DrawBorderForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view;
|
||||
@end
|
||||
|
||||
// A button cell used by ConstrainedWindowButton.
|
||||
@interface ConstrainedWindowButtonCell :
|
||||
NSButtonCell<ConstrainedWindowButtonDrawableCell> {
|
||||
@private
|
||||
BOOL isMouseInside_;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // CHROME_BROWSER_UI_COCOA_CONSTRAINED_WINDOW_CONSTRAINED_WINDOW_BUTTON_H_
|
@ -1,290 +0,0 @@
|
||||
// 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/constrained_window/constrained_window_button.h"
|
||||
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#import "third_party/molokocacao/NSBezierPath+MCAdditions.h"
|
||||
#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h"
|
||||
|
||||
@interface ConstrainedWindowButton ()
|
||||
- (BOOL)isMouseReallyInside;
|
||||
@end
|
||||
|
||||
namespace {
|
||||
|
||||
enum ButtonState {
|
||||
BUTTON_NORMAL,
|
||||
BUTTON_HOVER,
|
||||
BUTTON_PRESSED,
|
||||
BUTTON_DISABLED,
|
||||
};
|
||||
|
||||
const CGFloat kButtonHeight = 28;
|
||||
const CGFloat kButtonPaddingX = 14;
|
||||
|
||||
ButtonState cellButtonState(id<ConstrainedWindowButtonDrawableCell> cell) {
|
||||
if (!cell)
|
||||
return BUTTON_NORMAL;
|
||||
if (![cell isEnabled])
|
||||
return BUTTON_DISABLED;
|
||||
if ([cell isHighlighted])
|
||||
return BUTTON_PRESSED;
|
||||
if ([cell isMouseInside])
|
||||
return BUTTON_HOVER;
|
||||
return BUTTON_NORMAL;
|
||||
}
|
||||
|
||||
// The functions below use hex color values to make it easier to compare
|
||||
// the code with the spec. Table of hex values are also more readable
|
||||
// then tables of NSColor constructors.
|
||||
|
||||
NSGradient* GetButtonGradient(ButtonState button_state) {
|
||||
const SkColor start[] = {0xFFF0F0F0, 0xFFF4F4F4, 0xFFEBEBEB, 0xFFEDEDED};
|
||||
const SkColor end[] = {0xFFE0E0E0, 0xFFE4E4E4, 0xFFDBDBDB, 0xFFDEDEDE};
|
||||
|
||||
NSColor* start_color = skia::SkColorToCalibratedNSColor(start[button_state]);
|
||||
NSColor* end_color = skia::SkColorToCalibratedNSColor(end[button_state]);
|
||||
return [[[NSGradient alloc] initWithColorsAndLocations:
|
||||
start_color, 0.0,
|
||||
start_color, 0.38,
|
||||
end_color, 1.0,
|
||||
nil] autorelease];
|
||||
}
|
||||
|
||||
NSShadow* GetButtonHighlight(ButtonState button_state) {
|
||||
const SkColor color[] = {0xBFFFFFFF, 0xF2FFFFFF, 0x24000000, 0x00000000};
|
||||
|
||||
NSShadow* shadow = [[[NSShadow alloc] init] autorelease];
|
||||
[shadow setShadowColor:skia::SkColorToCalibratedNSColor(color[button_state])];
|
||||
[shadow setShadowOffset:NSMakeSize(0, -1)];
|
||||
[shadow setShadowBlurRadius:2];
|
||||
return shadow;
|
||||
}
|
||||
|
||||
NSShadow* GetButtonShadow(ButtonState button_state) {
|
||||
const SkColor color[] = {0x14000000, 0x1F000000, 0x00000000, 0x00000000};
|
||||
|
||||
NSShadow* shadow = [[[NSShadow alloc] init] autorelease];
|
||||
[shadow setShadowColor:skia::SkColorToCalibratedNSColor(color[button_state])];
|
||||
[shadow setShadowOffset:NSMakeSize(0, -1)];
|
||||
[shadow setShadowBlurRadius:0];
|
||||
return shadow;
|
||||
}
|
||||
|
||||
NSColor* GetButtonBorderColor(ButtonState button_state) {
|
||||
const SkColor color[] = {0x40000000, 0x4D000000, 0x4D000000, 0x1F000000};
|
||||
|
||||
return skia::SkColorToCalibratedNSColor(color[button_state]);
|
||||
}
|
||||
|
||||
NSAttributedString* GetButtonAttributedString(
|
||||
NSString* title,
|
||||
NSString* key_equivalent,
|
||||
id<ConstrainedWindowButtonDrawableCell> cell) {
|
||||
const SkColor text_color[] = {0xFF333333, 0XFF000000, 0xFF000000, 0xFFAAAAAA};
|
||||
// The shadow color should be 0xFFF0F0F0 but that doesn't show up so use
|
||||
// pure white instead.
|
||||
const SkColor shadow_color[] =
|
||||
{0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF};
|
||||
|
||||
base::scoped_nsobject<NSShadow> shadow([[NSShadow alloc] init]);
|
||||
[shadow setShadowColor:
|
||||
skia::SkColorToCalibratedNSColor(shadow_color[cellButtonState(cell)])];
|
||||
[shadow setShadowOffset:NSMakeSize(0, -1)];
|
||||
[shadow setShadowBlurRadius:0];
|
||||
|
||||
base::scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
|
||||
[[NSMutableParagraphStyle alloc] init]);
|
||||
[paragraphStyle setAlignment:NSCenterTextAlignment];
|
||||
|
||||
NSFont* font = nil;
|
||||
if ([key_equivalent isEqualToString:kKeyEquivalentReturn])
|
||||
font = [NSFont boldSystemFontOfSize:12];
|
||||
else
|
||||
font = [NSFont systemFontOfSize:12];
|
||||
|
||||
NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
font, NSFontAttributeName,
|
||||
skia::SkColorToCalibratedNSColor(text_color[cellButtonState(cell)]),
|
||||
NSForegroundColorAttributeName,
|
||||
shadow.get(), NSShadowAttributeName,
|
||||
paragraphStyle.get(), NSParagraphStyleAttributeName,
|
||||
nil];
|
||||
return [[[NSAttributedString alloc] initWithString:title
|
||||
attributes:attributes] autorelease];
|
||||
}
|
||||
|
||||
void DrawBackgroundAndShadow(const NSRect& frame,
|
||||
id<ConstrainedWindowButtonDrawableCell> cell,
|
||||
NSView* view) {
|
||||
NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:frame
|
||||
xRadius:2
|
||||
yRadius:2];
|
||||
[ConstrainedWindowButton DrawBackgroundAndShadowForPath:path
|
||||
withCell:cell
|
||||
inView:view];
|
||||
}
|
||||
|
||||
void DrawInnerHighlight(const NSRect& frame,
|
||||
id<ConstrainedWindowButtonDrawableCell> cell,
|
||||
NSView* view) {
|
||||
NSBezierPath* path =
|
||||
[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1, 1)
|
||||
xRadius:2
|
||||
yRadius:2];
|
||||
[ConstrainedWindowButton DrawInnerHighlightForPath:path
|
||||
withCell:cell
|
||||
inView:view];
|
||||
}
|
||||
|
||||
void DrawBorder(const NSRect& frame,
|
||||
id<ConstrainedWindowButtonDrawableCell> cell,
|
||||
NSView* view) {
|
||||
NSBezierPath* path =
|
||||
[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 0.5, 0.5)
|
||||
xRadius:2
|
||||
yRadius:2];
|
||||
[ConstrainedWindowButton DrawBorderForPath:path
|
||||
withCell:cell
|
||||
inView:view];
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@implementation ConstrainedWindowButton
|
||||
|
||||
+ (Class)cellClass {
|
||||
return [ConstrainedWindowButtonCell class];
|
||||
}
|
||||
|
||||
- (void)updateTrackingAreas {
|
||||
BOOL mouseInView = [self isMouseReallyInside];
|
||||
|
||||
if (trackingArea_.get())
|
||||
[self removeTrackingArea:trackingArea_.get()];
|
||||
|
||||
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
|
||||
NSTrackingActiveInActiveApp |
|
||||
NSTrackingInVisibleRect;
|
||||
if (mouseInView)
|
||||
options |= NSTrackingAssumeInside;
|
||||
|
||||
trackingArea_.reset([[CrTrackingArea alloc]
|
||||
initWithRect:NSZeroRect
|
||||
options:options
|
||||
owner:self
|
||||
userInfo:nil]);
|
||||
[self addTrackingArea:trackingArea_.get()];
|
||||
if ([[self cell] isMouseInside] != mouseInView) {
|
||||
[[self cell] setIsMouseInside:mouseInView];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseEntered:(NSEvent*)theEvent {
|
||||
[[self cell] setIsMouseInside:YES];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent*)theEvent {
|
||||
[[self cell] setIsMouseInside:YES];
|
||||
[[self cell] setIsMouseInside:NO];
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (BOOL)isMouseReallyInside {
|
||||
BOOL mouseInView = NO;
|
||||
NSWindow* window = [self window];
|
||||
if (window) {
|
||||
NSPoint mousePoint = [window mouseLocationOutsideOfEventStream];
|
||||
mousePoint = [self convertPoint:mousePoint fromView:nil];
|
||||
mouseInView = [self mouse:mousePoint inRect:[self bounds]];
|
||||
}
|
||||
return mouseInView;
|
||||
}
|
||||
|
||||
- (void)sizeToFit {
|
||||
[super sizeToFit];
|
||||
NSSize size = [self frame].size;
|
||||
if (size.width < constrained_window_button::kButtonMinWidth) {
|
||||
size.width = constrained_window_button::kButtonMinWidth;
|
||||
[self setFrameSize:size];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)DrawBackgroundAndShadowForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view {
|
||||
ButtonState buttonState = cellButtonState(cell);
|
||||
{
|
||||
gfx::ScopedNSGraphicsContextSaveGState scopedGState;
|
||||
[GetButtonShadow(buttonState) set];
|
||||
[[[view window] backgroundColor] set];
|
||||
[path fill];
|
||||
}
|
||||
[GetButtonGradient(buttonState) drawInBezierPath:path angle:90.0];
|
||||
}
|
||||
|
||||
+ (void)DrawInnerHighlightForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view {
|
||||
[path fillWithInnerShadow:GetButtonHighlight(cellButtonState(cell))];
|
||||
}
|
||||
|
||||
+ (void)DrawBorderForPath:(NSBezierPath*)path
|
||||
withCell:(id<ConstrainedWindowButtonDrawableCell>)cell
|
||||
inView:(NSView*)view {
|
||||
if ([[[view window] firstResponder] isEqual:view])
|
||||
[[NSColor colorWithCalibratedRed:0.30 green:0.57 blue:1.0 alpha:1.0] set];
|
||||
else
|
||||
[GetButtonBorderColor(cellButtonState(cell)) set];
|
||||
[path stroke];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation ConstrainedWindowButtonCell
|
||||
|
||||
@synthesize isMouseInside = isMouseInside_;
|
||||
|
||||
- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView*)controlView {
|
||||
// Inset to leave room for shadow.
|
||||
--frame.size.height;
|
||||
|
||||
// Background and shadow
|
||||
DrawBackgroundAndShadow(frame, self, controlView);
|
||||
|
||||
// Inner highlight
|
||||
DrawInnerHighlight(frame, self, controlView);
|
||||
|
||||
// Border
|
||||
DrawBorder(frame, self, controlView);
|
||||
}
|
||||
|
||||
- (void)drawInteriorWithFrame:(NSRect)frame inView:(NSView*)controlView {
|
||||
// Inset to leave room for shadow.
|
||||
--frame.size.height;
|
||||
NSAttributedString* title = GetButtonAttributedString(
|
||||
[self title], [self keyEquivalent], self);
|
||||
[self drawTitle:title withFrame:frame inView:controlView];
|
||||
}
|
||||
|
||||
- (NSSize)cellSize {
|
||||
NSAttributedString* title = GetButtonAttributedString(
|
||||
[self title], [self keyEquivalent], self);
|
||||
NSSize size = [title size];
|
||||
size.height = std::max(size.height, kButtonHeight);
|
||||
size.width += kButtonPaddingX * 2;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (NSAttributedString*)getAttributedTitle {
|
||||
return GetButtonAttributedString(
|
||||
[self title], [self keyEquivalent], self);
|
||||
}
|
||||
|
||||
@end
|
@ -1,61 +0,0 @@
|
||||
// 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 "base/mac/scoped_nsobject.h"
|
||||
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
|
||||
#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "testing/platform_test.h"
|
||||
#import "ui/events/test/cocoa_test_event_utils.h"
|
||||
|
||||
class ConstrainedWindowButtonTest : public CocoaTest {
|
||||
public:
|
||||
ConstrainedWindowButtonTest() {
|
||||
NSRect frame = NSMakeRect(0, 0, 50, 30);
|
||||
button_.reset([[ConstrainedWindowButton alloc] initWithFrame:frame]);
|
||||
[button_ setTitle:@"Abcdefg"];
|
||||
[button_ sizeToFit];
|
||||
[[test_window() contentView] addSubview:button_];
|
||||
}
|
||||
|
||||
protected:
|
||||
base::scoped_nsobject<ConstrainedWindowButton> button_;
|
||||
};
|
||||
|
||||
TEST_VIEW(ConstrainedWindowButtonTest, button_)
|
||||
|
||||
// Test hover, mostly to ensure nothing leaks or crashes.
|
||||
TEST_F(ConstrainedWindowButtonTest, DisplayWithHover) {
|
||||
[[button_ cell] setIsMouseInside:NO];
|
||||
[button_ display];
|
||||
[[button_ cell] setIsMouseInside:YES];
|
||||
[button_ display];
|
||||
}
|
||||
|
||||
// Test disabled, mostly to ensure nothing leaks or crashes.
|
||||
TEST_F(ConstrainedWindowButtonTest, DisplayWithDisable) {
|
||||
[button_ setEnabled:YES];
|
||||
[button_ display];
|
||||
[button_ setEnabled:NO];
|
||||
[button_ display];
|
||||
}
|
||||
|
||||
// Test pushed, mostly to ensure nothing leaks or crashes.
|
||||
TEST_F(ConstrainedWindowButtonTest, DisplayWithPushed) {
|
||||
[[button_ cell] setHighlighted:NO];
|
||||
[button_ display];
|
||||
[[button_ cell] setHighlighted:YES];
|
||||
[button_ display];
|
||||
}
|
||||
|
||||
// Tracking rects
|
||||
TEST_F(ConstrainedWindowButtonTest, TrackingRects) {
|
||||
ConstrainedWindowButtonCell* cell = [button_ cell];
|
||||
EXPECT_FALSE([cell isMouseInside]);
|
||||
|
||||
[button_ mouseEntered:cocoa_test_event_utils::EnterEvent()];
|
||||
EXPECT_TRUE([cell isMouseInside]);
|
||||
[button_ mouseExited:cocoa_test_event_utils::ExitEvent()];
|
||||
EXPECT_FALSE([cell isMouseInside]);
|
||||
}
|
@ -4130,8 +4130,6 @@ test("unit_tests") {
|
||||
"../browser/ui/cocoa/clickhold_button_cell_unittest.mm",
|
||||
"../browser/ui/cocoa/color_panel_cocoa_unittest.mm",
|
||||
"../browser/ui/cocoa/confirm_quit_panel_controller_unittest.mm",
|
||||
"../browser/ui/cocoa/constrained_window/constrained_window_alert_unittest.mm",
|
||||
"../browser/ui/cocoa/constrained_window/constrained_window_button_unittest.mm",
|
||||
"../browser/ui/cocoa/constrained_window/constrained_window_custom_window_unittest.mm",
|
||||
"../browser/ui/cocoa/constrained_window/constrained_window_sheet_controller_unittest.mm",
|
||||
"../browser/ui/cocoa/find_pasteboard_unittest.mm",
|
||||
|
16
third_party/molokocacao/BUILD.gn
vendored
16
third_party/molokocacao/BUILD.gn
vendored
@ -1,16 +0,0 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
source_set("molokocacao") {
|
||||
sources = [
|
||||
"NSBezierPath+MCAdditions.h",
|
||||
"NSBezierPath+MCAdditions.m",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//third_party/google_toolbox_for_mac",
|
||||
]
|
||||
|
||||
libs = [ "AppKit.framework" ]
|
||||
}
|
23
third_party/molokocacao/LICENSE
vendored
23
third_party/molokocacao/LICENSE
vendored
@ -1,23 +0,0 @@
|
||||
Copyright 2008 MolokoCacao
|
||||
All rights reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted providing that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
@ -1,27 +0,0 @@
|
||||
//
|
||||
// NSBezierPath+MCAdditions.h
|
||||
//
|
||||
// Created by Sean Patrick O'Brien on 4/1/08.
|
||||
// Copyright 2008 MolokoCacao. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef THIRD_PARTY_MOLOKOCACAO_NSBEZIERPATH_MCADDITIONS_H_
|
||||
#define THIRD_PARTY_MOLOKOCACAO_NSBEZIERPATH_MCADDITIONS_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface NSBezierPath (MCAdditions)
|
||||
|
||||
+ (NSBezierPath*)bezierPathWithCGPath:(CGPathRef)pathRef;
|
||||
|
||||
- (NSBezierPath*)pathWithStrokeWidth:(CGFloat)strokeWidth;
|
||||
|
||||
- (void)fillWithInnerShadow:(NSShadow *)shadow;
|
||||
- (void)drawBlurWithColor:(NSColor*)color radius:(CGFloat)radius;
|
||||
|
||||
- (void)strokeInside;
|
||||
- (void)strokeInsideWithinRect:(NSRect)clipRect;
|
||||
|
||||
@end
|
||||
|
||||
#endif // THIRD_PARTY_MOLOKOCACAO_NSBEZIERPATH_MCADDITIONS_H_
|
190
third_party/molokocacao/NSBezierPath+MCAdditions.m
vendored
190
third_party/molokocacao/NSBezierPath+MCAdditions.m
vendored
@ -1,190 +0,0 @@
|
||||
//
|
||||
// NSBezierPath+MCAdditions.m
|
||||
//
|
||||
// Created by Sean Patrick O'Brien on 4/1/08.
|
||||
// Copyright 2008 MolokoCacao. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSBezierPath+MCAdditions.h"
|
||||
|
||||
#import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+CGPath.h"
|
||||
|
||||
// remove/comment out this line of you don't want to use undocumented functions
|
||||
#define MCBEZIER_USE_PRIVATE_FUNCTION
|
||||
|
||||
#ifdef MCBEZIER_USE_PRIVATE_FUNCTION
|
||||
extern CGPathRef CGContextCopyPath(CGContextRef context);
|
||||
#endif
|
||||
|
||||
static void CGPathCallback(void *info, const CGPathElement *element)
|
||||
{
|
||||
NSBezierPath *path = info;
|
||||
CGPoint *points = element->points;
|
||||
|
||||
switch (element->type) {
|
||||
case kCGPathElementMoveToPoint:
|
||||
{
|
||||
[path moveToPoint:NSMakePoint(points[0].x, points[0].y)];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddLineToPoint:
|
||||
{
|
||||
[path lineToPoint:NSMakePoint(points[0].x, points[0].y)];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
{
|
||||
// NOTE: This is untested.
|
||||
NSPoint currentPoint = [path currentPoint];
|
||||
NSPoint interpolatedPoint = NSMakePoint((currentPoint.x + 2*points[0].x) / 3, (currentPoint.y + 2*points[0].y) / 3);
|
||||
[path curveToPoint:NSMakePoint(points[1].x, points[1].y) controlPoint1:interpolatedPoint controlPoint2:interpolatedPoint];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
{
|
||||
[path curveToPoint:NSMakePoint(points[2].x, points[2].y) controlPoint1:NSMakePoint(points[0].x, points[0].y) controlPoint2:NSMakePoint(points[1].x, points[1].y)];
|
||||
break;
|
||||
}
|
||||
case kCGPathElementCloseSubpath:
|
||||
{
|
||||
[path closePath];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@implementation NSBezierPath (MCAdditions)
|
||||
|
||||
+ (NSBezierPath *)bezierPathWithCGPath:(CGPathRef)pathRef
|
||||
{
|
||||
NSBezierPath *path = [NSBezierPath bezierPath];
|
||||
CGPathApply(pathRef, path, CGPathCallback);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (NSBezierPath *)pathWithStrokeWidth:(CGFloat)strokeWidth
|
||||
{
|
||||
#ifdef MCBEZIER_USE_PRIVATE_FUNCTION
|
||||
NSBezierPath *path = [self copy];
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
CGPathRef pathRef = [path gtm_CGPath];
|
||||
[path release];
|
||||
|
||||
CGContextSaveGState(context);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextAddPath(context, pathRef);
|
||||
CGContextSetLineWidth(context, strokeWidth);
|
||||
CGContextReplacePathWithStrokedPath(context);
|
||||
CGPathRef strokedPathRef = CGContextCopyPath(context);
|
||||
CGContextBeginPath(context);
|
||||
NSBezierPath *strokedPath = [NSBezierPath bezierPathWithCGPath:strokedPathRef];
|
||||
|
||||
CGContextRestoreGState(context);
|
||||
|
||||
CFRelease(pathRef);
|
||||
CFRelease(strokedPathRef);
|
||||
|
||||
return strokedPath;
|
||||
#else
|
||||
return nil;
|
||||
#endif // MCBEZIER_USE_PRIVATE_FUNCTION
|
||||
}
|
||||
|
||||
- (void)fillWithInnerShadow:(NSShadow *)shadow
|
||||
{
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
|
||||
NSSize offset = shadow.shadowOffset;
|
||||
NSSize originalOffset = offset;
|
||||
CGFloat radius = shadow.shadowBlurRadius;
|
||||
NSRect bounds = NSInsetRect(self.bounds, -(ABS(offset.width) + radius), -(ABS(offset.height) + radius));
|
||||
|
||||
// The context's user transform isn't automatically applied to shadow offsets.
|
||||
offset.height += bounds.size.height;
|
||||
shadow.shadowOffset = offset;
|
||||
NSAffineTransform *transform = [NSAffineTransform transform];
|
||||
if ([[NSGraphicsContext currentContext] isFlipped])
|
||||
[transform translateXBy:0 yBy:bounds.size.height];
|
||||
else
|
||||
[transform translateXBy:0 yBy:-bounds.size.height];
|
||||
|
||||
NSBezierPath *drawingPath = [NSBezierPath bezierPathWithRect:bounds];
|
||||
[drawingPath setWindingRule:NSEvenOddWindingRule];
|
||||
[drawingPath appendBezierPath:self];
|
||||
[drawingPath transformUsingAffineTransform:transform];
|
||||
|
||||
[self addClip];
|
||||
[shadow set];
|
||||
[[NSColor blackColor] set];
|
||||
[drawingPath fill];
|
||||
|
||||
shadow.shadowOffset = originalOffset;
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
}
|
||||
|
||||
- (void)drawBlurWithColor:(NSColor *)color radius:(CGFloat)radius
|
||||
{
|
||||
NSRect bounds = NSInsetRect(self.bounds, -radius, -radius);
|
||||
NSShadow *shadow = [[NSShadow alloc] init];
|
||||
shadow.shadowOffset = NSMakeSize(0, bounds.size.height);
|
||||
shadow.shadowBlurRadius = radius;
|
||||
shadow.shadowColor = color;
|
||||
NSBezierPath *path = [self copy];
|
||||
NSAffineTransform *transform = [NSAffineTransform transform];
|
||||
if ([[NSGraphicsContext currentContext] isFlipped])
|
||||
[transform translateXBy:0 yBy:bounds.size.height];
|
||||
else
|
||||
[transform translateXBy:0 yBy:-bounds.size.height];
|
||||
[path transformUsingAffineTransform:transform];
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
|
||||
[shadow set];
|
||||
[[NSColor blackColor] set];
|
||||
NSRectClip(bounds);
|
||||
[path fill];
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
|
||||
[path release];
|
||||
[shadow release];
|
||||
}
|
||||
|
||||
// Credit for the next two methods goes to Matt Gemmell
|
||||
- (void)strokeInside
|
||||
{
|
||||
/* Stroke within path using no additional clipping rectangle. */
|
||||
[self strokeInsideWithinRect:NSZeroRect];
|
||||
}
|
||||
|
||||
- (void)strokeInsideWithinRect:(NSRect)clipRect
|
||||
{
|
||||
NSGraphicsContext *thisContext = [NSGraphicsContext currentContext];
|
||||
float lineWidth = [self lineWidth];
|
||||
|
||||
/* Save the current graphics context. */
|
||||
[thisContext saveGraphicsState];
|
||||
|
||||
/* Double the stroke width, since -stroke centers strokes on paths. */
|
||||
[self setLineWidth:(lineWidth * 2.0)];
|
||||
|
||||
/* Clip drawing to this path; draw nothing outwith the path. */
|
||||
[self setClip];
|
||||
|
||||
/* Further clip drawing to clipRect, usually the view's frame. */
|
||||
if (clipRect.size.width > 0.0 && clipRect.size.height > 0.0) {
|
||||
[NSBezierPath clipRect:clipRect];
|
||||
}
|
||||
|
||||
/* Stroke the path. */
|
||||
[self stroke];
|
||||
|
||||
/* Restore the previous graphics context. */
|
||||
[thisContext restoreGraphicsState];
|
||||
[self setLineWidth:lineWidth];
|
||||
}
|
||||
|
||||
@end
|
15
third_party/molokocacao/README.chromium
vendored
15
third_party/molokocacao/README.chromium
vendored
@ -1,15 +0,0 @@
|
||||
Name: NSBezierPath additions from Sean Patrick O'Brien
|
||||
Short Name: NSBezierPath
|
||||
URL: http://www.seanpatrickobrien.com/journal/posts/3
|
||||
Source URL: http://www.seanpatrickobrien.com/downloads/track/?path=%2Ftutorials%2F1%2FExampleButton.zip
|
||||
Version: 1.0
|
||||
License: BSD
|
||||
Security critical: YES
|
||||
|
||||
Description:
|
||||
Additions to NSBezierPath to make certain operations more convenient (inner
|
||||
shadows on paths, for example).
|
||||
|
||||
Local Modifications:
|
||||
- Added LICENSE file based on email correspondence with Sean.
|
||||
- Added header guards.
|
@ -306,7 +306,6 @@ KNOWN_NON_IOS_LIBRARIES = set([
|
||||
os.path.join('third_party', 'lss'),
|
||||
os.path.join('third_party', 'lzma_sdk'),
|
||||
os.path.join('third_party', 'mesa'),
|
||||
os.path.join('third_party', 'molokocacao'),
|
||||
os.path.join('third_party', 'motemplate'),
|
||||
os.path.join('third_party', 'mozc'),
|
||||
os.path.join('third_party', 'mozilla'),
|
||||
|
Reference in New Issue
Block a user