1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_
6 #define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_
8 #import <Cocoa/Cocoa.h>
10 #include "base/mac/scoped_nsobject.h"
11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
12 #import "ui/base/cocoa/tracking_area.h"
16 @
class BookmarkBarController
;
17 @
class BookmarkBarFolderView
;
18 @
class BookmarkBarFolderHoverState
;
19 @
class BookmarkBarFolderWindow
;
20 @
class BookmarkBarFolderWindowContentView
;
21 @
class BookmarkFolderTarget
;
23 // A controller for the pop-up windows from bookmark folder buttons
24 // which look sort of like menus.
25 @interface BookmarkBarFolderController
:
26 NSWindowController
<BookmarkButtonDelegate
,
27 BookmarkButtonControllerProtocol
> {
29 // The button whose click opened us.
30 base::scoped_nsobject
<BookmarkButton
> parentButton_
;
32 // Bookmark bar folder controller chains are torn down in two ways:
33 // 1. Clicking "outside" the folder (see use of the NSEvent local event
34 // monitor in the bookmark bar controller).
35 // 2. Engaging a different folder (via hover over or explicit click).
37 // In either case, the BookmarkButtonControllerProtocol method
38 // closeAllBookmarkFolders gets called. For bookmark bar folder
39 // controllers, this is passed up the chain so we begin with a top
41 // When any bookmark folder window closes, it necessarily tells
42 // subcontroller windows to close (down the chain), and autoreleases
43 // the controller. (Must autorelease since the controller can still
44 // get delegate events such as windowDidClose).
46 // Bookmark bar folder controllers own their buttons. When doing
47 // drag and drop of a button from one sub-sub-folder to a different
48 // sub-sub-folder, we need to make sure the button's pointers stay
49 // valid until we've dropped (or cancelled). Note that such a drag
50 // causes the source sub-sub-folder (previous parent window) to go
51 // away (windows close, controllers autoreleased) since you're
52 // hovering over a different folder chain for dropping. To keep
53 // things valid (like the button's target, its delegate, the parent
54 // cotroller that we have a pointer to below [below], etc), we heep
55 // strong pointers to our owning controller, so the entire chain
58 // Our parent controller, if we are a nested folder, otherwise nil.
59 // Strong to insure the object lives as long as we need it.
60 base::scoped_nsobject
<BookmarkBarFolderController
> parentController_
;
62 // The main bar controller from whence we or a parent sprang.
63 BookmarkBarController
* barController_
; // WEAK: It owns us.
65 // Our buttons. We do not have buttons for nested folders.
66 base::scoped_nsobject
<NSMutableArray
> buttons_
;
68 // The scroll view that contains our main button view (below).
69 IBOutlet NSScrollView
* scrollView_
;
71 // The view defining the visible area in which we draw our content.
72 IBOutlet BookmarkBarFolderWindowContentView
* visibleView_
;
74 // The main view of this window (where the buttons go) within the scroller.
75 IBOutlet BookmarkBarFolderView
* folderView_
;
77 // A window used to show the shadow behind the main window when it is
78 // scrollable. (A 'shadow' window is needed because the main window, when
79 // scrollable in either or both directions, will reach completely to the
80 // top and/or bottom edge of the screen in order to support mouse tracking
81 // during scrolling operations. In that case, though, the 'visible'
82 // window must be inset a bit from the edge of the screen for aesthetics;
83 // it will also be inset much more from the bottom of the screen when the
84 // Dock is showing. When scrollable, the main window would show a shadow
85 // incorrectly positioned, hence the 'shadow' window.)
86 IBOutlet BookmarkBarFolderWindow
* shadowWindow_
;
88 // The up and down scroll arrow views. These arrows are hidden and shown
89 // as necessary (when scrolling is possible) and are contained in the nib
90 // as siblings to the scroll view.
91 IBOutlet NSView
* scrollDownArrowView_
; // Positioned at the top.
92 IBOutlet NSView
* scrollUpArrowView_
; // Positioned at the bottom.
94 // YES if subfolders should grow to the right (the default).
95 // Direction switches if we'd grow off the screen.
96 BOOL subFolderGrowthToRight_
;
98 // Weak; we keep track to work around a
99 // setShowsBorderOnlyWhileMouseInside bug.
100 BookmarkButton
* buttonThatMouseIsIn_
;
102 // We model hover state as a state machine with specific allowable
103 // transitions. |hoverState_| is the state of this machine at any
105 base::scoped_nsobject
<BookmarkBarFolderHoverState
> hoverState_
;
107 // Logic for dealing with a click on a bookmark folder button.
108 base::scoped_nsobject
<BookmarkFolderTarget
> folderTarget_
;
110 // A controller for a pop-up bookmark folder window (custom menu).
111 // We (self) are the parentController_ for our folderController_.
112 // This is not a scoped_nsobject because it owns itself (when its
113 // window closes the controller gets autoreleased).
114 BookmarkBarFolderController
* folderController_
;
116 // Implement basic menu scrolling through this tracking area.
117 ui::ScopedCrTrackingArea scrollTrackingArea_
;
119 // Timer to continue scrolling as needed. We own the timer but
120 // don't release it when done (we invalidate it).
121 NSTimer
* scrollTimer_
;
123 // Precalculated sum of left and right edge padding of buttons in a
124 // folder menu window. This is calculated from the widths of the main
125 // folder menu window and the scroll view within.
128 // Amount to scroll by on each timer fire. Can be + or -.
129 CGFloat verticalScrollDelta_
;
131 // We need to know the size of the vertical scrolling arrows so we
132 // can obscure/unobscure them.
133 CGFloat verticalScrollArrowHeight_
;
135 // Set to YES to prevent any node animations. Useful for unit testing so that
136 // incomplete animations do not cause valgrind complaints.
137 BOOL ignoreAnimations_
;
139 // The screen to which the menu should be restricted.
143 NSString
* typedPrefix_
;
148 // Designated initializer.
149 - (id
)initWithParentButton
:(BookmarkButton
*)button
150 parentController
:(BookmarkBarFolderController
*)parentController
151 barController
:(BookmarkBarController
*)barController
152 profile
:(Profile
*)profile
;
154 // Return the parent button that owns the bookmark folder we represent.
155 - (BookmarkButton
*)parentButton
;
157 // Text typed by user, for type-select and arrow key support.
158 // Returns YES if the menu should be closed now.
159 - (BOOL
)handleInputText
:(NSString
*)newText
;
161 // If you wanted to clear the type-select buffer. Currently only used
163 - (void)clearInputText
;
165 // Gets notified when a fav icon asynchronously loads, so we can now use the
166 // real icon instead of a generic placeholder.
167 - (void)faviconLoadedForNode
:(const BookmarkNode
*)node
;
169 - (void)setSelectedButtonByIndex
:(int)index
;
171 // Offset our folder menu window. This is usually needed in response to a
172 // parent folder menu window or the bookmark bar changing position due to
173 // the dragging of a bookmark node from the parent into this folder menu.
174 - (void)offsetFolderMenuWindow
:(NSSize
)offset
;
176 // Re-layout the window menu in case some buttons were added or removed,
177 // specifically as a result of the bookmark bar changing configuration
178 // and altering the contents of the off-the-side folder.
179 - (void)reconfigureMenu
;
181 // Passed up by a child view to tell us of a desire to scroll.
182 - (void)scrollWheel
:(NSEvent
*)theEvent
;
184 - (void)mouseDragged
:(NSEvent
*)theEvent
;
186 @
property(assign
, nonatomic
) BOOL subFolderGrowthToRight
;
190 @interface
BookmarkBarFolderController(TestingAPI
)
191 - (NSPoint
)windowTopLeftForWidth
:(int)windowWidth
192 height
:(int)windowHeight
;
194 - (BookmarkBarFolderController
*)folderController
;
196 - (void)configureWindowLevel
;
197 - (void)performOneScroll
:(CGFloat
)delta
;
198 - (BookmarkButton
*)buttonThatMouseIsIn
;
199 // Set to YES in order to prevent animations.
200 - (void)setIgnoreAnimations
:(BOOL
)ignore
;
202 // Return YES if the scroll-up or scroll-down arrows are showing.
204 - (BOOL
)canScrollDown
;
205 - (CGFloat
)verticalScrollArrowHeight
;
206 - (NSView
*)visibleView
;
207 - (NSScrollView
*)scrollView
;
208 - (NSView
*)folderView
;
210 - (IBAction
)openBookmarkFolderFromButton
:(id
)sender
;
212 - (BookmarkButton
*)buttonForDroppingOnAtPoint
:(NSPoint
)point
;
215 #endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_