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