OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ | 5 #ifndef VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ |
6 #define VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ | 6 #define VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
| 9 #include "base/gtest_prod_util.h" |
9 #include "views/view.h" | 10 #include "views/view.h" |
10 | 11 |
11 namespace views { | 12 namespace views { |
12 | 13 |
13 // SingleSplitView lays out two views horizontally. A splitter exists between | 14 // SingleSplitView lays out two views next to each other, either horizontally |
14 // the two views that the user can drag around to resize the views. | 15 // or vertically. A splitter exists between the two views that the user can |
| 16 // drag around to resize the views. |
| 17 // Observer's SplitHandleMoved notification helps to monitor user initiated |
| 18 // layout changes. |
15 class SingleSplitView : public views::View { | 19 class SingleSplitView : public views::View { |
16 public: | 20 public: |
17 enum Orientation { | 21 enum Orientation { |
18 HORIZONTAL_SPLIT, | 22 HORIZONTAL_SPLIT, |
19 VERTICAL_SPLIT | 23 VERTICAL_SPLIT |
20 }; | 24 }; |
21 | 25 |
22 SingleSplitView(View* leading, View* trailing, Orientation orientation); | 26 class Observer { |
| 27 public: |
| 28 // Invoked when split handle is moved by the user. |source|'s divider_offset |
| 29 // is already set to the new value, but Layout has not happened yet. |
| 30 // Returns false if the layout has been handled by the observer, returns |
| 31 // true if |source| should do it by itself. |
| 32 virtual bool SplitHandleMoved(SingleSplitView* source) = 0; |
| 33 protected: |
| 34 virtual ~Observer() {} |
| 35 }; |
| 36 |
| 37 SingleSplitView(View* leading, |
| 38 View* trailing, |
| 39 Orientation orientation, |
| 40 Observer* observer); |
23 | 41 |
24 virtual void DidChangeBounds(const gfx::Rect& previous, | 42 virtual void DidChangeBounds(const gfx::Rect& previous, |
25 const gfx::Rect& current); | 43 const gfx::Rect& current); |
26 | 44 |
27 virtual void Layout(); | 45 virtual void Layout(); |
28 | 46 |
29 virtual AccessibilityTypes::Role GetAccessibleRole(); | 47 virtual AccessibilityTypes::Role GetAccessibleRole(); |
30 | 48 |
31 // SingleSplitView's preferred size is the sum of the preferred widths | 49 // SingleSplitView's preferred size is the sum of the preferred widths |
32 // and the max of the heights. | 50 // and the max of the heights. |
33 virtual gfx::Size GetPreferredSize(); | 51 virtual gfx::Size GetPreferredSize(); |
34 | 52 |
35 // Overriden to return a resize cursor when over the divider. | 53 // Overriden to return a resize cursor when over the divider. |
36 virtual gfx::NativeCursor GetCursorForPoint(Event::EventType event_type, | 54 virtual gfx::NativeCursor GetCursorForPoint(Event::EventType event_type, |
37 const gfx::Point& p); | 55 const gfx::Point& p); |
38 | 56 |
| 57 Orientation orientation() const { |
| 58 return is_horizontal_ ? HORIZONTAL_SPLIT : VERTICAL_SPLIT; |
| 59 } |
| 60 |
39 void set_divider_offset(int divider_offset) { | 61 void set_divider_offset(int divider_offset) { |
40 divider_offset_ = divider_offset; | 62 divider_offset_ = divider_offset; |
41 } | 63 } |
42 int divider_offset() { return divider_offset_; } | 64 int divider_offset() const { return divider_offset_; } |
43 | 65 |
44 // Sets whether the leading component is resized when the split views size | 66 // Sets whether the leading component is resized when the split views size |
45 // changes. The default is true. A value of false results in the trailing | 67 // changes. The default is true. A value of false results in the trailing |
46 // component resizing on a bounds change. | 68 // component resizing on a bounds change. |
47 void set_resize_leading_on_bounds_change(bool resize) { | 69 void set_resize_leading_on_bounds_change(bool resize) { |
48 resize_leading_on_bounds_change_ = resize; | 70 resize_leading_on_bounds_change_ = resize; |
49 } | 71 } |
50 | 72 |
| 73 // Calculates ideal leading and trailing view bounds according to the given |
| 74 // split view |bounds|, current divider offset and children visiblity. |
| 75 // Does not change children view bounds. |
| 76 void CalculateChildrenBounds(const gfx::Rect& bounds, |
| 77 gfx::Rect* leading_bounds, |
| 78 gfx::Rect* trailing_bounds) const; |
| 79 |
51 protected: | 80 protected: |
52 virtual bool OnMousePressed(const MouseEvent& event); | 81 virtual bool OnMousePressed(const MouseEvent& event); |
53 virtual bool OnMouseDragged(const MouseEvent& event); | 82 virtual bool OnMouseDragged(const MouseEvent& event); |
54 virtual void OnMouseReleased(const MouseEvent& event, bool canceled); | 83 virtual void OnMouseReleased(const MouseEvent& event, bool canceled); |
55 | 84 |
56 private: | 85 private: |
| 86 // This test calls OnMouse* functions. |
| 87 FRIEND_TEST_ALL_PREFIXES(SingleSplitViewTest, MouseDrag); |
| 88 |
57 // Returns true if |x| or |y| is over the divider. | 89 // Returns true if |x| or |y| is over the divider. |
58 bool IsPointInDivider(const gfx::Point& p); | 90 bool IsPointInDivider(const gfx::Point& p); |
59 | 91 |
| 92 // Calculates the new |divider_offset| based on the changes of split view |
| 93 // bounds. |
| 94 int CalculateDividerOffset( |
| 95 int divider_offset, |
| 96 const gfx::Rect& previous_bounds, |
| 97 const gfx::Rect& new_bounds) const; |
| 98 |
| 99 // Returns divider offset within primary axis size range for given split |
| 100 // view |bounds|. |
| 101 int NormalizeDividerOffset(int divider_offset, const gfx::Rect& bounds) const; |
| 102 |
60 // Returns width in case of horizontal split and height otherwise. | 103 // Returns width in case of horizontal split and height otherwise. |
61 int GetPrimaryAxisSize() { | 104 int GetPrimaryAxisSize() const { |
62 return GetPrimaryAxisSize(width(), height()); | 105 return GetPrimaryAxisSize(width(), height()); |
63 } | 106 } |
64 | 107 |
65 int GetPrimaryAxisSize(int h, int v) { | 108 int GetPrimaryAxisSize(int h, int v) const { |
66 return is_horizontal_ ? h : v; | 109 return is_horizontal_ ? h : v; |
67 } | 110 } |
68 | 111 |
69 // Used to track drag info. | 112 // Used to track drag info. |
70 struct DragInfo { | 113 struct DragInfo { |
71 // The initial coordinate of the mouse when the user started the drag. | 114 // The initial coordinate of the mouse when the user started the drag. |
72 int initial_mouse_offset; | 115 int initial_mouse_offset; |
73 // The initial position of the divider when the user started the drag. | 116 // The initial position of the divider when the user started the drag. |
74 int initial_divider_offset; | 117 int initial_divider_offset; |
75 }; | 118 }; |
76 | 119 |
77 DragInfo drag_info_; | 120 DragInfo drag_info_; |
78 | 121 |
79 // Orientation of the split view. | 122 // Orientation of the split view. |
80 bool is_horizontal_; | 123 bool is_horizontal_; |
81 | 124 |
82 // Position of the divider. | 125 // Position of the divider. |
83 int divider_offset_; | 126 int divider_offset_; |
84 | 127 |
85 bool resize_leading_on_bounds_change_; | 128 bool resize_leading_on_bounds_change_; |
86 | 129 |
| 130 // Observer to notify about user initiated handle movements. Not own by us. |
| 131 Observer* observer_; |
| 132 |
87 DISALLOW_COPY_AND_ASSIGN(SingleSplitView); | 133 DISALLOW_COPY_AND_ASSIGN(SingleSplitView); |
88 }; | 134 }; |
89 | 135 |
90 } // namespace views | 136 } // namespace views |
91 | 137 |
92 #endif // VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ | 138 #endif // VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ |
OLD | NEW |