summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/status_bubble_mac.h
blob: e43b81fd5c43cb87a9e24acc3a58e6a9c2d0037a (plain)
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
// Copyright (c) 2009 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_COCOA_STATUS_BUBBLE_MAC_H_
#define CHROME_BROWSER_COCOA_STATUS_BUBBLE_MAC_H_

#include <string>

#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>

#include "base/task.h"
#include "chrome/browser/status_bubble.h"

class GURL;
class StatusBubbleMacTest;

class StatusBubbleMac : public StatusBubble {
 public:
  // The various states that a status bubble may be in.  Public for delegate
  // access (for testing).
  enum StatusBubbleState {
    kBubbleHidden,         // Fully hidden
    kBubbleShowingTimer,   // Waiting to fade in
    kBubbleShowingFadeIn,  // In a fade-in transition
    kBubbleShown,          // Fully visible
    kBubbleHidingTimer,    // Waiting to fade out
    kBubbleHidingFadeOut   // In a fade-out transition
  };

  StatusBubbleMac(NSWindow* parent, id delegate);
  virtual ~StatusBubbleMac();

  // StatusBubble implementation.
  virtual void SetStatus(const std::wstring& status);
  virtual void SetURL(const GURL& url, const std::wstring& languages);
  virtual void Hide();
  virtual void MouseMoved(const gfx::Point& location, bool left_content);
  virtual void UpdateDownloadShelfVisibility(bool visible);

  // Mac-specific method: Update the size and position of the status bubble to
  // match the parent window. Safe to call even when the status bubble does not
  // exist.
  void UpdateSizeAndPosition();

  // Delegate method called when a fade-in or fade-out transition has
  // completed.  This is public so that it may be visible to the CAAnimation
  // delegate, which is an Objective-C object.
  void AnimationDidStop(CAAnimation* animation, bool finished);

 private:
  friend class StatusBubbleMacTest;

  // Setter for state_.  Use this instead of writing to state_ directly so
  // that state changes can be observed by unit tests.
  void SetState(StatusBubbleState state);

  // Sets the bubble text for SetStatus and SetURL.
  void SetText(const std::wstring& text, bool is_url);

  // Construct the window/widget if it does not already exist. (Safe to call if
  // it does.)
  void Create();

  // Attaches the status bubble window to its parent window. Safe to call even
  // when already attached.
  void Attach();

  // Detaches the status bubble window from its parent window.
  void Detach();

  // Is the status bubble attached to the browser window? It should be attached
  // when shown and during any fades, but should be detached when hidden.
  bool is_attached() { return [window_ parentWindow] != nil; }

  // Begins fading the status bubble window in or out depending on the value
  // of |show|.  This must be called from the appropriate fade state,
  // kBubbleShowingFadeIn or kBubbleHidingFadeOut, or from the appropriate
  // fully-shown/hidden state, kBubbleShown or kBubbleHidden.  This may be
  // called at any point during a fade-in or fade-out; it is even possible to
  // reverse a transition before it has completed.
  void Fade(bool show);

  // One-shot timer operations to manage the delays associated with the
  // kBubbleShowingTimer and kBubbleHidingTimer states.  StartTimer and
  // TimerFired must be called from one of these states.  StartTimer may be
  // called while the timer is still running; in that case, the timer will be
  // reset. CancelTimer may be called from any state.
  void StartTimer(int64 time_ms);
  void CancelTimer();
  void TimerFired();

  // Begin the process of showing or hiding the status bubble.  These may be
  // called from any state, and will take the appropriate action to initiate
  // any state changes that may be needed.
  void StartShowing();
  void StartHiding();

  // The timer factory used for show and hide delay timers.
  ScopedRunnableMethodFactory<StatusBubbleMac> timer_factory_;

  // Calculate the appropriate frame for the status bubble window.
  NSRect CalculateWindowFrame();

  // The window we attach ourselves to.
  NSWindow* parent_;  // WEAK

  // The object that we query about our vertical offset for positioning.
  id delegate_;  // WEAK

  // The window we own.
  NSWindow* window_;

  // The status text we want to display when there are no URLs to display.
  NSString* status_text_;

  // The url we want to display when there is no status text to display.
  NSString* url_text_;

  // The status bubble's current state.  Do not write to this field directly;
  // use SetState().
  StatusBubbleState state_;

  // True if operations are to be performed immediately rather than waiting
  // for delays and transitions.  Normally false, this should only be set to
  // true for testing.
  bool immediate_;

  DISALLOW_COPY_AND_ASSIGN(StatusBubbleMac);
};

// Delegate interface
@interface NSObject(StatusBubbleDelegate)
// Called to query the delegate about the vertical offset (if any) that should
// be applied to the StatusBubble's position.
- (float)verticalOffsetForStatusBubble;

// Called from SetState to notify the delegate of state changes.
- (void)statusBubbleWillEnterState:(StatusBubbleMac::StatusBubbleState)state;
@end

#endif  // #ifndef CHROME_BROWSER_COCOA_STATUS_BUBBLE_MAC_H_