Home | History | Annotate | Download | only in panels
      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/panels/x11_panel_resizer.h"
      6 
      7 #include "chrome/browser/ui/panels/panel.h"
      8 #include "chrome/browser/ui/panels/panel_manager.h"
      9 #include "ui/aura/window.h"
     10 #include "ui/aura/window_delegate.h"
     11 #include "ui/base/hit_test.h"
     12 #include "ui/events/event.h"
     13 #include "ui/events/event_utils.h"
     14 #include "ui/views/view.h"
     15 
     16 namespace {
     17 
     18 // Returns true if the window can be resized via |component|.
     19 bool IsWindowBorder(int component) {
     20   return component == HTBOTTOM ||
     21       component == HTBOTTOMLEFT ||
     22       component == HTBOTTOMRIGHT ||
     23       component == HTLEFT ||
     24       component == HTRIGHT ||
     25       component == HTTOP ||
     26       component == HTTOPLEFT ||
     27       component == HTTOPRIGHT;
     28 }
     29 
     30 }  // namespace
     31 
     32 X11PanelResizer::X11PanelResizer(Panel* panel, aura::Window* window)
     33     : panel_(panel),
     34       window_(window),
     35       resize_state_(NOT_RESIZING),
     36       resize_component_(HTNOWHERE) {
     37 }
     38 
     39 X11PanelResizer::~X11PanelResizer() {
     40   StopResizing(NULL, true);
     41 }
     42 
     43 void X11PanelResizer::OnMousePressed(ui::MouseEvent* event) {
     44   if (resize_state_ != NOT_RESIZING ||
     45       event->type() != ui::ET_MOUSE_PRESSED ||
     46       !event->IsLeftMouseButton() ||
     47       !event->native_event()) {
     48     return;
     49   }
     50 
     51   int component = window_->delegate()->GetNonClientComponent(event->location());
     52   if (!IsWindowBorder(component))
     53     return;
     54 
     55   // Set capture so that we get notified of all subsequent events.
     56   window_->SetCapture();
     57 
     58   resize_state_ = RESIZE_CAN_START;
     59   initial_press_location_in_screen_ = ui::EventSystemLocationFromNative(
     60       event->native_event());
     61   resize_component_ = component;
     62   event->StopPropagation();
     63 }
     64 
     65 void X11PanelResizer::OnMouseDragged(ui::MouseEvent* event) {
     66   if (resize_state_ != RESIZE_CAN_START &&
     67       resize_state_ != RESIZE_IN_PROGRESS) {
     68     return;
     69   }
     70 
     71   if (!event->native_event())
     72     return;
     73 
     74   // Get the location in screen coordinates from the XEvent because converting
     75   // the mouse location to screen coordinates using ScreenPositionClient returns
     76   // an incorrect location while the panel is moving. See crbug.com/353393 for
     77   // more details.
     78   // TODO: Fix conversion to screen coordinates.
     79   gfx::Point location_in_screen = ui::EventSystemLocationFromNative(
     80       event->native_event());
     81   if (resize_state_ == RESIZE_CAN_START) {
     82     gfx::Vector2d delta =
     83         location_in_screen - initial_press_location_in_screen_;
     84     if (views::View::ExceededDragThreshold(delta)) {
     85       resize_state_ = RESIZE_IN_PROGRESS;
     86       panel_->manager()->StartResizingByMouse(panel_, location_in_screen,
     87                                               resize_component_);
     88     }
     89   }
     90 
     91   if (resize_state_ == RESIZE_IN_PROGRESS)
     92     panel_->manager()->ResizeByMouse(location_in_screen);
     93 
     94   event->StopPropagation();
     95 }
     96 
     97 void X11PanelResizer::StopResizing(ui::MouseEvent* event, bool canceled) {
     98   if (resize_state_ == NOT_RESIZING)
     99     return;
    100 
    101   if (resize_state_ == RESIZE_IN_PROGRESS) {
    102     panel_->manager()->EndResizingByMouse(canceled);
    103     window_->ReleaseCapture();
    104   }
    105   if (event)
    106     event->StopPropagation();
    107   resize_state_ = NOT_RESIZING;
    108 }
    109 
    110 void X11PanelResizer::OnMouseEvent(ui::MouseEvent* event) {
    111   switch (event->type()) {
    112     case ui::ET_MOUSE_PRESSED:
    113       OnMousePressed(event);
    114       break;
    115     case ui::ET_MOUSE_DRAGGED:
    116       OnMouseDragged(event);
    117       break;
    118     case ui::ET_MOUSE_RELEASED:
    119       StopResizing(event, false);
    120       break;
    121     case ui::ET_MOUSE_CAPTURE_CHANGED:
    122       StopResizing(event, true);
    123       break;
    124     default:
    125       break;
    126   }
    127 }
    128