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" | |
10 #include "views/view.h" | 9 #include "views/view.h" |
11 | 10 |
12 namespace views { | 11 namespace views { |
13 | 12 |
14 // SingleSplitView lays out two views next to each other, either horizontally | 13 // SingleSplitView lays out two views horizontally. A splitter exists between |
15 // or vertically. A splitter exists between the two views that the user can | 14 // the two views that the user can drag around to resize the views. |
16 // drag around to resize the views. | |
17 // Observer's SplitHandleMoved notification helps to monitor user initiated | |
18 // layout changes. | |
19 class SingleSplitView : public views::View { | 15 class SingleSplitView : public views::View { |
20 public: | 16 public: |
21 enum Orientation { | 17 enum Orientation { |
22 HORIZONTAL_SPLIT, | 18 HORIZONTAL_SPLIT, |
23 VERTICAL_SPLIT | 19 VERTICAL_SPLIT |
24 }; | 20 }; |
25 | 21 |
26 class Observer { | 22 SingleSplitView(View* leading, View* trailing, Orientation orientation); |
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); | |
41 | 23 |
42 virtual void DidChangeBounds(const gfx::Rect& previous, | 24 virtual void DidChangeBounds(const gfx::Rect& previous, |
43 const gfx::Rect& current); | 25 const gfx::Rect& current); |
44 | 26 |
45 virtual void Layout(); | 27 virtual void Layout(); |
46 | 28 |
47 virtual AccessibilityTypes::Role GetAccessibleRole(); | 29 virtual AccessibilityTypes::Role GetAccessibleRole(); |
48 | 30 |
49 // SingleSplitView's preferred size is the sum of the preferred widths | 31 // SingleSplitView's preferred size is the sum of the preferred widths |
50 // and the max of the heights. | 32 // and the max of the heights. |
51 virtual gfx::Size GetPreferredSize(); | 33 virtual gfx::Size GetPreferredSize(); |
52 | 34 |
53 // Overriden to return a resize cursor when over the divider. | 35 // Overriden to return a resize cursor when over the divider. |
54 virtual gfx::NativeCursor GetCursorForPoint(Event::EventType event_type, | 36 virtual gfx::NativeCursor GetCursorForPoint(Event::EventType event_type, |
55 const gfx::Point& p); | 37 const gfx::Point& p); |
56 | 38 |
57 Orientation orientation() const { | |
58 return is_horizontal_ ? HORIZONTAL_SPLIT : VERTICAL_SPLIT; | |
59 } | |
60 | |
61 void set_divider_offset(int divider_offset) { | 39 void set_divider_offset(int divider_offset) { |
62 divider_offset_ = divider_offset; | 40 divider_offset_ = divider_offset; |
63 } | 41 } |
64 int divider_offset() const { return divider_offset_; } | 42 int divider_offset() { return divider_offset_; } |
65 | 43 |
66 // Sets whether the leading component is resized when the split views size | 44 // Sets whether the leading component is resized when the split views size |
67 // changes. The default is true. A value of false results in the trailing | 45 // changes. The default is true. A value of false results in the trailing |
68 // component resizing on a bounds change. | 46 // component resizing on a bounds change. |
69 void set_resize_leading_on_bounds_change(bool resize) { | 47 void set_resize_leading_on_bounds_change(bool resize) { |
70 resize_leading_on_bounds_change_ = resize; | 48 resize_leading_on_bounds_change_ = resize; |
71 } | 49 } |
72 | 50 |
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 | |
80 protected: | 51 protected: |
81 virtual bool OnMousePressed(const MouseEvent& event); | 52 virtual bool OnMousePressed(const MouseEvent& event); |
82 virtual bool OnMouseDragged(const MouseEvent& event); | 53 virtual bool OnMouseDragged(const MouseEvent& event); |
83 virtual void OnMouseReleased(const MouseEvent& event, bool canceled); | 54 virtual void OnMouseReleased(const MouseEvent& event, bool canceled); |
84 | 55 |
85 private: | 56 private: |
86 // This test calls OnMouse* functions. | |
87 FRIEND_TEST_ALL_PREFIXES(SingleSplitViewTest, MouseDrag); | |
88 | |
89 // Returns true if |x| or |y| is over the divider. | 57 // Returns true if |x| or |y| is over the divider. |
90 bool IsPointInDivider(const gfx::Point& p); | 58 bool IsPointInDivider(const gfx::Point& p); |
91 | 59 |
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 | |
103 // Returns width in case of horizontal split and height otherwise. | 60 // Returns width in case of horizontal split and height otherwise. |
104 int GetPrimaryAxisSize() const { | 61 int GetPrimaryAxisSize() { |
105 return GetPrimaryAxisSize(width(), height()); | 62 return GetPrimaryAxisSize(width(), height()); |
106 } | 63 } |
107 | 64 |
108 int GetPrimaryAxisSize(int h, int v) const { | 65 int GetPrimaryAxisSize(int h, int v) { |
109 return is_horizontal_ ? h : v; | 66 return is_horizontal_ ? h : v; |
110 } | 67 } |
111 | 68 |
112 // Used to track drag info. | 69 // Used to track drag info. |
113 struct DragInfo { | 70 struct DragInfo { |
114 // The initial coordinate of the mouse when the user started the drag. | 71 // The initial coordinate of the mouse when the user started the drag. |
115 int initial_mouse_offset; | 72 int initial_mouse_offset; |
116 // The initial position of the divider when the user started the drag. | 73 // The initial position of the divider when the user started the drag. |
117 int initial_divider_offset; | 74 int initial_divider_offset; |
118 }; | 75 }; |
119 | 76 |
120 DragInfo drag_info_; | 77 DragInfo drag_info_; |
121 | 78 |
122 // Orientation of the split view. | 79 // Orientation of the split view. |
123 bool is_horizontal_; | 80 bool is_horizontal_; |
124 | 81 |
125 // Position of the divider. | 82 // Position of the divider. |
126 int divider_offset_; | 83 int divider_offset_; |
127 | 84 |
128 bool resize_leading_on_bounds_change_; | 85 bool resize_leading_on_bounds_change_; |
129 | 86 |
130 // Observer to notify about user initiated handle movements. Not own by us. | |
131 Observer* observer_; | |
132 | |
133 DISALLOW_COPY_AND_ASSIGN(SingleSplitView); | 87 DISALLOW_COPY_AND_ASSIGN(SingleSplitView); |
134 }; | 88 }; |
135 | 89 |
136 } // namespace views | 90 } // namespace views |
137 | 91 |
138 #endif // VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ | 92 #endif // VIEWS_CONTROLS_SINGLE_SPLIT_VIEW_H_ |
OLD | NEW |