// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/panels/panel_resize_controller.h" #include "base/logging.h" #include "chrome/browser/ui/panels/detached_panel_strip.h" #include "chrome/browser/ui/panels/docked_panel_strip.h" #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_manager.h" #include "chrome/browser/ui/panels/panel_strip.h" namespace { static bool ResizingLeft(PanelResizeController::ResizingSides sides) { return sides == PanelResizeController::RESIZE_TOP_LEFT || sides == PanelResizeController::RESIZE_LEFT || sides == PanelResizeController::RESIZE_BOTTOM_LEFT; } static bool ResizingRight(PanelResizeController::ResizingSides sides) { return sides == PanelResizeController::RESIZE_TOP_RIGHT || sides == PanelResizeController::RESIZE_RIGHT || sides == PanelResizeController::RESIZE_BOTTOM_RIGHT; } static bool ResizingTop(PanelResizeController::ResizingSides sides) { return sides == PanelResizeController::RESIZE_TOP_LEFT || sides == PanelResizeController::RESIZE_TOP || sides == PanelResizeController::RESIZE_TOP_RIGHT; } static bool ResizingBottom(PanelResizeController::ResizingSides sides) { return sides == PanelResizeController::RESIZE_BOTTOM_RIGHT || sides == PanelResizeController::RESIZE_BOTTOM || sides == PanelResizeController::RESIZE_BOTTOM_LEFT; } } PanelResizeController::PanelResizeController(PanelManager* panel_manager) : panel_manager_(panel_manager), resizing_panel_(NULL), sides_resized_(NO_SIDES) { } void PanelResizeController::StartResizing(Panel* panel, const gfx::Point& mouse_location, ResizingSides sides) { DCHECK(!IsResizing()); DCHECK(panel->panel_strip() && panel->panel_strip()->CanResizePanel(panel)); DCHECK_NE(NO_SIDES, sides); mouse_location_at_start_ = mouse_location; bounds_at_start_ = panel->GetBounds(); sides_resized_ = sides; resizing_panel_ = panel; } void PanelResizeController::Resize(const gfx::Point& mouse_location) { DCHECK(IsResizing()); if (resizing_panel_->panel_strip() == NULL || !resizing_panel_->panel_strip()->CanResizePanel(resizing_panel_)) { EndResizing(false); return; } gfx::Rect bounds = resizing_panel_->GetBounds(); if (ResizingRight(sides_resized_)) { bounds.set_width(std::max(bounds_at_start_.width() + mouse_location.x() - mouse_location_at_start_.x(), 0)); } if (ResizingBottom(sides_resized_)) { bounds.set_height(std::max(bounds_at_start_.height() + mouse_location.y() - mouse_location_at_start_.y(), 0)); } if (ResizingLeft(sides_resized_)) { bounds.set_width(std::max(bounds_at_start_.width() + mouse_location_at_start_.x() - mouse_location.x(), 0)); } if (ResizingTop(sides_resized_)) { bounds.set_height(std::max(bounds_at_start_.height() + mouse_location_at_start_.y() - mouse_location.y(), 0)); } // Give the panel a chance to adjust the bounds before setting them. gfx::Size size = bounds.size(); resizing_panel_->ClampSize(&size); bounds.set_size(size); if (ResizingLeft(sides_resized_)) { bounds.set_x(bounds_at_start_.x() - (bounds.width() - bounds_at_start_.width())); } if (ResizingTop(sides_resized_)) { bounds.set_y(bounds_at_start_.y() - (bounds.height() - bounds_at_start_.height())); } if (bounds != resizing_panel_->GetBounds()) panel_manager_->SetPanelBounds(resizing_panel_, bounds); } void PanelResizeController::EndResizing(bool cancelled) { DCHECK(IsResizing()); if (cancelled) { panel_manager_->SetPanelBounds(resizing_panel_, bounds_at_start_); } // Do a thorough cleanup. resizing_panel_ = NULL; sides_resized_ = NO_SIDES; bounds_at_start_ = gfx::Rect(); mouse_location_at_start_ = gfx::Point(); } void PanelResizeController::OnPanelClosed(Panel* panel) { if (!resizing_panel_) return; // If the resizing panel is closed, abort the resize operation. if (resizing_panel_ == panel) EndResizing(false); } PanelResizeController::ResizingSides PanelResizeController::IsMouseNearFrameSide( gfx::Point mouse_location, int resize_edge_thickness, Panel* panel) { gfx::Rect bounds = panel->GetBounds(); bool left = false, right = false, top = false, bottom = false; if (abs(mouse_location.x() - bounds.x()) <= resize_edge_thickness) left = true; if (abs(mouse_location.y() - bounds.y()) <= resize_edge_thickness) top = true; if (abs(mouse_location.x() - bounds.right()) <= resize_edge_thickness) right = true; if (abs(mouse_location.y() - bounds.bottom()) <= resize_edge_thickness) bottom = true; if (top && left) return RESIZE_TOP_LEFT; if (top && right) return RESIZE_TOP_RIGHT; if (bottom && left) return RESIZE_BOTTOM_LEFT; if (bottom && right) return RESIZE_BOTTOM_RIGHT; if (top) return RESIZE_TOP; if (bottom) return RESIZE_BOTTOM; if (left) return RESIZE_LEFT; if (right) return RESIZE_RIGHT; return NO_SIDES; }