File: bookmark_bar_controller.h

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (423 lines) | stat: -rw-r--r-- 17,670 bytes parent folder | download
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
// 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_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_
#define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_

#import <Cocoa/Cocoa.h>
#include <map>

#import "base/mac/cocoa_protocols.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_bridge.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_state.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_toolbar_view.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
#include "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h"
#include "ui/base/window_open_disposition.h"

@class BookmarkBarController;
@class BookmarkBarFolderController;
@class BookmarkBarView;
@class BookmarkButtonCell;
@class BookmarkFolderTarget;
@class BookmarkContextMenuCocoaController;
class BookmarkModel;
class BookmarkNode;
class Browser;
class ChromeBookmarkClient;
class GURL;
namespace ui {
class ThemeProvider;
}

namespace bookmarks {

// Magic numbers from Cole
// TODO(jrg): create an objc-friendly version of bookmark_bar_constants.h?

// Used as a maximum width for buttons on the bar.
const CGFloat kDefaultBookmarkWidth = 150.0;

// Horizontal frame inset for buttons in the bookmark bar.
const CGFloat kBookmarkHorizontalPadding = 1.0;

// Vertical frame inset for buttons in the bookmark bar.
const CGFloat kBookmarkVerticalPadding = 2.0;

// Left margin before the first button in the bookmark bar.
const CGFloat kBookmarkLeftMargin = 2.0;

// Right margin before the last button in the bookmark bar.
const CGFloat kBookmarkRightMargin = 2.0;

// Used as a min/max width for buttons on menus (not on the bar).
const CGFloat kBookmarkMenuButtonMinimumWidth = 100.0;
const CGFloat kBookmarkMenuButtonMaximumWidth = 485.0;

// The minimum separation between a folder menu and the edge of the screen.
// If the menu gets closer to the edge of the screen (either right or left)
// then it is pops up in the opposite direction.
// (See -[BookmarkBarFolderController childFolderWindowLeftForWidth:]).
const CGFloat kBookmarkHorizontalScreenPadding = 8.0;

// Our NSScrollView is supposed to be just barely big enough to fit its
// contentView.  It is actually a hair too small.
// This turns on horizontal scrolling which, although slight, is awkward.
// Make sure our window (and NSScrollView) are wider than its documentView
// by at least this much.
const CGFloat kScrollViewContentWidthMargin = 2;

// Make subfolder menus overlap their parent menu a bit to give a better
// perception of a menuing system.
const CGFloat kBookmarkMenuOverlap = 2.0;

// When constraining a scrolling bookmark bar folder window to the
// screen, shrink the "constrain" by this much vertically.  Currently
// this is 0.0 to avoid a problem with tracking areas leaving the
// window, but should probably be 8.0 or something.
const CGFloat kScrollWindowVerticalMargin = 6.0;

// How far to offset a folder menu from the top of the bookmark bar. This
// is set just above the bar so that it become distinctive when drawn.
const CGFloat kBookmarkBarMenuOffset = 2.0;

// How far to offset a folder menu's left edge horizontally in relation to
// the left edge of the button from which it springs. Because of drawing
// differences, simply aligning the |frame| of each does not render the
// pproper result, so we have to offset.
const CGFloat kBookmarkBarButtonOffset = 2.0;

// Delay before opening a subfolder (and closing the previous one)
// when hovering over a folder button.
const NSTimeInterval kHoverOpenDelay = 0.3;

// Delay on hover before a submenu opens when dragging.
// Experimentally a drag hover open delay needs to be bigger than a
// normal (non-drag) menu hover open such as used in the bookmark folder.
//  TODO(jrg): confirm feel of this constant with ui-team.
//  http://crbug.com/36276
const NSTimeInterval kDragHoverOpenDelay = 0.7;

// Notes on use of kDragHoverCloseDelay in
// -[BookmarkBarFolderController draggingEntered:].
//
// We have an implicit delay on stop-hover-open before a submenu
// closes.  This cannot be zero since it's nice to move the mouse in a
// direct line from "current position" to "position of item in
// submenu".  However, by doing so, it's possible to overlap a
// different button on the current menu.  Example:
//
//  Folder1
//  Folder2  ---> Sub1
//  Folder3       Sub2
//                Sub3
//
// If you hover over the F in Folder2 to open the sub, and then want to
// select Sub3, a direct line movement of the mouse may cross over
// Folder3.  Without this delay, that'll cause Sub to be closed before
// you get there, since a "hover over" of Folder3 gets activated.
// It's subtle but without the delay it feels broken.
//
// This is only really a problem with vertical menu --> vertical menu
// movement; the bookmark bar (horizontal menu, sort of) seems fine,
// perhaps because mouse move direction is purely vertical so there is
// no opportunity for overlap.
const NSTimeInterval kDragHoverCloseDelay = 0.4;

}  // namespace bookmarks

// The interface for the bookmark bar controller's delegate. Currently, the
// delegate is the BWC and is responsible for ensuring that the toolbar is
// displayed correctly (as specified by |-getDesiredToolbarHeightCompression|
// and |-toolbarDividerOpacity|) at the beginning and at the end of an animation
// (or after a state change).
@protocol BookmarkBarControllerDelegate

// Sent when the state has changed (after any animation), but before the final
// display update.
- (void)bookmarkBar:(BookmarkBarController*)controller
 didChangeFromState:(BookmarkBar::State)oldState
            toState:(BookmarkBar::State)newState;

// Sent before the animation begins.
- (void)bookmarkBar:(BookmarkBarController*)controller
willAnimateFromState:(BookmarkBar::State)oldState
            toState:(BookmarkBar::State)newState;

@end

// A controller for the bookmark bar in the browser window. Handles showing
// and hiding based on the preference in the given profile.
@interface BookmarkBarController :
    NSViewController<BookmarkBarState,
                     BookmarkBarToolbarViewController,
                     BookmarkButtonDelegate,
                     BookmarkButtonControllerProtocol,
                     NSDraggingDestination> {
 @private
  // The state of the bookmark bar. If an animation is running, this is set to
  // the "destination" and |lastState_| is set to the "original" state.
  BookmarkBar::State currentState_;

  // The "original" state of the bookmark bar if an animation is running.
  BookmarkBar::State lastState_;

  // YES if an animation is running.
  BOOL isAnimationRunning_;

  Browser* browser_;              // weak; owned by its window
  BookmarkModel* bookmarkModel_;  // weak; part of the profile owned by the
                                  // top-level Browser object.
  ChromeBookmarkClient* bookmarkClient_;

  // Our initial view width, which is applied in awakeFromNib.
  CGFloat initialWidth_;

  // BookmarkNodes have a 64bit id.  NSMenuItems have a 32bit tag used
  // to represent the bookmark node they refer to.  This map provides
  // a mapping from one to the other, so we can properly identify the
  // node from the item.  When adding items in, we start with seedId_.
  int32 seedId_;
  std::map<int32,int64> menuTagMap_;

  // Our bookmark buttons, ordered from L-->R.
  base::scoped_nsobject<NSMutableArray> buttons_;

  // The folder image so we can use one copy for all buttons
  base::scoped_nsobject<NSImage> folderImage_;

  // The default image, so we can use one copy for all buttons.
  base::scoped_nsobject<NSImage> defaultImage_;

  // If the bar is disabled, we hide it and ignore show/hide commands.
  // Set when using fullscreen mode.
  BOOL barIsEnabled_;

  // Bridge from Chrome-style C++ notifications (e.g. derived from
  // BookmarkModelObserver)
  scoped_ptr<BookmarkBarBridge> bridge_;

  // Delegate that is informed about state changes in the bookmark bar.
  id<BookmarkBarControllerDelegate> delegate_;  // weak

  // Delegate that can resize us.
  id<ViewResizer> resizeDelegate_;  // weak

  // Logic for dealing with a click on a bookmark folder button.
  base::scoped_nsobject<BookmarkFolderTarget> folderTarget_;

  // A controller for a pop-up bookmark folder window (custom menu).
  // This is not a scoped_nsobject because it owns itself (when its
  // window closes the controller gets autoreleased).
  BookmarkBarFolderController* folderController_;

  // The event tap that allows monitoring of all events, to properly close with
  // a click outside the bounds of the window.
  id exitEventTap_;

  IBOutlet BookmarkBarView* buttonView_;  // Contains 'no items' text fields.
  IBOutlet BookmarkButton* offTheSideButton_;  // aka the chevron.

  NSRect originalNoItemsRect_;  // Original, pre-resized field rect.
  NSRect originalImportBookmarksRect_;  // Original, pre-resized field rect.

  // "Apps" button on the left side.
  base::scoped_nsobject<BookmarkButton> appsPageShortcutButton_;

  // "Managed bookmarks" button on the left side, next to the apps button.
  base::scoped_nsobject<BookmarkButton> managedBookmarksButton_;

  // "Other bookmarks" button on the right side.
  base::scoped_nsobject<BookmarkButton> otherBookmarksButton_;

  // When doing a drag, this is folder button "hovered over" which we
  // may want to open after a short delay.  There are cases where a
  // mouse-enter can open a folder (e.g. if the menus are "active")
  // but that doesn't use this variable or need a delay so "hover" is
  // the wrong term.
  base::scoped_nsobject<BookmarkButton> hoverButton_;

  // We save the view width when we add bookmark buttons.  This lets
  // us avoid a rebuild until we've grown the window bigger than our
  // initial build.
  CGFloat savedFrameWidth_;

  // The number of buttons we display in the bookmark bar.  This does
  // not include the "off the side" chevron or the "Other Bookmarks"
  // button.  We use this number to determine if we need to display
  // the chevron, and to know what to place in the chevron's menu.
  // Since we create everything before doing layout we can't be sure
  // that all bookmark buttons we create will be visible.  Thus,
  // [buttons_ count] isn't a definitive check.
  int displayedButtonCount_;

  // A state flag which tracks when the bar's folder menus should be shown.
  // An initial click in any of the folder buttons turns this on and
  // one of the following will turn it off: another click in the button,
  // the window losing focus, a click somewhere other than in the bar
  // or a folder menu.
  BOOL showFolderMenus_;

  // If YES then state changes (for example, from hidden to shown) are animated.
  // This is turned off for unit tests.
  BOOL stateAnimationsEnabled_;

  // If YES then changes inside the bookmark bar (for example, removing a
  // bookmark) are animated. This is turned off for unit tests.
  BOOL innerContentAnimationsEnabled_;

  // YES if there is a possible drop about to happen in the bar.
  BOOL hasInsertionPos_;

  // The x point on the bar where the left edge of the new item will end
  // up if it is dropped.
  CGFloat insertionPos_;

  // Controller responsible for all bookmark context menus.
  base::scoped_nsobject<BookmarkContextMenuCocoaController>
      contextMenuController_;
}

@property(readonly, nonatomic) BookmarkBar::State currentState;
@property(readonly, nonatomic) BookmarkBar::State lastState;
@property(readonly, nonatomic) BOOL isAnimationRunning;
@property(assign, nonatomic) id<BookmarkBarControllerDelegate> delegate;
@property(assign, nonatomic) BOOL stateAnimationsEnabled;
@property(assign, nonatomic) BOOL innerContentAnimationsEnabled;

// Initializes the bookmark bar controller with the given browser
// profile and delegates.
- (id)initWithBrowser:(Browser*)browser
         initialWidth:(CGFloat)initialWidth
             delegate:(id<BookmarkBarControllerDelegate>)delegate
       resizeDelegate:(id<ViewResizer>)resizeDelegate;

// The Browser corresponding to this BookmarkBarController.
- (Browser*)browser;

// The controller for all bookmark bar context menus.
- (BookmarkContextMenuCocoaController*)menuController;

// Updates the bookmark bar (from its current, possibly in-transition) state to
// the new state.
- (void)updateState:(BookmarkBar::State)newState
         changeType:(BookmarkBar::AnimateChangeType)changeType;

// Update the visible state of the bookmark bar.
- (void)updateVisibility;

// Update the visible state of the extra butons on the bookmark bar: the
// apps shortcut and the managed bookmarks folder.
- (void)updateExtraButtonsVisibility;

// Hides or shows the bookmark bar depending on the current state.
- (void)updateHiddenState;

// Turn on or off the bookmark bar and prevent or reallow its appearance. On
// disable, toggle off if shown. On enable, show only if needed. App and popup
// windows do not show a bookmark bar.
- (void)setBookmarkBarEnabled:(BOOL)enabled;

// Returns the amount by which the toolbar above should be compressed.
- (CGFloat)getDesiredToolbarHeightCompression;

// Gets the appropriate opacity for the toolbar's divider; 0 means that it
// shouldn't be shown.
- (CGFloat)toolbarDividerOpacity;

// Updates the sizes and positions of the subviews.
// TODO(viettrungluu): I'm not convinced this should be public, but I currently
// need it for animations. Try not to propagate its use.
- (void)layoutSubviews;

