Chromium Code Reviews| Index: chrome_frame/infobars/internal/infobar_window.cc |
| =================================================================== |
| --- chrome_frame/infobars/internal/infobar_window.cc (revision 0) |
| +++ chrome_frame/infobars/internal/infobar_window.cc (revision 0) |
| @@ -0,0 +1,182 @@ |
| +// Copyright (c) 2010 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. |
| +// |
| +// Implementation of the manager for infobar windows. |
| + |
| +#include "chrome_frame/infobars/internal/infobar_window.h" |
| + |
| +#include <algorithm> |
| + |
| +#include "base/compiler_specific.h" |
| +#include "base/logging.h" |
| +#include "chrome_frame/function_stub.h" |
| + |
| +namespace { |
| + |
| +// length of each step when opening or closing |
| +const UINT kInfobarSlidingTimerIntervalMs = 50U; |
| +// pixels per step, when opening or closing |
| +const int kInfobarSlideOpenStep = 2; |
| +const int kInfobarSlideCloseStep = 6; |
| + |
| +} // namespace |
| + |
| +void OnSliderTimer(InfobarWindow::Host* host) { |
| + host->UpdateLayout(); |
| +} |
| + |
| +InfobarWindow::InfobarWindow(InfobarType type) |
| + : type_(type), |
| + host_(NULL), |
| + target_height_(0), |
| + initial_height_(0), |
| + current_height_(0), |
| + current_width_(0), |
| + timer_id_(0), |
| + timer_stub_(NULL), |
| + frame_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| + DCHECK(type_ >= FIRST_INFOBAR_TYPE); |
| + DCHECK(type_ < END_OF_INFOBAR_TYPE); |
| +} |
| + |
| +InfobarWindow::~InfobarWindow() { |
| + StopTimer(); |
| + FunctionStub::Destroy(timer_stub_); |
|
tommi (sloooow) - chröme
2010/12/01 21:51:28
check for NULL?
|
| +} |
| + |
| +void InfobarWindow::SetHost(Host* host) { |
| + DCHECK(host_ == NULL); |
| + DCHECK(host != NULL); |
| + host_ = host; |
| + 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);
|
| + OnSliderTimer); |
| +} |
| + |
| +bool InfobarWindow::Show(InfobarContent *content) { |
|
grt (UTC plus 2)
2010/12/02 16:27:52
InfobarContent* content
|
| + DCHECK(host_ != NULL); |
|
grt (UTC plus 2)
2010/12/02 16:27:52
maybe instead do:
if (host_ == NULL) {
NOTREACHE
|
| + if (host_ == NULL) |
| + return false; |
| + |
| + scoped_ptr<InfobarContent> new_content(content); |
| + content_.reset(); |
| + |
| + if (!new_content->InstallInFrame(&frame_impl_)) |
| + return false; |
| + |
| + // Force a call to ReserveSpace, which will capture the width of the displaced |
| + // window. |
| + if (current_width_ == 0) |
| + host_->UpdateLayout(); |
| + if (current_width_ == 0) |
| + return false; // Might not be any displaced window.. then we can't display. |
| + |
| + content_.swap(new_content); |
| + StartSlidingTowards(content_->GetDesiredSize(current_width_, 0)); |
| + |
| + return true; |
| +} |
| + |
| +void InfobarWindow::Hide() { |
| + DCHECK(host_ != NULL); |
|
grt (UTC plus 2)
2010/12/02 16:27:52
similar proposal as above
|
| + if (host_ == NULL) |
| + return; |
| + |
| + StartSlidingTowards(0); |
| +} |
| + |
| +void InfobarWindow::ReserveSpace(RECT* rect) { |
| + DCHECK(rect); |
| + DCHECK(host_ != NULL); |
| + if (rect == NULL || host_ == NULL) |
| + return; |
| + |
| + current_width_ = rect->right - rect->left; |
| + current_height_ = CalculateHeight(); |
| + |
| + RECT infobar_rect = *rect; |
| + |
| + switch (type_) { |
| + case TOP_INFOBAR: |
| + rect->top = std::min(rect->bottom, |
| + 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
|
| + break; |
| + case BOTTOM_INFOBAR: |
| + rect->bottom = std::max( |
|
tommi (sloooow) - chröme
2010/12/01 21:51:28
same here
|
| + rect->top, infobar_rect.top = rect->bottom - current_height_); |
| + break; |
| + default: |
| + NOTREACHED() << "Unknown InfobarType value."; |
| + break; |
| + } |
| + |
| + if (content_ != NULL) |
| + content_->SetDimensions(infobar_rect); |
| + |
| + // Done sliding? |
| + if (current_height_ == target_height_) { |
| + StopTimer(); |
| + if (current_height_ == 0) |
| + content_.reset(); |
| + } |
| +} |
| + |
| +void InfobarWindow::StartSlidingTowards(int target_height) { |
| + initial_height_ = current_height_; |
| + target_height_ = target_height; |
| + |
| + if (StartTimer()) |
| + slide_start_ = base::Time::Now(); |
| + else |
| + slide_start_ = base::Time(); // NULL time means don't slide, resize now |
| + |
| + // Trigger an immediate re-laying out. The timer will handle remaining steps. |
| + host_->UpdateLayout(); |
| +} |
| + |
| +bool InfobarWindow::StartTimer() { |
| + timer_id_ = ::SetTimer(NULL, |
| + timer_id_, |
| + kInfobarSlidingTimerIntervalMs, |
| + reinterpret_cast<TIMERPROC>(timer_stub_->code())); |
| + |
| + if (timer_id_ == 0) |
| + DPLOG(ERROR) << "Failure in SetTimer."; |
|
grt (UTC plus 2)
2010/12/02 16:27:52
DPLOG_IF(ERROR, timer_id_ == 0) << ...;
|
| + |
| + return timer_id_ != 0; |
| +} |
| + |
| +void InfobarWindow::StopTimer() { |
| + ::KillTimer(NULL, timer_id_); |
| +} |
| + |
| +int InfobarWindow::CalculateHeight() { |
| + if (slide_start_.is_null()) |
| + return target_height_; |
| + |
| + base::TimeDelta elapsed = base::Time::Now() - slide_start_; |
| + int elapsed_steps = static_cast<int>(elapsed.InMilliseconds()) / |
| + kInfobarSlidingTimerIntervalMs; |
| + |
| + if (initial_height_ < target_height_) { |
| + return std::min(initial_height_ + elapsed_steps * kInfobarSlideOpenStep, |
| + target_height_); |
| + } else if (initial_height_ > target_height_) { |
| + return std::max(initial_height_ - elapsed_steps * kInfobarSlideCloseStep, |
| + target_height_); |
| + } else { |
| + return target_height_; |
| + } |
| +} |
| + |
| +InfobarWindow::FrameImpl::FrameImpl(InfobarWindow* infobar_window) |
| + : infobar_window_(infobar_window) { |
| +} |
| + |
| +HWND InfobarWindow::FrameImpl::GetFrameWindow() { |
| + return infobar_window_->host_->GetContainerWindow(); |
| +} |
| + |
| +void InfobarWindow::FrameImpl::CloseInfobar() { |
| + infobar_window_->Hide(); |
| +} |
| Property changes on: chrome_frame\infobars\internal\infobar_window.cc |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |