zoukankan      html  css  js  c++  java
  • Chromium技术文章翻译——Views Windowing

    views Windowing

    views provides support for creating dialog boxes and other kinds of windows through its Widget object. The developer creates a WidgetDelegate (or sub-interface) implementation that provides the Window with the necessary information to display itself, and also provides callbacks for notifications about windowing events.
     
    Views框架支持通过Widget来创建对话框,甚至其他类型的窗口。开发者实现一个WidgetDelegate(或者子类接口)来提供窗口必要的显示信息,以及窗口事件通知的回调。
    -------------------------------------------------------------------------------------------------------------------------------------------------

    A Simple Example

    To create a simple window:
     
    #include "base/basictypes.h"
    #include "base/compiler_specific.h"
    #include "base/utf_string_conversions.h"
    #include "ui/gfx/canvas.h"
    #include "ui/views/controls/label.h"
    #include "ui/views/view.h"
    #include "ui/views/widget/widget.h"
    #include "ui/views/widget/widget_delegate.h"
     
    class WindowView : public views::WidgetDelegateView {
     public:
      WindowView() : label_(NULL) {
        Init();
      }
     
      virtual ~WindowView() {}
     
     private:
      // Overridden from views::View:
      virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
        canvas->FillRect(GetLocalBounds(), SK_ColorWHITE);
      }
      virtual void Layout() OVERRIDE {
        gfx::Size ps = label_->GetPreferredSize();
        label_->SetBounds((width() - ps.width()) / 2, (height() - ps.height()) / 2, ps.width(), ps.height());
      }
      virtual gfx::Size GetPreferredSize() OVERRIDE {
        gfx::Size ps = label_->GetPreferredSize();
        ps.set_width(ps.width() + 200);
        ps.set_height(ps.height() + 200);
        return ps;
      }
     
      // Overridden from views::WidgetDelegate:
      virtual string16 GetWindowTitle() const OVERRIDE{
        return ASCIIToUTF16("Hello World Window");
      }
      virtual bool CanResize() const OVERRIDE {
        return true;
      }
      virtual bool CanMaximize() const OVERRIDE {
        return true;
      }
      virtual views::View* GetContentsView() OVERRIDE {
        return this;
      }
     
      void Init() {
        label_ = new views::Label(ASCIIToUTF16("Hello, World!"));
        AddChildView(label_);
      }
     
      views::Label* label_;
     
      DISALLOW_COPY_AND_ASSIGN(WindowView);
    };
     
    ...
     
    views::Widget::CreateWindow(new WindowView)->Show();
     
    The window will delete itself when the user closes it, which will cause the RootView within it to be destroyed, including the WindowView.
    当用户关闭窗口的时候,窗口以及与窗口相关的RootView和WindowView都被删除。
    -------------------------------------------------------------------------------------------------------------------------------------------------

    WidgetDelegate

    The WidgetDelegate is an interface that provides information to the Widget class used when displaying the window, such as its title and icon, as well as properties such as whether or not the window can be resized. It also provides callbacks for events like closing. It has an accessor window() which provides access to the associated Window object. A Widget has a ContentsView, provided by theWidgetDelegate, which is a View that is inserted into the Window's client area.
     
    WidgetDelegate是一个接口,一方面是用于提供Widget类窗口的显示信息,诸如标题和图标以及一些其他属性,譬如窗口是否可以调节大等;另一方面,还提供了事件处理的回调,譬如closing函数。WidgetDelegate还有一个访问函数window(),这个函数用来获取与WidgetDelegate相关的窗口对象。WidgetDelegate提供给每个Widget一个ContentsView,用来插入到窗口口的客户区。
    -------------------------------------------------------------------------------------------------------------------------------------------------

    DialogDelegate

    A DialogDelegate is a specialized kind of WidgetDelegate specific to dialog boxes that have OK/Cancel buttons. TheDialogDelegate and its associated ClientView (see below) provide built in OK/Cancel buttons, keyboard handlers for Esc/Enter and enabling for those features. As a user, you write a View that is inserted into the DialogClientView that provides the contents of the dialog box, and implement DialogDelegate instead of WidgetDelegate, which provides callbacks for when the buttons are clicked as well as methods to provide the button text, etc.
     
    DialogDelegate是一种特殊的WidgetDelegate,是一个有着OK/Cancel按钮的对话框。DialogDelegate以及与其相关的ClientView提供了OK/Cancel按钮的构建,Esc/Enter的键盘处理并且开启了其他的一些特性。使用时,可以写一个View插入到DialogClientView中,提供对话框的内容。可以不用实现WidgetDelegate,只要实现DialogDelegate就提供了点击按钮的响应函数,如同提供的按钮上的文本填充函数一样。
    -------------------------------------------------------------------------------------------------------------------------------------------------

    Client and Non Client Views

     
    Due to Chrome's non-standard window design, views supports custom rendered non-client areas. This is supported via the Window class andNonClientFrameView subclasses. To provide a custom window frame, a View subclasses NonClientFrameView. This allows the overriding View to render and respond to events from the non-client areas of a window. views contains two built in type that do this -CustomFrameView and NativeFrameView. These are used for standard dialog boxes and top level windows.
     
    由于Chrome的窗口设计是非标准的,views可以支持非客户区的渲染。这部分的渲染由Winidow类和NonClientView的子类共同完成。作为View的子类,NonClientFrameView提供了定制窗口框架。它取代了View来负责窗口的非客户区进行渲染,以及这部分的消息处理。对于对话框和顶层窗口,Views框架中有两种类型的View可以实现这部分功能——分别是CustomFrameView和NativeFrameView。
    -------------------------------------------------------------------------------------------------------------------------------------------------
    For the Browser Window, different subclasses of NonClientFrameView are used (GlassBrowserFrameView andOpaqueBrowserFrameView). To allow these to be used the browser overrides Window's CreateFrameViewForWindow method to construct the appropriate frame view.
     
    对浏览器窗口而言,有NonClientFrameView有两个不同的子类(GlassBrowserFrameView和OpaqueBrowserFrameView)。为了使用它们,Browser重载了窗口的CreateFrameViewForWindow方法来构造一个最合适的框架视图。
    ----------------------------------------------------------------------------------------------
     
    Aside from the RootView, the topmost View in a Window's View hierarchy is the NonClientView. This view is a container of exactly two views - the NonClientFrameView described above and a ClientView or subclass. The ClientView subclass contains the contents of the client area of the window (the stuff inside the titlebar/frame). A common ClientView subclass is DialogClientView, which provides built in handling for OK/Cancel buttons and a dialog theme background. The specific ClientView to be used is specified by aWidgetDelegate in its CreateClientView implementation. The default implementation of DialogDelegate automatically creates aDialogClientView. Custom WidgetDelegates can implement this method to return their own ClientView, which is whatBrowserView does (the Browser window's WidgetDelegate implementor) to return itself. The ClientView API is fairly minimal except it is given a chance to perform non-client hit-testing, which is how the draggable title bar within the TabStrip and the resize corner of windows is implemented.
     
    除了RootView,在窗口视图层次结构中,最顶层的View就是NonClientView。它包含了两个View——NonClientFrameView以及ClientView或者ClientView的子类。ClientView的子类包含了窗口客户区的内容(填充在标题栏和窗体框架内)。最普遍的ClientView的子类就是DialogClientView,提供了对OK/Cancel按钮的消息处理以及一个对话框样式的背景。在WidgetDelegate的CreateClientView实现函数中确定将要被使用的ClientView。DialogDelegate的默认实现是自动创建一个DialogClientView。而定制的WidgetDelegate可以实现CreateClientView来获得需要的ClientView。BrowserView(Browser窗口的一个WidgetDelegate的实现者)中就是一个定制的WidgetDelegate的例子。通常情况ClientView的API是很少的,除非这个ClientView实现了非客户区点击的效果:例如实现了使用TabStrip拖动标题栏或者调节窗体边角的大小等功能。
    -------------------------------------------------------------------------------------------------------------------------------------------------
     
    The ClientView and NonClientFrameView are siblings because it is fairly common for Views to do one-time initialization when they are inserted into a View hierarchy and DWM toggling on Windows Vista and newer mean the NonClientFrameView needs to be swapped out when the DWM is enabled or disabled. As such if the ClientView were a child of the NonClientFrameView it would be re-parented, meaning its children might re-initialize with negative side-effects.
     
    ClientView和NonClientFrameView是一对兄弟,因为对于Views框架来说,通常当ClientView和NonClientFrameView插入到View的层次结构中时Views可以一次性初始化它们。并且在Windows Vista以及更高的版本中,DWM的触发意味着当DWM开启或者关闭的时候NonClientFrameView需要被换出。正因为如此,如果ClientView是NonClientFrameView的孩子,在上述情况下就必须重新挂载到新的父View下,这样的副作用就是它所有的子View都需要呗重新初始化。
    -------------------------------------------------------------------------------------------------------------------------------------------------

    Creating a Window

    Some simple code to create a window using the WindowView defined in the example above:
     
    views::Widget* window = views::Widget::CreateWindow(new WindowView);
    window->Show();
     
    ..
  • 相关阅读:
    Difference between sendRedirect, include, forward
    Selenium Study Notes
    Java基础知识2
    JSP上的JavaBeans
    Java Socket 7部曲
    Javascript版本排序1
    Java基础知识1
    JavaBean的属性
    测试基础
    annotation本质
  • 原文地址:https://www.cnblogs.com/stanleychan/p/2604844.html
Copyright © 2011-2022 走看看