// Copyright (c) 2010 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 VIEWS_EXAMPLES_WIDGET_EXAMPLE_H_ #define VIEWS_EXAMPLES_WIDGET_EXAMPLE_H_ #pragma once #include "views/background.h" #include "views/box_layout.h" #include "views/controls/button/text_button.h" #include "views/examples/example_base.h" #include "views/view.h" #include "views/widget/root_view.h" #include "views/widget/widget.h" #if defined(OS_LINUX) #include "views/widget/widget_gtk.h" #endif namespace { // A layout manager that layouts a single child at // the center of the host view. class CenterLayout : public views::LayoutManager { public: CenterLayout() {} virtual ~CenterLayout() {} // Overridden from LayoutManager: virtual void Layout(views::View* host) { views::View* child = host->GetChildViewAt(0); gfx::Size size = child->GetPreferredSize(); child->SetBounds((host->width() - size.width()) / 2, (host->height() - size.height()) / 2, size.width(), size.height()); } virtual gfx::Size GetPreferredSize(views::View* host) { return host->GetPreferredSize(); } private: DISALLOW_COPY_AND_ASSIGN(CenterLayout); }; } // namespace namespace examples { using views::Widget; // WidgetExample demonstrates how to create a popup widget. class WidgetExample : public ExampleBase, public views::ButtonListener { public: explicit WidgetExample(ExamplesMain* main) : ExampleBase(main) {} virtual ~WidgetExample() {} virtual std::wstring GetExampleTitle() { return L"Widget"; } virtual void CreateExampleView(views::View* container) { container->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 2)); BuildButton(container, L"Create a popup widget", POPUP); BuildButton(container, L"Create a transparent popup widget", TRANSPARENT_POPUP); #if defined(OS_LINUX) views::View* vert_container = new views::View(); container->AddChildView(vert_container); vert_container->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 20)); BuildButton(vert_container, L"Create a child widget", CHILD); BuildButton(vert_container, L"Create a transparent child widget", TRANSPARENT_CHILD); #endif } private: enum Command { POPUP, CHILD, TRANSPARENT_POPUP, TRANSPARENT_CHILD, CLOSE_WIDGET, }; void BuildButton(views::View* container, const std::wstring& label, int tag) { views::TextButton* button = new views::TextButton(this, label); button->set_tag(tag); container->AddChildView(button); } void InitWidget(Widget* widget, const Widget::TransparencyParam transparency) { // Add view/native buttons to close the popup widget. views::TextButton* close_button = new views::TextButton(this, L"Close"); close_button->set_tag(CLOSE_WIDGET); // TODO(oshima): support transparent native view. views::NativeButton* native_button = new views::NativeButton(this, L"Native Close"); native_button->set_tag(CLOSE_WIDGET); views::View* button_container = new views::View(); button_container->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 1)); button_container->AddChildView(close_button); button_container->AddChildView(native_button); views::View* widget_container = new views::View(); widget_container->SetLayoutManager(new CenterLayout); widget_container->AddChildView(button_container); widget->SetContentsView(widget_container); if (transparency != Widget::Transparent) { widget_container->set_background( views::Background::CreateStandardPanelBackground()); } // Show the widget. widget->Show(); } #if defined(OS_LINUX) void CreateChild(views::View* parent, const Widget::TransparencyParam transparency) { views::WidgetGtk* widget = new views::WidgetGtk(views::WidgetGtk::TYPE_CHILD); if (transparency == Widget::Transparent) widget->MakeTransparent(); // Compute where to place the child widget. // We'll place it at the center of the root widget. views::Widget* parent_widget = parent->GetWidget(); gfx::Rect bounds; parent_widget->GetBounds(&bounds, false); // Child widget is 200x200 square. bounds.SetRect((bounds.width() - 200) / 2, (bounds.height() - 200) / 2, 200, 200); // Initialize the child widget with the computed bounds. widget->InitWithWidget(parent_widget, bounds); InitWidget(widget, transparency); } #endif void CreatePopup(views::View* parent, const Widget::TransparencyParam transparency) { Widget* widget = Widget::CreatePopupWidget(transparency, Widget::AcceptEvents, Widget::DeleteOnDestroy, Widget::MirrorOriginInRTL); // Compute where to place the popup widget. // We'll place it right below the create button. gfx::Point point = parent->GetPosition(); // The position in point is relative to the parent. Make it absolute. views::View::ConvertPointToScreen(parent, &point); // Add the height of create_button_. point.Offset(0, parent->size().height()); gfx::Rect bounds(point.x(), point.y(), 200, 300); // Initialize the popup widget with the computed bounds. widget->InitWithWidget(parent->GetWidget(), bounds); InitWidget(widget, transparency); } // ButtonListner implementation. virtual void ButtonPressed(views::Button* sender, const views::Event& event) { switch (sender->tag()) { case POPUP: CreatePopup(sender, Widget::NotTransparent); break; case TRANSPARENT_POPUP: CreatePopup(sender, Widget::Transparent); break; #if defined(OS_LINUX) case CHILD: CreateChild(sender, Widget::NotTransparent); break; case TRANSPARENT_CHILD: CreateChild(sender, Widget::Transparent); break; #endif case CLOSE_WIDGET: sender->GetWidget()->Close(); break; } } DISALLOW_COPY_AND_ASSIGN(WidgetExample); }; } // namespace examples #endif // VIEWS_EXAMPLES_WIDGET_EXAMPLE_H_