diff options
author | dslomov@chromium.org <dslomov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-16 21:01:07 +0000 |
---|---|---|
committer | dslomov@chromium.org <dslomov@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-16 21:01:07 +0000 |
commit | 0540b17672e859e9c5df2ca8f9de160ccec108f9 (patch) | |
tree | 582ab61cfba2a42d7bb4edb4552b4b25d05ddd07 /ash | |
parent | 723738ee0b4c9bc493af7c3f10aed0aaf9fee126 (diff) | |
download | chromium_src-0540b17672e859e9c5df2ca8f9de160ccec108f9.zip chromium_src-0540b17672e859e9c5df2ca8f9de160ccec108f9.tar.gz chromium_src-0540b17672e859e9c5df2ca8f9de160ccec108f9.tar.bz2 |
Panel dragging in Compact mode Aura layout
Review URL: https://chromiumcodereview.appspot.com/9388032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122354 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/shell.cc | 8 | ||||
-rw-r--r-- | ash/wm/panel_frame_view.cc | 24 | ||||
-rw-r--r-- | ash/wm/panel_frame_view.h | 6 | ||||
-rw-r--r-- | ash/wm/panel_layout_manager.cc | 49 | ||||
-rw-r--r-- | ash/wm/panel_layout_manager.h | 5 | ||||
-rw-r--r-- | ash/wm/panel_window_event_filter.cc | 108 | ||||
-rw-r--r-- | ash/wm/panel_window_event_filter.h | 57 |
8 files changed, 248 insertions, 11 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 63cf478..1bc5a58 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -131,6 +131,8 @@ 'wm/panel_frame_view.h', 'wm/panel_layout_manager.cc', 'wm/panel_layout_manager.h', + 'wm/panel_window_event_filter.cc', + 'wm/panel_window_event_filter.h', 'wm/partial_screenshot_event_filter.cc', 'wm/partial_screenshot_event_filter.h', 'wm/partial_screenshot_view.cc', diff --git a/ash/shell.cc b/ash/shell.cc index b2f63fa..ac4a385 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -21,6 +21,7 @@ #include "ash/wm/compact_layout_manager.h" #include "ash/wm/compact_status_area_layout_manager.h" #include "ash/wm/dialog_frame_view.h" +#include "ash/wm/panel_window_event_filter.h" #include "ash/wm/panel_layout_manager.h" #include "ash/wm/partial_screenshot_event_filter.h" #include "ash/wm/power_button_controller.h" @@ -111,10 +112,11 @@ void CreateSpecialContainers(aura::Window::Windows* containers) { panel_container->set_id(internal::kShellWindowId_PanelContainer); if (CommandLine::ForCurrentProcess()-> HasSwitch(switches::kAuraPanelManager)) { + internal::PanelLayoutManager* layout_manager = + new internal::PanelLayoutManager(panel_container); panel_container->SetEventFilter( - new ToplevelWindowEventFilter(panel_container)); - panel_container->SetLayoutManager( - new internal::PanelLayoutManager(panel_container)); + new internal::PanelWindowEventFilter(panel_container, layout_manager)); + panel_container->SetLayoutManager(layout_manager); } containers->push_back(panel_container); diff --git a/ash/wm/panel_frame_view.cc b/ash/wm/panel_frame_view.cc index 1d0f6d1..0196a54 100644 --- a/ash/wm/panel_frame_view.cc +++ b/ash/wm/panel_frame_view.cc @@ -73,6 +73,20 @@ class PanelCaption : public views::View, } virtual ~PanelCaption() {} + // point is in parent's coordinates + int NonClientHitTest(const gfx::Point& point) { + if (!GetLocalBounds().Contains(point)) + return HTNOWHERE; + + gfx::Point translated_point(point); + View::ConvertPointToView(parent(), this, &translated_point); + if (close_button_->GetMirroredBounds().Contains(translated_point)) + return HTCLOSE; + else if (minimize_button_->GetMirroredBounds().Contains(translated_point)) + return HTMINBUTTON; + return HTCAPTION; + } + // Overridden from views::View: virtual gfx::Size GetPreferredSize() OVERRIDE { return gfx::Size(0, close_button_->GetPreferredSize().height()); @@ -154,9 +168,17 @@ int PanelFrameView::NonClientHitTest(const gfx::Point& point) { if (!GetLocalBounds().Contains(point)) return HTNOWHERE; - int client_view_result = GetWidget()->client_view()->NonClientHitTest(point); + gfx::Point translated_point(point); + View::ConvertPointToView(parent(), this, &translated_point); + + int client_view_result = + GetWidget()->client_view()->NonClientHitTest(translated_point); if (client_view_result != HTNOWHERE) return client_view_result; + + int caption_result = panel_caption_->NonClientHitTest(translated_point); + if (caption_result != HTNOWHERE) + return caption_result; return HTNOWHERE; } diff --git a/ash/wm/panel_frame_view.h b/ash/wm/panel_frame_view.h index beacc31..d12d7a7 100644 --- a/ash/wm/panel_frame_view.h +++ b/ash/wm/panel_frame_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ASH_SHELL_PANEL_FRAME_VIEW_H_ -#define ASH_SHELL_PANEL_FRAME_VIEW_H_ +#ifndef ASH_WM_PANEL_FRAME_VIEW_H_ +#define ASH_WM_PANEL_FRAME_VIEW_H_ #pragma once #include "ash/ash_export.h" @@ -47,4 +47,4 @@ class ASH_EXPORT PanelFrameView : public views::NonClientFrameView { } -#endif // ASH_SHELL_PANEL_FRAME_VIEW_H_ +#endif // ASH_WM_PANEL_FRAME_VIEW_H_ diff --git a/ash/wm/panel_layout_manager.cc b/ash/wm/panel_layout_manager.cc index 3591726..2cc2870 100644 --- a/ash/wm/panel_layout_manager.cc +++ b/ash/wm/panel_layout_manager.cc @@ -29,13 +29,26 @@ namespace internal { PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container) : panel_container_(panel_container), - in_layout_(false) { + in_layout_(false), + dragged_panel_(NULL) { DCHECK(panel_container); } PanelLayoutManager::~PanelLayoutManager() { } +void PanelLayoutManager::StartDragging(aura::Window* panel) { + DCHECK(dragged_panel_ == NULL); + DCHECK(panel->parent() == panel_container_); + dragged_panel_ = panel; +} + +void PanelLayoutManager::FinishDragging() { + DCHECK(dragged_panel_ != NULL); + dragged_panel_ = NULL; + Relayout(); +} + //////////////////////////////////////////////////////////////////////////////// // PanelLayoutManager, aura::LayoutManager implementation: @@ -53,6 +66,10 @@ void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) { std::find(panel_windows_.begin(), panel_windows_.end(), child); if (found != panel_windows_.end()) panel_windows_.erase(found); + + if (dragged_panel_ == child) + dragged_panel_ = NULL; + Relayout(); } @@ -71,6 +88,25 @@ void PanelLayoutManager::SetChildBounds(aura::Window* child, bounds.set_width(max_width); if (bounds.height() > max_height) bounds.set_height(max_height); + + // Reposition dragged panel in the panel order. + if (dragged_panel_ == child) { + PanelList::iterator dragged_panel_iter = + std::find(panel_windows_.begin(), panel_windows_.end(), dragged_panel_); + DCHECK(dragged_panel_iter != panel_windows_.end()); + PanelList::iterator new_position; + for (new_position = panel_windows_.begin(); + new_position != panel_windows_.end(); + ++new_position) { + const gfx::Rect& bounds = (*new_position)->bounds(); + if (bounds.x() + bounds.width()/2 <= requested_bounds.x()) break; + } + if (new_position != dragged_panel_iter) { + panel_windows_.erase(dragged_panel_iter); + panel_windows_.insert(new_position, dragged_panel_); + } + } + SetChildBoundsDirect(child, bounds); Relayout(); } @@ -107,9 +143,14 @@ void PanelLayoutManager::Relayout() { continue; int x = right - panel_win->bounds().width(); int y = bottom - panel_win->bounds().height(); - gfx::Rect bounds(x, y, - panel_win->bounds().width(), panel_win->bounds().height()); - SetChildBoundsDirect(panel_win, bounds); + + // Do not relayout dragged panel, but pretend it is in place + if (panel_win != dragged_panel_) { + gfx::Rect bounds(x, y, + panel_win->bounds().width(), + panel_win->bounds().height()); + SetChildBoundsDirect(panel_win, bounds); + } right = x - kPanelMarginMiddle; } } diff --git a/ash/wm/panel_layout_manager.h b/ash/wm/panel_layout_manager.h index a4921d7..90497ea 100644 --- a/ash/wm/panel_layout_manager.h +++ b/ash/wm/panel_layout_manager.h @@ -38,6 +38,9 @@ class ASH_EXPORT PanelLayoutManager : public aura::LayoutManager { explicit PanelLayoutManager(aura::Window* panel_container); virtual ~PanelLayoutManager(); + void StartDragging(aura::Window* panel); + void FinishDragging(); + // Overridden from aura::LayoutManager: virtual void OnWindowResized() OVERRIDE; virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE; @@ -60,6 +63,8 @@ class ASH_EXPORT PanelLayoutManager : public aura::LayoutManager { // Ordered list of unowned pointers to panel windows. PanelList panel_windows_; + aura::Window* dragged_panel_; + DISALLOW_COPY_AND_ASSIGN(PanelLayoutManager); }; diff --git a/ash/wm/panel_window_event_filter.cc b/ash/wm/panel_window_event_filter.cc new file mode 100644 index 0000000..50c5e962 --- /dev/null +++ b/ash/wm/panel_window_event_filter.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2012 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 "ash/wm/panel_window_event_filter.h" + +#include "ash/wm/window_util.h" +#include "base/message_loop.h" +#include "ui/aura/client/aura_constants.h" +#include "ui/aura/cursor.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/aura/window_delegate.h" +#include "ui/base/hit_test.h" +#include "ui/base/ui_base_types.h" +#include "ui/gfx/compositor/scoped_layer_animation_settings.h" +#include "ui/gfx/screen.h" + +namespace ash { +namespace internal { + +PanelWindowEventFilter::PanelWindowEventFilter( + aura::Window* panel_container, + PanelLayoutManager* layout_manager) + : aura::EventFilter(), + panel_container_(panel_container), + layout_manager_(layout_manager), + dragged_panel_(NULL) { +} + +PanelWindowEventFilter::~PanelWindowEventFilter() { +} + +bool PanelWindowEventFilter::PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) { + return false; +} + +bool PanelWindowEventFilter::PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) { + switch (event->type()) { + case ui::ET_MOUSE_PRESSED: { + int hitResult = target->delegate()-> + GetNonClientComponent(event->location()); + if (hitResult == HTCAPTION) { + StartDrag(target, event); + return true; + } else { + return false; + } + } + case ui::ET_MOUSE_DRAGGED: + if (dragged_panel_ != NULL) + return HandleDrag(target, event); + return false; + case ui::ET_MOUSE_RELEASED: + if (dragged_panel_ != NULL) { + CompleteDrag(target, event); + return true; + } + return false; + default: + return false; + } +} + +ui::TouchStatus PanelWindowEventFilter::PreHandleTouchEvent( + aura::Window* target, + aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +ui::GestureStatus PanelWindowEventFilter::PreHandleGestureEvent( + aura::Window* target, aura::GestureEvent* event) { + return ui::GESTURE_STATUS_UNKNOWN; +} + + +void PanelWindowEventFilter::StartDrag(aura::Window* target, + aura::LocatedEvent* event) { + dragged_panel_ = target; + drag_location_in_dragged_window_ = event->location(); + layout_manager_->StartDragging(target); +} + +bool PanelWindowEventFilter::HandleDrag(aura::Window* target, + aura::LocatedEvent* event) { + gfx::Rect target_bounds = dragged_panel_->bounds(); + gfx::Point event_location_in_parent(event->location()); + aura::Window::ConvertPointToWindow(target, + target->parent(), + &event_location_in_parent); + target_bounds.set_x( + event_location_in_parent.x() - drag_location_in_dragged_window_.x()); + dragged_panel_->SetBounds(target_bounds); + return true; + +} + +void PanelWindowEventFilter::CompleteDrag(aura::Window* target, + aura::LocatedEvent* event) { + dragged_panel_ = NULL; + layout_manager_->FinishDragging(); +} + +} +} diff --git a/ash/wm/panel_window_event_filter.h b/ash/wm/panel_window_event_filter.h new file mode 100644 index 0000000..bcbfed2 --- /dev/null +++ b/ash/wm/panel_window_event_filter.h @@ -0,0 +1,57 @@ +// Copyright (c) 2012 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 ASH_WM_PANEL_WINDOW_EVENT_FILTER_H +#define ASH_WM_PANEL_WINDOW_EVENT_FILTER_H +#pragma once + +#include "ui/aura/event_filter.h" +#include "ash/wm/panel_layout_manager.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" + +namespace aura { +class LocatedEvent; +class MouseEvent; +class Window; +} + +namespace ash { +namespace internal { + +class PanelWindowEventFilter : public aura::EventFilter { + public: + PanelWindowEventFilter(aura::Window* panel_container, + PanelLayoutManager* layout_manager); + virtual ~PanelWindowEventFilter(); + + // Overriden from aura::EventFilter: + virtual bool PreHandleKeyEvent(aura::Window* target, + aura::KeyEvent* event) OVERRIDE; + virtual bool PreHandleMouseEvent(aura::Window* target, + aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target, + aura::TouchEvent* event) OVERRIDE; + virtual ui::GestureStatus PreHandleGestureEvent( + aura::Window* target, + aura::GestureEvent* event) OVERRIDE; + + private: + void StartDrag(aura::Window* target, aura::LocatedEvent* event); + bool HandleDrag(aura::Window* target, aura::LocatedEvent* event); + void CompleteDrag(aura::Window* target, aura::LocatedEvent* event); + + aura::Window* panel_container_; + PanelLayoutManager* layout_manager_; + gfx::Point drag_origin_; + gfx::Point drag_location_in_dragged_window_; + bool started_dragging_; + aura::Window* dragged_panel_; + + DISALLOW_COPY_AND_ASSIGN(PanelWindowEventFilter); +}; + +} +} +#endif // ASH_WM_PANEL_EVENT_FILTER_H |