Chromium Code Reviews| Index: chrome/browser/ui/views/app_list/app_list_dialog_contents_view.cc |
| diff --git a/chrome/browser/ui/views/app_list/app_list_dialog_contents_view.cc b/chrome/browser/ui/views/app_list/app_list_dialog_contents_view.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4c5db8a2846a48291dd74f06f057d109eabdd50d |
| --- /dev/null |
| +++ b/chrome/browser/ui/views/app_list/app_list_dialog_contents_view.cc |
| @@ -0,0 +1,162 @@ |
| +// Copyright 2014 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/browser/ui/views/app_list/app_list_dialog_contents_view.h" |
| + |
| +#include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
| +#include "chrome/browser/ui/app_list/app_list_service.h" |
| +#include "chrome/browser/ui/host_desktop.h" |
| +#include "grit/ui_resources.h" |
| +#include "third_party/skia/include/core/SkPaint.h" |
| +#include "ui/app_list/app_list_constants.h" |
| +#include "ui/base/accelerators/accelerator.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/base/ui_base_types.h" |
| +#include "ui/events/event_constants.h" |
| +#include "ui/events/keycodes/keyboard_codes.h" |
| +#include "ui/gfx/canvas.h" |
| +#include "ui/views/background.h" |
| +#include "ui/views/border.h" |
| +#include "ui/views/controls/button/label_button.h" |
| +#include "ui/views/widget/widget.h" |
| +#include "ui/views/window/client_view.h" |
| +#include "ui/views/window/native_frame_view.h" |
| +#include "ui/views/window/non_client_view.h" |
| + |
| +namespace { |
| + |
| +// Margin of the close button from the top right-hand corner of the dialog. |
| +const int kCloseButtonDialogMargin = 10; |
| + |
| +// The radius of the app list overlay (the dialog's background). |
| +// TODO(sashab): Using SupportsShadow() from app_list_view.cc, make this |
| +// 1px smaller on platforms that support shadows. |
| +const int kAppListOverlayBorderRadius = 3; |
| + |
| +// The background for App List dialogs, which appears as a rounded rectangle |
| +// with the same border radius and color as the app list contents. |
| +class AppListOverlayBackground : public views::Background { |
| + public: |
| + AppListOverlayBackground() {} |
| + virtual ~AppListOverlayBackground() {} |
| + |
| + // Overridden from views::Background: |
| + virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE { |
| + SkPaint paint; |
| + paint.setStyle(SkPaint::kFill_Style); |
| + paint.setColor(app_list::kContentsBackgroundColor); |
| + canvas->DrawRoundRect( |
| + view->GetContentsBounds(), kAppListOverlayBorderRadius, paint); |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(AppListOverlayBackground); |
| +}; |
| + |
| +} // namespace |
| + |
| +AppListDialogContentsView::AppListDialogContentsView( |
| + AppListControllerDelegate* app_list_controller_delegate, |
| + views::View* dialog_body) |
| + : app_list_controller_delegate_(app_list_controller_delegate), |
| + dialog_body_(dialog_body), |
| + close_button_(NULL) { |
| + set_background(new AppListOverlayBackground()); |
| + AddChildView(dialog_body_); |
| + |
| + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| + close_button_ = new views::LabelButton(this, base::string16()); |
| + close_button_->SetImage(views::CustomButton::STATE_NORMAL, |
| + *rb.GetImageNamed(IDR_CLOSE_DIALOG).ToImageSkia()); |
| + close_button_->SetImage(views::CustomButton::STATE_HOVERED, |
| + *rb.GetImageNamed(IDR_CLOSE_DIALOG_H).ToImageSkia()); |
| + close_button_->SetImage(views::CustomButton::STATE_PRESSED, |
| + *rb.GetImageNamed(IDR_CLOSE_DIALOG_P).ToImageSkia()); |
| + close_button_->SetBorder(views::Border::NullBorder()); |
| + AddChildView(close_button_); |
| +} |
| + |
| +AppListDialogContentsView::~AppListDialogContentsView() { |
| +} |
| + |
| +// static |
| +views::Widget* AppListDialogContentsView::CreateDialogWidget( |
| + gfx::NativeWindow parent, |
| + const gfx::Rect& bounds, |
| + AppListDialogContentsView* dialog) { |
| + views::Widget::InitParams params; |
| + params.delegate = dialog; |
| + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| + params.remove_standard_frame = true; |
| + params.parent = parent; |
| + params.bounds = bounds; |
| + // Since this stretches to the corners of the app list, any shadow we add |
| + // would be hidden anyway, so don't add one. |
| + params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; |
| + // TODO(sashab): Plumb wm::WindowVisibilityAnimationType through to the |
| + // NativeWindow so that widgets can specify custom animations for their |
| + // windows. Then specify a matching animation for this type of widget, |
| + // such as WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL. |
| + |
| + views::Widget* widget = new views::Widget(); |
| + widget->Init(params); |
| + return widget; |
| +} |
| + |
| +void AppListDialogContentsView::Layout() { |
| + // Place the close button in the top right-hand corner. |
| + close_button_->SetSize(close_button_->GetPreferredSize()); |
| + close_button_->SetPosition( |
| + gfx::Point(width() - close_button_->width() - kCloseButtonDialogMargin, |
| + kCloseButtonDialogMargin)); |
| + close_button_->SetVisible(true); |
|
tapted
2014/06/16 06:11:55
I think this is redundant - (it shouldn't ever be
sashab
2014/06/16 07:01:19
Yup, artifact from old design. Done.
|
| + |
| + // Re-bind the ESCAPE key to trigger selecting the close button. |
|
tapted
2014/06/16 06:11:55
These 3 lines should be in the constructor I think
sashab
2014/06/16 07:01:19
Done.
|
| + ui::Accelerator escape(ui::VKEY_ESCAPE, ui::EF_NONE); |
| + close_button_->AddAccelerator(escape); |
| + |
| + // Stretch the dialog body to fill the whole dialog area. |
| + dialog_body_->SetBoundsRect(GetContentsBounds()); |
| + |
| + views::View::Layout(); |
|
tapted
2014/06/16 06:11:55
If there's no layout manager at this level, this s
sashab
2014/06/16 07:01:19
For some reason, although SetBoundsRect() calls La
tapted
2014/06/16 07:24:45
Ah - this makes sense then - it matches the behavi
|
| +} |
| + |
| +views::View* AppListDialogContentsView::GetInitiallyFocusedView() { |
| + return GetContentsView(); |
| +} |
| + |
| +views::View* AppListDialogContentsView::GetContentsView() { |
| + return this; |
| +} |
| + |
| +views::ClientView* AppListDialogContentsView::CreateClientView( |
| + views::Widget* widget) { |
| + return new views::ClientView(widget, GetContentsView()); |
| +} |
| + |
| +views::NonClientFrameView* AppListDialogContentsView::CreateNonClientFrameView( |
| + views::Widget* widget) { |
| + return new views::NativeFrameView(widget); |
| +} |
| + |
| +void AppListDialogContentsView::ButtonPressed(views::Button* sender, |
| + const ui::Event& event) { |
| + if (sender == close_button_) { |
| + GetWidget()->Close(); |
| + } else { |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +ui::ModalType AppListDialogContentsView::GetModalType() const { |
| + return ui::MODAL_TYPE_WINDOW; |
| +} |
| + |
| +ui::AXRole AppListDialogContentsView::GetAccessibleWindowRole() const { |
| + return ui::AX_ROLE_DIALOG; |
| +} |
| + |
| +void AppListDialogContentsView::WindowClosing() { |
| + app_list_controller_delegate_->OnCloseChildDialog(); |
| +} |