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

Unified 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 side-by-side diff with in-line comments
Download patch
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,183 @@
+// 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();
+ if (timer_stub_ != NULL)
+ FunctionStub::Destroy(timer_stub_);
+}
+
+void InfobarWindow::SetHost(Host* host) {
+ DCHECK(host_ == NULL);
+ DCHECK(timer_stub_ == NULL);
+ DCHECK(host != NULL);
+ host_ = host;
+ timer_stub_ = FunctionStub::Create(reinterpret_cast<uintptr_t>(host),
+ OnSliderTimer);
+}
+
+bool InfobarWindow::Show(InfobarContent* content) {
+ DCHECK(host_ != NULL);
+ 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);
+ 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:
+ infobar_rect.bottom = rect->top + current_height_;
+ rect->top = std::min(rect->bottom, infobar_rect.bottom);
+ break;
+ case BOTTOM_INFOBAR:
+ infobar_rect.top = rect->bottom - current_height_;
+ rect->bottom = std::max(rect->top, infobar_rect.top);
+ 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()));
+
+ DPLOG_IF(ERROR, timer_id_ == 0) << "Failure in SetTimer.";
+
+ 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
« 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