glass_app_window_frame_view_win.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/views/apps/glass_app_window_frame_view_win.h" 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "apps/ui/native_app_window.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/hit_test.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/win/dpi.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/widget/widget.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/widget/widget_delegate.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace { 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)const int kResizeAreaCornerSize = 16; 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char GlassAppWindowFrameViewWin::kViewClassName[] = 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "ui/views/apps/GlassAppWindowFrameViewWin"; 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)GlassAppWindowFrameViewWin::GlassAppWindowFrameViewWin( 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) apps::NativeAppWindow* window, 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) views::Widget* widget) 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : window_(window), widget_(widget) { 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)GlassAppWindowFrameViewWin::~GlassAppWindowFrameViewWin() { 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Insets GlassAppWindowFrameViewWin::GetGlassInsets() const { 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If 1 is not subtracted, they are too big. There is possibly some reason 338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // for that. 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Also make sure the insets don't go below 1, as bad things happen when they 358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // do. 368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int caption_height = std::max(0, 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::win::GetSystemMetricsInDIP(SM_CYSMICON) + 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::win::GetSystemMetricsInDIP(SM_CYSIZEFRAME) - 1); 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int frame_size = 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::max(1, gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME) - 1); 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gfx::Insets( 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_size + caption_height, frame_size, frame_size, frame_size); 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Rect GlassAppWindowFrameViewWin::GetBoundsForClientView() const { 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (widget_->IsFullscreen()) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return bounds(); 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::Insets insets = GetGlassInsets(); 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return gfx::Rect(insets.left(), 518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) insets.top(), 528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::max(0, width() - insets.left() - insets.right()), 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::max(0, height() - insets.top() - insets.bottom())); 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Rect GlassAppWindowFrameViewWin::GetWindowBoundsForClientBounds( 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const gfx::Rect& client_bounds) const { 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Insets insets = GetGlassInsets(); 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Our bounds are not the same as the window's due to the offset added by 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // AppWindowDesktopWindowTreeHostWin::GetClientAreaInsets. So account for it 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // here. 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) insets += gfx::Insets(0, 0, 1, 1); 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return gfx::Rect(client_bounds.x() - insets.left(), 648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) client_bounds.y() - insets.top(), 658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) client_bounds.width() + insets.left() + insets.right(), 668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) client_bounds.height() + insets.top() + insets.bottom()); 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int GlassAppWindowFrameViewWin::NonClientHitTest(const gfx::Point& point) { 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (widget_->IsFullscreen()) 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return HTCLIENT; 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!bounds().Contains(point)) 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return HTNOWHERE; 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Check the frame first, as we allow a small area overlapping the contents 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // to be used for resize handles. 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) bool can_ever_resize = widget_->widget_delegate() 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ? widget_->widget_delegate()->CanResize() 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : false; 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Don't allow overlapping resize handles when the window is maximized or 828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // fullscreen, as it can't be resized in those states. 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int resize_border = gfx::win::GetSystemMetricsInDIP(SM_CXSIZEFRAME); 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int frame_component = 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetHTComponentForFrame(point, 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) resize_border, 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) resize_border, 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kResizeAreaCornerSize - resize_border, 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) kResizeAreaCornerSize - resize_border, 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) can_ever_resize); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (frame_component != HTNOWHERE) 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return frame_component; 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int client_component = widget_->client_view()->NonClientHitTest(point); 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (client_component != HTNOWHERE) 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return client_component; 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Caption is a safe default. 99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return HTCAPTION; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void GlassAppWindowFrameViewWin::GetWindowMask(const gfx::Size& size, 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Path* window_mask) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We got nothing to say about no window mask. 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Size GlassAppWindowFrameViewWin::GetPreferredSize() const { 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Size pref = widget_->client_view()->GetPreferredSize(); 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Rect bounds(0, 0, pref.width(), pref.height()); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return widget_->non_client_view() 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ->GetWindowBoundsForClientBounds(bounds) 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) .size(); 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char* GlassAppWindowFrameViewWin::GetClassName() const { 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return kViewClassName; 117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)gfx::Size GlassAppWindowFrameViewWin::GetMinimumSize() const { 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) gfx::Size min_size = widget_->client_view()->GetMinimumSize(); 1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Rect client_bounds = GetBoundsForClientView(); 1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) min_size.Enlarge(width() - client_bounds.width(), 1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) height() - client_bounds.height()); 1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return min_size; 1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)gfx::Size GlassAppWindowFrameViewWin::GetMaximumSize() const { 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Size max_size = widget_->client_view()->GetMaximumSize(); 1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Add to the client maximum size the height of any title bar and borders. 1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gfx::Size client_size = GetBoundsForClientView().size(); 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (max_size.width()) 1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) max_size.Enlarge(width() - client_size.width(), 0); 1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (max_size.height()) 1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) max_size.Enlarge(0, height() - client_size.height()); 1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return max_size; 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)