1// Copyright 2014 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#include "chrome/browser/ui/views/apps/glass_app_window_frame_view_win.h" 6 7#include "extensions/browser/app_window/native_app_window.h" 8#include "ui/base/hit_test.h" 9#include "ui/gfx/win/dpi.h" 10#include "ui/views/widget/widget.h" 11#include "ui/views/widget/widget_delegate.h" 12 13namespace { 14 15const int kResizeAreaCornerSize = 16; 16 17} // namespace 18 19const char GlassAppWindowFrameViewWin::kViewClassName[] = 20 "ui/views/apps/GlassAppWindowFrameViewWin"; 21 22GlassAppWindowFrameViewWin::GlassAppWindowFrameViewWin( 23 extensions::NativeAppWindow* window, 24 views::Widget* widget) 25 : window_(window), widget_(widget) { 26} 27 28GlassAppWindowFrameViewWin::~GlassAppWindowFrameViewWin() { 29} 30 31gfx::Insets GlassAppWindowFrameViewWin::GetGlassInsets() const { 32 // If 1 is not subtracted, they are too big. There is possibly some reason 33 // for that. 34 // Also make sure the insets don't go below 1, as bad things happen when they 35 // do. 36 int caption_height = std::max(0, 37 gfx::win::GetSystemMetricsInDIP(SM_CYSMICON) + 38 gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME) - 1); 39 int frame_size = 40 std::max(1, gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME) - 1); 41 return gfx::Insets( 42 frame_size + caption_height, frame_size, frame_size, frame_size); 43} 44 45gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const { 46 if (widget_->IsFullscreen()) 47 return bounds(); 48 49 gfx::Insets insets = GetGlassInsets(); 50 return gfx::Rect(insets.left(), 51 insets.top(), 52 std::max(0, width() - insets.left() - insets.right()), 53 std::max(0, height() - insets.top() - insets.bottom())); 54} 55 56gfx::Rect GlassAppWindowFrameViewWin::GetWindowBoundsForClientBounds( 57 const gfx::Rect& client_bounds) const { 58 gfx::Insets insets = GetGlassInsets(); 59 // Our bounds are not the same as the window's due to the offset added by 60 // AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets. So account for it 61 // here. 62 insets += gfx::Insets(0, 0, 1, 1); 63 return gfx::Rect(client_bounds.x() - insets.left(), 64 client_bounds.y() - insets.top(), 65 client_bounds.width() + insets.left() + insets.right(), 66 client_bounds.height() + insets.top() + insets.bottom()); 67} 68 69int GlassAppWindowFrameViewWin::NonClientHitTest(const gfx::Point& point) { 70 if (widget_->IsFullscreen()) 71 return HTCLIENT; 72 73 if (!bounds().Contains(point)) 74 return HTNOWHERE; 75 76 // Check the frame first, as we allow a small area overlapping the contents 77 // to be used for resize handles. 78 bool can_ever_resize = widget_->widget_delegate() 79 ? widget_->widget_delegate()->CanResize() 80 : false; 81 // Don't allow overlapping resize handles when the window is maximized or 82 // fullscreen, as it can't be resized in those states. 83 int resize_border = gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME); 84 int frame_component = 85 GetHTComponentForFrame(point, 86 resize_border, 87 resize_border, 88 kResizeAreaCornerSize - resize_border, 89 kResizeAreaCornerSize - resize_border, 90 can_ever_resize); 91 if (frame_component != HTNOWHERE) 92 return frame_component; 93 94 int client_component = widget_->client_view()->NonClientHitTest(point); 95 if (client_component != HTNOWHERE) 96 return client_component; 97 98 // Caption is a safe default. 99 return HTCAPTION; 100} 101 102void GlassAppWindowFrameViewWin::GetWindowMask(const gfx::Size& size, 103 gfx::Path* window_mask) { 104 // We got nothing to say about no window mask. 105} 106 107gfx::Size GlassAppWindowFrameViewWin::GetPreferredSize() const { 108 gfx::Size pref = widget_->client_view()->GetPreferredSize(); 109 gfx::Rect bounds(0, 0, pref.width(), pref.height()); 110 return widget_->non_client_view() 111 ->GetWindowBoundsForClientBounds(bounds) 112 .size(); 113} 114 115const char* GlassAppWindowFrameViewWin::GetClassName() const { 116 return kViewClassName; 117} 118 119gfx::Size GlassAppWindowFrameViewWin::GetMinimumSize() const { 120 gfx::Size min_size = widget_->client_view()->GetMinimumSize(); 121 122 gfx::Rect client_bounds = GetBoundsForClientView(); 123 min_size.Enlarge(width() - client_bounds.width(), 124 height() - client_bounds.height()); 125 return min_size; 126} 127 128gfx::Size GlassAppWindowFrameViewWin::GetMaximumSize() const { 129 gfx::Size max_size = widget_->client_view()->GetMaximumSize(); 130 131 // Add to the client maximum size the height of any title bar and borders. 132 gfx::Size client_size = GetBoundsForClientView().size(); 133 if (max_size.width()) 134 max_size.Enlarge(width() - client_size.width(), 0); 135 if (max_size.height()) 136 max_size.Enlarge(0, height() - client_size.height()); 137 138 return max_size; 139} 140