single_split_view.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/single_split_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/skia_utils_win.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/background.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/single_split_view_listener.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/cursor/cursor.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char SingleSplitView::kViewClassName[] =
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "ui/views/controls/SingleSplitView";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size of the divider in pixels.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kDividerSize = 4;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SingleSplitView::SingleSplitView(View* leading,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 View* trailing,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Orientation orientation,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 SingleSplitViewListener* listener)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : is_horizontal_(orientation == HORIZONTAL_SPLIT),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      divider_offset_(-1),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resize_leading_on_bounds_change_(true),
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      resize_disabled_(false),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      listener_(listener) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(leading);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(trailing);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_background(
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      views::Background::CreateSolidBackground(
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          skia::COLORREFToSkColor(GetSysColor(COLOR_3DFACE))));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::Layout() {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect leading_bounds;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect trailing_bounds;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CalculateChildrenBounds(bounds(), &leading_bounds, &trailing_bounds);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_children()) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (child_at(0)->visible())
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      child_at(0)->SetBoundsRect(leading_bounds);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (child_count() > 1) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (child_at(1)->visible())
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        child_at(1)->SetBoundsRect(trailing_bounds);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoke super's implementation so that the children are layed out.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::Layout();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string SingleSplitView::GetClassName() const {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kViewClassName;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::GetAccessibleState(ui::AccessibleViewState* state) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state->role = ui::AccessibilityTypes::ROLE_GROUPING;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state->name = accessible_name_;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size SingleSplitView::GetPreferredSize() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = 0;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2 && i < child_count(); ++i) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* view = child_at(i);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size pref = view->GetPreferredSize();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_horizontal_) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width += pref.width();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height = std::max(height, pref.height());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width = std::max(width, pref.width());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height += pref.height();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_horizontal_)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    width += GetDividerSize();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    height += GetDividerSize();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(width, height);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeCursor SingleSplitView::GetCursor(const ui::MouseEvent& event) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsPointInDivider(event.location()))
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::kNullCursor;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_horizontal_ ?
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::kCursorEastWestResize : ui::kCursorNorthSouthResize;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HCURSOR we_resize_cursor = LoadCursor(NULL, IDC_SIZEWE);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static HCURSOR ns_resize_cursor = LoadCursor(NULL, IDC_SIZENS);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return is_horizontal_ ? we_resize_cursor : ns_resize_cursor;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SingleSplitView::GetDividerSize() const {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool both_visible = child_count() > 1 && child_at(0)->visible() &&
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      child_at(1)->visible();
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return both_visible && !resize_disabled_ ? kDividerSize : 0;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::CalculateChildrenBounds(
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& bounds,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect* leading_bounds,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect* trailing_bounds) const {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_leading_visible = has_children() && child_at(0)->visible();
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_trailing_visible = child_count() > 1 && child_at(1)->visible();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_leading_visible && !is_trailing_visible) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *leading_bounds = gfx::Rect();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *trailing_bounds = gfx::Rect();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int divider_at;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_trailing_visible) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_at = GetPrimaryAxisSize(bounds.width(), bounds.height());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!is_leading_visible) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_at = 0;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_at =
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CalculateDividerOffset(divider_offset_, this->bounds(), bounds);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_at = NormalizeDividerOffset(divider_at, bounds);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int divider_size = GetDividerSize();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_horizontal_) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *leading_bounds = gfx::Rect(0, 0, divider_at, bounds.height());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *trailing_bounds =
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gfx::Rect(divider_at + divider_size, 0,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  std::max(0, bounds.width() - divider_at - divider_size),
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bounds.height());
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *leading_bounds = gfx::Rect(0, 0, bounds.width(), divider_at);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *trailing_bounds =
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gfx::Rect(0, divider_at + divider_size, bounds.width(),
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  std::max(0, bounds.height() - divider_at - divider_size));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::SetAccessibleName(const string16& name) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  accessible_name_ = name;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SingleSplitView::OnMousePressed(const ui::MouseEvent& event) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsPointInDivider(event.location()))
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drag_info_.initial_mouse_offset = GetPrimaryAxisSize(event.x(), event.y());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drag_info_.initial_divider_offset =
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NormalizeDividerOffset(divider_offset_, bounds());
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SingleSplitView::OnMouseDragged(const ui::MouseEvent& event) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (child_count() < 2)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int delta_offset = GetPrimaryAxisSize(event.x(), event.y()) -
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      drag_info_.initial_mouse_offset;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_horizontal_ && base::i18n::IsRTL())
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delta_offset *= -1;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Honor the first child's minimum size when resizing.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size min = child_at(0)->GetMinimumSize();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int new_size = std::max(GetPrimaryAxisSize(min.width(), min.height()),
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          drag_info_.initial_divider_offset + delta_offset);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Honor the second child's minimum size, and don't let the view
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // get bigger than our width.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  min = child_at(1)->GetMinimumSize();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  new_size = std::min(GetPrimaryAxisSize() - kDividerSize -
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetPrimaryAxisSize(min.width(), min.height()), new_size);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_size != divider_offset_) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_divider_offset(new_size);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!listener_ || listener_->SplitHandleMoved(this))
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Layout();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::OnMouseCaptureLost() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (child_count() < 2)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (drag_info_.initial_divider_offset != divider_offset_) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_divider_offset(drag_info_.initial_divider_offset);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!listener_ || listener_->SplitHandleMoved(this))
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Layout();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleSplitView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  divider_offset_ = CalculateDividerOffset(divider_offset_, previous_bounds,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           bounds());
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SingleSplitView::IsPointInDivider(const gfx::Point& p) {
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (resize_disabled_)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (child_count() < 2)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!child_at(0)->visible() || !child_at(1)->visible())
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int divider_relative_offset;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_horizontal_) {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_relative_offset =
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        p.x() - child_at(base::i18n::IsRTL() ? 1 : 0)->width();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    divider_relative_offset = p.y() - child_at(0)->height();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (divider_relative_offset >= 0 &&
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      divider_relative_offset < GetDividerSize());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SingleSplitView::CalculateDividerOffset(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int divider_offset,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& previous_bounds,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& new_bounds) const {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (resize_leading_on_bounds_change_ && divider_offset != -1) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We do not update divider_offset on minimize (to zero) and on restore
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (to largest value). As a result we get back to the original value upon
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // window restore.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_minimize_or_restore =
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        previous_bounds.height() == 0 || new_bounds.height() == 0;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_minimize_or_restore) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_horizontal_)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        divider_offset += new_bounds.width() - previous_bounds.width();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        divider_offset += new_bounds.height() - previous_bounds.height();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (divider_offset < 0)
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        divider_offset = GetDividerSize();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return divider_offset;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SingleSplitView::NormalizeDividerOffset(int divider_offset,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const gfx::Rect& bounds) const {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int primary_axis_size = GetPrimaryAxisSize(bounds.width(), bounds.height());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (divider_offset < 0)
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // primary_axis_size may < GetDividerSize during initial layout.
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::max(0, (primary_axis_size - GetDividerSize()) / 2);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::min(divider_offset,
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  std::max(primary_axis_size - GetDividerSize(), 0));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
265