Home | History | Annotate | Download | only in apps
      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 
     13 namespace {
     14 
     15 const int kResizeAreaCornerSize = 16;
     16 
     17 }  // namespace
     18 
     19 const char GlassAppWindowFrameViewWin::kViewClassName[] =
     20     "ui/views/apps/GlassAppWindowFrameViewWin";
     21 
     22 GlassAppWindowFrameViewWin::GlassAppWindowFrameViewWin(
     23     extensions::NativeAppWindow* window,
     24     views::Widget* widget)
     25     : window_(window), widget_(widget) {
     26 }
     27 
     28 GlassAppWindowFrameViewWin::~GlassAppWindowFrameViewWin() {
     29 }
     30 
     31 gfx::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 
     45 gfx::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 
     56 gfx::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 
     69 int 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 
    102 void GlassAppWindowFrameViewWin::GetWindowMask(const gfx::Size& size,
    103                                                gfx::Path* window_mask) {
    104   // We got nothing to say about no window mask.
    105 }
    106 
    107 gfx::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 
    115 const char* GlassAppWindowFrameViewWin::GetClassName() const {
    116   return kViewClassName;
    117 }
    118 
    119 gfx::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 
    128 gfx::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