Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: ash/wm/maximize_bubble_controller.cc

Issue 10823025: Adding new maximize menu according to spec (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: git try Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/wm/maximize_bubble_controller.h ('k') | ash/wm/workspace/frame_maximize_button.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/maximize_bubble_controller.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h"
9 #include "ash/wm/window_animations.h"
10 #include "ash/wm/workspace/frame_maximize_button.h"
11 #include "base/timer.h"
12 #include "grit/ash_strings.h"
13 #include "grit/ui_resources.h"
14 #include "ui/aura/event.h"
15 #include "ui/aura/focus_manager.h"
16 #include "ui/aura/window.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/screen.h"
21 #include "ui/views/bubble/bubble_delegate.h"
22 #include "ui/views/bubble/bubble_frame_view.h"
23 #include "ui/views/controls/button/button.h"
24 #include "ui/views/controls/button/image_button.h"
25 #include "ui/views/controls/label.h"
26 #include "ui/views/events/event.h"
27 #include "ui/views/layout/box_layout.h"
28 #include "ui/views/mouse_watcher.h"
29 #include "ui/views/widget/widget.h"
30
31 namespace {
32
33 // The spacing between two buttons.
34 const int kLayoutSpacing = -1;
35
36 // The background color.
37 const SkColor kBubbleBackgroundColor = 0xc8141414;
38
39 // The text color within the bubble.
40 const SkColor kBubbleTextColor = SK_ColorWHITE;
41
42 // The line width of the bubble.
43 const int kLineWidth = 1;
44
45 // The pixel dimensions of the arrow.
46 const int kArrowHeight = 10;
47 const int kArrowWidth = 20;
48
49 // The delay of the bubble appearance.
50 const int kBubbleAppearanceDelayMS = 200;
51 const int kAnimationDurationForPopupMS = 200;
52
53 class MaximizeBubbleBorder : public views::BubbleBorder {
54 public:
55 MaximizeBubbleBorder(views::View* content_view, views::View* anchor);
56
57 virtual ~MaximizeBubbleBorder() {}
58
59 // Overridden from views::BubbleBorder to match the design specs.
60 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
61 const gfx::Size& contents_size) const OVERRIDE;
62
63 // Overridden from views::Border.
64 virtual void Paint(const views::View& view,
65 gfx::Canvas* canvas) const OVERRIDE;
66 private:
67 views::View* anchor_;
68 views::View* content_view_;
69
70 DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleBorder);
71 };
72
73 MaximizeBubbleBorder::MaximizeBubbleBorder(views::View* content_view,
74 views::View* anchor)
75 : views::BubbleBorder(views::BubbleBorder::TOP_RIGHT,
76 views::BubbleBorder::NO_SHADOW),
77 anchor_(anchor),
78 content_view_(content_view) {
79 set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
80 }
81
82 gfx::Rect MaximizeBubbleBorder::GetBounds(
83 const gfx::Rect& position_relative_to,
84 const gfx::Size& contents_size) const {
85 gfx::Size border_size(contents_size);
86 gfx::Insets insets;
87 GetInsets(&insets);
88 border_size.Enlarge(insets.width(), insets.height());
89
90 // Position the bubble to center the box on the anchor.
91 int x = (-border_size.width() + anchor_->width()) / 2;
92 // Position the bubble under the anchor, overlapping the arrow with it.
93 int y = anchor_->height() - insets.top();
94
95 gfx::Point view_origin(x, y);
96 views::View::ConvertPointToScreen(anchor_, &view_origin);
97
98 return gfx::Rect(view_origin, border_size);
99 }
100
101 void MaximizeBubbleBorder::Paint(const views::View& view,
102 gfx::Canvas* canvas) const {
103 gfx::Insets inset;
104 GetInsets(&inset);
105
106 // Draw the border line around everything.
107 int y = inset.top();
108 // Top
109 canvas->FillRect(gfx::Rect(inset.left(),
110 y - kLineWidth,
111 content_view_->width(),
112 kLineWidth),
113 kBubbleBackgroundColor);
114 // Bottom
115 canvas->FillRect(gfx::Rect(inset.left(),
116 y + content_view_->height(),
117 content_view_->width(),
118 kLineWidth),
119 kBubbleBackgroundColor);
120 // Left
121 canvas->FillRect(gfx::Rect(inset.left() - kLineWidth,
122 y - kLineWidth,
123 kLineWidth,
124 content_view_->height() + 2 * kLineWidth),
125 kBubbleBackgroundColor);
126 // Right
127 canvas->FillRect(gfx::Rect(inset.left() + content_view_->width(),
128 y - kLineWidth,
129 kLineWidth,
130 content_view_->height() + 2 * kLineWidth),
131 kBubbleBackgroundColor);
132
133 // Draw the arrow afterwards covering the border.
134 SkPath path;
135 path.incReserve(4);
136 // The center of the tip should be in the middle of the button.
137 int tip_x = inset.left() + content_view_->width() / 2;
138 int left_base_x = tip_x - kArrowWidth / 2;
139 int left_base_y = y;
140 int tip_y = left_base_y - kArrowHeight;
141 path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
142 path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
143 path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
144 SkIntToScalar(left_base_y));
145
146 SkPaint paint;
147 paint.setStyle(SkPaint::kFill_Style);
148 paint.setColor(kBubbleBackgroundColor);
149 canvas->DrawPath(path, paint);
150 }
151
152 } // namespace
153
154 namespace ash {
155
156 class BubbleContentsButtonRow;
157 class BubbleContentsView;
158 class BubbleDialogButton;
159
160 // The mouse watcher host which makes sure that the bubble does not get closed
161 // while the mouse cursor is over the maximize button or the balloon content.
162 // Note: This object gets destroyed when the MouseWatcher gets destroyed.
163 class BubbleMouseWatcherHost: public views::MouseWatcherHost {
164 public:
165 explicit BubbleMouseWatcherHost(MaximizeBubbleController::Bubble* bubble)
166 : bubble_(bubble) {}
167 virtual ~BubbleMouseWatcherHost() {}
168
169 // Implementation of MouseWatcherHost.
170 virtual bool Contains(const gfx::Point& screen_point,
171 views::MouseWatcherHost::MouseEventType type);
172 private:
173 MaximizeBubbleController::Bubble* bubble_;
174
175 DISALLOW_COPY_AND_ASSIGN(BubbleMouseWatcherHost);
176 };
177
178 // The class which creates and manages the bubble menu element.
179 // It creates a 'bubble border' and the content accordingly.
180 // Note: Since the SnapSizer will show animations on top of the maximize button
181 // this menu gets created as a separate window and the SnapSizer will be
182 // created underneath this window.
183 class MaximizeBubbleController::Bubble : public views::BubbleDelegateView,
184 public views::MouseWatcherListener {
185 public:
186 explicit Bubble(MaximizeBubbleController* owner);
187 virtual ~Bubble() {}
188
189 // The window of the menu under which the SnapSizer will get created.
190 aura::Window* GetBubbleWindow();
191
192 // Overridden from views::BubbleDelegateView.
193 virtual gfx::Rect GetAnchorRect() OVERRIDE;
194
195 // Implementation of MouseWatcherListener.
196 virtual void MouseMovedOutOfHost();
197
198 // Implementation of MouseWatcherHost.
199 virtual bool Contains(const gfx::Point& screen_point,
200 views::MouseWatcherHost::MouseEventType type);
201
202 // Overridden from views::View.
203 virtual gfx::Size GetPreferredSize() OVERRIDE;
204
205 // Overridden from views::Widget::Observer.
206 virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
207
208 // Called from the controller class to indicate that the menu should get
209 // destroyed.
210 virtual void ControllerRequestsCloseAndDelete();
211
212 // Called from the owning class to change the menu content to the given
213 // |snap_type| so that the user knows what is selected.
214 void SetSnapType(SnapType snap_type);
215
216 // Get the owning MaximizeBubbleController. This might return NULL in case
217 // of an asynchronous shutdown.
218 MaximizeBubbleController* controller() const { return owner_; }
219
220 private:
221 // True if the shut down has been initiated.
222 bool shutting_down_;
223
224 // Our owning class.
225 MaximizeBubbleController* owner_;
226
227 // The widget which contains our menu and the bubble border.
228 views::Widget* bubble_widget_;
229
230 // The content accessor of the menu.
231 BubbleContentsView* contents_view_;
232
233 // The mouse watcher which takes care of out of window hover events.
234 scoped_ptr<views::MouseWatcher> mouse_watcher_;
235
236 DISALLOW_COPY_AND_ASSIGN(Bubble);
237 };
238
239 // A class that creates all buttons and put them into a view.
240 class BubbleContentsButtonRow : public views::View,
241 public views::ButtonListener {
242 public:
243 explicit BubbleContentsButtonRow(MaximizeBubbleController::Bubble* bubble);
244
245 virtual ~BubbleContentsButtonRow() {}
246
247 // Overridden from ButtonListener.
248 virtual void ButtonPressed(views::Button* sender,
249 const views::Event& event) OVERRIDE;
250 // Called from BubbleDialogButton.
251 void ButtonHovered(BubbleDialogButton* sender);
252
253 private:
254 // The owning object which gets notifications.
255 MaximizeBubbleController::Bubble* bubble_;
256
257 // The created buttons for our menu.
258 BubbleDialogButton* left_button_;
259 BubbleDialogButton* minimize_button_;
260 BubbleDialogButton* right_button_;
261
262 DISALLOW_COPY_AND_ASSIGN(BubbleContentsButtonRow);
263 };
264
265 // A class which creates the content of the bubble: The buttons, and the label.
266 class BubbleContentsView : public views::View {
267 public:
268 explicit BubbleContentsView(MaximizeBubbleController::Bubble* bubble);
269
270 virtual ~BubbleContentsView() {}
271
272 // Set the label content to reflect the currently selected |snap_type|.
273 // This function can be executed through the frame maximize button as well as
274 // through hover operations.
275 void SetSnapType(SnapType snap_type);
276
277 private:
278 // The owning class.
279 MaximizeBubbleController::Bubble* bubble_;
280
281 // The object which owns all the buttons.
282 BubbleContentsButtonRow* buttons_view_;
283
284 // The label object which shows the user the selected action.
285 views::Label* label_view_;
286
287 DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
288 };
289
290 // The image button gets overridden to be able to capture mouse hover events.
291 // The constructor also assigns all button states and
292 class BubbleDialogButton : public views::ImageButton {
293 public:
294 explicit BubbleDialogButton(
295 BubbleContentsButtonRow* button_row_listener,
296 int normal_image,
297 int hovered_image,
298 int pressed_image);
299 virtual ~BubbleDialogButton() {}
300
301 // CustomButton overrides:
302 virtual void OnMouseCaptureLost() OVERRIDE;
303 virtual void OnMouseEntered(const views::MouseEvent& event) OVERRIDE;
304 virtual void OnMouseExited(const views::MouseEvent& event) OVERRIDE;
305
306 private:
307 // The creating class which needs to get notified in case of a hover event.
308 BubbleContentsButtonRow* button_row_;
309
310 DISALLOW_COPY_AND_ASSIGN(BubbleDialogButton);
311 };
312
313 MaximizeBubbleController::Bubble::Bubble(MaximizeBubbleController* owner)
314 : views::BubbleDelegateView(owner->frame_maximize_button(),
315 views::BubbleBorder::TOP_RIGHT),
316 shutting_down_(false),
317 owner_(owner),
318 bubble_widget_(NULL),
319 contents_view_(NULL) {
320 set_margins(gfx::Insets());
321
322 // The window needs to be owned by the root so that the SnapSizer does not
323 // cover it upon animation.
324 aura::Window* parent = Shell::GetContainer(
325 Shell::GetActiveRootWindow(),
326 internal::kShellWindowId_LauncherContainer);
327 set_parent_window(parent);
328
329 set_notify_enter_exit_on_child(true);
330 set_try_mirroring_arrow(false);
331 SetPaintToLayer(true);
332 SetFillsBoundsOpaquely(false);
333 set_color(kBubbleBackgroundColor);
334 set_close_on_deactivate(false);
335 set_background(
336 views::Background::CreateSolidBackground(kBubbleBackgroundColor));
337
338 SetLayoutManager(new views::BoxLayout(
339 views::BoxLayout::kVertical, 0, 0, kLayoutSpacing));
340
341 contents_view_ = new BubbleContentsView(this);
342 AddChildView(contents_view_);
343
344 // Note that the returned widget has an observer which points to our
345 // functions.
346 bubble_widget_ = views::BubbleDelegateView::CreateBubble(this);
347
348 SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
349 bubble_widget_->non_client_view()->frame_view()->set_background(NULL);
350
351 MaximizeBubbleBorder* bubble_border = new MaximizeBubbleBorder(
352 this,
353 anchor_view());
354 GetBubbleFrameView()->SetBubbleBorder(bubble_border);
355 GetBubbleFrameView()->set_background(NULL);
356
357 // Recalculate size with new border.
358 SizeToContents();
359
360 // Setup animation.
361 ash::SetWindowVisibilityAnimationType(
362 bubble_widget_->GetNativeWindow(),
363 ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
364 ash::SetWindowVisibilityAnimationTransition(
365 bubble_widget_->GetNativeWindow(),
366 ash::ANIMATE_BOTH);
367 ash::SetWindowVisibilityAnimationDuration(
368 bubble_widget_->GetNativeWindow(),
369 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
370
371 Show();
372 // We don't want to lose the focus on our parent window because the button
373 // would otherwise lose the highlight when the "helper bubble" is shown.
374 views::Widget* widget =
375 owner_->frame_maximize_button()->parent()->GetWidget();
376 if (widget) {
377 aura::Window* parent_window = widget->GetNativeWindow();
378 parent_window->GetFocusManager()->SetFocusedWindow(parent_window, NULL);
379 }
380 mouse_watcher_.reset(new views::MouseWatcher(
381 new BubbleMouseWatcherHost(this),
382 this));
383 mouse_watcher_->Start();
384 }
385
386 bool BubbleMouseWatcherHost::Contains(
387 const gfx::Point& screen_point,
388 views::MouseWatcherHost::MouseEventType type) {
389 return bubble_->Contains(screen_point, type);
390 }
391
392 aura::Window* MaximizeBubbleController::Bubble::GetBubbleWindow() {
393 return bubble_widget_ ? bubble_widget_->GetNativeWindow() : NULL;
394 }
395
396 gfx::Rect MaximizeBubbleController::Bubble::GetAnchorRect() {
397 if (!owner_)
398 return gfx::Rect();
399
400 gfx::Rect anchor_rect =
401 owner_->frame_maximize_button()->GetBoundsInScreen();
402 return anchor_rect;
403 }
404
405 void MaximizeBubbleController::Bubble::MouseMovedOutOfHost() {
406 if (!owner_ || shutting_down_)
407 return;
408 // When we leave the bubble, we might be still be in gesture mode or over
409 // the maximize button. So only close if none of the other cases apply.
410 if (!owner_->frame_maximize_button()->is_snap_enabled()) {
411 gfx::Point screen_location = gfx::Screen::GetCursorScreenPoint();
412 if (!owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
413 screen_location)) {
414 owner_->RequestDestructionThroughOwner();
415 }
416 }
417 }
418
419 bool MaximizeBubbleController::Bubble::Contains(
420 const gfx::Point& screen_point,
421 views::MouseWatcherHost::MouseEventType type) {
422 if (!owner_ || shutting_down_)
423 return false;
424 // Check if either a gesture is taking place (=> bubble stays no matter what
425 // the mouse does) or the mouse is over the maximize button or the bubble
426 // content.
427 return (owner_->frame_maximize_button()->is_snap_enabled() ||
428 owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
429 screen_point) ||
430 contents_view_->GetBoundsInScreen().Contains(screen_point));
431 }
432
433 gfx::Size MaximizeBubbleController::Bubble::GetPreferredSize() {
434 return contents_view_->GetPreferredSize();
435 }
436
437 void MaximizeBubbleController::Bubble::OnWidgetClosing(views::Widget* widget) {
438 if (bubble_widget_ != widget)
439 return;
440
441 mouse_watcher_->Stop();
442
443 if (owner_) {
444 // If the bubble destruction was triggered by some other external influence
445 // then ourselves, the owner needs to be informed that the menu is gone.
446 shutting_down_ = true;
447 owner_->RequestDestructionThroughOwner();
448 owner_ = NULL;
449 }
450 // Remove any existing observers.
451 bubble_widget_->RemoveObserver(this);
452 anchor_widget()->RemoveObserver(this);
453 }
454
455 void MaximizeBubbleController::Bubble::ControllerRequestsCloseAndDelete() {
456 // This only gets called from the owning base class once it is deleted.
457 if (shutting_down_)
458 return;
459 shutting_down_ = true;
460 owner_ = NULL;
461
462 // Close the widget asynchronously.
463 bubble_widget_->Close();
464 }
465
466 void MaximizeBubbleController::Bubble::SetSnapType(SnapType snap_type) {
467 if (contents_view_)
468 contents_view_->SetSnapType(snap_type);
469 }
470
471 BubbleContentsButtonRow::BubbleContentsButtonRow(
472 MaximizeBubbleController::Bubble* bubble)
473 : bubble_(bubble),
474 left_button_(NULL),
475 minimize_button_(NULL),
476 right_button_(NULL) {
477 SetLayoutManager(new views::BoxLayout(
478 views::BoxLayout::kHorizontal, 0, 0, kLayoutSpacing));
479 set_background(
480 views::Background::CreateSolidBackground(kBubbleBackgroundColor));
481
482 left_button_ = new BubbleDialogButton(
483 this,
484 IDR_AURA_WINDOW_POSITION_LEFT,
485 IDR_AURA_WINDOW_POSITION_LEFT_H,
486 IDR_AURA_WINDOW_POSITION_LEFT_P);
487 minimize_button_ = new BubbleDialogButton(
488 this,
489 IDR_AURA_WINDOW_POSITION_MIDDLE,
490 IDR_AURA_WINDOW_POSITION_MIDDLE_H,
491 IDR_AURA_WINDOW_POSITION_MIDDLE_P);
492 right_button_ = new BubbleDialogButton(
493 this,
494 IDR_AURA_WINDOW_POSITION_RIGHT,
495 IDR_AURA_WINDOW_POSITION_RIGHT_H,
496 IDR_AURA_WINDOW_POSITION_RIGHT_P);
497 }
498
499 // Overridden from ButtonListener.
500 void BubbleContentsButtonRow::ButtonPressed(views::Button* sender,
501 const views::Event& event) {
502 // While shutting down, the connection to the owner might already be broken.
503 if (!bubble_->controller())
504 return;
505 if (sender == left_button_)
506 bubble_->controller()->OnButtonClicked(SNAP_LEFT);
507 else if (sender == minimize_button_)
508 bubble_->controller()->OnButtonClicked(SNAP_MINIMIZE);
509 else if (sender == right_button_)
510 bubble_->controller()->OnButtonClicked(SNAP_RIGHT);
511 else
512 NOTREACHED() << "Unknown button pressed.";
513 }
514
515 // Called from BubbleDialogButton.
516 void BubbleContentsButtonRow::ButtonHovered(BubbleDialogButton* sender) {
517 // While shutting down, the connection to the owner might already be broken.
518 if (!bubble_->controller())
519 return;
520 if (sender == left_button_)
521 bubble_->controller()->OnButtonHover(SNAP_LEFT);
522 else if (sender == minimize_button_)
523 bubble_->controller()->OnButtonHover(SNAP_MINIMIZE);
524 else if (sender == right_button_)
525 bubble_->controller()->OnButtonHover(SNAP_RIGHT);
526 else
527 bubble_->controller()->OnButtonHover(SNAP_NONE);
528 }
529
530 BubbleContentsView::BubbleContentsView(
531 MaximizeBubbleController::Bubble* bubble)
532 : bubble_(bubble),
533 buttons_view_(NULL),
534 label_view_(NULL) {
535 SetLayoutManager(new views::BoxLayout(
536 views::BoxLayout::kVertical, 0, 0, kLayoutSpacing));
537 set_background(
538 views::Background::CreateSolidBackground(kBubbleBackgroundColor));
539
540 buttons_view_ = new BubbleContentsButtonRow(bubble);
541 AddChildView(buttons_view_);
542
543 label_view_ = new views::Label();
544 SetSnapType(SNAP_NONE);
545 label_view_->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
546 label_view_->SetBackgroundColor(kBubbleBackgroundColor);
547 label_view_->SetEnabledColor(kBubbleTextColor);
548 AddChildView(label_view_);
549 }
550
551 // Set the label content to reflect the currently selected |snap_type|.
552 // This function can be executed through the frame maximize button as well as
553 // through hover operations.
554 void BubbleContentsView::SetSnapType(SnapType snap_type) {
555 if (!bubble_->controller())
556 return;
557
558 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
559 int id = 0;
560 switch (snap_type) {
561 case SNAP_LEFT:
562 id = IDS_ASH_SNAP_WINDOW_LEFT;
563 break;
564 case SNAP_RIGHT:
565 id = IDS_ASH_SNAP_WINDOW_RIGHT;
566 break;
567 case SNAP_MAXIMIZE:
568 DCHECK(!bubble_->controller()->is_maximized());
569 id = IDS_ASH_MAXIMIZE_WINDOW;
570 break;
571 case SNAP_MINIMIZE:
572 id = IDS_ASH_MINIMIZE_WINDOW;
573 break;
574 case SNAP_RESTORE:
575 DCHECK(bubble_->controller()->is_maximized());
576 id = IDS_ASH_RESTORE_WINDOW;
577 break;
578 default:
579 // If nothing is selected, we automatically select the click operation.
580 id = bubble_->controller()->is_maximized() ? IDS_ASH_RESTORE_WINDOW :
581 IDS_ASH_MAXIMIZE_WINDOW;
582 break;
583 }
584 label_view_->SetText(rb.GetLocalizedString(id));
585 }
586
587 MaximizeBubbleController::MaximizeBubbleController(
588 FrameMaximizeButton* frame_maximize_button,
589 bool is_maximized)
590 : frame_maximize_button_(frame_maximize_button),
591 bubble_(NULL),
592 is_maximized_(is_maximized) {
593 // Create the task which will create the bubble delayed.
594 base::OneShotTimer<MaximizeBubbleController>* new_timer =
595 new base::OneShotTimer<MaximizeBubbleController>();
596 new_timer->Start(
597 FROM_HERE,
598 base::TimeDelta::FromMilliseconds(kBubbleAppearanceDelayMS),
599 this,
600 &MaximizeBubbleController::CreateBubble);
601 timer_.reset(new_timer);
602 }
603
604 MaximizeBubbleController::~MaximizeBubbleController() {
605 // Note: The destructor only gets initiated through the owner.
606 timer_.reset();
607 if (bubble_) {
608 bubble_->ControllerRequestsCloseAndDelete();
609 bubble_ = NULL;
610 }
611 }
612
613 void MaximizeBubbleController::SetSnapType(SnapType snap_type) {
614 if (bubble_)
615 bubble_->SetSnapType(snap_type);
616 }
617
618 aura::Window* MaximizeBubbleController::GetBubbleWindow() {
619 return bubble_ ? bubble_->GetBubbleWindow() : NULL;
620 }
621
622 void MaximizeBubbleController::DelayCreation() {
623 if (timer_.get() && timer_->IsRunning())
624 timer_->Reset();
625 }
626
627 void MaximizeBubbleController::OnButtonClicked(SnapType snap_type) {
628 frame_maximize_button_->ExecuteSnapAndCloseMenu(snap_type);
629 }
630
631 void MaximizeBubbleController::OnButtonHover(SnapType snap_type) {
632 frame_maximize_button_->SnapButtonHovered(snap_type);
633 }
634
635 void MaximizeBubbleController::RequestDestructionThroughOwner() {
636 // Tell the parent to destroy us (if this didn't happen yet).
637 if (timer_.get()) {
638 timer_.reset(NULL);
639 // Informs the owner that the menu is gone and requests |this| destruction.
640 frame_maximize_button_->DestroyMaximizeMenu();
641 // Note: After this call |this| is destroyed.
642 }
643 }
644
645 void MaximizeBubbleController::CreateBubble() {
646 if (!bubble_)
647 bubble_ = new Bubble(this);
648
649 timer_->Stop();
650 }
651
652 BubbleDialogButton::BubbleDialogButton(
653 BubbleContentsButtonRow* button_row,
654 int normal_image,
655 int hovered_image,
656 int pressed_image)
657 : views::ImageButton(button_row),
658 button_row_(button_row) {
659 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
660 SetImage(views::CustomButton::BS_NORMAL, rb.GetImageSkiaNamed(normal_image));
661 SetImage(views::CustomButton::BS_HOT, rb.GetImageSkiaNamed(hovered_image));
662 SetImage(views::CustomButton::BS_PUSHED,
663 rb.GetImageSkiaNamed(pressed_image));
664 button_row->AddChildView(this);
665 }
666
667 void BubbleDialogButton::OnMouseCaptureLost() {
668 button_row_->ButtonHovered(NULL);
669 views::ImageButton::OnMouseCaptureLost();
670 }
671
672 void BubbleDialogButton::OnMouseEntered(const views::MouseEvent& event) {
673 button_row_->ButtonHovered(this);
674 views::ImageButton::OnMouseEntered(event);
675 }
676
677 void BubbleDialogButton::OnMouseExited(const views::MouseEvent& event) {
678 button_row_->ButtonHovered(NULL);
679 views::ImageButton::OnMouseExited(event);
680 }
681
682 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/maximize_bubble_controller.h ('k') | ash/wm/workspace/frame_maximize_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698