在上一课中,我们讨论了如何基于Content API 着手设计最小的应用程序。如果您错过了上一课,可在此处阅读相关内容。
在本课中,我们将介绍如何创建独立于平台的窗口类。然后,我们将使用平台特定的 (Linux) 行为对其进行扩展。
我们首先从窗口类开始。(browser/window.h)
public:
static gfx::Size AdjustWindowSize(const gfx::Size& initial_size);
static void Initialize();
static void Deinitialize();
static SprocketWindow* CreateNewWindow(const gfx::Size& initial_size);
private:
static void PlatformInitialize();
static void PlatformExit();
void PlatformCreateWindow(int width, int height);
如您所见,窗口类中的许多方法都带有“Platform”前缀。这表示这些方法可以拥有针对不同平台的特定实现。首先,我们将介绍如何添加 Linux 支持。在后面课程中,也会介绍怎样实现支持Android的代码。
回到窗口类的实现 (browser/window.cc)。首先是简单的初始化程序和取消初始化程序。
// static
void SprocketWindow::Initialize() {
PlatformInitialize();
}
void SprocketWindow::Deinitialize() {
PlatformExit();
这些方法调用平台特定的函数,稍后将介绍相关内容。现在,先创建一个新窗口。
SprocketWindow* SprocketWindow::CreateNewWindow(const gfx::Size& initial_size){
SprocketWindow* window = new SprocketWindow;
// if the initial size is empty, the size will be 800x600
const gfx::Size& size = SprocketWindow::AdjustWindowSize(initial_size);
window->PlatformCreateWindow(size.width(), size.height());
return window;
首先,应定义窗口的大小。可以采用默认窗口大小,即 800x600,也可以使用任何其他首选值。有关窗口的其他一切信息均取决于平台。在 Linux 中,窗口管理环境为 Aura。Chromium、Chrome 和 Chrome OS 均使用该环境。我们再来创建一个文件 (window_aura.cc),从中可实现许多带“Platform”前缀的私有方法。
void SprocketWindow::PlatformInitialize() {
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen());
void SprocketWindow::PlatformExit() {
aura::Env::DeleteInstance();
首先,我们基于桌面屏幕的视图创建屏幕实例。在 Linux 中,这将是一个DesktopScreenX11 类。退出时,我们需要清理在浏览器启动阶段创建的 aura 实例。下面,我们来看窗口创建过程:
void SprocketWindow::PlatformCreateWindow(int width, int height) {
window_widget_ = new views::Widget;
views::Widget::InitParams params;
params.bounds = gfx::Rect(0, 0, width, height);
params.delegate = NULL;
window_widget_->Init(params);
window_ = window_widget_->GetNativeWindow();
window_->GetHost()->Show();
window_widget_->Show();
通过参数按所需的大小创建窗口。现在,我们将delegate成员变量设置为 NULL,表示窗口中不显示任何内容。稍后,我们将介绍如何创建 WidgetDelegateView 类的示例实例,以便在窗口中绘制内容。下一步是使用 Init 方法创建您的 WindowWidget。此widget基于本地 (Aura) 窗口,其 Show 方法可显示内容。您可能注意到,我们甚至没有使用任何 Aura 特定的方法进行初始化(在退出时使用到了一个)。原因是,Aura 是在surface之下的一层,唯一需要做的就是告知Content API 我们要使用的本地widget(在我们的例子中为 Aura)。要连接Content API 和widget,需要使用 ViewsDelegate 类。视图代表的新实例默认执行一些操作(例如窗口放置)及高级应用实用程序。如果想要了解其他功能的详细信息,请查看此处。
void SprocketViewsDelegate::OnBeforeWidgetInit(
views::Widget::InitParams* params,
views::internal::NativeWidgetDelegate* delegate) {
if (!params->native_widget)
params->native_widget = new views::DesktopNativeWidgetAura(delegate);
您可以看到,我们的本地widget现在使用 Aura。最后,我们将在初始化窗口时对其实例化,并在退出时将其销毁。
/* … */
views_delegate_ = new SprocketViewsDelegate;
这就是本课的全部内容。下次,我们将介绍如何连接窗口与应用程序。
敬请期待下一课!
第二课的资源仓库在此。
附件:Window, Aura, ViewsDelegate.