// Called by our view when it is moved to a window.
- (void)viewDidMoveToWindow;

// Provide a favicon for a bookmark node.  May return nil.
- (NSImage*)faviconForNode:(const BookmarkNode*)node;

// Used for situations where the bookmark bar folder menus should no longer
// be actively popping up. Called when the window loses focus, a click has
// occured outside the menus or a bookmark has been activated. (Note that this
// differs from the behavior of the -[BookmarkButtonControllerProtocol
// closeAllBookmarkFolders] method in that the latter does not terminate menu
// tracking since it may be being called in response to actions (such as
// dragging) where a 'stale' menu presentation should first be collapsed before
// presenting a new menu.)
- (void)closeFolderAndStopTrackingMenus;

// Checks if operations such as edit or delete are allowed.
- (BOOL)canEditBookmark:(const BookmarkNode*)node;

// Checks if bookmark editing is enabled at all.
- (BOOL)canEditBookmarks;

// Actions for manipulating bookmarks.
// Open a normal bookmark or folder from a button, ...
- (IBAction)openBookmark:(id)sender;
- (IBAction)openBookmarkFolderFromButton:(id)sender;
// From the "off the side" button, ...
- (IBAction)openOffTheSideFolderFromButton:(id)sender;
// Import bookmarks from another browser.
- (IBAction)importBookmarks:(id)sender;
@end

// Redirects from BookmarkBarBridge, the C++ object which glues us to
// the rest of Chromium.  Internal to BookmarkBarController.
@interface BookmarkBarController(BridgeRedirect)
- (void)loaded:(BookmarkModel*)model;
- (void)beingDeleted:(BookmarkModel*)model;
- (void)nodeAdded:(BookmarkModel*)model
           parent:(const BookmarkNode*)oldParent index:(int)index;
- (void)nodeChanged:(BookmarkModel*)model
               node:(const BookmarkNode*)node;
- (void)nodeMoved:(BookmarkModel*)model
        oldParent:(const BookmarkNode*)oldParent oldIndex:(int)oldIndex
        newParent:(const BookmarkNode*)newParent newIndex:(int)newIndex;
- (void)nodeRemoved:(BookmarkModel*)model
             parent:(const BookmarkNode*)oldParent index:(int)index;
- (void)nodeFaviconLoaded:(BookmarkModel*)model
                     node:(const BookmarkNode*)node;
- (void)nodeChildrenReordered:(BookmarkModel*)model
                         node:(const BookmarkNode*)node;
@end

// These APIs should only be used by unit tests (or used internally).
@interface BookmarkBarController(InternalOrTestingAPI)
- (void)openBookmarkFolder:(id)sender;
- (void)openOrCloseBookmarkFolderForOffTheSideButton;
- (BookmarkBarView*)buttonView;
- (NSMutableArray*)buttons;
- (NSButton*)offTheSideButton;
- (NSButton*)appsPageShortcutButton;
- (BOOL)offTheSideButtonIsHidden;
- (BOOL)appsPageShortcutButtonIsHidden;
- (BookmarkButton*)otherBookmarksButton;
- (BookmarkBarFolderController*)folderController;
- (id)folderTarget;
- (int)displayedButtonCount;
- (void)openURL:(GURL)url disposition:(WindowOpenDisposition)disposition;
- (void)clearBookmarkBar;
- (BookmarkButtonCell*)cellForBookmarkNode:(const BookmarkNode*)node;
- (BookmarkButtonCell*)cellForCustomButtonWithText:(NSString*)text
                                             image:(NSImage*)image;
- (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell xOffset:(int*)xOffset;
- (void)checkForBookmarkButtonGrowth:(NSButton*)button;
- (void)frameDidChange;
- (int64)nodeIdFromMenuTag:(int32)tag;
- (int32)menuTagFromNodeId:(int64)menuid;
- (void)updateTheme:(ui::ThemeProvider*)themeProvider;
- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point;
- (BOOL)isEventAnExitEvent:(NSEvent*)event;
- (BOOL)shrinkOrHideView:(NSView*)view forMaxX:(CGFloat)maxViewX;
- (void)unhighlightBookmark:(const BookmarkNode*)node;

// The following are for testing purposes only and are not used internally.
- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node;
@end

#endif  // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_CONTROLLER_H_