Commit 9f9bb414 authored by skuhne@chromium.org's avatar skuhne@chromium.org

Adding new maximize menu according to specification.


BUG=132686
TEST=Visually tested


Review URL: https://chromiumcodereview.appspot.com/10823025

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150012 0039d316-1c4b-4281-b951-d872f2087c98
parent 79a3233a
...@@ -252,6 +252,8 @@ ...@@ -252,6 +252,8 @@
'wm/frame_painter.h', 'wm/frame_painter.h',
'wm/image_grid.cc', 'wm/image_grid.cc',
'wm/image_grid.h', 'wm/image_grid.h',
'wm/maximize_bubble_controller.cc',
'wm/maximize_bubble_controller.h',
'wm/overlay_event_filter.cc', 'wm/overlay_event_filter.cc',
'wm/overlay_event_filter.h', 'wm/overlay_event_filter.h',
'wm/panel_frame_view.cc', 'wm/panel_frame_view.cc',
...@@ -333,6 +335,7 @@ ...@@ -333,6 +335,7 @@
'wm/workspace/phantom_window_controller.h', 'wm/workspace/phantom_window_controller.h',
'wm/workspace/snap_sizer.cc', 'wm/workspace/snap_sizer.cc',
'wm/workspace/snap_sizer.h', 'wm/workspace/snap_sizer.h',
'wm/workspace/snap_types.h',
'wm/workspace/workspace.cc', 'wm/workspace/workspace.cc',
'wm/workspace/workspace.h', 'wm/workspace/workspace.h',
'wm/workspace/workspace_event_filter.cc', 'wm/workspace/workspace_event_filter.cc',
......
...@@ -196,10 +196,6 @@ This file contains the strings for ash. ...@@ -196,10 +196,6 @@ This file contains the strings for ash.
Set wallpaper... Set wallpaper...
</message> </message>
<message name="IDS_FRAME_MAXIMIZE_BUTTON_TOOLTIP" desc="Tooltip for the maximize/restore button in window frames in aura">
Pull down to minimize, left or right to tile
</message>
<message name="IDS_ASH_KEYBOARD_OVERLAY_TITLE" desc="The title of the keyboard overlay."> <message name="IDS_ASH_KEYBOARD_OVERLAY_TITLE" desc="The title of the keyboard overlay.">
Keyboard Overlay Keyboard Overlay
</message> </message>
...@@ -441,6 +437,21 @@ Press Search key to cancel. ...@@ -441,6 +437,21 @@ Press Search key to cancel.
<message name="IDS_ASH_WEB_NOTFICATION_TRAY_CLEAR_ALL" desc="The button for clearing all notifications."> <message name="IDS_ASH_WEB_NOTFICATION_TRAY_CLEAR_ALL" desc="The button for clearing all notifications.">
Clear All Clear All
</message> </message>
<message name="IDS_ASH_MAXIMIZE_WINDOW" desc="A help text to show that when the button gets clicked the window get maximized.">
Maximize
</message>
<message name="IDS_ASH_SNAP_WINDOW_RIGHT" desc="A help text to show that when the button gets clicked the window get snapped to the right side.">
Snap to right side
</message>
<message name="IDS_ASH_SNAP_WINDOW_LEFT" desc="A help text to show that when the button gets clicked the window get snapped to the left side.">
Snap to left side
</message>
<message name="IDS_ASH_RESTORE_WINDOW" desc="A help text to show that when the button gets clicked the window gets restored to its normal - non maximized - state.">
Restore
</message>
<message name="IDS_ASH_MINIMIZE_WINDOW" desc="A help text to show that when the button gets clicked the window gets minimized.">
Minimize
</message>
</messages> </messages>
</release> </release>
</grit> </grit>
......
...@@ -466,25 +466,19 @@ void FramePainter::LayoutHeader(views::NonClientFrameView* view, ...@@ -466,25 +466,19 @@ void FramePainter::LayoutHeader(views::NonClientFrameView* view,
IDR_AURA_WINDOW_MAXIMIZED_CLOSE, IDR_AURA_WINDOW_MAXIMIZED_CLOSE,
IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H, IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H,
IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P); IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P);
if (size_button_behavior_ == SIZE_BUTTON_MINIMIZES) { // The chat window cannot be restored but only minimized.
SetButtonImages(size_button_, // Case: (size_button_behavior_ == SIZE_BUTTON_MINIMIZES). We used to have
IDR_AURA_WINDOW_MAXIMIZED_MINIMIZE, // a special set of artwork to show this case, but per discussion we
IDR_AURA_WINDOW_MAXIMIZED_MINIMIZE_H, // removed this.
IDR_AURA_WINDOW_MAXIMIZED_MINIMIZE_P); SetButtonImages(size_button_,
} else { IDR_AURA_WINDOW_MAXIMIZED_RESTORE,
SetButtonImages(size_button_, IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H,
IDR_AURA_WINDOW_MAXIMIZED_RESTORE, IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P);
IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H,
IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P);
}
} else { } else {
SetButtonImages(close_button_, SetButtonImages(close_button_,
IDR_AURA_WINDOW_CLOSE, IDR_AURA_WINDOW_CLOSE,
IDR_AURA_WINDOW_CLOSE_H, IDR_AURA_WINDOW_CLOSE_H,
IDR_AURA_WINDOW_CLOSE_P); IDR_AURA_WINDOW_CLOSE_P);
// TODO(jamescook): If we ever have normal-layout windows (with the
// standard 35 pixel tall headers) that can only minimize, we'll need art
// assets for SIZE_BUTTON_MINIMIZES. As of R19 we don't use them.
SetButtonImages(size_button_, SetButtonImages(size_button_,
IDR_AURA_WINDOW_MAXIMIZE, IDR_AURA_WINDOW_MAXIMIZE,
IDR_AURA_WINDOW_MAXIMIZE_H, IDR_AURA_WINDOW_MAXIMIZE_H,
......
This diff is collapsed.
// 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_MAXIMIZE_BUBBLE_CONTROLLER_H_
#define ASH_WM_MAXIMIZE_BUBBLE_CONTROLLER_H_
#include "ash/ash_export.h"
#include "ash/wm/workspace/snap_types.h"
#include "base/memory/scoped_ptr.h"
namespace base {
class Timer;
}
namespace aura {
class Window;
}
namespace ash {
class FrameMaximizeButton;
// A class which shows a helper UI for the maximize button after a delay.
class ASH_EXPORT MaximizeBubbleController {
public:
class Bubble;
MaximizeBubbleController(FrameMaximizeButton* frame_maximize_button,
bool is_maximized);
// Called from the outside to destroy the interface to the UI visuals.
// The visuals will then delete when possible (maybe asynchronously).
virtual ~MaximizeBubbleController();
// Update the UI visuals to reflect the previewed |snap_type| snapping state.
void SetSnapType(SnapType snap_type);
// To achieve proper Z-sorting with the snap animation, this window will be
// presented above the phantom window.
aura::Window* GetBubbleWindow();
// Reset the delay of the menu creation (if it was not created yet).
void DelayCreation();
// Called to tell the owning FrameMaximizeButton that a button was clicked.
void OnButtonClicked(SnapType snap_type);
// Called to tell the the owning FrameMaximizeButton that the hover status
// for a button has changed. |snap_type| can be either SNAP_LEFT, SNAP_RIGHT,
// SNAP_MINIMIZE or SNAP_NONE.
void OnButtonHover(SnapType snap_type);
// Get the owning FrameMaximizeButton.
FrameMaximizeButton* frame_maximize_button() {
return frame_maximize_button_;
}
// The status of the associated window: Maximized or normal.
bool is_maximized() const { return is_maximized_; }
protected:
// Called from the the Bubble class to destroy itself: It tells the owning
// object that it will destroy itself asynchronously. The owner will then
// destroy |this|.
void RequestDestructionThroughOwner();
private:
// The function which creates the bubble once the delay is elapsed.
void CreateBubble();
// The owning button which is also the anchor for the menu.
FrameMaximizeButton* frame_maximize_button_;
// The bubble menu.
Bubble* bubble_;
// If true the owning window is maximized.
const bool is_maximized_;
// The timer for the delayed creation of the menu.
scoped_ptr<base::Timer> timer_;
DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleController);
};
} // namespace ash
#endif // ASH_WM_MAXIMIZE_BUBBLE_CONTROLLER_H_
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ash/screen_ash.h" #include "ash/screen_ash.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/property_util.h" #include "ash/wm/property_util.h"
#include "ash/wm/maximize_bubble_controller.h"
#include "ash/wm/workspace/phantom_window_controller.h" #include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/wm/workspace/snap_sizer.h" #include "ash/wm/workspace/snap_sizer.h"
#include "grit/ash_strings.h" #include "grit/ash_strings.h"
...@@ -74,7 +75,7 @@ bool FrameMaximizeButton::EscapeEventFilter::PreHandleKeyEvent( ...@@ -74,7 +75,7 @@ bool FrameMaximizeButton::EscapeEventFilter::PreHandleKeyEvent(
aura::KeyEvent* event) { aura::KeyEvent* event) {
if (event->type() == ui::ET_KEY_PRESSED && if (event->type() == ui::ET_KEY_PRESSED &&
event->key_code() == ui::VKEY_ESCAPE) { event->key_code() == ui::VKEY_ESCAPE) {
button_->Cancel(); button_->Cancel(false);
} }
return false; return false;
} }
...@@ -105,13 +106,78 @@ FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener, ...@@ -105,13 +106,78 @@ FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener,
frame_(frame), frame_(frame),
is_snap_enabled_(false), is_snap_enabled_(false),
exceeded_drag_threshold_(false), exceeded_drag_threshold_(false),
window_(NULL),
snap_type_(SNAP_NONE) { snap_type_(SNAP_NONE) {
// TODO(sky): nuke this. It's temporary while we don't have good images. // TODO(sky): nuke this. It's temporary while we don't have good images.
SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM); SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM);
SetTooltipText(l10n_util::GetStringUTF16(IDS_FRAME_MAXIMIZE_BUTTON_TOOLTIP));
} }
FrameMaximizeButton::~FrameMaximizeButton() { FrameMaximizeButton::~FrameMaximizeButton() {
if (window_)
OnWindowDestroying(window_);
}
void FrameMaximizeButton::SnapButtonHovered(SnapType type) {
// Make sure to only show hover operations when no button is pressed and
// a similar snap operation in progress does not get re-applied.
if (is_snap_enabled_ || (type == snap_type_ && snap_sizer_.get()))
return;
// Prime the mouse location with the center of the (local) button.
press_location_ = gfx::Point(width() / 2, height() / 2);
// Then get an adjusted mouse position to initiate the effect.
gfx::Point location = press_location_;
switch (type) {
case SNAP_LEFT:
location.set_x(location.x() - width());
break;
case SNAP_RIGHT:
location.set_x(location.x() + width());
break;
case SNAP_MINIMIZE:
location.set_y(location.y() + height());
break;
case SNAP_MAXIMIZE:
case SNAP_RESTORE:
break;
case SNAP_NONE:
Cancel(true);
return;
default:
// We should not come here.
NOTREACHED();
}
UpdateSnap(location);
}
void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) {
DCHECK_NE(snap_type_, SNAP_NONE);
snap_type_ = snap_type;
Snap();
// Remove any pending snap previews.
SnapButtonHovered(SNAP_NONE);
// At this point the operation has been performed and the menu should be
// closed - if not, it'll get now closed.
maximizer_.reset();
}
void FrameMaximizeButton::DestroyMaximizeMenu() {
maximizer_.reset();
}
void FrameMaximizeButton::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
Cancel(false);
}
void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) {
maximizer_.reset();
if (window_) {
CHECK_EQ(window_, window);
window_->RemoveObserver(this);
window_ = NULL;
}
} }
bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) { bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) {
...@@ -124,10 +190,31 @@ bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) { ...@@ -124,10 +190,31 @@ bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) {
void FrameMaximizeButton::OnMouseEntered(const views::MouseEvent& event) { void FrameMaximizeButton::OnMouseEntered(const views::MouseEvent& event) {
ImageButton::OnMouseEntered(event); ImageButton::OnMouseEntered(event);
if (!maximizer_.get()) {
DCHECK(GetWidget());
if (!window_) {
window_ = frame_->GetWidget()->GetNativeWindow();
window_->AddObserver(this);
}
maximizer_.reset(new MaximizeBubbleController(
this,
frame_->GetWidget()->IsMaximized()));
}
} }
void FrameMaximizeButton::OnMouseExited(const views::MouseEvent& event) { void FrameMaximizeButton::OnMouseExited(const views::MouseEvent& event) {
ImageButton::OnMouseExited(event); ImageButton::OnMouseExited(event);
// Remove the bubble menu when the button is not pressed and the mouse is not
// within the bubble.
if (!is_snap_enabled_ && maximizer_.get() && maximizer_->GetBubbleWindow()) {
gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint();
if (!maximizer_->GetBubbleWindow()->GetBoundsInScreen().Contains(
screen_location)) {
maximizer_.reset();
// Make sure that all remaining snap hover states get removed.
SnapButtonHovered(SNAP_NONE);
}
}
} }
bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) {
...@@ -137,12 +224,14 @@ bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { ...@@ -137,12 +224,14 @@ bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) {
} }
void FrameMaximizeButton::OnMouseReleased(const views::MouseEvent& event) { void FrameMaximizeButton::OnMouseReleased(const views::MouseEvent& event) {
maximizer_.reset();
if (!ProcessEndEvent(event)) if (!ProcessEndEvent(event))
ImageButton::OnMouseReleased(event); ImageButton::OnMouseReleased(event);
// At this point |this| might be already destroyed.
} }
void FrameMaximizeButton::OnMouseCaptureLost() { void FrameMaximizeButton::OnMouseCaptureLost() {
Cancel(); Cancel(false);
ImageButton::OnMouseCaptureLost(); ImageButton::OnMouseCaptureLost();
} }
...@@ -180,56 +269,17 @@ ui::GestureStatus FrameMaximizeButton::OnGestureEvent( ...@@ -180,56 +269,17 @@ ui::GestureStatus FrameMaximizeButton::OnGestureEvent(
return ImageButton::OnGestureEvent(event); return ImageButton::OnGestureEvent(event);
} }
gfx::ImageSkia FrameMaximizeButton::GetImageToPaint() {
if (is_snap_enabled_) {
int id = 0;
if (frame_->GetWidget()->IsMaximized()) {
switch (snap_type_) {
case SNAP_LEFT:
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_LEFT_P;
break;
case SNAP_RIGHT:
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_RIGHT_P;
break;
case SNAP_MAXIMIZE:
case SNAP_RESTORE:
case SNAP_NONE:
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_P;
break;
case SNAP_MINIMIZE:
id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_MINIMIZE_P;
break;
default:
NOTREACHED();
}
} else {
switch (snap_type_) {
case SNAP_LEFT:
id = IDR_AURA_WINDOW_SNAP_LEFT_P;
break;
case SNAP_RIGHT:
id = IDR_AURA_WINDOW_SNAP_RIGHT_P;
break;
case SNAP_MAXIMIZE:
case SNAP_RESTORE:
case SNAP_NONE:
id = IDR_AURA_WINDOW_SNAP_P;
break;
case SNAP_MINIMIZE:
id = IDR_AURA_WINDOW_SNAP_MINIMIZE_P;
break;
default:
NOTREACHED();
}
}
return *ResourceBundle::GetSharedInstance().GetImageNamed(id).ToImageSkia();
}
// Hot and pressed states handled by regular ImageButton.
return ImageButton::GetImageToPaint();
}
void FrameMaximizeButton::ProcessStartEvent(const views::LocatedEvent& event) { void FrameMaximizeButton::ProcessStartEvent(const views::LocatedEvent& event) {
DCHECK(is_snap_enabled_); DCHECK(is_snap_enabled_);
// Prepare the help menu.
if (!maximizer_.get()) {
maximizer_.reset(new MaximizeBubbleController(
this,
frame_->GetWidget()->IsMaximized()));
} else {
// If the menu did not show up yet, we delay it even a bit more.
maximizer_->DelayCreation();
}
snap_sizer_.reset(NULL); snap_sizer_.reset(NULL);
InstallEventFilter(); InstallEventFilter();
snap_type_ = SNAP_NONE; snap_type_ = SNAP_NONE;
...@@ -260,6 +310,9 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) { ...@@ -260,6 +310,9 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) {
bool should_snap = is_snap_enabled_; bool should_snap = is_snap_enabled_;
is_snap_enabled_ = false; is_snap_enabled_ = false;
// Remove our help bubble.
maximizer_.reset();
if (!should_snap || snap_type_ == SNAP_NONE) if (!should_snap || snap_type_ == SNAP_NONE)
return false; return false;
...@@ -272,11 +325,15 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) { ...@@ -272,11 +325,15 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) {
return true; return true;
} }
void FrameMaximizeButton::Cancel() { void FrameMaximizeButton::Cancel(bool keep_menu_open) {
UninstallEventFilter(); if (!keep_menu_open) {
is_snap_enabled_ = false; maximizer_.reset();
UninstallEventFilter();
is_snap_enabled_ = false;
}
phantom_window_.reset(); phantom_window_.reset();
snap_sizer_.reset(); snap_sizer_.reset();
snap_type_ = SNAP_NONE;
update_timer_.Stop(); update_timer_.Stop();
SchedulePaint(); SchedulePaint();
} }
...@@ -333,10 +390,14 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) { ...@@ -333,10 +390,14 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) {
phantom_window_.reset(new internal::PhantomWindowController( phantom_window_.reset(new internal::PhantomWindowController(
frame_->GetWidget()->GetNativeWindow())); frame_->GetWidget()->GetNativeWindow()));
} }
if (maximizer_.get()) {
phantom_window_->set_phantom_below_window(maximizer_->GetBubbleWindow());
maximizer_->SetSnapType(snap_type_);
}
phantom_window_->Show(ScreenBoundsForType(snap_type_)); phantom_window_->Show(ScreenBoundsForType(snap_type_));
} }
FrameMaximizeButton::SnapType FrameMaximizeButton::SnapTypeForLocation( SnapType FrameMaximizeButton::SnapTypeForLocation(
const gfx::Point& location) const { const gfx::Point& location) const {
int delta_x = location.x() - press_location_.x(); int delta_x = location.x() - press_location_.x();
int delta_y = location.y() - press_location_.y(); int delta_y = location.y() - press_location_.y();
......
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
#define ASH_WM_WORKSPACE_FRAME_MAXIMIZE_BUTTON_H_ #define ASH_WM_WORKSPACE_FRAME_MAXIMIZE_BUTTON_H_
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/wm/workspace/snap_types.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/timer.h" #include "base/timer.h"
#include "ui/aura/window_observer.h"
#include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button.h"
namespace views { namespace views {
...@@ -21,13 +23,36 @@ class PhantomWindowController; ...@@ -21,13 +23,36 @@ class PhantomWindowController;
class SnapSizer; class SnapSizer;
} }
class MaximizeBubbleController;
// Button used for the maximize control on the frame. Handles snapping logic. // Button used for the maximize control on the frame. Handles snapping logic.
class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { class ASH_EXPORT FrameMaximizeButton : public views::ImageButton,
public aura::WindowObserver {
public: public:
FrameMaximizeButton(views::ButtonListener* listener, FrameMaximizeButton(views::ButtonListener* listener,
views::NonClientFrameView* frame); views::NonClientFrameView* frame);
virtual ~FrameMaximizeButton(); virtual ~FrameMaximizeButton();
// Updates |snap_type_| based on a a given snap type. This is used by
// external hover events from the button menu.
void SnapButtonHovered(SnapType type);
// The user clicked the |type| button and the action needs to be performed,
// which will at the same time close the window.
void ExecuteSnapAndCloseMenu(SnapType type);
// Remove the maximize menu from the screen (and destroy it).
void DestroyMaximizeMenu();
// Returns true when the user clicks and drags the button.
bool is_snap_enabled() const { return is_snap_enabled_; }
// WindowObserver overrides:
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE;
virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
// ImageButton overrides: // ImageButton overrides:
virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE; virtual bool OnMousePressed(const views::MouseEvent& event) OVERRIDE;
virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE; virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
...@@ -38,23 +63,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { ...@@ -38,23 +63,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
virtual ui::GestureStatus OnGestureEvent( virtual ui::GestureStatus OnGestureEvent(
const views::GestureEvent& event) OVERRIDE; const views::GestureEvent& event) OVERRIDE;
protected:
// ImageButton overrides:
virtual gfx::ImageSkia GetImageToPaint() OVERRIDE;
private: private:
class EscapeEventFilter; class EscapeEventFilter;
// Where to snap to.
enum SnapType {
SNAP_LEFT,
SNAP_RIGHT,
SNAP_MAXIMIZE,
SNAP_MINIMIZE,
SNAP_RESTORE,
SNAP_NONE
};
// Initializes the snap-gesture based on the event. This should only be called // Initializes the snap-gesture based on the event. This should only be called
// when the event is confirmed to have started a snap gesture. // when the event is confirmed to have started a snap gesture.
void ProcessStartEvent(const views::LocatedEvent& event); void ProcessStartEvent(const views::LocatedEvent& event);
...@@ -66,8 +77,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { ...@@ -66,8 +77,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
// Returns true if the window was snapped. Returns false otherwise. // Returns true if the window was snapped. Returns false otherwise.
bool ProcessEndEvent(const views::LocatedEvent& event); bool ProcessEndEvent(const views::LocatedEvent& event);
// Cancels snap behavior. // Cancels snap behavior. If |keep_menu_open| is set, a possibly opened
void Cancel(); // bubble help will remain open.
void Cancel(bool keep_menu_open);
// Installs/uninstalls an EventFilter to track when escape is pressed. // Installs/uninstalls an EventFilter to track when escape is pressed.
void InstallEventFilter(); void InstallEventFilter();
...@@ -106,6 +118,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { ...@@ -106,6 +118,9 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
// Did the user drag far enough to trigger snapping? // Did the user drag far enough to trigger snapping?
bool exceeded_drag_threshold_; bool exceeded_drag_threshold_;
// This is the Window we are contained in.
aura::Window* window_;
// Location of the press. // Location of the press.
gfx::Point press_location_; gfx::Point press_location_;
...@@ -118,6 +133,8 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton { ...@@ -118,6 +133,8 @@ class ASH_EXPORT FrameMaximizeButton : public views::ImageButton {
base::OneShotTimer<FrameMaximizeButton> update_timer_; base::OneShotTimer<FrameMaximizeButton> update_timer_;
scoped_ptr<MaximizeBubbleController> maximizer_;
DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButton); DISALLOW_COPY_AND_ASSIGN(FrameMaximizeButton);
}; };
......
...@@ -72,7 +72,9 @@ class EdgePainter : public views::Painter { ...@@ -72,7 +72,9 @@ class EdgePainter : public views::Painter {
} // namespace } // namespace
PhantomWindowController::PhantomWindowController(aura::Window* window) PhantomWindowController::PhantomWindowController(aura::Window* window)
: window_(window) { : window_(window),
phantom_below_window_(NULL),
phantom_widget_(NULL) {
} }
PhantomWindowController::~PhantomWindowController() { PhantomWindowController::~PhantomWindowController() {
...@@ -83,7 +85,7 @@ void PhantomWindowController::Show(const gfx::Rect& bounds) { ...@@ -83,7 +85,7 @@ void PhantomWindowController::Show(const gfx::Rect& bounds) {
if (bounds == bounds_) if (bounds == bounds_)
return; return;
bounds_ = bounds; bounds_ = bounds;
if (!phantom_widget_.get()) { if (!phantom_widget_) {
// Show the phantom at the bounds of the window. We'll animate to the target // Show the phantom at the bounds of the window. We'll animate to the target
// bounds. // bounds.
start_bounds_ = window_->GetBoundsInScreen(); start_bounds_ = window_->GetBoundsInScreen();
...@@ -103,11 +105,12 @@ void PhantomWindowController::SetBounds(const gfx::Rect& bounds) { ...@@ -103,11 +105,12 @@ void PhantomWindowController::SetBounds(const gfx::Rect& bounds) {
} }
void PhantomWindowController::Hide() { void PhantomWindowController::Hide() {
phantom_widget_.reset(); phantom_widget_->Close();
phantom_widget_ = NULL;
} }
bool PhantomWindowController::IsShowing() const { bool PhantomWindowController::IsShowing() const {
return phantom_widget_.get() != NULL; return phantom_widget_ != NULL;
} }
void PhantomWindowController::AnimationProgressed( void PhantomWindowController::AnimationProgressed(
...@@ -117,11 +120,10 @@ void PhantomWindowController::AnimationProgressed( ...@@ -117,11 +120,10 @@ void PhantomWindowController::AnimationProgressed(
} }
void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
DCHECK(!phantom_widget_.get()); DCHECK(!phantom_widget_);
phantom_widget_.reset(new views::Widget); phantom_widget_ = new views::Widget;
views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
params.transparent = true; params.transparent = true;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
// PhantomWindowController is used by FrameMaximizeButton to highlight the // PhantomWindowController is used by FrameMaximizeButton to highlight the
// launcher button. Put the phantom in the same window as the launcher so that // launcher button. Put the phantom in the same window as the launcher so that
// the phantom is visible. // the phantom is visible.
...@@ -139,7 +141,10 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) { ...@@ -139,7 +141,10 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
views::Background::CreateBackgroundPainter(true, new EdgePainter)); views::Background::CreateBackgroundPainter(true, new EdgePainter));
phantom_widget_->SetContentsView(content_view); phantom_widget_->SetContentsView(content_view);
phantom_widget_->SetBounds(bounds); phantom_widget_->SetBounds(bounds);
phantom_widget_->StackAbove(window_); if (phantom_below_window_)
phantom_widget_->StackBelow(phantom_below_window_);
else
phantom_widget_->StackAbove(window_);
phantom_widget_->Show(); phantom_widget_->Show();
// Fade the window in. // Fade the window in.
ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer(); ui::Layer* layer = phantom_widget_->GetNativeWindow()->layer();
......
...@@ -50,6 +50,12 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -50,6 +50,12 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
// Returns true if the phantom is showing. // Returns true if the phantom is showing.
bool IsShowing() const; bool IsShowing() const;
// If set, the phantom window is stacked below this window, otherwise it
// is stacked above the window passed to the constructor.
void set_phantom_below_window(aura::Window* phantom_below_window) {
phantom_below_window_ = phantom_below_window;
}
// ui::AnimationDelegate overrides: // ui::AnimationDelegate overrides:
virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
...@@ -60,6 +66,9 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -60,6 +66,9 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
// Window the phantom is placed beneath. // Window the phantom is placed beneath.
aura::Window* window_; aura::Window* window_;
// If set, the phantom window should get stacked below this window.
aura::Window* phantom_below_window_;
// Initially the bounds of |window_|. Each time Show() is invoked // Initially the bounds of |window_|. Each time Show() is invoked
// |start_bounds_| is then reset to the bounds of |phantom_widget_| and // |start_bounds_| is then reset to the bounds of |phantom_widget_| and
// |bounds_| is set to the value passed into Show(). The animation animates // |bounds_| is set to the value passed into Show(). The animation animates
...@@ -67,7 +76,7 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate { ...@@ -67,7 +76,7 @@ class ASH_EXPORT PhantomWindowController : public ui::AnimationDelegate {
gfx::Rect start_bounds_; gfx::Rect start_bounds_;
gfx::Rect bounds_; gfx::Rect bounds_;
scoped_ptr<views::Widget> phantom_widget_; views::Widget* phantom_widget_;
// Used to transition the bounds. // Used to transition the bounds.
scoped_ptr<ui::SlideAnimation> animation_; scoped_ptr<ui::SlideAnimation> animation_;
......
// 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_WORKSPACE_SNAP_TYPES_H_
#define ASH_WM_WORKSPACE_SNAP_TYPES_H_
namespace ash {
// These are the window snap types which can be used for window resizing.
// Their main use case is the class FrameMaximizeButton.
enum SnapType {
SNAP_LEFT,
SNAP_RIGHT,
SNAP_MAXIMIZE,
SNAP_MINIMIZE,
SNAP_RESTORE,
SNAP_NONE
};
} // namespace ash
#endif // ASH_WM_WORKSPACE_SNAP_TYPES_H_
...@@ -69,9 +69,6 @@ class AppNonClientFrameViewAura::ControlView ...@@ -69,9 +69,6 @@ class AppNonClientFrameViewAura::ControlView
IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_ACTIVE : IDR_AURA_WINDOW_HEADER_BASE_INCOGNITO_ACTIVE :
IDR_AURA_WINDOW_HEADER_BASE_ACTIVE; IDR_AURA_WINDOW_HEADER_BASE_ACTIVE;
control_base_ = rb.GetImageNamed(control_base_resource_id).ToImageSkia(); control_base_ = rb.GetImageNamed(control_base_resource_id).ToImageSkia();
separator_ =
rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SEPARATOR).ToImageSkia();
shadow_ = rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SHADOW).ToImageSkia(); shadow_ = rb.GetImageNamed(IDR_AURA_WINDOW_FULLSCREEN_SHADOW).ToImageSkia();
AddChildView(close_button_); AddChildView(close_button_);
...@@ -117,9 +114,6 @@ class AppNonClientFrameViewAura::ControlView ...@@ -117,9 +114,6 @@ class AppNonClientFrameViewAura::ControlView
views::View::OnPaint(canvas); views::View::OnPaint(canvas);
// Separator overlaps the left edge of the close button.
canvas->DrawImageInt(*separator_,
close_button_->x(), 0);
canvas->DrawImageInt(*shadow_, 0, kShadowHeightStretch); canvas->DrawImageInt(*shadow_, 0, kShadowHeightStretch);
} }
...@@ -151,7 +145,6 @@ class AppNonClientFrameViewAura::ControlView ...@@ -151,7 +145,6 @@ class AppNonClientFrameViewAura::ControlView
views::ImageButton* close_button_; views::ImageButton* close_button_;
views::ImageButton* restore_button_; views::ImageButton* restore_button_;
const gfx::ImageSkia* control_base_; const gfx::ImageSkia* control_base_;
const gfx::ImageSkia* separator_;
const gfx::ImageSkia* shadow_; const gfx::ImageSkia* shadow_;
DISALLOW_COPY_AND_ASSIGN(ControlView); DISALLOW_COPY_AND_ASSIGN(ControlView);
......
This diff is collapsed.
...@@ -115,6 +115,7 @@ BubbleDelegateView::BubbleDelegateView() ...@@ -115,6 +115,7 @@ BubbleDelegateView::BubbleDelegateView()
original_opacity_(255), original_opacity_(255),
border_widget_(NULL), border_widget_(NULL),
use_focusless_(false), use_focusless_(false),
try_mirroring_arrow_(true),
parent_window_(NULL) { parent_window_(NULL) {
set_background(Background::CreateSolidBackground(color_)); set_background(Background::CreateSolidBackground(color_));
AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
...@@ -134,6 +135,7 @@ BubbleDelegateView::BubbleDelegateView( ...@@ -134,6 +135,7 @@ BubbleDelegateView::BubbleDelegateView(
original_opacity_(255), original_opacity_(255),
border_widget_(NULL), border_widget_(NULL),
use_focusless_(false), use_focusless_(false),
try_mirroring_arrow_(true),
parent_window_(NULL) { parent_window_(NULL) {
set_background(Background::CreateSolidBackground(color_)); set_background(Background::CreateSolidBackground(color_));
AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
...@@ -336,7 +338,7 @@ gfx::Rect BubbleDelegateView::GetBubbleBounds() { ...@@ -336,7 +338,7 @@ gfx::Rect BubbleDelegateView::GetBubbleBounds() {
// The argument rect has its origin at the bubble's arrow anchor point; // The argument rect has its origin at the bubble's arrow anchor point;
// its size is the preferred size of the bubble's client view (this view). // its size is the preferred size of the bubble's client view (this view).
return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(), return GetBubbleFrameView()->GetUpdatedWindowBounds(GetAnchorRect(),
GetPreferredSize(), true /*try_mirroring_arrow*/); GetPreferredSize(), try_mirroring_arrow_);
} }
#if defined(OS_WIN) && !defined(USE_AURA) #if defined(OS_WIN) && !defined(USE_AURA)
......
...@@ -83,6 +83,11 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView, ...@@ -83,6 +83,11 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
use_focusless_ = use_focusless; use_focusless_ = use_focusless;
} }
bool try_mirroring_arrow() const { return try_mirroring_arrow_; }
void set_try_mirroring_arrow(bool try_mirroring_arrow) {
try_mirroring_arrow_ = try_mirroring_arrow;
}
// Get the arrow's anchor rect in screen space. // Get the arrow's anchor rect in screen space.
virtual gfx::Rect GetAnchorRect(); virtual gfx::Rect GetAnchorRect();
...@@ -173,6 +178,10 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView, ...@@ -173,6 +178,10 @@ class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView,
// These bubbles are not interactive and should not gain focus. // These bubbles are not interactive and should not gain focus.
bool use_focusless_; bool use_focusless_;
// If true (defaults to true), the arrow may be mirrored to fit the
// bubble on screen better.
bool try_mirroring_arrow_;
// Parent native window of the bubble. // Parent native window of the bubble.
gfx::NativeView parent_window_; gfx::NativeView parent_window_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment