blob: 25eb9d8f1e32ba9df2c08b9d914c221e54970902 [file] [log] [blame] [view]
ellyjonesfbb554982017-05-19 14:43:281# Views Overview
2
3This document is an overview of Views concepts, terminology, and architecture.
4The target audience is engineers using or working on Views.
5
6## General Things
7
8Points in this document are written as `(x,y)`, and rectangles are written as
9`[(x,y) wxh]`. For example, the rectangle `[(100,100) 50x20]` contains the point
10`(130,110)`.
11
12Views uses a coordinate system with `(0,0)` at the top-left, with increasing
13x-coordinates moving rightwards and increasing y-coordinates moving downwards.
14This is the same as the Windows and GTK coordinate systems, but *different from*
sdyf6f8f66f2017-05-22 16:24:5615the Cocoa coordinate system, which has `(0,0)` at the bottom-left. Coordinates
ellyjonesfbb554982017-05-19 14:43:2816in this document use the Views coordinate system.
17
18Views generally *take ownership* of objects passed to them even via raw
19pointers, although there are some exceptions, such as delegates.
20
21## Views
22
23A **View** is a UI element, similar to an HTML DOM element. Each View occupies a
24rectangle, called its **bounds**, which is expressed in the coordinate system of
25its parent View. Views may have child Views, which are laid out according to the
26View's **layout manager**, although individual Views may also override
27`View::Layout` to implement their own layout logic. Each View may also have a
28**border** and/or a **background**.
29
30Each View can calculate different sizes, which are used by the View's parent
31View to decide how to position and size it. Views may have any or all of a
32preferred size, a minimum size, and a maximum size. These may instead be
33calculated by the View's LayoutManager, and may be used by the parent View's
34LayoutManager.
35
36It is generally not a good idea to explicitly change the bounds of a View.
37Typically, bounds are computed by the parent View's Layout method or the parent
38View's LayoutManager. It is better to build a LayoutManager that does what you
39want than to hand-layout Views by changing their bounds.
40
41For more details about Views, see [view.h].
42
43### Border
44
45The **border** is conventionally drawn around the edges of the View's bounding
46rectangle, and also defines the View's **content bounds**, which are the area
47inside which the View's content is drawn. For example, a View that is at
48`[(0,0) 100x100]` which has a solid border of thickness 2 will have content
49bounds of `[(2,2) 96x96]`.
50
51For more details, see [border.h].
52
53### Background
54
55The **background** is drawn below any other part of the View, including the
56border. Any View can have a background, but most Views do not. A background is
57usually responsible for filling the View's entire bounds. Backgrounds are
58usually a color, but can be a gradient or something else entirely.
59
60For more details, see [background.h].
61
62### Content
63
64The **content** is the area inside the content bounds of the View. A View's
65child Views, if it has any, are also positioned and drawn inside the content
66bounds of a View. There is no class representing the content area of a View; it
67only exists as the space enclosed by the View's border, and its shape is defined
68by the border's insets.
69
70### Layout & Layout Managers
71
72A View's **layout manager** defines how the View's child views should be laid
73out within the View's content bounds. There are a few layout managers supplied
74with Views. The simplest is [FillLayout], which lays out all a View's children
Dana Fried9ddbafc2020-06-15 19:20:5275occupying the View's entire content bounds. [FlexLayout] provides a CSS-like
76layout for horizontal and vertical arrangements of views.
77
78Other commonly-used layouts managers are [BoxLayout], a predecessor of
Peter Kasting2ead0ee2021-10-20 16:55:2779FlexLayout, and [TableLayout], which provides a flexible row-and-column
Dana Fried9ddbafc2020-06-15 19:20:5280system.
ellyjonesfbb554982017-05-19 14:43:2881
82### Painting
83
84Views are painted by pre-order traversal of the View tree - i.e., a parent View
85is painted before its child Views are. Each View paints all its children in
86z-order, as determined by `View::GetChildrenInZOrder()`, so the last child in
87z-order is painted last and therefore over the previous children. The default
88z-order is the order in which children were added to the parent View.
89
90Different View subclasses implement their own painting logic inside
91`View::OnPaint`, which by default simply calls `View::OnPaintBackground` and
92`View::OnPaintBorder`. Generally, subclass implementations of `View::OnPaint`
93begin by calling the superclass `View::OnPaint`.
94
95If you need a special background or border for a View subclass, it is better to
96create a subclass of `Background` or `Border` and install that, rather than
97overriding `::OnPaintBackground` or `::OnPaintBorder`. Doing this helps preserve
98the separation of Views into the three parts described above and makes painting
99code easier to understand.
100
Erik Chen14380c42024-01-16 21:27:52101### Debugging
102
103See [page](../ui_devtools/index.md) for details.
104
ellyjonesfbb554982017-05-19 14:43:28105## Widgets
106
107Views need an underlying canvas to paint onto. This has to be supplied by the
108operating system, usually by creating a native drawing surface of some kind.
109Views calls these **widgets**. A Widget is the bridge between a tree of Views
110and a native window of some sort, which Views calls a **native widget**. Each
111Widget has a **root view**, which is a special subclass of View that helps with
112this bridging; the root view in turn has a single child view, called the
113Widget's **contents view**, which fills the entire root view. All other Views
sdyf6f8f66f2017-05-22 16:24:56114inside a given Widget are children of that Widget's contents view.
ellyjonesfbb554982017-05-19 14:43:28115
116Widgets have many responsibilities, including but not limited to:
117
1181. Keyboard focus management, via [FocusManager]
1192. Window resizing/minimization/maximization
1203. Window shaping, for non-rectangular windows
1214. Input event routing
122
123For more details, see [widget.h].
124
125### Client and Non-Client Views
126
sdyf6f8f66f2017-05-22 16:24:56127The contents view of most Widgets is a **Non-Client View**, which is either a
ellyjonesfbb554982017-05-19 14:43:28128[NonClientView] or one of its descendants. The Non-Client View has two children,
129which are the **Non-Client Frame View** (a [NonClientFrameView]) and the
130**Client View** (a [ClientView]). The non-client frame view is responsible for
131painting window decorations, the Widget's border, the shadow, and so on; the
132client view is responsible for painting the Widget's contents. The area the
133client view occupies is sometimes referred to as the Widget's "client area". The
134non-client frame view may be swapped out as the system theme changes without
135affecting the client view.
136
Elly Fong-Jones8f74ca12019-01-09 17:54:38137The overall structure of a Widget and its helper Views looks like this:
138
Keren Zhu5f2e01b62022-12-14 17:28:38139![views](images/views.png)
Elly Fong-Jones8f74ca12019-01-09 17:54:38140
ellyjonesfbb554982017-05-19 14:43:28141## Dialogs
142
143A commonly-used type of client view is a **dialog client view**, which has a
sdyf6f8f66f2017-05-22 16:24:56144**contents view**, optional buttons on the lower-right, and an optional extra
ellyjonesfbb554982017-05-19 14:43:28145view on the lower-left. Dialogs are usually created by subclassing
146[DialogDelegate] or [DialogDelegateView] and then calling
sdyf6f8f66f2017-05-22 16:24:56147`DialogDelegate::CreateDialogWidget`. The dialog's contents view fills the
148entire top part of the widget's client view, and the bottom part is taken over
149by the dialog's buttons and extra view.
ellyjonesfbb554982017-05-19 14:43:28150
151## Bubbles
152
153A common type of dialog is a **bubble**, which is a dialog that is anchored to a
154parent View and moves as the parent View moves. Bubbles are usually created by
155subclassing [BubbleDialogDelegateView] and then calling
156`BubbleDialogDelegateView::CreateBubble`. Bubbles can have a title, which is
157drawn alongside the window controls as part of the Bubble's Widget's
158NonClientFrameView.
159
160[BoxLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/box_layout.h
Takashi Toyoshima33928e72023-11-27 06:41:05161[BubbleDialogDelegateView]: https://cs.chromium.org/chromium/src/ui/views/bubble/bubble_dialog_delegate_view.h
ellyjonesfbb554982017-05-19 14:43:28162[ClientView]: https://cs.chromium.org/chromium/src/ui/views/window/client_view.h
163[DialogDelegate]: https://cs.chromium.org/chromium/src/ui/views/window/dialog_delegate.h
164[DialogDelegateView]: https://cs.chromium.org/chromium/src/ui/views/window/dialog_delegate.h
165[FillLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/fill_layout.h
Peter Kasting2ead0ee2021-10-20 16:55:27166[FlexLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/flex_layout.h
ellyjonesfbb554982017-05-19 14:43:28167[FocusManager]: https://cs.chromium.org/chromium/src/ui/views/focus/focus_manager.h
Peter Kasting2ead0ee2021-10-20 16:55:27168[TableLayout]: https://cs.chromium.org/chromium/src/ui/views/layout/table_layout.h
ellyjonesfbb554982017-05-19 14:43:28169
170[NonClientView]: https://cs.chromium.org/chromium/src/ui/views/window/non_client_view.h
171[NonClientFrameView]: https://cs.chromium.org/chromium/src/ui/views/window/non_client_view.h
172[background.h]: https://cs.chromium.org/chromium/src/ui/views/background.h
173[border.h]: https://cs.chromium.org/chromium/src/ui/views/border.h
174[canvas.h]: https://cs.chromium.org/chromium/src/ui/gfx/canvas.h
175[view.h]: https://cs.chromium.org/chromium/src/ui/views/view.h
176[widget.h]: https://cs.chromium.org/chromium/src/ui/views/widget/widget.h