Index: chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc |
=================================================================== |
--- chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc (revision 0) |
+++ chrome/browser/ui/panels/auto_hide_bottom_bar_win.cc (revision 0) |
@@ -0,0 +1,190 @@ |
+// Copyright (c) 2011 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. |
+ |
+#include "chrome/browser/ui/panels/auto_hide_bottom_bar.h" |
+ |
+#include <windows.h> |
+#include <shellapi.h> |
+ |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
+#include "base/timer.h" |
+#include "ui/gfx/rect.h" |
+ |
+namespace { |
+ |
+// The thickness of an auto-hide taskbar in pixels. |
+const int kAutoHideTaskbarThicknessPx = 2; |
+ |
+// The polling interval to check auto-hide taskbar. |
+const int kCheckTaskbarPollingIntervalMs = 500; |
+ |
+class AutoHideBottomBarWin : public AutoHideBottomBar { |
+ public: |
+ explicit AutoHideBottomBarWin(Observer* observer); |
+ virtual ~AutoHideBottomBarWin(); |
+ |
+ virtual void UpdateWorkArea(const gfx::Rect& work_area) OVERRIDE; |
+ virtual bool Exists() OVERRIDE; |
+ virtual int GetHeight() OVERRIDE; |
+ virtual Visibility GetVisibility() OVERRIDE; |
+ |
+ private: |
+ void ValidateAndGetWindow(); |
+ HWND GetAutoHideWindowOnScreenEdge(UINT edge) const; |
+ gfx::Rect GetBounds(); |
+ int GetHeightFromBounds(const gfx::Rect& bounds) const; |
+ Visibility GetVisibilityFromBounds(const gfx::Rect& bounds) const; |
+ void CheckTaskbar(); |
+ |
+ Observer* observer_; |
+ gfx::Rect work_area_; |
+ HMONITOR monitor_; |
+ HWND window_; |
+ bool aligned_to_bottom_; |
+ Visibility visibility_; |
+ int height_; |
+ base::RepeatingTimer<AutoHideBottomBarWin> polling_timer_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AutoHideBottomBarWin); |
+}; |
+ |
+AutoHideBottomBarWin::AutoHideBottomBarWin(Observer* observer) |
+ : observer_(observer), |
+ window_(NULL), |
+ aligned_to_bottom_(false), |
+ visibility_(VISIBLE), |
+ height_(0) { |
+ DCHECK(observer); |
+} |
+ |
+AutoHideBottomBarWin::~AutoHideBottomBarWin() { |
+} |
+ |
+void AutoHideBottomBarWin::UpdateWorkArea(const gfx::Rect& work_area) { |
+ if (work_area_ == work_area) |
+ return; |
+ work_area_ = work_area; |
+ |
+ RECT rect = work_area_.ToRECT(); |
+ monitor_ = ::MonitorFromRect(&rect, MONITOR_DEFAULTTOPRIMARY); |
+ DCHECK(monitor_); |
+ |
+ ValidateAndGetWindow(); |
+ |
+ if (window_) { |
+ visibility_ = GetVisibility(); |
+ height_ = GetHeight(); |
+ |
+ if (!polling_timer_.IsRunning()) { |
+ polling_timer_.Start( |
+ base::TimeDelta::FromMilliseconds(kCheckTaskbarPollingIntervalMs), |
+ this, |
+ &AutoHideBottomBarWin::CheckTaskbar); |
+ } |
+ } else { |
+ if (polling_timer_.IsRunning()) |
+ polling_timer_.Stop(); |
+ } |
+} |
+ |
+bool AutoHideBottomBarWin::Exists() { |
+ ValidateAndGetWindow(); |
+ return window_ != NULL && aligned_to_bottom_; |
+} |
+ |
+int AutoHideBottomBarWin::GetHeight() { |
+ return GetHeightFromBounds(GetBounds()); |
+} |
+ |
+AutoHideBottomBar::Visibility AutoHideBottomBarWin::GetVisibility() { |
+ return GetVisibilityFromBounds(GetBounds()); |
+} |
+ |
+void AutoHideBottomBarWin::ValidateAndGetWindow() { |
+ // Make sure |window_| is still valid since Shell might be restarted. |
+ if (window_) { |
+ if (::IsWindow(window_)) { |
+ // Re-check the edge alignment. |
+ aligned_to_bottom_ = window_ == GetAutoHideWindowOnScreenEdge(ABE_BOTTOM); |
+ return; |
+ } |
+ |
+ window_ = NULL; |
+ } |
+ |
+ // Otherwise, find the auto-hide taskbar window that could appear in any edge |
+ // of the work area. Note that we have to check all edges because the user |
+ // might move the taskbar from non-bottom edge to bottom edge. |
+ UINT edges[] = { ABE_BOTTOM, ABE_RIGHT, ABE_LEFT, ABE_TOP }; |
+ for (size_t i = 0; i < arraysize(edges); ++i) { |
+ window_ = GetAutoHideWindowOnScreenEdge(edges[i]); |
+ if (window_) { |
+ aligned_to_bottom_ = edges[i] == ABE_BOTTOM; |
+ break; |
+ } |
+ } |
+} |
+ |
+HWND AutoHideBottomBarWin::GetAutoHideWindowOnScreenEdge(UINT edge) const { |
+ APPBARDATA taskbar_data = { 0 }; |
+ taskbar_data.cbSize = sizeof APPBARDATA; |
+ taskbar_data.uEdge = edge; |
+ HWND window = reinterpret_cast<HWND>(SHAppBarMessage(ABM_GETAUTOHIDEBAR, |
+ &taskbar_data)); |
+ return (::IsWindow(window) && |
+ (::MonitorFromWindow(window, MONITOR_DEFAULTTONULL) == monitor_) && |
+ (::GetWindowLong(window, GWL_EXSTYLE) & WS_EX_TOPMOST)) ? |
+ window : NULL; |
+} |
+ |
+gfx::Rect AutoHideBottomBarWin::GetBounds() { |
+ ValidateAndGetWindow(); |
+ if (!window_ || !aligned_to_bottom_) |
+ return gfx::Rect(); |
+ |
+ RECT rect; |
+ if (!::GetWindowRect(window_, &rect)) |
+ return gfx::Rect(); |
+ return gfx::Rect(rect); |
+} |
+ |
+int AutoHideBottomBarWin::GetHeightFromBounds(const gfx::Rect& bounds) const { |
+ return bounds.height(); |
+} |
+ |
+AutoHideBottomBar::Visibility AutoHideBottomBarWin::GetVisibilityFromBounds( |
+ const gfx::Rect& bounds) const { |
+ if (bounds.bottom() <= work_area_.bottom()) |
+ return VISIBLE; |
+ else if (bounds.y() >= work_area_.bottom() - kAutoHideTaskbarThicknessPx) |
+ return HIDDEN; |
+ else |
+ return ANIMATING; |
+} |
+ |
+void AutoHideBottomBarWin::CheckTaskbar() { |
+ gfx::Rect bounds = GetBounds(); |
+ |
+ // Check and notify the visibility change. |
+ Visibility visibility = GetVisibilityFromBounds(bounds); |
+ if (visibility != visibility_) { |
+ visibility_ = visibility; |
+ observer_->OnAutoHideBottomBarVisibilityChanged(visibility); |
+ } |
+ |
+ // Check and notify the height change. |
+ int height = GetHeightFromBounds(bounds); |
+ if (height != height_) { |
+ height_ = height; |
+ observer_->OnAutoHideBottomBarHeightChanged(height); |
+ } |
+} |
+ |
+} |
+ |
+// static |
+AutoHideBottomBar* AutoHideBottomBar::Create(Observer* observer) { |
+ return new AutoHideBottomBarWin(observer); |
+} |
Property changes on: chrome\browser\ui\panels\auto_hide_bottom_bar_win.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |