Index: ash/wm/workspace/frame_maximize_button.cc |
diff --git a/ash/wm/workspace/frame_maximize_button.cc b/ash/wm/workspace/frame_maximize_button.cc |
index 213f4d21228762557d251138335c7d1dfec32277..30ca24ab8ec72e47e97497e8b1480ba9add7390d 100644 |
--- a/ash/wm/workspace/frame_maximize_button.cc |
+++ b/ash/wm/workspace/frame_maximize_button.cc |
@@ -8,6 +8,7 @@ |
#include "ash/screen_ash.h" |
#include "ash/shell.h" |
#include "ash/wm/property_util.h" |
+#include "ash/wm/window_maximize.h" |
#include "ash/wm/workspace/phantom_window_controller.h" |
#include "ash/wm/workspace/snap_sizer.h" |
#include "grit/ash_strings.h" |
@@ -105,15 +106,34 @@ FrameMaximizeButton::FrameMaximizeButton(views::ButtonListener* listener, |
frame_(frame), |
is_snap_enabled_(false), |
exceeded_drag_threshold_(false), |
- snap_type_(SNAP_NONE) { |
+ window_moved_listener_installed_for_(NULL), |
+ snap_type_(SNAP_NONE), |
+ maximizer_(NULL) { |
// TODO(sky): nuke this. It's temporary while we don't have good images. |
SetImageAlignment(ALIGN_LEFT, ALIGN_BOTTOM); |
- SetTooltipText(l10n_util::GetStringUTF16(IDS_FRAME_MAXIMIZE_BUTTON_TOOLTIP)); |
} |
FrameMaximizeButton::~FrameMaximizeButton() { |
} |
+void FrameMaximizeButton::OnWindowDestroying(aura::Window* window) { |
+ maximizer_.reset(NULL); |
sky
2012/07/31 16:11:06
.reset()
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ if (window_moved_listener_installed_for_) { |
+ CHECK_EQ(window_moved_listener_installed_for_, window); |
+ window_moved_listener_installed_for_->RemoveObserver(this); |
+ window_moved_listener_installed_for_ = NULL; |
+ } |
+} |
+ |
+void FrameMaximizeButton::OnWindowBoundsChanged( |
sky
2012/07/31 16:11:06
Make order match header.
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ aura::Window* window, |
+ const gfx::Rect& old_bounds, |
+ const gfx::Rect& new_bounds) { |
+ maximizer_.reset(NULL); |
sky
2012/07/31 16:11:06
Cancel() ?
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ // Make sure that all remaining snap hover states get removed. |
+ SnapButtonHovered(SNAP_NONE); |
+} |
+ |
bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) { |
is_snap_enabled_ = event.IsLeftMouseButton(); |
if (is_snap_enabled_) |
@@ -124,10 +144,30 @@ bool FrameMaximizeButton::OnMousePressed(const views::MouseEvent& event) { |
void FrameMaximizeButton::OnMouseEntered(const views::MouseEvent& event) { |
ImageButton::OnMouseEntered(event); |
+ if (!maximizer_.get()) { |
+ if (!window_moved_listener_installed_for_ && parent() && |
sky
2012/07/31 16:11:06
No need to check parent() here, you can invoke Get
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Hmmm.. But I *want* to add the observer on the par
|
+ parent()->GetWidget()) { |
+ window_moved_listener_installed_for_ = |
+ parent()->GetWidget()->GetNativeWindow(); |
+ window_moved_listener_installed_for_->AddObserver(this); |
sky
2012/07/31 16:11:06
You need to remove the observer at the right point
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Please correct me if I am wrong - but isn't the "F
|
+ } |
+ maximizer_.reset(new MaximizeBubble(this, |
+ frame_->GetWidget()->IsMaximized())); |
+ } |
} |
void FrameMaximizeButton::OnMouseExited(const views::MouseEvent& 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_->GetMenuWindow()) { |
+ gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); |
+ if (!maximizer_->GetMenuWindow()->bounds().Contains(screen_location)) { |
+ maximizer_.reset(NULL); |
+ // Make sure that all remaining snap hover states get removed. |
+ SnapButtonHovered(SNAP_NONE); |
+ } |
+ } |
} |
bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { |
@@ -139,11 +179,17 @@ bool FrameMaximizeButton::OnMouseDragged(const views::MouseEvent& event) { |
void FrameMaximizeButton::OnMouseReleased(const views::MouseEvent& event) { |
if (!ProcessEndEvent(event)) |
ImageButton::OnMouseReleased(event); |
+ maximizer_.reset(NULL); |
} |
void FrameMaximizeButton::OnMouseCaptureLost() { |
Cancel(); |
ImageButton::OnMouseCaptureLost(); |
+ if (!is_snap_enabled_) { |
sky
2012/07/31 16:11:06
All of this should be moved to Cancel().
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ maximizer_.reset(NULL); |
+ // Make sure that all remaining snap hover states get removed. |
+ SnapButtonHovered(SNAP_NONE); |
sky
2012/07/31 16:11:06
spacing is off.
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ } |
} |
ui::GestureStatus FrameMaximizeButton::OnGestureEvent( |
@@ -184,44 +230,16 @@ 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(); |
- } |
- } |
+ // TODO(SKUHNE): Remove old bitmaps as soon as the final artwork comes in: |
+ // IDR_AURA_WINDOW_MAXIMIZED_SNAP_LEFT_P |
+ // IDR_AURA_WINDOW_MAXIMIZED_SNAP_RIGHT_P |
+ // IDR_AURA_WINDOW_MAXIMIZED_SNAP_MINIMIZE_P |
+ // IDR_AURA_WINDOW_SNAP_LEFT_P |
+ // IDR_AURA_WINDOW_SNAP_RIGHT_P |
+ // IDR_AURA_WINDOW_SNAP_MINIMIZE_P |
+ id = IDR_AURA_WINDOW_MAXIMIZED_SNAP_P; |
+ } else |
+ id = IDR_AURA_WINDOW_SNAP_P; |
return *ResourceBundle::GetSharedInstance().GetImageNamed(id).ToImageSkia(); |
} |
// Hot and pressed states handled by regular ImageButton. |
@@ -230,6 +248,14 @@ gfx::ImageSkia FrameMaximizeButton::GetImageToPaint() { |
void FrameMaximizeButton::ProcessStartEvent(const views::LocatedEvent& event) { |
DCHECK(is_snap_enabled_); |
+ // Prepare the help / helo menu. |
sky
2012/07/31 16:11:06
halo?
Mr4D (OOO till 08-26)
2012/08/01 20:48:22
Done.
|
+ if (!maximizer_.get()) { |
+ maximizer_.reset(new MaximizeBubble(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); |
InstallEventFilter(); |
snap_type_ = SNAP_NONE; |
@@ -252,6 +278,14 @@ void FrameMaximizeButton::ProcessUpdateEvent(const views::LocatedEvent& event) { |
} |
if (exceeded_drag_threshold_) |
UpdateSnap(event.location()); |
+ |
+ // Update the halo menu. |
+ if (maximizer_.get() && maximizer_->IsRadialMenu()) { |
+ gfx::Point pt = event.location(); |
+ views::View::ConvertPointToScreen(this, &pt); |
+ FrameMaximizeButton::SnapType type; |
+ maximizer_->SnapTypeForLocation(pt, type); |
+ } |
} |
bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) { |
@@ -260,6 +294,11 @@ bool FrameMaximizeButton::ProcessEndEvent(const views::LocatedEvent& event) { |
bool should_snap = is_snap_enabled_; |
is_snap_enabled_ = false; |
+ // Remove our help / halo menu if the mouse cursor is not still over it. |
+ gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint(); |
+ if (!GetBoundsInScreen().Contains(screen_location)) |
+ maximizer_.reset(); |
+ |
if (!should_snap || snap_type_ == SNAP_NONE) |
return false; |
@@ -277,6 +316,7 @@ void FrameMaximizeButton::Cancel() { |
is_snap_enabled_ = false; |
phantom_window_.reset(); |
snap_sizer_.reset(); |
+ snap_type_ = SNAP_NONE; |
update_timer_.Stop(); |
SchedulePaint(); |
} |
@@ -300,6 +340,42 @@ void FrameMaximizeButton::UpdateSnapFromEventLocation() { |
UpdateSnap(press_location_); |
} |
+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: |
+ snap_type_ = type; |
+ snap_sizer_.reset(); |
+ SchedulePaint(); |
+ phantom_window_.reset(); |
+ return; |
+ default: |
+ // We should not come here. |
+ DCHECK(false); |
+ return; |
+ } |
+ UpdateSnap(location); |
+} |
+ |
void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) { |
SnapType type = SnapTypeForLocation(location); |
if (type == snap_type_) { |
@@ -333,11 +409,26 @@ void FrameMaximizeButton::UpdateSnap(const gfx::Point& location) { |
phantom_window_.reset(new internal::PhantomWindowController( |
frame_->GetWidget()->GetNativeWindow())); |
} |
+ if (maximizer_.get()) |
+ phantom_window_->set_phantom_below_window(maximizer_->GetMenuWindow()); |
+ |
phantom_window_->Show(ScreenBoundsForType(snap_type_)); |
+ |
+ if (maximizer_.get()) |
+ maximizer_->SetMenuState(snap_type_); |
} |
FrameMaximizeButton::SnapType FrameMaximizeButton::SnapTypeForLocation( |
const gfx::Point& location) const { |
+ if (maximizer_.get() && maximizer_->IsRadialMenu()) { |
+ FrameMaximizeButton::SnapType code; |
+ gfx::Point pt = location; |
+ views::View::ConvertPointToScreen(this, &pt); |
+ maximizer_->SnapTypeForLocation(pt, code); |
+ if (code != SNAP_NONE) |
+ return code; |
+ return !frame_->GetWidget()->IsMaximized() ? SNAP_MAXIMIZE : SNAP_RESTORE; |
+ } |
int delta_x = location.x() - press_location_.x(); |
int delta_y = location.y() - press_location_.y(); |
if (!views::View::ExceededDragThreshold(delta_x, delta_y)) |
@@ -392,6 +483,17 @@ gfx::Point FrameMaximizeButton::LocationForSnapSizer( |
return result; |
} |
+void FrameMaximizeButton::ExecuteSnapAndCloseMenu(SnapType snap_type) { |
+ 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 (due to the resize operation). If not, it'll get now closed. |
+ if (maximizer_.get()) |
+ maximizer_.reset(); |
+} |
+ |
void FrameMaximizeButton::Snap() { |
switch (snap_type_) { |
case SNAP_LEFT: |
@@ -418,4 +520,9 @@ void FrameMaximizeButton::Snap() { |
} |
} |
+void FrameMaximizeButton::DestroyMaximizeMenu() { |
+ if (maximizer_.get()) |
+ maximizer_.reset(NULL); |
+ } |
+ |
} // namespace ash |