blob: ec27fea3f039a054eea0ef25914b03e7dc360b2e [file] [log] [blame]
// 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.
#ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_
#define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#import "chrome/browser/ui/cocoa/bookmarks/bookmark_button.h"
#import "ui/base/cocoa/tracking_area.h"
class Profile;
@class BookmarkBarController;
@class BookmarkBarFolderView;
@class BookmarkBarFolderHoverState;
@class BookmarkBarFolderWindow;
@class BookmarkBarFolderWindowContentView;
@class BookmarkFolderTarget;
// A controller for the pop-up windows from bookmark folder buttons
// which look sort of like menus.
@interface BookmarkBarFolderController :
NSWindowController<BookmarkButtonDelegate,
BookmarkButtonControllerProtocol> {
@private
// The button whose click opened us.
base::scoped_nsobject<BookmarkButton> parentButton_;
// Bookmark bar folder controller chains are torn down in two ways:
// 1. Clicking "outside" the folder (see use of the NSEvent local event
// monitor in the bookmark bar controller).
// 2. Engaging a different folder (via hover over or explicit click).
//
// In either case, the BookmarkButtonControllerProtocol method
// closeAllBookmarkFolders gets called. For bookmark bar folder
// controllers, this is passed up the chain so we begin with a top
// level "close".
// When any bookmark folder window closes, it necessarily tells
// subcontroller windows to close (down the chain), and autoreleases
// the controller. (Must autorelease since the controller can still
// get delegate events such as windowDidClose).
//
// Bookmark bar folder controllers own their buttons. When doing
// drag and drop of a button from one sub-sub-folder to a different
// sub-sub-folder, we need to make sure the button's pointers stay
// valid until we've dropped (or cancelled). Note that such a drag
// causes the source sub-sub-folder (previous parent window) to go
// away (windows close, controllers autoreleased) since you're
// hovering over a different folder chain for dropping. To keep
// things valid (like the button's target, its delegate, the parent
// cotroller that we have a pointer to below [below], etc), we heep
// strong pointers to our owning controller, so the entire chain
// stays owned.
// Our parent controller, if we are a nested folder, otherwise nil.
// Strong to insure the object lives as long as we need it.
base::scoped_nsobject<BookmarkBarFolderController> parentController_;
// The main bar controller from whence we or a parent sprang.
BookmarkBarController* barController_; // WEAK: It owns us.
// Our buttons. We do not have buttons for nested folders.
base::scoped_nsobject<NSMutableArray> buttons_;
// The scroll view that contains our main button view (below).
IBOutlet NSScrollView* scrollView_;
// The view defining the visible area in which we draw our content.
IBOutlet BookmarkBarFolderWindowContentView* visibleView_;
// The main view of this window (where the buttons go) within the scroller.
IBOutlet BookmarkBarFolderView* folderView_;
// A window used to show the shadow behind the main window when it is
// scrollable. (A 'shadow' window is needed because the main window, when
// scrollable in either or both directions, will reach completely to the
// top and/or bottom edge of the screen in order to support mouse tracking
// during scrolling operations. In that case, though, the 'visible'
// window must be inset a bit from the edge of the screen for aesthetics;
// it will also be inset much more from the bottom of the screen when the
// Dock is showing. When scrollable, the main window would show a shadow
// incorrectly positioned, hence the 'shadow' window.)
IBOutlet BookmarkBarFolderWindow* shadowWindow_;
// The up and down scroll arrow views. These arrows are hidden and shown
// as necessary (when scrolling is possible) and are contained in the nib
// as siblings to the scroll view.
IBOutlet NSView* scrollDownArrowView_; // Positioned at the top.
IBOutlet NSView* scrollUpArrowView_; // Positioned at the bottom.
// YES if subfolders should grow to the right (the default).
// Direction switches if we'd grow off the screen.
BOOL subFolderGrowthToRight_;
// Weak; we keep track to work around a
// setShowsBorderOnlyWhileMouseInside bug.
BookmarkButton* buttonThatMouseIsIn_;
// We model hover state as a state machine with specific allowable
// transitions. |hoverState_| is the state of this machine at any
// given time.
base::scoped_nsobject<BookmarkBarFolderHoverState> hoverState_;
// 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).
// We (self) are the parentController_ for our folderController_.
// This is not a scoped_nsobject because it owns itself (when its
// window closes the controller gets autoreleased).
BookmarkBarFolderController* folderController_;
// Implement basic menu scrolling through this tracking area.
ui::ScopedCrTrackingArea scrollTrackingArea_;
// Timer to continue scrolling as needed. We own the timer but
// don't release it when done (we invalidate it).
NSTimer* scrollTimer_;
// Precalculated sum of left and right edge padding of buttons in a
// folder menu window. This is calculated from the widths of the main
// folder menu window and the scroll view within.
CGFloat padding_;
// Amount to scroll by on each timer fire. Can be + or -.
CGFloat verticalScrollDelta_;
// We need to know the size of the vertical scrolling arrows so we
// can obscure/unobscure them.
CGFloat verticalScrollArrowHeight_;
// Set to YES to prevent any node animations. Useful for unit testing so that
// incomplete animations do not cause valgrind complaints.
BOOL ignoreAnimations_;
// The screen to which the menu should be restricted.
NSScreen* screen_;
int selectedIndex_;
NSString* typedPrefix_;
Profile* profile_;
}
// Designated initializer.
- (id)initWithParentButton:(BookmarkButton*)button
parentController:(BookmarkBarFolderController*)parentController
barController:(BookmarkBarController*)barController
profile:(Profile*)profile;
// Return the parent button that owns the bookmark folder we represent.
- (BookmarkButton*)parentButton;
// Text typed by user, for type-select and arrow key support.
// Returns YES if the menu should be closed now.
- (BOOL)handleInputText:(NSString*)newText;
// If you wanted to clear the type-select buffer. Currently only used
// internally.
- (void)clearInputText;
// Gets notified when a fav icon asynchronously loads, so we can now use the
// real icon instead of a generic placeholder.
- (void)faviconLoadedForNode:(const BookmarkNode*)node;
- (void)setSelectedButtonByIndex:(int)index;
// Offset our folder menu window. This is usually needed in response to a
// parent folder menu window or the bookmark bar changing position due to
// the dragging of a bookmark node from the parent into this folder menu.
- (void)offsetFolderMenuWindow:(NSSize)offset;
// Re-layout the window menu in case some buttons were added or removed,
// specifically as a result of the bookmark bar changing configuration
// and altering the contents of the off-the-side folder.
- (void)reconfigureMenu;
// Passed up by a child view to tell us of a desire to scroll.
- (void)scrollWheel:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent*)theEvent;
@property(assign, nonatomic) BOOL subFolderGrowthToRight;
@end
@interface BookmarkBarFolderController(TestingAPI)
- (NSPoint)windowTopLeftForWidth:(int)windowWidth
height:(int)windowHeight;
- (NSArray*)buttons;
- (BookmarkBarFolderController*)folderController;
- (id)folderTarget;
- (void)configureWindowLevel;
- (void)performOneScroll:(CGFloat)delta;
- (BookmarkButton*)buttonThatMouseIsIn;
// Set to YES in order to prevent animations.
- (void)setIgnoreAnimations:(BOOL)ignore;
// Return YES if the scroll-up or scroll-down arrows are showing.
- (BOOL)canScrollUp;
- (BOOL)canScrollDown;
- (CGFloat)verticalScrollArrowHeight;
- (NSView*)visibleView;
- (NSScrollView*)scrollView;
- (NSView*)folderView;
- (IBAction)openBookmarkFolderFromButton:(id)sender;
- (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point;
@end
#endif // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_BAR_FOLDER_CONTROLLER_H_