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