Home | History | Annotate | Download | only in tabs
      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.
      4 
      5 #ifndef CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_
      6 #define CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_
      7 #pragma once
      8 
      9 // A class acting as the Objective-C window controller for a window that has
     10 // tabs which can be dragged around. Tabs can be re-arranged within the same
     11 // window or dragged into other TabWindowController windows. This class doesn't
     12 // know anything about the actual tab implementation or model, as that is fairly
     13 // application-specific. It only provides an API to be overridden by subclasses
     14 // to fill in the details.
     15 //
     16 // This assumes that there will be a view in the nib, connected to
     17 // |tabContentArea_|, that indicates the content that it switched when switching
     18 // between tabs. It needs to be a regular NSView, not something like an NSBox
     19 // because the TabStripController makes certain assumptions about how it can
     20 // swap out subviews.
     21 //
     22 // The tab strip can exist in different orientations and window locations,
     23 // depending on the return value of -usesVerticalTabs. If NO (the default),
     24 // the tab strip is placed outside the window's content area, overlapping the
     25 // title area and window controls and will be stretched to fill the width
     26 // of the window. If YES, the tab strip is vertical and lives within the
     27 // window's content area. It will be stretched to fill the window's height.
     28 
     29 #import <Cocoa/Cocoa.h>
     30 
     31 #import "base/mac/cocoa_protocols.h"
     32 #include "base/memory/scoped_nsobject.h"
     33 
     34 @class FastResizeView;
     35 @class FocusTracker;
     36 @class TabStripView;
     37 @class TabView;
     38 
     39 @interface TabWindowController : NSWindowController<NSWindowDelegate> {
     40  @private
     41   IBOutlet FastResizeView* tabContentArea_;
     42   // TODO(pinkerton): Figure out a better way to initialize one or the other
     43   // w/out needing both to be in the nib.
     44   IBOutlet TabStripView* topTabStripView_;
     45   IBOutlet TabStripView* sideTabStripView_;
     46   NSWindow* overlayWindow_;  // Used during dragging for window opacity tricks
     47   NSView* cachedContentView_;  // Used during dragging for identifying which
     48                                // view is the proper content area in the overlay
     49                                // (weak)
     50   scoped_nsobject<FocusTracker> focusBeforeOverlay_;
     51   scoped_nsobject<NSMutableSet> lockedTabs_;
     52   BOOL closeDeferred_;  // If YES, call performClose: in removeOverlay:.
     53   // Difference between height of window content area and height of the
     54   // |tabContentArea_|. Calculated when the window is loaded from the nib and
     55   // cached in order to restore the delta when switching tab modes.
     56   CGFloat contentAreaHeightDelta_;
     57 }
     58 @property(readonly, nonatomic) TabStripView* tabStripView;
     59 @property(readonly, nonatomic) FastResizeView* tabContentArea;
     60 
     61 // Used during tab dragging to turn on/off the overlay window when a tab
     62 // is torn off. If -deferPerformClose (below) is used, -removeOverlay will
     63 // cause the controller to be autoreleased before returning.
     64 - (void)showOverlay;
     65 - (void)removeOverlay;
     66 - (NSWindow*)overlayWindow;
     67 
     68 // Returns YES if it is ok to constrain the window's frame to fit the screen.
     69 - (BOOL)shouldConstrainFrameRect;
     70 
     71 // A collection of methods, stubbed out in this base class, that provide
     72 // the implementation of tab dragging based on whatever model is most
     73 // appropriate.
     74 
     75 // Layout the tabs based on the current ordering of the model.
     76 - (void)layoutTabs;
     77 
     78 // Creates a new window by pulling the given tab out and placing it in
     79 // the new window. Returns the controller for the new window. The size of the
     80 // new window will be the same size as this window.
     81 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView;
     82 
     83 // Make room in the tab strip for |tab| at the given x coordinate. Will hide the
     84 // new tab button while there's a placeholder. Subclasses need to call the
     85 // superclass implementation.
     86 - (void)insertPlaceholderForTab:(TabView*)tab
     87                           frame:(NSRect)frame
     88                   yStretchiness:(CGFloat)yStretchiness;
     89 
     90 // Removes the placeholder installed by |-insertPlaceholderForTab:atLocation:|
     91 // and restores the new tab button. Subclasses need to call the superclass
     92 // implementation.
     93 - (void)removePlaceholder;
     94 
     95 // Returns whether one of the window's tabs is being dragged.
     96 - (BOOL)isDragSessionActive;
     97 
     98 // The follow return YES if tab dragging/tab tearing (off the tab strip)/window
     99 // movement is currently allowed. Any number of things can choose to disable it,
    100 // such as pending animations. The default implementations always return YES.
    101 // Subclasses should override as appropriate.
    102 - (BOOL)tabDraggingAllowed;
    103 - (BOOL)tabTearingAllowed;
    104 - (BOOL)windowMovementAllowed;
    105 
    106 // Show or hide the new tab button. The button is hidden immediately, but
    107 // waits until the next call to |-layoutTabs| to show it again.
    108 - (void)showNewTabButton:(BOOL)show;
    109 
    110 // Returns whether or not |tab| can still be fully seen in the tab strip or if
    111 // its current position would cause it be obscured by things such as the edge
    112 // of the window or the window decorations. Returns YES only if the entire tab
    113 // is visible. The default implementation always returns YES.
    114 - (BOOL)isTabFullyVisible:(TabView*)tab;
    115 
    116 // Called to check if the receiver can receive dragged tabs from
    117 // source.  Return YES if so.  The default implementation returns NO.
    118 - (BOOL)canReceiveFrom:(TabWindowController*)source;
    119 
    120 // Move a given tab view to the location of the current placeholder. If there is
    121 // no placeholder, it will go at the end. |controller| is the window controller
    122 // of a tab being dropped from a different window. It will be nil if the drag is
    123 // within the window, otherwise the tab is removed from that window before being
    124 // placed into this one. The implementation will call |-removePlaceholder| since
    125 // the drag is now complete.  This also calls |-layoutTabs| internally so
    126 // clients do not need to call it again.
    127 - (void)moveTabView:(NSView*)view
    128      fromController:(TabWindowController*)controller;
    129 
    130 // Number of tabs in the tab strip. Useful, for example, to know if we're
    131 // dragging the only tab in the window. This includes pinned tabs (both live
    132 // and not).
    133 - (NSInteger)numberOfTabs;
    134 
    135 // YES if there are tabs in the tab strip which have content, allowing for
    136 // the notion of tabs in the tab strip that are placeholders but currently have
    137 // no content.
    138 - (BOOL)hasLiveTabs;
    139 
    140 // Return the view of the selected tab.
    141 - (NSView *)selectedTabView;
    142 
    143 // The title of the selected tab.
    144 - (NSString*)selectedTabTitle;
    145 
    146 // Called to check whether or not this controller's window has a tab strip (YES
    147 // if it does, NO otherwise). The default implementation returns YES.
    148 - (BOOL)hasTabStrip;
    149 
    150 // Returns YES if the tab strip lives in the window content area alongside the
    151 // tab contents. Returns NO if the tab strip is outside the window content
    152 // area, along the top of the window.
    153 - (BOOL)useVerticalTabs;
    154 
    155 // Get/set whether a particular tab is draggable between windows.
    156 - (BOOL)isTabDraggable:(NSView*)tabView;
    157 - (void)setTab:(NSView*)tabView isDraggable:(BOOL)draggable;
    158 
    159 // Tell the window that it needs to call performClose: as soon as the current
    160 // drag is complete. This prevents a window (and its overlay) from going away
    161 // during a drag.
    162 - (void)deferPerformClose;
    163 
    164 @end
    165 
    166 @interface TabWindowController(ProtectedMethods)
    167 // Tells the tab strip to forget about this tab in preparation for it being
    168 // put into a different tab strip, such as during a drop on another window.
    169 - (void)detachTabView:(NSView*)view;
    170 
    171 // Toggles from one display mode of the tab strip to another. Will automatically
    172 // call -layoutSubviews to reposition other content.
    173 - (void)toggleTabStripDisplayMode;
    174 
    175 // Called when the size of the window content area has changed. Override to
    176 // position specific views. Base class implementation does nothing.
    177 - (void)layoutSubviews;
    178 @end
    179 
    180 #endif  // CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_
    181