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

Side by Side Diff: chrome_frame/infobars/internal/infobar_window.cc

Issue 4766003: Preview CL for adding an Infobar facility to Google Chrome Frame.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 // Implementation of the manager for infobar windows.
6
7 #include "chrome_frame/infobars/internal/infobar_window.h"
8
9 #include <algorithm>
10
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "chrome_frame/function_stub.h"
14
15 namespace {
16
17 // length of each step when opening or closing
18 const UINT kInfobarSlidingTimerIntervalMs = 50U;
19 // pixels per step, when opening or closing
20 const int kInfobarSlideOpenStep = 2;
21 const int kInfobarSlideCloseStep = 6;
22
23 } // namespace
24
25 void OnSliderTimer(InfobarWindow::Host* host) {
26 host->UpdateLayout();
27 }
28
29 InfobarWindow::InfobarWindow(InfobarType type)
30 : type_(type),
31 host_(NULL),
32 target_height_(0),
33 initial_height_(0),
34 current_height_(0),
35 current_width_(0),
36 timer_id_(0),
37 timer_stub_(NULL),
38 frame_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
39 DCHECK(type_ >= FIRST_INFOBAR_TYPE);
40 DCHECK(type_ < END_OF_INFOBAR_TYPE);
41 }
42
43 InfobarWindow::~InfobarWindow() {
44 StopTimer();
45 FunctionStub::Destroy(timer_stub_);
tommi (sloooow) - chröme 2010/12/01 21:51:28 check for NULL?
46 }
47
48 void InfobarWindow::SetHost(Host* host) {
49 DCHECK(host_ == NULL);
50 DCHECK(host != NULL);
51 host_ = host;
52 timer_stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(host),
tommi (sloooow) - chröme 2010/12/01 21:51:28 maybe first DCHECK(timer_stub_ == NULL);
53 OnSliderTimer);
54 }
55
56 bool InfobarWindow::Show(InfobarContent *content) {
grt (UTC plus 2) 2010/12/02 16:27:52 InfobarContent* content
57 DCHECK(host_ != NULL);
grt (UTC plus 2) 2010/12/02 16:27:52 maybe instead do: if (host_ == NULL) { NOTREACHE
58 if (host_ == NULL)
59 return false;
60
61 scoped_ptr<InfobarContent> new_content(content);
62 content_.reset();
63
64 if (!new_content->InstallInFrame(&frame_impl_))
65 return false;
66
67 // Force a call to ReserveSpace, which will capture the width of the displaced
68 // window.
69 if (current_width_ == 0)
70 host_->UpdateLayout();
71 if (current_width_ == 0)
72 return false; // Might not be any displaced window.. then we can't display.
73
74 content_.swap(new_content);
75 StartSlidingTowards(content_->GetDesiredSize(current_width_, 0));
76
77 return true;
78 }
79
80 void InfobarWindow::Hide() {
81 DCHECK(host_ != NULL);
grt (UTC plus 2) 2010/12/02 16:27:52 similar proposal as above
82 if (host_ == NULL)
83 return;
84
85 StartSlidingTowards(0);
86 }
87
88 void InfobarWindow::ReserveSpace(RECT* rect) {
89 DCHECK(rect);
90 DCHECK(host_ != NULL);
91 if (rect == NULL || host_ == NULL)
92 return;
93
94 current_width_ = rect->right - rect->left;
95 current_height_ = CalculateHeight();
96
97 RECT infobar_rect = *rect;
98
99 switch (type_) {
100 case TOP_INFOBAR:
101 rect->top = std::min(rect->bottom,
102 infobar_rect.bottom = rect->top + current_height_);
tommi (sloooow) - chröme 2010/12/01 21:51:28 this is a bit confusing because the assignment to
103 break;
104 case BOTTOM_INFOBAR:
105 rect->bottom = std::max(
tommi (sloooow) - chröme 2010/12/01 21:51:28 same here
106 rect->top, infobar_rect.top = rect->bottom - current_height_);
107 break;
108 default:
109 NOTREACHED() << "Unknown InfobarType value.";
110 break;
111 }
112
113 if (content_ != NULL)
114 content_->SetDimensions(infobar_rect);
115
116 // Done sliding?
117 if (current_height_ == target_height_) {
118 StopTimer();
119 if (current_height_ == 0)
120 content_.reset();
121 }
122 }
123
124 void InfobarWindow::StartSlidingTowards(int target_height) {
125 initial_height_ = current_height_;
126 target_height_ = target_height;
127
128 if (StartTimer())
129 slide_start_ = base::Time::Now();
130 else
131 slide_start_ = base::Time(); // NULL time means don't slide, resize now
132
133 // Trigger an immediate re-laying out. The timer will handle remaining steps.
134 host_->UpdateLayout();
135 }
136
137 bool InfobarWindow::StartTimer() {
138 timer_id_ = ::SetTimer(NULL,
139 timer_id_,
140 kInfobarSlidingTimerIntervalMs,
141 reinterpret_cast<TIMERPROC>(timer_stub_->code()));
142
143 if (timer_id_ == 0)
144 DPLOG(ERROR) << "Failure in SetTimer.";
grt (UTC plus 2) 2010/12/02 16:27:52 DPLOG_IF(ERROR, timer_id_ == 0) << ...;
145
146 return timer_id_ != 0;
147 }
148
149 void InfobarWindow::StopTimer() {
150 ::KillTimer(NULL, timer_id_);
151 }
152
153 int InfobarWindow::CalculateHeight() {
154 if (slide_start_.is_null())
155 return target_height_;
156
157 base::TimeDelta elapsed = base::Time::Now() - slide_start_;
158 int elapsed_steps = static_cast<int>(elapsed.InMilliseconds()) /
159 kInfobarSlidingTimerIntervalMs;
160
161 if (initial_height_ < target_height_) {
162 return std::min(initial_height_ + elapsed_steps * kInfobarSlideOpenStep,
163 target_height_);
164 } else if (initial_height_ > target_height_) {
165 return std::max(initial_height_ - elapsed_steps * kInfobarSlideCloseStep,
166 target_height_);
167 } else {
168 return target_height_;
169 }
170 }
171
172 InfobarWindow::FrameImpl::FrameImpl(InfobarWindow* infobar_window)
173 : infobar_window_(infobar_window) {
174 }
175
176 HWND InfobarWindow::FrameImpl::GetFrameWindow() {
177 return infobar_window_->host_->GetContainerWindow();
178 }
179
180 void InfobarWindow::FrameImpl::CloseInfobar() {
181 infobar_window_->Hide();
182 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698