panel_resize_controller.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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/panels/panel_resize_controller.h" 6 7#include "base/logging.h" 8#include "chrome/browser/ui/panels/panel.h" 9#include "chrome/browser/ui/panels/panel_manager.h" 10 11namespace { 12 static bool ResizingLeft(panel::ResizingSides sides) { 13 return sides == panel::RESIZE_TOP_LEFT || 14 sides == panel::RESIZE_LEFT || 15 sides == panel::RESIZE_BOTTOM_LEFT; 16 } 17 18 static bool ResizingRight(panel::ResizingSides sides) { 19 return sides == panel::RESIZE_TOP_RIGHT || 20 sides == panel::RESIZE_RIGHT || 21 sides == panel::RESIZE_BOTTOM_RIGHT; 22 } 23 24 static bool ResizingTop(panel::ResizingSides sides) { 25 return sides == panel::RESIZE_TOP_LEFT || 26 sides == panel::RESIZE_TOP || 27 sides == panel::RESIZE_TOP_RIGHT; 28 } 29 30 static bool ResizingBottom(panel::ResizingSides sides) { 31 return sides == panel::RESIZE_BOTTOM_RIGHT || 32 sides == panel::RESIZE_BOTTOM || 33 sides == panel::RESIZE_BOTTOM_LEFT; 34 } 35} 36 37PanelResizeController::PanelResizeController(PanelManager* panel_manager) 38 : panel_manager_(panel_manager), 39 resizing_panel_(NULL), 40 sides_resized_(panel::RESIZE_NONE) { 41} 42 43void PanelResizeController::StartResizing(Panel* panel, 44 const gfx::Point& mouse_location, 45 panel::ResizingSides sides) { 46 DCHECK(!IsResizing()); 47 DCHECK_NE(panel::RESIZE_NONE, sides); 48 49 panel::Resizability resizability = panel->CanResizeByMouse(); 50 DCHECK_NE(panel::NOT_RESIZABLE, resizability); 51 if (panel::RESIZABLE_ALL_SIDES_EXCEPT_BOTTOM == resizability && 52 ResizingBottom(sides)) { 53 DLOG(WARNING) << "Resizing from bottom not allowed. Is this a test?"; 54 return; 55 } 56 57 mouse_location_at_start_ = mouse_location; 58 bounds_at_start_ = panel->GetBounds(); 59 sides_resized_ = sides; 60 resizing_panel_ = panel; 61 resizing_panel_->OnPanelStartUserResizing(); 62} 63 64void PanelResizeController::Resize(const gfx::Point& mouse_location) { 65 DCHECK(IsResizing()); 66 panel::Resizability resizability = resizing_panel_->CanResizeByMouse(); 67 if (panel::NOT_RESIZABLE == resizability) { 68 EndResizing(false); 69 return; 70 } 71 gfx::Rect bounds = resizing_panel_->GetBounds(); 72 73 if (ResizingRight(sides_resized_)) { 74 bounds.set_width(std::max(bounds_at_start_.width() + 75 mouse_location.x() - mouse_location_at_start_.x(), 0)); 76 } 77 if (ResizingBottom(sides_resized_)) { 78 DCHECK_EQ(panel::RESIZABLE_ALL_SIDES, resizability); 79 bounds.set_height(std::max(bounds_at_start_.height() + 80 mouse_location.y() - mouse_location_at_start_.y(), 0)); 81 } 82 if (ResizingLeft(sides_resized_)) { 83 bounds.set_width(std::max(bounds_at_start_.width() + 84 mouse_location_at_start_.x() - mouse_location.x(), 0)); 85 } 86 if (ResizingTop(sides_resized_)) { 87 int new_height = std::max(bounds_at_start_.height() + 88 mouse_location_at_start_.y() - mouse_location.y(), 0); 89 int new_y = bounds_at_start_.bottom() - new_height; 90 91 // If the mouse is within the main screen area, make sure that the top 92 // border of panel cannot go outside the work area. This is to prevent 93 // panel's titlebar from being resized under the taskbar or OSX menu bar 94 // that is aligned to top screen edge. 95 int display_area_top_position = panel_manager_->display_area().y(); 96 if (panel_manager_->display_settings_provider()-> 97 GetPrimaryScreenArea().Contains(mouse_location) && 98 new_y < display_area_top_position) { 99 new_height -= display_area_top_position - new_y; 100 } 101 102 bounds.set_height(new_height); 103 } 104 105 resizing_panel_->IncreaseMaxSize(bounds.size()); 106 107 // This effectively only clamps using the min size, since the max_size was 108 // updated above. 109 bounds.set_size(resizing_panel_->ClampSize(bounds.size())); 110 111 if (ResizingLeft(sides_resized_)) 112 bounds.set_x(bounds_at_start_.right() - bounds.width()); 113 114 if (ResizingTop(sides_resized_)) 115 bounds.set_y(bounds_at_start_.bottom() - bounds.height()); 116 117 if (bounds != resizing_panel_->GetBounds()) 118 resizing_panel_->OnWindowResizedByMouse(bounds); 119} 120 121Panel* PanelResizeController::EndResizing(bool cancelled) { 122 DCHECK(IsResizing()); 123 124 if (cancelled) 125 resizing_panel_->OnWindowResizedByMouse(bounds_at_start_); 126 127 // Do a thorough cleanup. 128 resizing_panel_->OnPanelEndUserResizing(); 129 Panel* resized_panel = resizing_panel_; 130 resizing_panel_ = NULL; 131 sides_resized_ = panel::RESIZE_NONE; 132 bounds_at_start_ = gfx::Rect(); 133 mouse_location_at_start_ = gfx::Point(); 134 return resized_panel; 135} 136 137void PanelResizeController::OnPanelClosed(Panel* panel) { 138 if (!resizing_panel_) 139 return; 140 141 // If the resizing panel is closed, abort the resize operation. 142 if (resizing_panel_ == panel) 143 EndResizing(false); 144} 145