diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-24 01:55:03 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-24 01:55:03 +0000 |
commit | 066e70a48bbaa480f7718db210d98c00d1c1310c (patch) | |
tree | 614419c22a71e93d97b864ec9dc5028e850644b2 /chrome | |
parent | 9eb381798e60beac696ba13855b85691e9d22fb7 (diff) | |
download | chromium_src-066e70a48bbaa480f7718db210d98c00d1c1310c.zip chromium_src-066e70a48bbaa480f7718db210d98c00d1c1310c.tar.gz chromium_src-066e70a48bbaa480f7718db210d98c00d1c1310c.tar.bz2 |
Adds a horizontal split view.
BUG=674
TEST=none
Review URL: http://codereview.chromium.org/7930
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3897 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/views/single_split_view.cc | 118 | ||||
-rw-r--r-- | chrome/views/single_split_view.h | 58 | ||||
-rw-r--r-- | chrome/views/view.cc | 2 | ||||
-rw-r--r-- | chrome/views/views.vcproj | 8 |
4 files changed, 185 insertions, 1 deletions
diff --git a/chrome/views/single_split_view.cc b/chrome/views/single_split_view.cc new file mode 100644 index 0000000..613d3e22 --- /dev/null +++ b/chrome/views/single_split_view.cc @@ -0,0 +1,118 @@ +// Copyright (c) 2006-2008 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/views/single_split_view.h" + +#include "base/gfx/skia_utils.h" +#include "chrome/common/gfx/chrome_canvas.h" + +namespace views { + +// Size of the divider in pixels. +static const int kDividerSize = 6; + +SingleSplitView::SingleSplitView(View* leading, + View* trailing) : divider_x_(-1) { + AddChildView(leading); + AddChildView(trailing); +} + +void SingleSplitView::PaintBackground(ChromeCanvas* canvas) { + canvas->drawColor(gfx::COLORREFToSkColor(GetSysColor(COLOR_3DFACE)), + SkPorterDuff::kSrc_Mode); +} + +void SingleSplitView::Layout() { + if (GetChildViewCount() != 2) + return; + + View* leading = GetChildViewAt(0); + View* trailing = GetChildViewAt(1); + if (divider_x_ < 0) + divider_x_ = (width() - kDividerSize) / 2; + else + divider_x_ = std::min(divider_x_, width() - kDividerSize); + leading->SetBounds(0, 0, divider_x_, height()); + trailing->SetBounds(divider_x_ + kDividerSize, 0, + width() - divider_x_ - kDividerSize, height()); + + SchedulePaint(); + + // Invoke super's implementation so that the children are layed out. + View::Layout(); +} + +gfx::Size SingleSplitView::GetPreferredSize() { + int width = 0; + int height = 0; + for (int i = 0; i < 2 && i < GetChildViewCount(); ++i) { + View* view = GetChildViewAt(i); + gfx::Size pref = view->GetPreferredSize(); + width += pref.width(); + height = std::max(height, pref.height()); + } + width += kDividerSize; + return gfx::Size(width, height); +} + +HCURSOR SingleSplitView::GetCursorForPoint(Event::EventType event_type, + int x, + int y) { + if (IsPointInDivider(x)) { + static HCURSOR resize_cursor = LoadCursor(NULL, IDC_SIZEWE); + return resize_cursor; + } + return NULL; +} + +bool SingleSplitView::OnMousePressed(const MouseEvent& event) { + if (!IsPointInDivider(event.x())) + return false; + drag_info_.initial_mouse_x = event.x(); + drag_info_.initial_divider_x = divider_x_; + return true; +} + +bool SingleSplitView::OnMouseDragged(const MouseEvent& event) { + if (GetChildViewCount() < 2) + return false; + + int delta_x = event.x() - drag_info_.initial_mouse_x; + if (UILayoutIsRightToLeft()) + delta_x *= -1; + // Honor the minimum size when resizing. + int new_width = std::max(GetChildViewAt(0)->GetMinimumSize().width(), + drag_info_.initial_divider_x + delta_x); + + // And don't let the view get bigger than our width. + new_width = std::min(width() - kDividerSize, new_width); + + if (new_width != divider_x_) { + set_divider_x(new_width); + Layout(); + } + return true; +} + +void SingleSplitView::OnMouseReleased(const MouseEvent& event, bool canceled) { + if (GetChildViewCount() < 2) + return; + + if (canceled && drag_info_.initial_divider_x != divider_x_) { + set_divider_x(drag_info_.initial_divider_x); + Layout(); + } +} + +bool SingleSplitView::IsPointInDivider(int x) { + if (GetChildViewCount() < 2) + return false; + + View* leading = GetChildViewAt(0); + int divider_relative_x = + x - MirroredXCoordinateInsideView(leading->width()); + return (divider_relative_x >= 0 && divider_relative_x < kDividerSize); +} + +} // namespace views diff --git a/chrome/views/single_split_view.h b/chrome/views/single_split_view.h new file mode 100644 index 0000000..b23a086 --- /dev/null +++ b/chrome/views/single_split_view.h @@ -0,0 +1,58 @@ +// Copyright (c) 2006-2008 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. + +#ifndef CHROME_VIEWS_SINGLE_SPLIT_VIEW_H_ +#define CHROME_VIEWS_SINGLE_SPLIT_VIEW_H_ + +#include "chrome/views/view.h" + +namespace views { + +// SingleSplitView lays out two views horizontally. A splitter exists between +// the two views that the user can drag around to resize the views. +class SingleSplitView : public views::View { + public: + SingleSplitView(View* leading, View* trailing); + + virtual void PaintBackground(ChromeCanvas* canvas); + virtual void Layout(); + + // SingleSplitView's preferred size is the sum of the preferred widths + // and the max of the heights. + virtual gfx::Size GetPreferredSize(); + + // Overriden to return a resize cursor when over the divider. + virtual HCURSOR GetCursorForPoint(Event::EventType event_type, int x, int y); + + void set_divider_x(int divider_x) { divider_x_ = divider_x; } + int divider_x() { return divider_x_; } + + protected: + virtual bool OnMousePressed(const MouseEvent& event); + virtual bool OnMouseDragged(const MouseEvent& event); + virtual void OnMouseReleased(const MouseEvent& event, bool canceled); + + private: + // Returns true if |x| is over the divider. + bool IsPointInDivider(int x); + + // Used to track drag info. + struct DragInfo { + // The initial coordinate of the mouse when the user started the drag. + int initial_mouse_x; + // The initial position of the divider when the user started the drag. + int initial_divider_x; + }; + + DragInfo drag_info_; + + // Position of the divider. + int divider_x_; + + DISALLOW_COPY_AND_ASSIGN(SingleSplitView); +}; + +} // namespace views + +#endif // CHROME_VIEWS_SINGLE_SPLIT_VIEW_H_ diff --git a/chrome/views/view.cc b/chrome/views/view.cc index 285aed7..7dff258 100644 --- a/chrome/views/view.cc +++ b/chrome/views/view.cc @@ -543,7 +543,7 @@ void View::DoDrag(const MouseEvent& e, int press_x, int press_y) { WriteDragData(press_x, press_y, data.get()); // Message the RootView to do the drag and drop. That way if we're removed - // the RootView can detect it and avoid callins us back. + // the RootView can detect it and avoid calling us back. RootView* root_view = GetRootView(); root_view->StartDragForViewFromMouseEvent( this, data, GetDragOperations(press_x, press_y)); diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj index 0a6ef96..247dbab 100644 --- a/chrome/views/views.vcproj +++ b/chrome/views/views.vcproj @@ -534,6 +534,14 @@ > </File> <File + RelativePath=".\single_split_view.cc" + > + </File> + <File + RelativePath=".\single_split_view.h" + > + </File> + <File RelativePath=".\tabbed_pane.cc" > </File> |