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

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 if (timer_stub_ != NULL)
46 FunctionStub::Destroy(timer_stub_);
47 }
48
49 void InfobarWindow::SetHost(Host* host) {
50 DCHECK(host_ == NULL);
51 DCHECK(timer_stub_ == NULL);
52 DCHECK(host != NULL);
53 host_ = host;
54 timer_stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(host),
55 OnSliderTimer);
56 }
57
58 bool InfobarWindow::Show(InfobarContent* content) {
59 DCHECK(host_ != NULL);
60 if (host_ == NULL)
61 return false;
62
63 scoped_ptr<InfobarContent> new_content(content);
64 content_.reset();
65
66 if (!new_content->InstallInFrame(&frame_impl_))
67 return false;
68
69 // Force a call to ReserveSpace, which will capture the width of the displaced
70 // window.
71 if (current_width_ == 0)
72 host_->UpdateLayout();
73 if (current_width_ == 0)
74 return false; // Might not be any displaced window.. then we can't display.
75
76 content_.swap(new_content);
77 StartSlidingTowards(content_->GetDesiredSize(current_width_, 0));
78
79 return true;
80 }
81
82 void InfobarWindow::Hide() {
83 DCHECK(host_ != NULL);
84 if (host_ == NULL)
85 return;
86
87 StartSlidingTowards(0);
88 }
89
90 void InfobarWindow::ReserveSpace(RECT* rect) {
91 DCHECK(rect);
92 DCHECK(host_ != NULL);
93 if (rect == NULL || host_ == NULL)
94 return;
95
96 current_width_ = rect->right - rect->left;
97 current_height_ = CalculateHeight();
98
99 RECT infobar_rect = *rect;
100
101 switch (type_) {
102 case TOP_INFOBAR:
103 infobar_rect.bottom = rect->top + current_height_;
104 rect->top = std::min(rect->bottom, infobar_rect.bottom);
105 break;
106 case BOTTOM_INFOBAR:
107 infobar_rect.top = rect->bottom - current_height_;
108 rect->bottom = std::max(rect->top, infobar_rect.top);
109 break;
110 default:
111 NOTREACHED() << "Unknown InfobarType value.";
112 break;
113 }
114
115 if (content_ != NULL)
116 content_->SetDimensions(infobar_rect);
117
118 // Done sliding?
119 if (current_height_ == target_height_) {
120 StopTimer();
121 if (current_height_ == 0)
122 content_.reset();
123 }
124 }
125
126 void InfobarWindow::StartSlidingTowards(int target_height) {
127 initial_height_ = current_height_;
128 target_height_ = target_height;
129
130 if (StartTimer())
131 slide_start_ = base::Time::Now();
132 else
133 slide_start_ = base::Time(); // NULL time means don't slide, resize now
134
135 // Trigger an immediate re-laying out. The timer will handle remaining steps.
136 host_->UpdateLayout();
137 }
138
139 bool InfobarWindow::StartTimer() {
140 timer_id_ = ::SetTimer(NULL,
141 timer_id_,
142 kInfobarSlidingTimerIntervalMs,
143 reinterpret_cast<TIMERPROC>(timer_stub_->code()));
144
145 DPLOG_IF(ERROR, timer_id_ == 0) << "Failure in SetTimer.";
146
147 return timer_id_ != 0;
148 }
149
150 void InfobarWindow::StopTimer() {
151 ::KillTimer(NULL, timer_id_);
152 }
153
154 int InfobarWindow::CalculateHeight() {
155 if (slide_start_.is_null())
156 return target_height_;
157
158 base::TimeDelta elapsed = base::Time::Now() - slide_start_;
159 int elapsed_steps = static_cast<int>(elapsed.InMilliseconds()) /
160 kInfobarSlidingTimerIntervalMs;
161
162 if (initial_height_ < target_height_) {
163 return std::min(initial_height_ + elapsed_steps * kInfobarSlideOpenStep,
164 target_height_);
165 } else if (initial_height_ > target_height_) {
166 return std::max(initial_height_ - elapsed_steps * kInfobarSlideCloseStep,
167 target_height_);
168 } else {
169 return target_height_;
170 }
171 }
172
173 InfobarWindow::FrameImpl::FrameImpl(InfobarWindow* infobar_window)
174 : infobar_window_(infobar_window) {
175 }
176
177 HWND InfobarWindow::FrameImpl::GetFrameWindow() {
178 return infobar_window_->host_->GetContainerWindow();
179 }
180
181 void InfobarWindow::FrameImpl::CloseInfobar() {
182 infobar_window_->Hide();
183 }
OLDNEW
« no previous file with comments | « chrome_frame/infobars/internal/infobar_window.h ('k') | chrome_frame/infobars/internal/subclassing_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698