- add sources.
[platform/framework/web/crosswalk.git] / src / ash / wm / frame_border_hit_test_controller.cc
1 // Copyright 2013 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 "ash/wm/frame_border_hit_test_controller.h"
6
7 #include "ash/ash_constants.h"
8 #include "ash/wm/header_painter.h"
9 #include "ash/wm/window_state.h"
10 #include "ui/aura/env.h"
11 #include "ui/aura/window.h"
12 #include "ui/base/hit_test.h"
13 #include "ui/views/widget/widget.h"
14 #include "ui/views/widget/widget_delegate.h"
15 #include "ui/views/window/non_client_view.h"
16
17 namespace ash {
18
19 FrameBorderHitTestController::FrameBorderHitTestController(views::Widget* frame)
20     : frame_window_(frame->GetNativeWindow()) {
21   gfx::Insets mouse_outer_insets(-kResizeOutsideBoundsSize,
22                                  -kResizeOutsideBoundsSize,
23                                  -kResizeOutsideBoundsSize,
24                                  -kResizeOutsideBoundsSize);
25   gfx::Insets touch_outer_insets = mouse_outer_insets.Scale(
26       kResizeOutsideBoundsScaleForTouch);
27   // Ensure we get resize cursors for a few pixels outside our bounds.
28   frame_window_->SetHitTestBoundsOverrideOuter(mouse_outer_insets,
29                                                touch_outer_insets);
30   // Ensure we get resize cursors just inside our bounds as well.
31   UpdateHitTestBoundsOverrideInner();
32
33   frame_window_->AddObserver(this);
34   ash::wm::GetWindowState(frame_window_)->AddObserver(this);
35 }
36
37 FrameBorderHitTestController::~FrameBorderHitTestController() {
38   if (frame_window_) {
39     frame_window_->RemoveObserver(this);
40     ash::wm::GetWindowState(frame_window_)->RemoveObserver(this);
41   }
42 }
43
44 // static
45 int FrameBorderHitTestController::NonClientHitTest(
46     views::NonClientFrameView* view,
47     HeaderPainter* header_painter,
48     const gfx::Point& point) {
49   gfx::Rect expanded_bounds = view->bounds();
50   int outside_bounds = kResizeOutsideBoundsSize;
51
52   if (aura::Env::GetInstance()->is_touch_down())
53     outside_bounds *= kResizeOutsideBoundsScaleForTouch;
54   expanded_bounds.Inset(-outside_bounds, -outside_bounds);
55
56   if (!expanded_bounds.Contains(point))
57     return HTNOWHERE;
58
59   // Check the frame first, as we allow a small area overlapping the contents
60   // to be used for resize handles.
61   views::Widget* frame = view->GetWidget();
62   bool can_ever_resize = frame->widget_delegate()->CanResize();
63   // Don't allow overlapping resize handles when the window is maximized or
64   // fullscreen, as it can't be resized in those states.
65   int resize_border =
66       frame->IsMaximized() || frame->IsFullscreen() ? 0 :
67       kResizeInsideBoundsSize;
68   int frame_component = view->GetHTComponentForFrame(point,
69                                                      resize_border,
70                                                      resize_border,
71                                                      kResizeAreaCornerSize,
72                                                      kResizeAreaCornerSize,
73                                                      can_ever_resize);
74   if (frame_component != HTNOWHERE)
75     return frame_component;
76
77   int client_component = frame->client_view()->NonClientHitTest(point);
78   if (client_component != HTNOWHERE)
79     return client_component;
80
81   return header_painter->NonClientHitTest(point);
82 }
83
84 void FrameBorderHitTestController::UpdateHitTestBoundsOverrideInner() {
85   // Maximized and fullscreen windows don't want resize handles overlapping the
86   // content area, because when the user moves the cursor to the right screen
87   // edge we want them to be able to hit the scroll bar.
88   if (wm::GetWindowState(frame_window_)->IsMaximizedOrFullscreen()) {
89     frame_window_->set_hit_test_bounds_override_inner(gfx::Insets());
90   } else {
91     frame_window_->set_hit_test_bounds_override_inner(
92         gfx::Insets(kResizeInsideBoundsSize, kResizeInsideBoundsSize,
93                     kResizeInsideBoundsSize, kResizeInsideBoundsSize));
94   }
95 }
96
97 void FrameBorderHitTestController::OnWindowShowTypeChanged(
98     wm::WindowState* window_state,
99     wm::WindowShowType old_type) {
100   UpdateHitTestBoundsOverrideInner();
101 }
102
103 void FrameBorderHitTestController::OnWindowDestroying(aura::Window* window) {
104   frame_window_->RemoveObserver(this);
105   ash::wm::GetWindowState(frame_window_)->RemoveObserver(this);
106   frame_window_ = NULL;
107 }
108
109 }  // namespace ash