Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(333)

Side by Side Diff: chrome/browser/views/fullscreen_exit_bubble.cc

Issue 28012: Fullscreen mode UI.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/fullscreen_exit_bubble.h ('k') | chrome/browser/views/toolbar_view.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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 #include "chrome/browser/views/fullscreen_exit_bubble.h"
6
7 #include "chrome/app/chrome_dll_resource.h"
8 #include "chrome/common/l10n_util.h"
9 #include "chrome/common/resource_bundle.h"
10 #include "chrome/views/root_view.h"
11 #include "grit/generated_resources.h"
12
13
14 // FullscreenExitView ----------------------------------------------------------
15
16 class FullscreenExitBubble::FullscreenExitView : public views::View {
17 public:
18 FullscreenExitView(FullscreenExitBubble* bubble,
19 views::WidgetWin* popup,
20 const std::wstring& accelerator);
21 virtual ~FullscreenExitView();
22
23 // views::View
24 virtual gfx::Size GetPreferredSize();
25
26 private:
27 static const int kPaddingPixels; // Number of pixels around all sides of link
28
29 // views::View
30 virtual void Layout();
31 virtual void Paint(ChromeCanvas* canvas);
32
33 // Handle to the HWND that contains us.
34 views::WidgetWin* popup_;
35
36 // Clickable hint text to show in the bubble.
37 views::Link link_;
38 };
39
40 const int FullscreenExitBubble::FullscreenExitView::kPaddingPixels = 8;
41
42 FullscreenExitBubble::FullscreenExitView::FullscreenExitView(
43 FullscreenExitBubble* bubble,
44 views::WidgetWin* popup,
45 const std::wstring& accelerator)
46 : popup_(popup) {
47 AddChildView(&link_);
48 link_.SetParentOwned(false);
49 link_.SetText(l10n_util::GetStringF(IDS_EXIT_FULLSCREEN_MODE, accelerator));
50 link_.SetController(bubble);
51 link_.SetFont(ResourceBundle::GetSharedInstance().GetFont(
52 ResourceBundle::LargeFont));
53 link_.SetNormalColor(SK_ColorWHITE);
54 link_.SetHighlightedColor(SK_ColorWHITE);
55 }
56
57 FullscreenExitBubble::FullscreenExitView::~FullscreenExitView() {
58 }
59
60 gfx::Size FullscreenExitBubble::FullscreenExitView::GetPreferredSize() {
61 gfx::Size preferred_size(link_.GetPreferredSize());
62 preferred_size.Enlarge(kPaddingPixels * 2, kPaddingPixels * 2);
63 return preferred_size;
64 }
65
66 void FullscreenExitBubble::FullscreenExitView::Layout() {
67 gfx::Size link_preferred_size(link_.GetPreferredSize());
68 link_.SetBounds(kPaddingPixels,
69 height() - kPaddingPixels - link_preferred_size.height(),
70 link_preferred_size.width(), link_preferred_size.height());
71 }
72
73 void FullscreenExitBubble::FullscreenExitView::Paint(ChromeCanvas* canvas) {
74 // Create a round-bottomed rect to fill the whole View.
75 CRect parent_rect;
76 SkRect rect;
77 SkScalar padding = SkIntToScalar(kPaddingPixels);
78 // The "-padding" top coordinate ensures that the rect is always tall enough
79 // to contain the complete rounded corner radius. If we set this to 0, as the
80 // popup slides offscreen (in reality, squishes to 0 height), the corners will
81 // flatten out as the height becomes less than the corner radius.
82 rect.set(0, -padding, SkIntToScalar(width()), SkIntToScalar(height()));
83 SkScalar rad[8] = { 0, 0, 0, 0, padding, padding, padding, padding };
84 SkPath path;
85 path.addRoundRect(rect, rad, SkPath::kCW_Direction);
86
87 // Fill it black.
88 SkPaint paint;
89 paint.setStyle(SkPaint::kFill_Style);
90 paint.setFlags(SkPaint::kAntiAlias_Flag);
91 paint.setColor(SK_ColorBLACK);
92 canvas->drawPath(path, paint);
93 }
94
95
96 // FullscreenExitBubble --------------------------------------------------------
97
98 const double FullscreenExitBubble::kOpacity = 0.7;
99 const int FullscreenExitBubble::kInitialDelayMs = 2300;
100 const int FullscreenExitBubble::kPositionCheckHz = 10;
101 const int FullscreenExitBubble::kSlideInRegionHeightPx = 4;
102 const int FullscreenExitBubble::kSlideInDurationMs = 350;
103 const int FullscreenExitBubble::kSlideOutDurationMs = 700;
104
105 FullscreenExitBubble::FullscreenExitBubble(
106 views::Widget* frame,
107 CommandUpdater::CommandUpdaterDelegate* delegate)
108 : root_view_(frame->GetRootView()),
109 delegate_(delegate),
110 popup_(new views::WidgetWin()),
111 size_animation_(new SlideAnimation(this)) {
112 size_animation_->Reset(1);
113
114 // Create the contents view.
115 views::Accelerator accelerator(0, false, false, false);
116 bool got_accelerator = frame->GetAccelerator(IDC_FULLSCREEN, &accelerator);
117 DCHECK(got_accelerator);
118 view_ = new FullscreenExitView(this, popup_, accelerator.GetShortcutText());
119
120 // Initialize the popup.
121 popup_->set_delete_on_destroy(false);
122 popup_->set_window_style(WS_POPUP);
123 popup_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW |
124 l10n_util::GetExtendedTooltipStyles());
125 popup_->SetLayeredAlpha(static_cast<int>(0xff * kOpacity));
126 popup_->Init(frame->GetHWND(), GetPopupRect(false), false);
127 popup_->SetContentsView(view_);
128 popup_->Show();
129
130 // Start the initial delay timer.
131 initial_delay_.Start(base::TimeDelta::FromMilliseconds(kInitialDelayMs), this,
132 &FullscreenExitBubble::AfterInitialDelay);
133 }
134
135 FullscreenExitBubble::~FullscreenExitBubble() {
136 // This is tricky. We may be in an ATL message handler stack, in which case
137 // the popup cannot be deleted yet. We also can't blindly use
138 // set_delete_on_destroy(true) on the popup to delete it when it closes,
139 // because if the user closed the last tab while in fullscreen mode, Windows
140 // has already destroyed the popup HWND by the time we get here, and thus
141 // either the popup will already have been deleted (if we set this in our
142 // constructor) or the popup will never get another OnFinalMessage() call (if
143 // not, as currently). So instead, we tell the popup to synchronously hide,
144 // and then asynchronously close and delete itself.
145 popup_->Close();
146 MessageLoop::current()->DeleteSoon(FROM_HERE, popup_);
147 }
148
149 void FullscreenExitBubble::LinkActivated(views::Link* source, int event_flags) {
150 delegate_->ExecuteCommand(IDC_FULLSCREEN);
151 }
152
153 void FullscreenExitBubble::AnimationProgressed(
154 const Animation* animation) {
155 gfx::Rect popup_rect(GetPopupRect(false));
156 if (popup_rect.IsEmpty()) {
157 popup_->Hide();
158 } else {
159 popup_->MoveWindow(popup_rect.x(), popup_rect.y(), popup_rect.width(),
160 popup_rect.height());
161 popup_->Show();
162 }
163 }
164 void FullscreenExitBubble::AnimationEnded(
165 const Animation* animation) {
166 AnimationProgressed(animation);
167 }
168
169 void FullscreenExitBubble::AfterInitialDelay() {
170 // Check the mouse position immediately and every 50 ms afterwards.
171 CheckMousePosition();
172 mouse_position_checker_.Start(
173 base::TimeDelta::FromMilliseconds(1000 / kPositionCheckHz), this,
174 &FullscreenExitBubble::CheckMousePosition);
175 }
176
177 void FullscreenExitBubble::CheckMousePosition() {
178 // Desired behavior:
179 //
180 // +------------+-----------------------------+------------+
181 // | _ _ _ _ | Exit full screen mode (F11) | _ _ _ _ | Slide-in region
182 // | _ _ _ _ \_____________________________/ _ _ _ _ | Neutral region
183 // | | Slide-out region
184 // : :
185 //
186 // * If the mouse is in the slide-in region, we show the popup.
187 // * If the mouse is in the slide-out region, we hide the popup.
188 // * If the mouse is in the neutral region, we do nothing, except if the popup
189 // is currently sliding out, in which case we show it again. This
190 // facilitates users correcting us if they try to mouse horizontally towards
191 // the popup and unintentionally drop too low.
192
193 POINT cursor_pos;
194 GetCursorPos(&cursor_pos);
195 gfx::Point transformed_pos(cursor_pos);
196 views::View::ConvertPointToView(NULL, root_view_, &transformed_pos);
197 gfx::Rect trigger_rect(GetPopupRect(true));
198 if (!root_view_->HitTest(transformed_pos) ||
199 (cursor_pos.y >= trigger_rect.bottom())) {
200 size_animation_->SetSlideDuration(kSlideOutDurationMs);
201 size_animation_->Hide();
202 } else if ((cursor_pos.y < kSlideInRegionHeightPx) ||
203 (size_animation_->GetCurrentValue() != 0)) {
204 size_animation_->SetSlideDuration(kSlideInDurationMs);
205 size_animation_->Show();
206 }
207 }
208
209 gfx::Rect FullscreenExitBubble::GetPopupRect(
210 bool ignore_animation_state) const {
211 gfx::Size size(view_->GetPreferredSize());
212 if (!ignore_animation_state) {
213 size.set_height(static_cast<int>(static_cast<double>(size.height()) *
214 size_animation_->GetCurrentValue()));
215 }
216 gfx::Point origin((root_view_->width() - size.width()) / 2, 0);
217 views::View::ConvertPointToScreen(root_view_, &origin);
218 return gfx::Rect(origin, size);
219 }
OLDNEW
« no previous file with comments | « chrome/browser/views/fullscreen_exit_bubble.h ('k') | chrome/browser/views/toolbar_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698