summaryrefslogtreecommitdiffstats
path: root/examples/webenginequick/recipebrowser/doc/src/recipebrowser.qdoc
blob: a9fb5baee5d969e91a2a25294cb904b0b0f1ed29 (plain)
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \example webenginequick/recipebrowser
    \title WebEngine Recipe Browser
    \ingroup webengine-examples
    \brief A small hybrid application based on the WebEngineView QML type and Qt Quick Controls 2.

    \image recipebrowser-demo.jpg

    \e {Recipe Browser} demonstrates how to use the \l{WebEngineView} item, \l{Qt Quick} items, and
    \l{Qt Quick Controls 2} items to develop a small hybrid web browser application.
    A \l{ListView}-based item is used to display a list of recipe names. Clicking on
    a name causes the web view to load the respective recipe page. The overall appearance
    of the application is provided by the \l{Qt Quick Controls 2} items, which have their active
    style set to the \l{Material Style}{Material} style. The web content is a mix of HTML and
    Markdown source compiled to HTML, along with CSS and JavaScript.

    \include examples-run.qdocinc

    \section1 C++ Code

    In \c main.cpp, we use the \l{QGuiApplication} and \l{QQmlApplicationEngine}
    classes to set up and load the main QML file. We call \l{QtWebEngineQuick::initialize} so we can use
    \l{WebEngineView} in our QML code. We set the default Qt Quick Controls 2 style
    to the Material style, so we do not have to specify it for each new item we add. Finally, we use
    a C++ define to check whether the application is compiled for an embedded platform.
    The value will be used in the main QML code to determine the window size.

    \quotefromfile webenginequick/recipebrowser/main.cpp
    \skipto #include
    \printuntil }

    \section1 QML Code

    In the \c main.qml file, we first create a top-level window and set a title for it. We also set
    up the size of the window depending on its primary orientation as well as the platform, so that
    the application is usable on both desktop and embedded platforms. On desktop, the size
    is constrained by a minimum of 320x480 pixels up to the maximum size that the screen supports.
    The default window size is 1024 pixels wide and 768 pixels high in landscape orientation.
    On embedded devices, the window will occupy the whole screen.

    \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
    \skipto ApplicationWindow
    \printuntil minimumHeight

    Next, we add a \l{RowLayout} item so we can divide the window into two parts: one being a
    custom \c RecipeList item containing the recipe titles, and the other being the
    \l{WebEngineView}, which shows the recipe details. The spacing is set to zero so the items are
    positioned directly next to each other.

    \printuntil RecipeList
    \dots 16
    \skipuntil webView.showRecipe
    \printline }
    \printuntil WebEngineView
    \dots 16
    \skipuntil busy.running = true
    \skipline }
    \skipline }
    \printline }
    \printline }

    The \c RecipeList item has a few \l{Layout}{attached Layout properties}, in order to scale the
    item to a maximum of one third of the layout width. We give the item focus, so that the keyboard
    can be used to navigate the recipes, in addition to using mouse and touch. We also add a handler
    for the custom \c recipeSelected signal, to tell the WebEngineView to load the URL of the
    selected recipe.

    \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
    \skipto RecipeList
    \printuntil }

    The WebEngineView has similar layout properties, to make it occupy two thirds of the layout
    width.

    \skipto WebEngineView
    \printuntil Layout.fillHeight

    We then disable the \l{WebEngineSettings::focusOnNavigationEnabled}{focusOnNavigationEnabled}
    setting to make sure that the \l{WebEngineView} does not steal focus from the \c RecipeList
    item every time its URL is changed. This allows the user to continue navigating through the
    recipes using the keyboard. We also disable the default context menu by accepting the
    ContextMenuRequest.

    \skipto focusOnNavigationEnabled
    \printuntil }

    When the application starts, instead of directly showing the \l{WebEngineView}, we show a
    placeholder \l{Rectangle} with a \l{BusyIndicator} to provide a nicer user experience while the
    application is loading.

    \printuntil }
    \dots 12
    \skipto Rectangle
    \printuntil }

    Once the first page in the view is loaded, we start a \l{Timer} that
    will hide the placeholder and show the actual page. The delay provides more time for the recipe
    images to load, so that when the view is shown, the page is completely rendered. The timer also
    shows a help \l{ToolTip} that informs the user on how to navigate the recipes.

    \quotefromfile webenginequick/recipebrowser/resources/qml/main.qml
    \skipto Timer {
    \printuntil }

    Let's see what the \c RecipeList item looks like from the inside. The root item is a
    FocusScope to allow transferring focus to the child ListView whenever the root item receives
    focus. We also declare a custom \c recipeSelected signal, which will be emitted when the current
    item of the ListView changes.

    \quotefromfile webenginequick/recipebrowser/resources/qml/RecipeList.qml
    \skipto FocusScope
    \printuntil recipeSelected

    A ColumnLayout holds a header \l{Label} above the ListView, and the ListView itself.
    Again, we set the spacing to zero and make sure the layout occupies the whole space of
    the parent item.

    \skipto ColumnLayout
    \printuntil anchors.fill

    Inside the layout there is a styled \l{ToolBar} item, with a \l{Label} inside of it serving as
    the ListView header.

    \skipto ToolBar
    \printuntil Label
    \printuntil }
    \printuntil }

    The second item inside the layout is a \l{ListView}, whose contents will fill the remaining
    space in the layout. We set \l{Item::}{clip} to true, so that the delegates that are scrolled
    up are not seen under the ToolBar item. We set \l{Item::}{focus} to true, so the ListView gains
    focus when the FocusScope does. We add a vertical scroll bar, so the user can scroll through the
    recipes if the window size is small. We also specify the recipe model to be used by the
    ListView as described later in this topic.

    \skipto ListView
    \printuntil model

    We have an \l{ItemDelegate} set as the ListView delegate, which displays the
    recipe title. The contentItem is a \l{Text} item, customized with a few properties to adjust the
    visual appearance and position of the text. We create a binding to the current delegate's model
    URL, so we can access the respective URL outside the delegate itself. We set the
    \l{ItemDelegate::}{highlighted} property to \c true whenever the item is the current one in the
    ListView to provide visual feedback. And we set the focus on the ListView whenever a delegate
    is clicked, so that keyboard navigation works in case the focus was previously in the
    WebEngineView.

    \skipto delegate
    \printuntil onClicked
    \printuntil }
    \printuntil }

    A handler is defined for the \c currentItemChanged signal to emit our own \c recipeSelected
    signal with the URL that the WebEngineView should load.

    \skipto onCurrentItemChanged
    \printuntil }

    We use a \l{ListModel} with seven \l{ListElement}s, each of which contains a recipe
    title and the URL to an HTML page contained in a resource file. The model is used to populate
    the ListView with the recipes and to show the recipe details in the WebEngineView.

    \skipto ListModel
    \printuntil Cupcakes
    \printuntil }
    \printuntil }

    We use a \l{ToolTip} item that is displayed on application startup to inform the users
    how they can navigate and view the details of each recipe. The ToolTip is shown using the
    \c showHelp method, which is invoked by the \l{Timer} in the main.qml file.

    \skipto ToolTip
    \printuntil help.open()
    \printuntil }
    \printuntil }

    An example of a recipe page can be seen below. The page uses two stylesheets and
    two JavaScript files:
    \list
        \li \l{https://bitbucket.org/kevinburke/markdowncss/src/master/}{markdown.css} is
            a markdown-friendly stylesheet created by Kevin Burke
        \li \l{https://github.com/chjj/marked}{marked.min.js} is a markdown parser and
            compiler designed for speed written by Christopher Jeffrey
        \li custom.css makes some small styling adjustments to the final recipe page
        \li custom.js is used to invoke the conversion of the recipe content (which is written in
            markdown syntax) into HTML
    \endlist

    The images on the pages are loaded from the compiled resource file.

    \quotefromfile webenginequick/recipebrowser/resources/pages/soup.html
    \printuntil </html>

    \section1 Files and Attributions

    The example bundles the following code with third-party licenses:

    \table
    \row
        \li \l{recipebrowser-marked}{Marked}
        \li MIT License
    \row
        \li \l{recipebrowser-markdowncss}{Markdown.css}
        \li Apache License 2.0
    \endtable
*/