Web Sprocket(s) | Lesson 2 - Crafting a window (Part I)

In the previous lesson we have discussed how to start with a minimal application based on Content API. If you missed it you can read it here.

In this lesson we show how to create a platform independent Window class. After that we will expand this with platform specific (Linux) behaviors.

Let’s start with the Window class. (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);

As you can see, several methods in the Window class have a “Platform” prefix. This indicates that these methods can have different platform specific implementations. We are going to show how to add Linux support first. In later sessions Android specific code path will be introduced as well.

Back to the implementation of the Window class (browser/window.cc). Let’s start with a simple initializer and deinitializer!

// static
void SprocketWindow::Initialize() {
  PlatformInitialize();
}

// static
void SprocketWindow::Deinitialize() {
  PlatformExit();
}

These methods call platform specific functions which will be discussed later. Now, move on to create a new window!

// static
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;
}

The first thing you should define is the size of the window. You can go with default window size which is 800x600 (or use any other preferred value). Everything else about the window is platform dependent. On Linux the window management environment is the Aura which is used by Chromium, Chrome, and Chrome OS. Let’s create an additional file (window_aura.cc) where you can implement several private “Platform” prefixed methods.

// static
void SprocketWindow::PlatformInitialize() {
  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen());
}

// static
void SprocketWindow::PlatformExit() {
  aura::Env::DeleteInstance();
}

First, we create the screen instance based on the view of desktop screen. On Linux, this will be a DesktopScreenX11 class. On exit, we need to clean up the aura instance created in the browser startup phase. Now let’s see the window creation:

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();
}

The window is created with the desired size via parameters. Right now we set the delegate member to NULL which indicates that no content will be displayed in the window. Later we will show how to create a sample instance of the WidgetDelegateView class to draw something on the window. The next step is to create your WindowWidget using the Init method. This widget is based on Native (Aura) Window, and its Show method will display the content. Probably you might noticed that we didn’t even used any Aura specific method for the initialization (you can see one for the exit). The reason is that Aura is one layer beneath the surface, and the only thing is needed to tell the Content API which native widget we want to use - in our case it is Aura. To connect the Content API and the widget the ViewsDelegate class is required to use. A new instance of the Views delegate performs some actions by default, for example window placement, and high level application utilities. If you would like to read more what else you can do with it, check out this.

void SprocketViewsDelegate::OnBeforeWidgetInit(
    views::Widget::InitParams* params,
    views::internal::NativeWidgetDelegate* delegate) {
  if (!params->native_widget)
    params->native_widget = new views::DesktopNativeWidgetAura(delegate);
}

As you can see our native widget uses Aura now. Finally, we instantiate it when initializing the window, and destroy it on exit.

void SprocketWindow::PlatformInitialize() {
  /* … */
  views_delegate_ = new SprocketViewsDelegate;
}

That’s all for now. Next time we will connect our window to the application.

Stay tuned for the upcoming lesson!


The lesson 2 repository can be found here.

Attachments: Window, Aura, ViewsDelegate.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • No HTML tags allowed
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Fill in the blank