1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// Copyright (c) 2009 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 "base/logging.h"
#import "chrome/browser/cocoa/bookmark_button_cell.h"
#import "chrome/browser/cocoa/bookmark_menu.h"
@implementation BookmarkButtonCell
- (id)initTextCell:(NSString*)string {
if ((self = [super initTextCell:string])) {
[self setButtonType:NSMomentaryPushInButton];
[self setBezelStyle:NSShadowlessSquareBezelStyle];
[self setShowsBorderOnlyWhileMouseInside:YES];
[self setControlSize:NSSmallControlSize];
[self setAlignment:NSLeftTextAlignment];
[self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[self setWraps:NO];
// NSLineBreakByTruncatingMiddle seems more common on OSX but let's
// try to match Windows for a bit to see what happens.
[self setLineBreakMode:NSLineBreakByTruncatingTail];
// Theming doesn't work for bookmark buttons yet (text chucked).
[super setShouldTheme:NO];
}
return self;
}
- (BOOL)empty {
return empty_;
}
- (void)setEmpty:(BOOL)empty {
empty_ = empty;
[self setShowsBorderOnlyWhileMouseInside:!empty];
}
- (NSSize)cellSizeForBounds:(NSRect)aRect {
NSSize size = [super cellSizeForBounds:aRect];
size.width += 2;
size.height += 4;
return size;
}
- (void)setBookmarkCellText:(NSString*)title
image:(NSImage*)image {
title = [title stringByReplacingOccurrencesOfString:@"\n"
withString:@" "];
title = [title stringByReplacingOccurrencesOfString:@"\r"
withString:@" "];
// Center the image if we have a title, or if there already was a
// title set.
BOOL hasTitle = (([title length] > 0) ||
([[self title] length] > 0));
if (image) {
[self setImage:image];
if (hasTitle) {
[self setImagePosition:NSImageLeft];
} else {
[self setImagePosition:NSImageOnly];
}
}
if (title)
[self setTitle:title];
}
- (void)setBookmarkNode:(const BookmarkNode*)node {
[self setRepresentedObject:[NSValue valueWithPointer:node]];
}
- (const BookmarkNode*)bookmarkNode {
return static_cast<const BookmarkNode*>([[self representedObject]
pointerValue]);
}
// We share the context menu among all bookmark buttons. To allow us
// to disambiguate when needed (e.g. "open bookmark"), we set the
// menu's associated node to be our represented object.
- (NSMenu*)menu {
if (empty_)
return nil;
BookmarkMenu* menu = (BookmarkMenu*)[super menu];
[menu setRepresentedObject:[self representedObject]];
return menu;
}
// Unfortunately, NSCell doesn't already have something like this.
// TODO(jrg): consider placing in GTM.
- (void)setTextColor:(NSColor*)color {
// We can't properly set the cell's text color without a control.
// In theory we could just save the next for later and wait until
// the cell is moved to a control, but there is no obvious way to
// accomplish that (e.g. no "cellDidMoveToControl" notification.)
DCHECK([self controlView]);
scoped_nsobject<NSMutableParagraphStyle> style([NSMutableParagraphStyle new]);
[style setAlignment:NSCenterTextAlignment];
NSDictionary* dict = [NSDictionary
dictionaryWithObjectsAndKeys:color,
NSForegroundColorAttributeName,
[self font], NSFontAttributeName,
style.get(), NSParagraphStyleAttributeName,
nil];
scoped_nsobject<NSAttributedString> ats([[NSAttributedString alloc]
initWithString:[self title]
attributes:dict]);
NSButton* button = static_cast<NSButton*>([self controlView]);
if (button) {
DCHECK([button isKindOfClass:[NSButton class]]);
[button setAttributedTitle:ats.get()];
}
}
// To implement "hover open a bookmark button to open the folder"
// which feels like menus, we override NSButtonCell's mouseEntered:
// and mouseExited:, then and pass them along to our owning control.
- (void)mouseEntered:(NSEvent*)event {
[super mouseEntered:event];
[[self controlView] mouseEntered:event];
}
// See comment above mouseEntered:, above.
- (void)mouseExited:(NSEvent*)event {
[super mouseExited:event];
[[self controlView] mouseExited:event];
}
@end
|