blob: 7cb85409c2eff2259c2aef77627e624c125efe39 [file] [log] [blame]
[email protected]34338252011-03-29 00:39:051// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]066e70a2008-10-24 01:55:032// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]2362e4f2009-05-08 00:34:055#ifndef VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_
6#define VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_
[email protected]32b76ef2010-07-26 23:08:247#pragma once
[email protected]066e70a2008-10-24 01:55:038
[email protected]1d4389b2011-01-13 00:12:359#include "base/gtest_prod_util.h"
[email protected]2362e4f2009-05-08 00:34:0510#include "views/view.h"
[email protected]066e70a2008-10-24 01:55:0311
12namespace views {
13
[email protected]3d2fdb02011-10-25 18:42:2514class SingleSplitViewListener;
15
[email protected]1d4389b2011-01-13 00:12:3516// SingleSplitView lays out two views next to each other, either horizontally
17// or vertically. A splitter exists between the two views that the user can
18// drag around to resize the views.
[email protected]3d2fdb02011-10-25 18:42:2519// SingleSplitViewListener's SplitHandleMoved notification helps to monitor user
20// initiated layout changes.
[email protected]5036f182011-08-05 20:58:2921class VIEWS_EXPORT SingleSplitView : public View {
[email protected]066e70a2008-10-24 01:55:0322 public:
[email protected]ea36e322009-06-24 09:40:3523 enum Orientation {
24 HORIZONTAL_SPLIT,
25 VERTICAL_SPLIT
26 };
27
[email protected]66753952011-06-02 21:32:4728 static const char kViewClassName[];
29
[email protected]1d4389b2011-01-13 00:12:3530 SingleSplitView(View* leading,
31 View* trailing,
32 Orientation orientation,
[email protected]3d2fdb02011-10-25 18:42:2533 SingleSplitViewListener* listener);
[email protected]066e70a2008-10-24 01:55:0334
[email protected]8eb52a9a2011-03-09 16:52:0035 virtual void Layout() OVERRIDE;
[email protected]66753952011-06-02 21:32:4736 virtual std::string GetClassName() const OVERRIDE;
[email protected]066e70a2008-10-24 01:55:0337
[email protected]79e549f2011-03-14 06:56:3338 virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
[email protected]008541252010-03-16 00:24:2039
[email protected]066e70a2008-10-24 01:55:0340 // SingleSplitView's preferred size is the sum of the preferred widths
41 // and the max of the heights.
[email protected]8eb52a9a2011-03-09 16:52:0042 virtual gfx::Size GetPreferredSize() OVERRIDE;
[email protected]066e70a2008-10-24 01:55:0343
44 // Overriden to return a resize cursor when over the divider.
[email protected]3446c062011-05-03 21:48:0045 virtual gfx::NativeCursor GetCursor(const MouseEvent& event) OVERRIDE;
[email protected]066e70a2008-10-24 01:55:0346
[email protected]1d4389b2011-01-13 00:12:3547 Orientation orientation() const {
48 return is_horizontal_ ? HORIZONTAL_SPLIT : VERTICAL_SPLIT;
49 }
50
[email protected]ea36e322009-06-24 09:40:3551 void set_divider_offset(int divider_offset) {
52 divider_offset_ = divider_offset;
53 }
[email protected]1d4389b2011-01-13 00:12:3554 int divider_offset() const { return divider_offset_; }
[email protected]066e70a2008-10-24 01:55:0355
[email protected]e46318e2009-07-09 14:13:0856 // Sets whether the leading component is resized when the split views size
57 // changes. The default is true. A value of false results in the trailing
58 // component resizing on a bounds change.
59 void set_resize_leading_on_bounds_change(bool resize) {
60 resize_leading_on_bounds_change_ = resize;
61 }
62
[email protected]1d4389b2011-01-13 00:12:3563 // Calculates ideal leading and trailing view bounds according to the given
64 // split view |bounds|, current divider offset and children visiblity.
65 // Does not change children view bounds.
66 void CalculateChildrenBounds(const gfx::Rect& bounds,
67 gfx::Rect* leading_bounds,
68 gfx::Rect* trailing_bounds) const;
69
[email protected]79e549f2011-03-14 06:56:3370 void SetAccessibleName(const string16& name);
71
[email protected]066e70a2008-10-24 01:55:0372 protected:
[email protected]8eb52a9a2011-03-09 16:52:0073 // View overrides.
74 virtual bool OnMousePressed(const MouseEvent& event) OVERRIDE;
75 virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE;
[email protected]34338252011-03-29 00:39:0576 virtual void OnMouseCaptureLost() OVERRIDE;
[email protected]8eb52a9a2011-03-09 16:52:0077 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE;
[email protected]066e70a2008-10-24 01:55:0378
79 private:
[email protected]1d4389b2011-01-13 00:12:3580 // This test calls OnMouse* functions.
81 FRIEND_TEST_ALL_PREFIXES(SingleSplitViewTest, MouseDrag);
82
[email protected]ea36e322009-06-24 09:40:3583 // Returns true if |x| or |y| is over the divider.
[email protected]008541252010-03-16 00:24:2084 bool IsPointInDivider(const gfx::Point& p);
[email protected]ea36e322009-06-24 09:40:3585
[email protected]1d4389b2011-01-13 00:12:3586 // Calculates the new |divider_offset| based on the changes of split view
87 // bounds.
[email protected]3d2fdb02011-10-25 18:42:2588 int CalculateDividerOffset(int divider_offset,
89 const gfx::Rect& previous_bounds,
90 const gfx::Rect& new_bounds) const;
[email protected]1d4389b2011-01-13 00:12:3591
92 // Returns divider offset within primary axis size range for given split
93 // view |bounds|.
94 int NormalizeDividerOffset(int divider_offset, const gfx::Rect& bounds) const;
95
[email protected]ea36e322009-06-24 09:40:3596 // Returns width in case of horizontal split and height otherwise.
[email protected]1d4389b2011-01-13 00:12:3597 int GetPrimaryAxisSize() const {
[email protected]ea36e322009-06-24 09:40:3598 return GetPrimaryAxisSize(width(), height());
99 }
100
[email protected]1d4389b2011-01-13 00:12:35101 int GetPrimaryAxisSize(int h, int v) const {
[email protected]ea36e322009-06-24 09:40:35102 return is_horizontal_ ? h : v;
103 }
[email protected]066e70a2008-10-24 01:55:03104
105 // Used to track drag info.
106 struct DragInfo {
107 // The initial coordinate of the mouse when the user started the drag.
[email protected]ea36e322009-06-24 09:40:35108 int initial_mouse_offset;
[email protected]066e70a2008-10-24 01:55:03109 // The initial position of the divider when the user started the drag.
[email protected]ea36e322009-06-24 09:40:35110 int initial_divider_offset;
[email protected]066e70a2008-10-24 01:55:03111 };
112
113 DragInfo drag_info_;
114
[email protected]ea36e322009-06-24 09:40:35115 // Orientation of the split view.
116 bool is_horizontal_;
117
[email protected]066e70a2008-10-24 01:55:03118 // Position of the divider.
[email protected]ea36e322009-06-24 09:40:35119 int divider_offset_;
[email protected]066e70a2008-10-24 01:55:03120
[email protected]e46318e2009-07-09 14:13:08121 bool resize_leading_on_bounds_change_;
122
[email protected]3d2fdb02011-10-25 18:42:25123 // Listener to notify about user initiated handle movements. Not owned.
124 SingleSplitViewListener* listener_;
[email protected]1d4389b2011-01-13 00:12:35125
[email protected]79e549f2011-03-14 06:56:33126 // The accessible name of this view.
127 string16 accessible_name_;
128
[email protected]066e70a2008-10-24 01:55:03129 DISALLOW_COPY_AND_ASSIGN(SingleSplitView);
130};
131
132} // namespace views
133
[email protected]2362e4f2009-05-08 00:34:05134#endif // VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_