Home | History | Annotate | Download | only in cocoa
      1 // Copyright (c) 2009 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_STATUS_BUBBLE_MAC_H_
      6 #define CHROME_BROWSER_UI_COCOA_STATUS_BUBBLE_MAC_H_
      7 #pragma once
      8 
      9 #include <string>
     10 
     11 #import <Cocoa/Cocoa.h>
     12 #import <QuartzCore/QuartzCore.h>
     13 
     14 #include "base/string16.h"
     15 #include "base/task.h"
     16 #include "chrome/browser/ui/status_bubble.h"
     17 #include "googleurl/src/gurl.h"
     18 
     19 class GURL;
     20 class StatusBubbleMacTest;
     21 
     22 class StatusBubbleMac : public StatusBubble {
     23  public:
     24   // The various states that a status bubble may be in.  Public for delegate
     25   // access (for testing).
     26   enum StatusBubbleState {
     27     kBubbleHidden,         // Fully hidden
     28     kBubbleShowingTimer,   // Waiting to fade in
     29     kBubbleShowingFadeIn,  // In a fade-in transition
     30     kBubbleShown,          // Fully visible
     31     kBubbleHidingTimer,    // Waiting to fade out
     32     kBubbleHidingFadeOut   // In a fade-out transition
     33   };
     34 
     35   StatusBubbleMac(NSWindow* parent, id delegate);
     36   virtual ~StatusBubbleMac();
     37 
     38   // StatusBubble implementation.
     39   virtual void SetStatus(const string16& status);
     40   virtual void SetURL(const GURL& url, const string16& languages);
     41   virtual void Hide();
     42   virtual void MouseMoved(const gfx::Point& location, bool left_content);
     43   virtual void UpdateDownloadShelfVisibility(bool visible);
     44 
     45   // Mac-specific method: Update the size and position of the status bubble to
     46   // match the parent window. Safe to call even when the status bubble does not
     47   // exist.
     48   void UpdateSizeAndPosition();
     49 
     50   // Mac-specific method: Change the parent window of the status bubble. Safe to
     51   // call even when the status bubble does not exist.
     52   void SwitchParentWindow(NSWindow* parent);
     53 
     54   // Delegate method called when a fade-in or fade-out transition has
     55   // completed.  This is public so that it may be visible to the CAAnimation
     56   // delegate, which is an Objective-C object.
     57   void AnimationDidStop(CAAnimation* animation, bool finished);
     58 
     59   // Expand the bubble to fit a URL too long for the standard bubble size.
     60   void ExpandBubble();
     61 
     62  private:
     63   friend class StatusBubbleMacTest;
     64 
     65   // Setter for state_.  Use this instead of writing to state_ directly so
     66   // that state changes can be observed by unit tests.
     67   void SetState(StatusBubbleState state);
     68 
     69   // Sets the bubble text for SetStatus and SetURL.
     70   void SetText(const string16& text, bool is_url);
     71 
     72   // Construct the window/widget if it does not already exist. (Safe to call if
     73   // it does.)
     74   void Create();
     75 
     76   // Attaches the status bubble window to its parent window. Safe to call even
     77   // when already attached.
     78   void Attach();
     79 
     80   // Detaches the status bubble window from its parent window.
     81   void Detach();
     82 
     83   // Is the status bubble attached to the browser window? It should be attached
     84   // when shown and during any fades, but should be detached when hidden.
     85   bool is_attached() { return [window_ parentWindow] != nil; }
     86 
     87   // Begins fading the status bubble window in or out depending on the value
     88   // of |show|.  This must be called from the appropriate fade state,
     89   // kBubbleShowingFadeIn or kBubbleHidingFadeOut, or from the appropriate
     90   // fully-shown/hidden state, kBubbleShown or kBubbleHidden.  This may be
     91   // called at any point during a fade-in or fade-out; it is even possible to
     92   // reverse a transition before it has completed.
     93   void Fade(bool show);
     94 
     95   // One-shot timer operations to manage the delays associated with the
     96   // kBubbleShowingTimer and kBubbleHidingTimer states.  StartTimer and
     97   // TimerFired must be called from one of these states.  StartTimer may be
     98   // called while the timer is still running; in that case, the timer will be
     99   // reset. CancelTimer may be called from any state.
    100   void StartTimer(int64 time_ms);
    101   void CancelTimer();
    102   void TimerFired();
    103 
    104   // Begin the process of showing or hiding the status bubble.  These may be
    105   // called from any state, and will take the appropriate action to initiate
    106   // any state changes that may be needed.
    107   void StartShowing();
    108   void StartHiding();
    109 
    110   // Cancel the expansion timer.
    111   void CancelExpandTimer();
    112 
    113   // The timer factory used for show and hide delay timers.
    114   ScopedRunnableMethodFactory<StatusBubbleMac> timer_factory_;
    115 
    116   // The timer factory used for the expansion delay timer.
    117   ScopedRunnableMethodFactory<StatusBubbleMac> expand_timer_factory_;
    118 
    119   // Calculate the appropriate frame for the status bubble window. If
    120   // |expanded_width|, use entire width of parent frame.
    121   NSRect CalculateWindowFrame(bool expanded_width);
    122 
    123   // The window we attach ourselves to.
    124   NSWindow* parent_;  // WEAK
    125 
    126   // The object that we query about our vertical offset for positioning.
    127   id delegate_;  // WEAK
    128 
    129   // The window we own.
    130   NSWindow* window_;
    131 
    132   // The status text we want to display when there are no URLs to display.
    133   NSString* status_text_;
    134 
    135   // The url we want to display when there is no status text to display.
    136   NSString* url_text_;
    137 
    138   // The status bubble's current state.  Do not write to this field directly;
    139   // use SetState().
    140   StatusBubbleState state_;
    141 
    142   // True if operations are to be performed immediately rather than waiting
    143   // for delays and transitions.  Normally false, this should only be set to
    144   // true for testing.
    145   bool immediate_;
    146 
    147   // True if the status bubble has been expanded. If the bubble is in the
    148   // expanded state and encounters a new URL, change size immediately,
    149   // with no hover delay.
    150   bool is_expanded_;
    151 
    152   // The original, non-elided URL.
    153   GURL url_;
    154 
    155   // Needs to be passed to ElideURL if the original URL string is wider than
    156   // the standard bubble width.
    157   string16 languages_;
    158 
    159   DISALLOW_COPY_AND_ASSIGN(StatusBubbleMac);
    160 };
    161 
    162 // Delegate interface
    163 @interface NSObject(StatusBubbleDelegate)
    164 // Called to query the delegate about the frame StatusBubble should position
    165 // itself in. Frame is returned in the parent window coordinates.
    166 - (NSRect)statusBubbleBaseFrame;
    167 
    168 // Called from SetState to notify the delegate of state changes.
    169 - (void)statusBubbleWillEnterState:(StatusBubbleMac::StatusBubbleState)state;
    170 @end
    171 
    172 #endif  // CHROME_BROWSER_UI_COCOA_STATUS_BUBBLE_MAC_H_
    173