From 1df70118583e069bde41d03bc9753cef949b3e39 Mon Sep 17 00:00:00 2001 From: Nico Vertriest <nico.vertriest@qt.io> Date: Fri, 3 Aug 2018 14:21:05 +0200 Subject: [PATCH] Doc: tutorial Get Started with Qt Quick Task-number: QTBUG-68739 Change-Id: Ib14e4eb4c20583af2be9198539077f1be5ae471a Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> --- doc/config/qtdoc.qdocconf | 2 +- .../getting-started/gettingstartedqml.qdoc | 1196 +++-------------- doc/src/images/addalarms.png | Bin 0 -> 5231 bytes doc/src/images/alarms2.png | Bin 0 -> 24310 bytes doc/src/images/alarms3.png | Bin 0 -> 14194 bytes doc/src/images/detailscreen.png | Bin 0 -> 10657 bytes doc/src/images/mainscreen.png | Bin 0 -> 7056 bytes examples/tutorials/alarms/AlarmDelegate.qml | 142 ++ examples/tutorials/alarms/AlarmDialog.qml | 168 +++ examples/tutorials/alarms/AlarmModel.qml | 152 +++ examples/tutorials/alarms/TumblerDelegate.qml | 62 + examples/tutorials/alarms/alarms.pro | 29 + examples/tutorials/alarms/main.cpp | 65 + examples/tutorials/alarms/main.qml | 86 ++ examples/tutorials/alarms/qml.qrc | 10 + .../tutorials/alarms/qtquickcontrols2.conf | 5 + 16 files changed, 915 insertions(+), 1002 deletions(-) create mode 100644 doc/src/images/addalarms.png create mode 100644 doc/src/images/alarms2.png create mode 100644 doc/src/images/alarms3.png create mode 100644 doc/src/images/detailscreen.png create mode 100644 doc/src/images/mainscreen.png create mode 100644 examples/tutorials/alarms/AlarmDelegate.qml create mode 100644 examples/tutorials/alarms/AlarmDialog.qml create mode 100644 examples/tutorials/alarms/AlarmModel.qml create mode 100644 examples/tutorials/alarms/TumblerDelegate.qml create mode 100644 examples/tutorials/alarms/alarms.pro create mode 100644 examples/tutorials/alarms/main.cpp create mode 100644 examples/tutorials/alarms/main.qml create mode 100644 examples/tutorials/alarms/qml.qrc create mode 100644 examples/tutorials/alarms/qtquickcontrols2.conf diff --git a/doc/config/qtdoc.qdocconf b/doc/config/qtdoc.qdocconf index 623cf0d6..5a346f4f 100644 --- a/doc/config/qtdoc.qdocconf +++ b/doc/config/qtdoc.qdocconf @@ -88,7 +88,7 @@ exampledirs += \ excludedirs += \ ../src/snippets -examplesinstallpath = demos +examplesinstallpath = qhp.projects = QtDoc diff --git a/doc/src/getting-started/gettingstartedqml.qdoc b/doc/src/getting-started/gettingstartedqml.qdoc index cd6cedf1..f66f1a01 100644 --- a/doc/src/getting-started/gettingstartedqml.qdoc +++ b/doc/src/getting-started/gettingstartedqml.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -26,1063 +26,257 @@ ****************************************************************************/ /*! - \page gettingstartedqml.html + \example tutorials/gettingstartedqtquick \title Getting Started Programming with Qt Quick + \brief A tutorial for Qt Quick based on an alarms application + + This tutorial shows how to develop a simple alarm application as + an introduction to Qt Quick and Qt Quick Controls2. + + This application is similar to the alarm application usually + found on an Android phone. Its features let you enter, edit, + or delete alarms. An alarm can trigger on a given date, and you + can set it to repeat on a series of subsequent days. + + The main screen shows the list of saved alarms: + + \image mainscreen.png "Alarms application" + + The detail screen lets you edit or delete existing alarms: + + \image detailscreen.png "Detail screen" + + The dialog screen is used for adding new alarms. It pops up + when you click on the "+" RoundButton on the bottom of the main + screen: + + \image addalarms.png "Add alarms" + + The source files are located in the qtdoc repository. + You can either fetch the Qt 5 sources from the Qt Project, + or install them as part of Qt 5. The application is also available + in the example list of Qt Creator's Welcome mode. + + \section1 Creating the Alarms Project + + This section shows how to create the project in Qt Creator. It discusses + the files generated automatically by Qt Creator, and the two files + the programmer has to create in Qt Creator or some other editor. + The latter two files are included with the source code for this + tutorial. + + \section1 Qt Creator - Welcome to the world of \b QML, the declarative UI language. In this Getting - Started guide, we will create a simple text editor application using QML. - After reading this guide, you should be ready to develop your own applications - using QML and Qt C++. + Setting up a new project in Qt Creator is aided by a wizard that + guides you step-by-step through the project creation process. The + wizard prompts you to enter the settings needed for that particular + type of project and creates the project for you. + + To create the Alarms project, select \uicontrol{File} > + \uicontrol{New File or Project} > \uicontrol{Application} > + \uicontrol{Qt Quick Application - Empty} > \uicontrol{Choose}. + Type "alarms" in the \b{Name} field, and follow the instructions + of the wizard. - \section1 QML to Build User Interfaces + \image alarms2.png "Qt Creator New File or Project dialog" + + \image alarms3.png "Project Location" - The application we are building is a simple text editor that will load, save, - and perform some text manipulation. This guide will consist of two parts. The - first part will involve designing the application layout and behaviors using - declarative language in QML. For the second part, file loading and saving will - be implemented using Qt C++. Using - \l {The Meta-Object System}{Qt's Meta-Object System}, we can expose C++ functions - as properties that \l{QML Object Types}{QML object types} can use. Utilizing QML and Qt C++, we can - efficiently decouple the interface logic from the application logic. + The Qt Quick application wizard creates a project that contains + the following source files: - \image qml-texteditor5_editmenu.png + \table + \header + \li Source file + \li Purpose + \row + \li alarms.pro + \li The project file + \row + \li main.cpp + \li The main C++ code file for the application. + \row + \li qml.qrc + \li The resource file, which contains the names of the + source files, except main.cpp and the project file. + \endtable - The complete source code is in the \c{examples/quick/tutorials/gettingStartedQml} - directory. If you wish to see how the finalized application looks like, you - can skip to chapter \l {Running the Text Editor}. + The wizard generates the code in the main.cpp file below. + This code block enables High DPI scaling and declares \c app + and \c engine. The engine then loads our main QML file. - The C++ portion of this tutorial assumes that the reader possesses basic knowledge of - Qt's compilation procedures. + \quotefromfile tutorials/alarms/main.cpp + \skipto main + \printuntil } - Tutorial chapters: - \list 1 - \li \l {Defining a Button and a Menu} - \li \l {Implementing a Menu Bar} - \li \l {Building a Text Editor} - \li \l {Decorating the Text Editor} - \li \l {Extending QML using Qt C++} - \endlist + \section1 Additional source files - Information about QML, such as syntax and features, is included in the - \l{The QML Reference}. + \table + \header + \li Source file + \li Purpose + \row + \li \c qtquickcontrols2.conf + \li Selects the \c Material style with the \c Dark theme. + \row + \li \c main.qml + \li The QML code that links AlarmDialog.qml, AlarmModel.qml, + AlarmDelegate.qml and TumblerDelegate.qml + \row + \li \c AlarmDialog.qml + \li Defines the dialog for adding new alarms. + \row + \li \c AlarmDelegate.qml + \li Defines the layout of the main screen of the app. + \row + \li \c AlarmModel.qml + \li Defines the ListModel used for storing the alarms' data. + \row + \li \c TumblerDelegate.qml + \li Defines the graphical layout of the Tumblers + \endtable - \section1 Defining a Button and a Menu - \section2 Basic Component - a Button + \section2 \c qtquickcontrols2.conf - We start our text editor by building a button. Functionally, a button has a mouse - sensitive area and a label. Buttons perform actions when a user presses the button. + The following snippet shows how to set the \c Dark theme in the + \c Material style: - In QML, the basic visual item is the \l Rectangle type. The - \c Rectangle \l{QML Object Types}{QML object type} has - \l{Property Binding}{QML properties} to control its appearance and location. + \quotefile tutorials/alarms/qtquickcontrols2.conf - \code - import QtQuick 2.3 - - Rectangle { - id: simpleButton - color: "grey" - width: 150; height: 75 - - Text { - id: buttonLabel - anchors.centerIn: parent - text: "button label" - } - } - \endcode - - First, the \c {import QtQuick 2.3} statement allows the - \l{Prototyping with qmlscene}{qmlscene} tool to import the QML types we will later use. - This line must exist for every QML file. Notice that the version of Qt modules is - included in the import statement. - - This simple rectangle has a unique identifier, \c simpleButton, which is bound to the - \c id property. The \c Rectangle object's properties are bound to values by listing the - property, followed by a colon, then the value. In the code sample, the color \c grey - is bound to the Rectangle's \c color property. Similarly, we bind the \c width - and \c height of the Rectangle. - - The \l Text type is a non-editable text field. We name this object \c buttonLabel. To set - the string content of the Text field, we bind a value to the \c text property. The label - is contained within the Rectangle and in order to center it in the middle, we assign the - \c anchors of the Text object to its parent, which is called \c simpleButton. Anchors may - bind to other items' anchors, allowing layout assignments simpler. - - We shall save this code as \c SimpleButton.qml. Running \c qmlscene with the file as the - argument will display the grey rectangle with a text label. - - \image qml-texteditor1_simplebutton.png - - To implement the button click functionality, we can use QML's event handling. QML's event - handling is very similar to \l {Signals & Slots}{Qt's signal and slot} mechanism. Signals - are emitted and the connected slot is called. - - \code - Rectangle { - id: simpleButton - ... - - MouseArea { - id: buttonMouseArea - - // Anchor all sides of the mouse area to the rectangle's anchors - anchors.fill: parent - // onClicked handles valid mouse button clicks - onClicked: console.log(buttonLabel.text + " clicked") - } - } - \endcode - - We include a \l MouseArea object in our simpleButton. \c MouseArea objects describe - the interactive area where mouse movements are detected. For our button, we anchor the - whole \c MouseArea to its parent, which is \c simpleButton. The \c anchors.fill syntax is - one way of accessing a specific property called \c fill inside a group of properties - called \c anchors. QML uses \l {Positioning with Anchors}{anchor-based layouts} where - items can anchor to another item, creating robust layouts. - - The \c MouseArea has many signal handlers that are called during mouse movements within - the specified \c MouseArea boundaries. One of them is \c onClicked and it is called - whenever the acceptable mouse button is clicked, the left click being the default. We - can bind actions to the onClicked handler. In our example, \c console.log() outputs text - whenever the mouse area is clicked. The function \c console.log() is a useful tool for - debugging purposes and for outputting text. - - The code in \c SimpleButton.qml is sufficient to display a button on the screen and - output text whenever it is clicked with a mouse. - - \code - Rectangle { - id: button - ... - - property color buttonColor: "lightblue" - property color onHoverColor: "gold" - property color borderColor: "white" - - signal buttonClick() - - onButtonClick: { - console.log(buttonLabel.text + " clicked") - } - - MouseArea{ - id: buttonMouseArea - onClicked: buttonClick() - hoverEnabled: true - onEntered: parent.border.color = onHoverColor - onExited: parent.border.color = borderColor - } - - // Determines the color of the button by using the conditional operator - color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor - } - \endcode - - A fully functioning button is in \c Button.qml. The code snippets in this article - have some code omitted, denoted by ellipses because they were either introduced - earlier in the previous sections or irrelevant to the current code discussion. - - Custom properties are declared using the \c {property type name} syntax. In the - code, the property \c buttonColor, of type \c color, is declared and bound to - the value \c{"lightblue"}. The \c buttonColor is later used in a conditional - operation to determine the button's fill color. Note that property value - assignment is possible using the \c= equals sign, in addition to value binding - using the \c : colon character. Custom properties allow internal items to be - accessible outside of the Rectangle's scope. There are basic - \l{QML Basic Types}{QML types} such as \c int, \c string, \c real, as well as - a type called \c variant. - - By binding the \c onEntered and \c onExited signal handlers to colors, the - button's border will turn yellow when the mouse hovers above the button and - reverts the color when the mouse exits the mouse area. - - A \c buttonClick() signal is declared in \c Button.qml by placing the \c signal - keyword in front of the signal name. All signals have their handlers automatically - created, their names starting with \c on. As a result, the \c onButtonClick is - \c buttonClick's handler. The \c onButtonClick is then assigned an action to - perform. In our button example, the \c onClicked mouse handler will simply call - \c onButtonClick, which displays a text. The \c onButtonClick enables outside - objects to access the \c {Button}'s mouse area easily. For example, items may - have more than one \c MouseArea declarations and a \c buttonClick signal can - make the distinction between the several \c MouseArea signal handlers better. - - We now have the basic knowledge to implement items in QML that can handle - basic mouse movements. We created a \c Text label inside a \c Rectangle, - customized its properties, and implemented behaviors that respond to mouse - movements. This idea of creating QML objects within objects is repeated - throughout the text editor application. - - This button is not useful unless used as a component to perform an action. - In the next section, we will soon create a menu containing several of these - buttons. - - \image qml-texteditor1_button.png - - \section2 Creating a Menu Page - - Up to this stage, we covered how to create objects and assign behaviors inside - a single QML file. In this section, we will cover how to import QML types and how - to reuse some of the created components to build other components. - - Menus display the contents of a list, each item having the ability to perform an action. - In QML, we can create a menu in several ways. First, we will create a menu containing - buttons which will eventually perform different actions. The menu code is in - \c FileMenu.qml. - - \code - import QtQuick 2.3 // Import the main Qt QML module - import "folderName" // import the contents of a folder - import "script.js" as Script // Import a Javascript file and name it as Script - \endcode - - The syntax shown above shows how to use the \c import keyword. This is required to - use JavaScript files, or QML files that are not within the same directory. Since - \c Button.qml is in the same directory as \c FileMenu.qml, we do not need to import - the \c Button.qml file to use it. We can directly create a \c Button object by declaring - \c Button{}, similar to a \c Rectangle{} declaration. - - \code - In FileMenu.qml: - - Row { - anchors.centerIn: parent - spacing: parent.width / 6 - - Button { - id: loadButton - buttonColor: "lightgrey" - label: "Load" - } - Button { - buttonColor: "grey" - id: saveButton - label: "Save" - } - Button { - id: exitButton - label: "Exit" - buttonColor: "darkgrey" - - onButtonClick: Qt.quit() - } - } - \endcode - - In \c FileMenu.qml, we declare three \c Button objects. They are declared - inside a \l Row type, a positioner that will position its children - along a vertical row. The \c Button declaration resides in Button.qml, - which is the same as the one we used in the previous section. - New property bindings can be declared within the newly created buttons, - effectively overwriting the properties set in \c Button.qml. The button - called \c exitButton will quit and close the window when it is clicked. - Note that the signal handler \c onButtonClick in \c Button.qml will be - called in addition to the \c onButtonClick handler in \c exitButton. - - \image qml-texteditor1_filemenu.png - - The \c Row declaration is declared in a \c Rectangle, creating a rectangle - container for the row of buttons. This additional rectangle creates an indirect - way of organizing the row of buttons inside a menu. - - The declaration of the edit menu is very similar at this stage. The menu has - buttons that have the labels: \c Copy, \c Paste, and \c {Select All}. - - \image qml-texteditor1_editmenu.png - - Armed with our knowledge of importing and customizing previously made - components, we may now combine these menu pages to create a menu bar, - consisting of buttons to select the menu, and look at how we may structure - data using QML. - - \section1 Implementing a Menu Bar - - Our text editor application will need a way to display menus using a menu bar. - The menu bar will switch the different menus and the user can choose which menu - to display. Menu switching implies that the menus need more structure than - merely displaying them in a row. QML uses models and views to structure data - and display the structured data. - - \section2 Using Data Models and Views - - QML has different \l{QML Data Models}{data views} that display - \l{QML Data Models}{data models}. Our menu bar will display the menus in a list, - with a header that displays a row of menu names. The list of menus are declared - inside a \l ObjectModel. The \c ObjectModel type contains items that already are - displayable, such as \c Rectangle objects. Other model types, like the - \l ListModel type, need a delegate to display their data. - - We declare two visual items in the \c menuListModel, the \c FileMenu and the - \c EditMenu. We customize the two menus and display them in a \l ListView. - The \c MenuBar.qml file contains the QML declarations and a simple edit menu is - defined in \c EditMenu.qml. - - \code - ObjectModel { - id: menuListModel - - FileMenu { - width: menuListView.width - height: menuBar.height - color: fileColor - } - - EditMenu { - color: editColor - width: menuListView.width - height: menuBar.height - } - } - \endcode - - The \l ListView type will display a model according to a delegate. The delegate - can display the model items in a \c Row object or in a grid. Our \c menuListModel - already has visible items, therefore, we do not need to declare a delegate. - - \code - ListView { - id: menuListView - - // Anchors are set to react to window anchors - anchors.fill: parent - anchors.bottom: parent.bottom - width: parent.width - height: parent.height - - // The model contains the data - model: menuListModel - - // Control the movement of the menu switching - snapMode: ListView.SnapOneItem - orientation: ListView.Horizontal - boundsBehavior: Flickable.StopAtBounds - flickDeceleration: 5000 - highlightFollowsCurrentItem: true - highlightMoveDuration: 240 - highlightRangeMode: ListView.StrictlyEnforceRange - } - \endcode - - Additionally, \c ListView inherits from \l Flickable, making the list respond - to mouse drags and other gestures. The last portion of the code above sets - \c Flickable properties to create the desired flicking movement to our view. - In particular, the property \c highlightMoveDuration changes the duration of - the flick transition. A higher \c highlightMoveDuration value results in - slower menu switching. - - The \c ListView maintains the model items through an \c index and each visual - item in the model is accessible through the \c index, in the order of the - declaration. Changing the \c currentIndex effectively changes the highlighted - item in the \c ListView. The header of our menu bar exemplifies this effect. - There are two buttons in a row, both changing the current menu when clicked. - The \c fileButton changes the current menu to the file menu when clicked, - the \c index being \c 0 because \c FileMenu is declared first in the - \c menuListModel. Similarly, the \c editButton will change the current - menu to the \c EditMenu when clicked. - - The \c labelList rectangle has \c z value of \c 1, denoting that it is displayed - at the front of the menu bar. Items with higher \c z values are displayed in front - of items with lower \c z values. The default \c z value is \c 0. - - \code - Rectangle { - id: labelList - ... - z: 1 - - Row { - anchors.centerIn: parent - spacing: 40 - - Button { - label: "File" - id: fileButton - ... - onButtonClick: menuListView.currentIndex = 0 - } - - Button { - id: editButton - label: "Edit" - ... - onButtonClick: menuListView.currentIndex = 1 - } - } - } - \endcode - - The menu bar we just created can be flicked to access the menus or by clicking - on the menu names at the top. Switching menu screens feel intuitive and responsive. - - \image qml-texteditor2_menubar.png - - \section1 Building a Text Editor - - \section2 Declaring a TextArea - - Our text editor is not a text editor if it didn't contain an editable text area. - QML's \l TextEdit type allows the declaration of a multi-line editable text area. - \c TextEdit is different from the \l Text type, which doesn't allow the user to - directly edit the text. - - \code - TextEdit { - id: textEditor - anchors.fill: parent - width: parent.width - height: parent.height - color: "midnightblue" - focus: true - - wrapMode: TextEdit.Wrap - - onCursorRectangleChanged: flickArea.ensureVisible(cursorRectangle) - } - \endcode - - The editor has its font \c color property set and \c wrapMode set to wrap the text. - The \c TextEdit area is inside a flickable item that will scroll the text if the - text cursor is outside the visible area. The function \c ensureVisible() will - check if the cursor rectangle is outside the visible boundaries and move the - text area accordingly. QML uses Javascript syntax for its scripts, and as previously - mentioned, Javascript files can be imported and used within a QML file. - - \code - function ensureVisible(r) { - if (contentX >= r.x) - contentX = r.x; - else if (contentX + width <= r.x + r.width) - contentX = r.x + r.width - width; - if (contentY >= r.y) - contentY = r.y; - else if (contentY + height <= r.y + r.height) - contentY = r.y + r.height - height; - } - \endcode - - \section2 Combining Components for the Text Editor - - We are now ready to create the layout of our text editor using QML. The text - editor has two components, the menu bar we created and the text area. QML allows - us to reuse components, therefore making our code simpler, by importing components - and customizing when necessary. Our text editor splits the window into two; - one-third of the screen is dedicated to the menu bar and two-thirds of the screen - displays the text area. The menu bar is displayed in front of any other objects. - - \code - Rectangle { - id: screen - width: 1000 - height: 1000 - - // The screen is partitioned into the MenuBar and TextArea. - // One-third of the screen is assigned to the MenuBar - property int partition: height / 3 - - MenuBar { - id: menuBar - height: partition - width: parent.width - z: 1 - } - - TextArea { - id: textArea - anchors.bottom: parent.bottom - y: partition - color: "white" - width: parent.width - height: partition * 2 - } - } - \endcode - - By importing reusable components, our \c TextEditor code looks much simpler. - We can then customize the main application, without worrying about properties - that already have defined behaviors. Using this approach, application layouts - and UI components can be created easily. - - \image qml-texteditor3_texteditor.png - - \section1 Decorating the Text Editor - \section2 Implementing a Drawer Interface - - Our text editor looks simple and we need to decorate it. Using QML, we can declare - transitions and animate our text editor. Our menu bar is occupying one-third of the - screen and it would be nice to have it only appear when we want it. - - We can add a drawer interface, that will contract or expand the menu bar when clicked. - In our implementation, we have a thin rectangle that responds to mouse clicks. The - \c drawer, as well as the application, has two sates: the "drawer is open" state and - the "drawer is closed" state. The \c drawer item is a strip of rectangle with a small - height. There is a nested \l Image object declaring that an arrow icon will - be centered inside the drawer. The drawer assigns a state to the whole application, - with the identifier \c screen, whenever a user clicks the mouse area. - - \code - Rectangle { - id: drawer - height: 15 - - Image { - id: arrowIcon - source: "images/arrow.png" - anchors.horizontalCenter: parent.horizontalCenter - } - - MouseArea { - id: drawerMouseArea - anchors.fill: parent - - onClicked: { - if (screen.state == "DRAWER_CLOSED") - screen.state = "DRAWER_OPEN" - else if (screen.state == "DRAWER_OPEN") - screen.state = "DRAWER_CLOSED" - } - ... - } - } - \endcode - - A state is simply a collection of configurations and it is declared with the - \l State type. A list of states can be listed and bound to the \c states property. - In our application, the two states are called \c DRAWER_CLOSED and \c DRAWER_OPEN. - Item configurations are declared in \l PropertyChanges objects. In the - \c DRAWER_OPEN state, there are four items that will receive property changes. - The first target, \c menuBar, will change its \c y property to \c 0. Similarly, - the \c textArea will lower to a new position when the state is \c DRAWER_OPEN. - The \c textArea, the \c drawer, and the drawer's icon will undergo property - changes to meet the current state. - - \code - states:[ - State { - name: "DRAWER_OPEN" - PropertyChanges { target: menuBar; y: 0 } - PropertyChanges { target: textArea; y: partition + drawer.height } - PropertyChanges { target: drawer; y: partition } - PropertyChanges { target: arrowIcon; rotation: 180 } - }, - State { - name: "DRAWER_CLOSED" - PropertyChanges { target: menuBar; y: -height; } - PropertyChanges { target: textArea; y: drawer.height; height: screen.height - drawer.height } - PropertyChanges { target: drawer; y: 0 } - PropertyChanges { target: arrowIcon; rotation: 0 } - } - ] - \endcode - - State changes are abrupt and needs smoother transitions. Transitions between states - are defined using the \l Transition type, which can then bind to the item's - \c transitions property. Our text editor has a state transition whenever the state - changes to either \c DRAWER_OPEN or \c DRAWER_CLOSED. Importantly, the transition - needs a \c from and a \c to state but for our transitions, we can use the wild card - \c * symbol to denote that the transition applies to all state changes. - - During transitions, we can assign animations to the property changes. Our \c menuBar - switches position from \c {y: 0} to \c {y: -partition} and we can animate this - transition using the \l NumberAnimation type. We declare that the targets' - properties will animate for a certain duration of time and using a certain easing - curve. An easing curve controls the animation rates and interpolation behavior - during state transitions. The easing curve we chose is - \l{PropertyAnimation::easing.type}{\c Easing.OutExpo}, which slows the movement near - the end of the animation. For more information, see QML's - \l {Animation and Transitions in Qt Quick}{animation} article. - - \code - transitions: [ - Transition { - to: "*" - NumberAnimation { target: textArea; properties: "y, height"; duration: 100; easing.type:Easing.OutExpo } - NumberAnimation { target: menuBar; properties: "y"; duration: 100; easing.type: Easing.OutExpo } - NumberAnimation { target: drawer; properties: "y"; duration: 100; easing.type: Easing.OutExpo } - } - ] - \endcode - - Another way of animating property changes is by declaring a \l Behavior - type. A transition only works during state changes and \c Behavior can set an - animation for a general property change. In the text editor, the arrow has a - \c NumberAnimation animating its \c rotation property whenever the property changes. - - In \c {TextEditor.qml}: - - \code - Behavior { - NumberAnimation { property: "rotation"; easing.type: Easing.OutExpo } - } - \endcode - - Going back to our components with knowledge of states and animations, we can improve - the appearances of the components. In \c Button.qml, we can add \c color and \c scale - property changes when the button is clicked. Color types are animated using - \l ColorAnimation and numbers are animated using \l NumberAnimation. The - \c {on propertyName} syntax displayed below is helpful when targeting a single property. - - In \c {Button.qml}: - \code - ... - - color: buttonMouseArea.pressed ? Qt.darker(buttonColor, 1.5) : buttonColor - Behavior on color { ColorAnimation{ duration: 55 } } - - scale: buttonMouseArea.pressed ? 1.1 : 1.0 - Behavior on scale { NumberAnimation{ duration: 55 } } - \endcode - - Additionally, we can enhance the appearances of our QML components by adding color - effects such as gradients and opacity effects. Declaring a \l Gradient object will - override the \c color property. You may declare a color in the gradient using the - \l GradientStop type. The gradient is positioned using a scale, between \c 0.0 and - \c 1.0. - - In \c {MenuBar.qml}: - - \code - gradient: Gradient { - GradientStop { position: 0.0; color: "#8C8F8C" } - GradientStop { position: 0.17; color: "#6A6D6A" } - GradientStop { position: 0.98; color: "#3F3F3F" } - GradientStop { position: 1.0; color: "#0e1B20" } - } - \endcode - - This gradient is used by the menu bar to display a gradient simulating depth. - The first color starts at \c 0.0 and the last color is at \c 1.0. - - \section3 Where to Go from Here + \section2 \c main.qml - We are finished building the user interface of a very simple text editor. - Going forward, the user interface is complete, and we can implement the - application logic using regular Qt and C++. QML works nicely as a prototyping - tool, separating the application logic away from the UI design. + \c mainWindow, an ApplicationWindow QML type, is the root item in + this app. - \image qml-texteditor4_texteditor.png + \quotefromfile tutorials/alarms/main.qml + \skipto ApplicationWindow + \printuntil visible - \section2 Extending QML using Qt C++ + The ListView \c alarmListView combines the data from \c alarmModel + with the layout defined in \c alarmDelegate. - Now that we have our text editor layout, we may now implement the text editor - functionalities in C++. Using QML with C++ enables us to create our application - logic using Qt. We can create a QML context in a C++ application using - \l {Integrating QML and C++}{Qt's Quick classes} and display the QML - types using a QQuickView. Alternatively, we can export our C++ code into - an extension plugin, and make it accessible to QML as a new - \l {Identified Modules}{identified module}. - When launching QML files with \l {Prototyping with qmlscene}{qmlscene}, - we only need to ensure our module is found under one of the - \l {QML Import Path}{import paths} the QML engine searches for modules - to import. For our application we shall the latter approach. This way, we can - load the QML file directly with \c qmlscene instead of running an executable. + \quotefromfile tutorials/alarms/main.qml + \skipuntil visible + \printto RoundButton - \section3 Exposing C++ Classes to QML + New alarms can be added by clicking RoundButton \c addAlarmButton. + Clicking it opens a \l {Dialog: QtQuickControls2}{dialog} screen \c alarmDialog. - We will be implementing file loading and saving using Qt and C++. C++ classes - and functions can be used in QML by registering them. They also needs to be - compiled as a Qt plugin and then exposed as a QML module. + \printuntil alarmDialog.open + \printuntil alarmListView.model + \printline } - For our application, we need to create the following items: - \list 1 - \li \c Directory class that will handle directory related operations - \li \c File class which is a QObject, simulating the list of files in a directory - \li A plugin class that will register the classes to the QML context - \li Qt project file that will compile the plugin - \li A \l {Module Definition qmldir Files}{module definition qmldir file} that - defines the identifier (import URI) and content (in this case, our plugin) - to be made available by the QML module - \endlist - - \note Since Qt 5.1, \l{Qt Quick Dialogs} module provides a file dialog component - that you can use for choosing files from the local file system. For illustrative - purposes, we write our own in this tutorial. - - \section3 Building a Qt Plugin - - To build a plugin, we need to set the following in a Qt project file. First, - the necessary sources, headers, and Qt modules need to be added into our - project file. All the C++ code and project files are in the \c filedialog - directory. - - In \c {filedialog.pro}: - - \code - TEMPLATE = lib - CONFIG += qt plugin - QT += qml - - DESTDIR += ../imports/FileDialog - OBJECTS_DIR = tmp - MOC_DIR = tmp - - TARGET = filedialogplugin - - HEADERS += \ - directory.h \ - file.h \ - dialogPlugin.h - - SOURCES += \ - directory.cpp \ - file.cpp \ - dialogPlugin.cpp - \endcode + \section2 \c AlarmDialog.qml - In particular, we link the project with the \c qml module and configure it as a - \c plugin, using a \c lib template. We shall put the compiled plugin into the - parent's \c {imports/FileDialog} directory. + This dialog screen has a RowLayout with a \l {Tumbler} each for hours + and minutes, and another RowLayout with a Tumbler each for day, month, + and year. - \section3 Registering a Class into QML + \quotefromfile tutorials/alarms/AlarmDialog.qml + \skipto contentItem + \printuntil "model: years" + \printuntil } - In \c {dialogPlugin.h}: + If you click on \b OK in the dialog, the entered data will be + added to \c alarmModel: - \code - #include <QtQml/QQmlExtensionPlugin> + \quotefromfile tutorials/alarms/AlarmDialog.qml + \skipto onAccepted + \printuntil onRejected - class DialogPlugin : public QQmlExtensionPlugin - { - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.QmlExtensionPlugin.FileDialog") + \section2 \c AlarmDelegate.qml - public: - // registerTypes is inherited from QQmlExtensionPlugin - void registerTypes(const char *uri); - }; + Each alarm in the main screen is an ItemDelegate. The ItemDelegate + \c root contains all fields on the main screen and the detail + screen. The detail screen's fields are only visible after an alarm + has been clicked on, i.e. when \c root.checked is \c true. - \endcode + \quotefromfile tutorials/alarms/AlarmDelegate.qml + \skipto ItemDelegate + \printuntil /^\}/ - We need to export the plugin using the \l {How To Create Qt Plugins}{Q_PLUGIN_METADATA} macro. - Note that in our \c dialogPlugin.h file, we have the \l Q_OBJECT - macro at the top of our class. As well, we need to run \c qmake on the project - file to generate the necessary meta-object code. + \section2 \c AlarmModel.qml - Our plugin class, \c {DialogPlugin}, is a subclass of \l{QQmlExtensionPlugin}. - We need to implement the inherited function, - \l {QQmlExtensionPlugin::registerTypes()}{registerTypes()}. + This QML file contains the definition of \c alarmModel, the ListModel + that manages the alarm data. - In \c {DialogPlugin.cpp}: + It creates five \l {ListElement}{ListElements} with example alarms. - \code - #include "dialogPlugin.h" - #include "directory.h" - #include "file.h" - #include <QtQml> - - void DialogPlugin::registerTypes(const char *uri) - { - // Register the class Directory into QML as a "Directory" type version 1.0 - // @uri FileDialog - qmlRegisterType<Directory>(uri, 1, 0, "Directory"); - qmlRegisterType<File>(uri, 1, 0, "File"); - } - \endcode + \quotefromfile tutorials/alarms/AlarmModel.qml + \skipto import + \printuntil /^\}/ - The \c registerTypes() function registers our File and Directory classes into - QML. This function needs the class name for its template, a major version number, - a minor version number, and a name for our classes. - A \c {// @uri <module identifier>} comment allows Qt Creator to be aware of the - registered types when editing QML files that import this module. + \section2 TumblerDelegate.qml - \section3 Creating QML Properties in a C++ Class + TumblerDelegate defines the graphical properties of the Tumblers. - We can create QML types and properties using C++ and - \l {The Meta-Object System}{Qt's Meta-Object System}. We can implement - properties using slots and signals, making Qt aware of these properties. - These properties can then be used in QML. + \quotefromfile tutorials/alarms/TumblerDelegate.qml + \skipto import + \printuntil /^\}/ - For the text editor, we need to be able to load and save files. Typically, - these features are contained in a file dialog. Fortunately, we can use - \l QDir, \l QFile, and \l QTextStream to implement directory reading and - input/output streams. + \section1 Entering new alarms - \code - class Directory : public QObject { - Q_OBJECT - - Q_PROPERTY (int filesCount READ filesCount CONSTANT) - Q_PROPERTY (QString filename READ filename WRITE setFilename NOTIFY filenameChanged) - Q_PROPERTY (QString fileContent READ fileContent WRITE setFileContent NOTIFY fileContentChanged) - Q_PROPERTY (QQmlListProperty<File> files READ files CONSTANT) - ... - \endcode + At the bottom of the startup screen, you can see a Button for adding + alarms. Click it to open the \b {Add new alarm} dialog. - The \c Directory class uses Qt's Meta-Object System to register properties it - needs to accomplish file handling. The \c Directory class is exported as a plugin - and is useable in QML as the \c Directory type. Each of the listed properties - using the \l Q_PROPERTY() macro is a QML property. + \quotefromfile tutorials/alarms/main.qml + \skipto RoundButton + \printto AlarmDialog - The \l {Q_PROPERTY()}{Q_PROPERTY} declares a property as well as its read and - write functions into Qt's Meta-Object System. For example, the \c filename - property, of type \l QString, is readable using the \c filename() - function and writable using the function \c setFilename(). Additionally, there - is a signal associated to the filename property called \c {filenameChanged()}, - which is emitted whenever the property changes. The read and write functions - are declared as \c public in the header file. + The dialog for new alarms: - Similarly, we have the other properties declared according to their uses. The - \c filesCount property indicates the number of files in a directory. The filename - property is set to the currently selected file's name and the loaded/saved file - content is stored in \c fileContent property. + \image addalarms.png "Add alarms" - \code - Q_PROPERTY(QQmlListProperty<File> files READ files CONSTANT) - \endcode + All fields are entered using \l {Tumbler} QML types. If you press \c OK, + the values selected in the Tumblers are written to \c alarmModel. - The \c files list property is a list of all the filtered files in a directory. - The \c Directory class is implemented to filter out invalid text files; only - files with a \c .txt extension are valid. Further, \l{QList}s can be - used in QML files by declaring them as a QQmlListProperty in C++. - The templated object needs to inherit from a QObject, therefore, - the \c File class must also inherit from QObject. In the \c Directory class, - the list of \c File objects is stored in a QList called \c m_fileList. + \quotefromfile tutorials/alarms/AlarmDialog.qml + \skipto contentItem + \printuntil " }" - \code - class File : public QObject{ + \section1 Editing alarms - Q_OBJECT - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + If you click on a particular alarm, you can edit it in the detail + screen. - ... - }; - \endcode + \image detailscreen.png - The properties can then be used in QML as part of the \c Directory object's - properties. Note that we do not have to create an identifier \c id property - in our C++ code. + Clicking on an alarm sets \c root.checked to \c true, which makes + visible the fields of the detail screen. \code - Directory { - id: directory - - filesCount - filename - fileContent - files - - files[0].name - } + visible: root.checked \endcode - Because QML uses Javascript's syntax and structure, we can iterate through - the list of files and retrieve its properties. To retrieve the first file's - name property, we can call \c {files[0].name}. + If you want the alarm to trigger also on other days, check \c alarmRepeat. + The Repeater will display a checkable RoundButton for each day of the week. - Regular C++ functions are also accessible from QML. The file loading and saving - functions are implemented in C++ and declared using the \l Q_INVOKABLE macro. - Alternatively, we can declare the functions as a \c slot and the functions will - be accessible from QML. + \quotefromfile tutorials/alarms/AlarmDelegate.qml + \skipto Flow + \printto TextField - In \c {directory.h}: + If you modify the description of the alarm, it will be reflected in + the main screen afterwards. - \code - Q_INVOKABLE void saveFile(); - Q_INVOKABLE void loadFile(); - \endcode + \printto Button - The \c Directory class also has to notify other objects whenever the directory - contents change. This feature is performed using a \c signal. As previously - mentioned, QML signals have a corresponding handler with their names prepended - with \c on. The signal is called \c directoryChanged and it is emitted whenever - there is a directory refresh. The refresh simply reloads the directory contents - and updates the list of valid files in the directory. QML items can then be - notified by attaching an action to the \c onDirectoryChanged signal handler. - - The \c list properties need to be explored further. This is because list - properties use callbacks to access and modify the list contents. The list - property is of type \c QQmlListProperty<File>. Whenever the list - is accessed, the accessor function needs to return a - \c QQmlListProperty<File>. The template type, \c File, needs to be a - \c QObject derivative. Further, to create the - \c QQmlListProperty, the list's accessor - and modifiers need to be passed to the constructor as function pointers. The list, - a \c QList in our case, also needs to be a list of \c File pointers. - - The constructor of \l QQmlListProperty is declared - as follows: - \code - QQmlListProperty (QObject *object, void *data, AppendFunction append, - CountFunction count = 0, AtFunction at = 0, ClearFunction clear = 0); - \endcode + \section1 Deleting alarms - It takes pointers to functions that will append the list, count - the list, retrieve the item using an index, and empty the list. Only the \c append - function is mandatory. Note that the function pointers must match the definition - of \l {QQmlListProperty::AppendFunction}{AppendFunction}, - \l {QQmlListProperty::CountFunction}{CountFunction}, - \l {QQmlListProperty::AtFunction}{AtFunction}, or - \l {QQmlListProperty::ClearFunction}{ClearFunction}. + The detail screen (see above) has a Button for deleting alarms. + When \c onClicked is emitted, the current ListElement is deleted + from \c alarmModel. - The \c Directory class constructs a QQmlListProperty instance like this: + \printuntil alarmModel.remove + \printuntil } - \code - QQmlListProperty<File>(this, &m_fileList, &appendFiles, &filesSize, &fileAt, &clearFilesPtr); - \endcode - - Where the parameters are pointers to following functions: - - \code - void appendFiles(QQmlListProperty<File> *property, File *file); - File* fileAt(QQmlListProperty<File> *property, int index); - int filesSize(QQmlListProperty<File> *property); - void clearFilesPtr(QQmlListProperty<File> *property); - \endcode + \section2 Summary - To simplify our file dialog, the \c Directory class filters out invalid text - files, which are files that do not have a \c .txt extension. If a file name - doesn't have the \c .txt extension, then it won't be seen in our file dialog. - Also, the implementation makes sure that saved files have a \c .txt extension in - the file name. \c Directory uses \l {QTextStream} to read the file and to output - the file contents to a file. + The app has no code for adding sound or vibration to the alarm, nor does + it store the alarms in any format or database. Maybe it could be an + interesting coding project to add those features. Adding sound to this + program can be realized with \l{Qt Multimedia QML Types}. Storing the data + could be done quickly and easily in \l{JSON Support in Qt}{JSON format}. - With our \c Directory object, we can retrieve the files as a list, know how many - text files is in the application directory, get the file's name and content as a - string, and be notified whenever there are changes in the directory contents. - - To build the plugin, run \c qmake on the \c filedialog.pro project file, then run - \c make to build and transfer the plugin to the \c plugins directory. - - - \section3 Importing a Plugin in QML - - The \c qmlscene tool imports files that are in the same directory as the - application. We can also create a \c qmldir file containing the locations of - content we wish to import. In this case, there is only the plugin, but other - resources (QML types, JavaScript files) can be defined in a \c qmldir as well. - - Contents of the \c qmldir file: - \code - module FileDialog - plugin filedialogplugin - \endcode - - The module we just created is called \c FileDialog, and it makes available a plugin - called \c filedialogplugin that matches the \c TARGET field in the project file. - Because we did not specify a path for the plugin, the QML engine expects to find it - in the same directory as the \c qmldir file. - - The QML types that are registered by our plugin can now be imported in QML: - - \code - import FileDialog 1.0 - - Directory { - id: directory - } - ... - \endcode - - - \section3 Integrating a File Dialog into the File Menu - - Our \c FileMenu needs to display the \c FileDialog object, containing a list of - the text files in a directory thus allowing the user to select the file by - clicking on the list. We also need to assign the save, load, and new buttons - to their respective actions. The FileMenu contains an editable text input to - allow the user to type a file name using the keyboard. - - The \c Directory object is used in the \c FileMenu.qml file and it notifies the - \c FileDialog object that the directory refreshed its contents. This notification - is performed in the signal handler, \c onDirectoryChanged. - - In \c {FileMenu.qml}: - - \code - Directory { - id: directory - filename: textInput.text - onDirectoryChanged: fileDialog.notifyRefresh() - } - \endcode - - Keeping with the simplicity of our application, the file dialog will always be - visible and will not display invalid text files, which do not have a \c .txt - extension to their filenames. - - In \c {FileDialog.qml}: - - \code - signal notifyRefresh() - onNotifyRefresh: dirView.model = directory.files - \endcode - - The \c FileDialog object will display the contents of a directory by reading its - list property called \c files. The files are used as the model of a - \l {GridView} object, which displays data items in a grid according - to a delegate. The delegate handles the appearance of the model and our file - dialog will simply create a grid with text centered in the middle. Clicking on - the file name will result in the appearance of a rectangle to highlight the file - name. The \c FileDialog is notified whenever the \c notifyRefresh signal is emitted, - reloading the files in the directory. - - In \c {FileMenu.qml}: - - \code - Button { - id: newButton - label: "New" - onButtonClick: { - textArea.textContent = "" - } - } - Button { - id: loadButton - label: "Load" - onButtonClick: { - directory.filename = textInput.text - directory.loadFile() - textArea.textContent = directory.fileContent - } - } - Button { - id: saveButton - label: "Save" - onButtonClick: { - directory.fileContent = textArea.textContent - directory.filename = textInput.text - directory.saveFile() - } - } - Button { - id: exitButton - label: "Exit" - onButtonClick: { - Qt.quit() - } - } - \endcode - - Our \c FileMenu can now connect to their respective actions. The \c saveButton - will transfer the text from the \c TextEdit onto the directory's \c fileContent - property, then copy its file name from the editable text input. Finally, the button - calls the \c saveFile() function, saving the file. The \c loadButton has a similar - execution. Also, the \c New action will empty the contents of the \c TextEdit. - - Further, the \c EditMenu buttons are connected to the \c TextEdit functions to copy, - paste, and select all the text in the text editor. - - \image qml-texteditor5_filemenu.png - - \section2 Final Text Editor Application - - \image qml-texteditor5_newfile.png - - The application can function as a simple text editor, able to accept text - and save it into a file. It can also load a file and perform text manipulation. - - \section1 Running the Text Editor - - We need to build the file dialog C++ plugin before the text editor can run. - To build it, enter the \c filedialog directory, then run \c qmake and compile - using \c make or \c nmake, depending on your platform. - - Run the text editor with \l{Prototyping with qmlscene}{qmlscene}, passing the - imports directory as a parameter so that the QML engine knows where to look for - the module that imports our file dialog plugin: - - \code - qmlscene -I ./imports texteditor.qml - \endcode + \sa {Qt Multimedia QML Types}, {JSON Support in Qt} - The complete source code is in \c{examples/quick/tutorials/gettingStartedQml} directory. -*/ diff --git a/doc/src/images/addalarms.png b/doc/src/images/addalarms.png new file mode 100644 index 0000000000000000000000000000000000000000..2874d2e6ca22679a5ffbed4b3d7437783e27d317 GIT binary patch literal 5231 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 EALchveE<Le literal 0 HcmV?d00001 diff --git a/doc/src/images/alarms2.png b/doc/src/images/alarms2.png new file mode 100644 index 0000000000000000000000000000000000000000..dbcb852c62abb50a3ee78c65b53a326c30a6c9ea GIT binary patch literal 24310 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 a@yzk@POGFC3~@Z+hMKarQmKMf*#81xH9oxn literal 0 HcmV?d00001 diff --git a/doc/src/images/alarms3.png b/doc/src/images/alarms3.png new file mode 100644 index 0000000000000000000000000000000000000000..48abec6a371119988eb97edd2690aa8ca42ab03b GIT binary patch literal 14194 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 literal 0 HcmV?d00001 diff --git a/doc/src/images/detailscreen.png b/doc/src/images/detailscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..bc0f0afb470b0819ab18dbeded3c7270a8acbb9b GIT binary patch literal 10657 zcmbt)XH*nXuqIJ5$Ow{=Fyx%GFfa@=L(U*MgOZbEa6n~9!Z73<Bq$llNph5^f|3MB z$qYG3Sl-*SyXT#=yFYgS^tts_-RiE}RrPiEZKR%#1_dc2DGm+}1q=!{z`?;q;o#u0 z5aZt?YzAaz_ri^ymXW%ssHmc%A{L81QIkGCJ{A%ZIz2rV5D<Vup;=j3cXxN^=jUBr zUE12(o}Qi-it_*d{VOUe`tjpOOG`^oP>`;!uD-rL91cgxOGt=`@$m4NE6B-;i9Ubs zCMqiK?CK&SE^TONSf(s1Co6k%cPlEcZ07u2R7^foMNUCPcvn>#BqCfOCuSxmb9Z-T zDJ>2a7rVPV^!N9dl9CdY0H596sVgZ+Y9i|D>N*s~9Ubh|)KtCHqz^`sDvFAt%I@-t zY7Jg0j(RF^B}F|kVf5^A?AU>*w5h0=ri4NAh?2y%subqmoh-;C-Auaf&y7XeteCu( zJlNLF!N?jatE6M+VgZkYh#QFsd({4RRuoH=6$_9Q89KT%O#HH1<_Zhxy!x3hsupBr zWf`w8V=N<8B`;pEe54M6=qZZdU1L;S%H*|uwQbxLl{9-o)Qgm)L#0Hf&+f#{3r=Uz z5V%R1lhWEcMo&ordv|wxH2GFqB&v5epnZE}WJuM-1-rf0eemmg{ey{;f*DwPdi&_^ z;yV`e(L+LHaqsB%U|&?hu1;S34%@H#?5(-3Mxm87_TnGdx6$#1{mJphQ_J+BXsxzL zgKtNZ@aQ4zkKFYd?=U@uQ;7V$iq!AJv3Hiru9a&?>ka##!@s4Oo~WtbT`rl&_AXxB zjUTP(n^~XPn=h(JZSJ&gHu)_U*p_?3Yzr1mHC3iQMt|Phz1?o<s>x1DN?NQ5Mn!wg zB<WvXTsCZPT{L0P9p5S{K13s;jhrL<vOMQ<98)~>{q)t3kA5C*j+#V#xT*Ij4Yjm2 z)O)G|&T&%Ha?h^)byz#{OGDFUB=K3-)^*<0{(0$QSi{ezfzj>x=77|XPTs*4Uk?&` zFoWNIZ7q(yEE-xkSoSRYHaj(ouINFOcC3svFMZCRneCNzYdDMkU>lk9r{mRaZ`kfc z!N>H-C|ivSONE=C^X{n6*BQ1~Q@gXRZ6{{YCmPl--{oC@8NH6zzI0U`8*I5+KD>zV zcg^Kq#lhjWfq_9rK|go%BK2sDnLod5i9RaazbJya<@#uy?ObrZrOqYF=mE?UOSl;k z)5Bt!)n%C@^<)MzIk}><$1XyrGYQBwk&uCFsieYaiu7lXv!vzzCP;j_a9M4^2Cn+P zobV=D>JKk)ND6O>_d9?3FMRd<Y~@O}BsL#}yFmCh{8LjC;e|vP6o>b-iL4`-*!mHD z-+|bx7YIU3%-jw>0)PBx!m~H;#G2Cx9}sPx=B`9)*Xgf5{(K<k5#oSlj8vkVW~y>= zivi%BbamlcszaIF8;EGBA|u10g!4?hQ-!g=tcCRsT=Zfdj%c5`=nXp7EEj-i_q0en zKKX$d9~cw70^CtwOkZ5Hkk8<w>v)S2**w3FD69cl$INCD@VGeNslUleWBig|@n=Vp z>ItX8=#~t5s)-T-oV?A6QQN$Dja|<G&?Vgtp}&N4({rQKr09nd!nm4pT$smmd_hJA zq3eyUGE*jfff^r*4$3Q%T7J)BTe3MjC|~gFgn2-*AHGg&9{heoLh*(tT8WPuGD+p_ zY~8mO{zlCVHhy!K`lh-szhcWYf5C=Us*+Rkr=I^c+AgV1rg#&&(-rVFLUEUXDaD4h zNPm{T#dsmTCoJ!)w=rzd%wR0REgQ4h6NA}|agda8$HSzMJm}vP?-Y8KM%=CJ)G6Ec z+>kt$!7wFij%T+{snMVa(+~S7wWtE~i0>E8+vdgPbQq!^V&lOCl!6~7r&1qt8mU)P zQBZ`B*PYsaJsR8dvC8oJ>%fIz<D*UnfGS#pWqh01E^d`VuW%VvG=9*lMdKvTrvSdh zh7c!12r6z$&pn;AdwlxzSiUl@>5uNc>3Nrn@F?i{9ifaYD$;sbIR5Qi2mz>aA5bh9 zwTQ%x_~x0EyUJ33yCA2DA%aN=d<1hDlXC5NcC#EVE$tk9z^?j5P7xdxSH%3BK0Cmt z66uZ9*l<Bhx-K!*yk$6?o4I5_G9I1Pp{UbWN6Xogr+!_g&RsDquXLj|D?B|%C3+n+ zV-A<5-8TOvfC)l;k$?xrqFi5l(RxINsw`S00sl)V1ZIM03xToshZq-fF6WL(+P7c& z&UGW<-&b10b{0DxXVBfk{`?a^cL_QzH5Ycd4r`-JV*p6Mox~4pY=OsN-@D<??P*nh z2wiWA%`BnJw^a&NQQXz}U}XJfygcYl?CY4=7llFP1M=ld{*6*6W^I)-Nr_q#L)SkT zL+{qJtU3|9l5@J%MUka$sR8zFe{s+bMV6>hiCF4)3!MfHZsrqI&Z3RV9;1)-XNoR# zC(VO?Db}*Bp|*Gpz6Y?CG3^Oud$jMVI9>RC52WU_mOHE}4eF*Y_&fOV;L@fGXM0Ia za4<3#$l7eNR3|KWS2pSPP?|pM38!v6uZ<X$C2VFl^Gnc2ZjV302Is<#g3?l1dHTjS zW5-*D+KWYk{FbOb33vDt0+j9qzP>8hRxZQ7xv(7)pv(KT<8Lkl(ri|6{D%vO<Eejo zdG_P_^zq$IPK;B^Q-fW6lLkG?IPzpWTro`PFsN`@@9l)gNHoCn7o$g5k$Xc>Q($eL zsY2lE<ct7pcZ0+CDwf*LkD=!5gNiC#-<OASwK}t&QfxCeY3BJw-l|tz9OqKVxIe?V zvpbT@T>=#@s{gRTZ|VFy$Hc}VY$`+Dx3Q`7!*NBbeU3QrLPQgn{GTn#@<?d5i5Q-F zsG{+tsB8g~razeaXIkpOM`k85)ah=OhNH7mj(Tn;Q5k_EP+_DjuNL>o>1tBJLGP*L zp7jD}=m?C1R6MveRx+I5#9lL7CUAYgB~Q?*okkTr+Q_Q|)d*72$J^-41)dcHsr^n~ zY%J7u|7fC0VB!aGwbJF5tn?Opu7C-|j>gEs(>g^>C?5^u_>HnxypYRK>1jTQLbuGN zS@Gp6Kt-K0G`Chr4OlwiGukxfaCF#dESZA8Z>HIUQi5$0`DKa6!~P}uA>ow``(mYU z3I8TnY7=cMq$!C8*yn5*sUk4cGSJNXKpf}9D}z705i8_%E*QKy(TxI;F?7drPIwNQ z8NLT<4<xhwSgXMV$mJ|NC<EeC^uyX!gv^nXKfH^U`clCT!*+z)^rY;Yq^b2~@T`pw znD@0yX<>iz0Jf2GMtt2##Pd{xK39)vxRZ_1<&hNdv!H_&*GK2VuwJ;aq5<<x8HVsB zmk34^zKd^!7tp>TOn<5W&xd6{dT_p<cjjjRjG43SoOqq~*NO2E1&`46(u*OA;@)-E z-(${3Nj5)5Kc=zk;~Ck^X7hg^eDVInmy4N-n@{c~`eXs`L@F>yeSca?fyIjIVKD;A zM0<uo^fLyt{xqypKOqgvBC!qoN}E91Tx|)K>V<`Y&qIdP05e*0)~2!o9eye`r&GqY z#wBzR9J?Zb8^`4P#4vqI1{2|t(mb4*Cep!LX3x$l-zyTlOVG0v$&>j-kHOu)2EJrb z!=jG@5KW=Uh4$%;(h-l&$@nj4^=2l~<Vu(ZPLfCS<4Ko}W_@UKPH7graC6j?CZk}V z2sd=qfSn!u4Rt)e07&O3&BpEzC#M-Q(FOkIQI5_U5PnrG6G#7w?cRhoK2H{x51<$H zY!aw7dSD+oqJsk?7PH^TLahyzWfpUQxGQ7@wMM<wa&5sZ1F=~y@UW;a;q9DR+au@; zf)O6pdW)d40gcSPn<cA0^aW+|dV~$L;kw0yG|{1*hH55Y)j@30J+R{oH+MjpW6T;1 zcGwj_d(RK`XA9MetcL#j4|}GnyLqpF3WhTXer<Lv&VdLFu3j%Owa5q8Th0`(T$Za9 z4ajdyj3$xAPcY0szq{$HEZyvz8QAg0ZkCOu4}_L0sQdJ^bbj-pb@p_^D$e_yHY;^$ z9B*X2ujBkDi8fYP^ns#j!l?}DUQm8FuXXf9q1~(D2szbw!444U@OsZT-mFzZ#DQPy z_0q|pa5tyaT8RN`pv=!-L9|o3PyD&`z66YDlDfm;ai*MPWSYz!GmgW%9`ct9(E$=Y zyWqwhX*HOUz0xP4Ie8xQrnygVRbgknK+9n;?CLA`rxN~3XBVEO&_v45A3~ZJ+4QEt zd)zRRiNEp^!Q~+v-zktNek%Cc8p~jh7fp<{`RHwQKxaj1(6dx^1B2s5WjZP4iogfk z4|!inuCI857+=L87^`U83idJ>Yx-8RgVB)WMo(rgD7Sl{aYIKHkuHgmdm~Uy2kQsN ze4^~hYq>FcvfmtqAj?r_K%t8J`9|WOW1Z>oxb*&TWiiZqE?yiHTG{OKi<YnUkTvxT z&YoKEd3B+lD|PtM*(`5IB^^?|qopyc^827edyd}xb+G*|o6K6fAdu(u`Zn)FSB@R@ zO&r5K9^O6>6fwP%c$J9-JXZM_&@5iqyhz?5{UF!vjrF%N#htJ&<*IU1(nnh|4|Xem z7m>f+p)-%GX>Q6hIRx*q>)};B+&ImTq_tZko2U?Fq`D=Al%P(H8<?y^ErVsRFX_)B z)lP^yhNST9;1$t)MU-VR@|l2b+y5%Kaw7PODDGA3DkQ^&r2ku+|I_SET@u0Oj=zhB zc0mdzApUY73rpb3T+4{#r)b@z-}KSdKwo9+lJm`f6-LB_$jmQ=u)bfGB{Fj3=KH=i zGdY7|4@{AEcEJ;0rUmLC*fUpN6B|nZBhBE6x49D%Qf_4m)uz*oU0Cm8g-;M{8dDv_ zi)NVKh)W`4&|jI#xnVB7)SEP4!SULR8VCDDS}5*;#A_n&U9Bt+`8b+BK+iw3MX3rn zhn-MC7-c5Gj$qdib>U=AK2JRX*`%YL;h~&)q4SGN8JImoU|rexl-B`T<%=dmiKs`v zViL~B^G*<at~{HK-rML~<fM;;t-7F~pj|J@KxgoRkDi&UZr>~)sF9`MT-6796fAwP zB&!duG@P`bduay+#|eIfbqQq@kVO{~FtRP}C#!s(u*5+OuuVtc_a4(xvM+s>>Lwnw z5@(RJ>5$1b<Qq}7+)vR@<so7jO;meNWQqq<<bfxVRlHDvQ^RBfKgpTf3bPsztu!tY zucca1#+61EVOVtX*ocrNczFqM@E;-*ydPHZ?UXu5ZI$DVJztwkj5GX49<Ls6h_hW- z61=0A7i_PF=cH<{U#M6I*mO}J4?KgUVs1y7n0r+aB)e$vE244^Vz#Ehw!*6?i4?p2 zDF+9KzlW9AfQm2u2ku;31N-G_wE$6XS;ctS^znSS&R?Z)G(kw{VKMaj0AFUgU_`RT zuO@&&QK=0X@E1mB<N@KBzcv1rb(Vz@@$+T`o|Wqp5q|arkpmNw$`{ZlM^Zxls=55c z<3(?|a$YbJ<=ML~lt%r$RV-K4OD1T4)ei=F#>l`&MyNC%xWjJjm_=jm*~?DC=?q2l zhuE*H^}VXfD0MNyzoQP&=ZZxq|1>QlqYp^N2oK{;-n5SPDM^WcH)7{)Yv~YhdufQ; zsYba>kL^wNDzNgQu7+Y@>F~kAD5rFN9@|G%GXng1WgbR<pwxUMKBfQ^J?n}othEKs zru8XwyHEBL#0yoNhWc5|aG!;eS6z&cHz<CK*D%!g!j2OK6o!4aln%Z5v=XCIiuCb- z6Oedpu~dj0`PSMx8Goynl=`!hmLFMa7^x8BEEt#z#L852K;+&UMedWhk`v&&q($Z$ zl24E#cFEHDdVce@UT<gcO_Z5QIkn!bO$b$F-ANMC@-QolGv+nlhs!pE52lX9`F+%e ziB?^u5i##p`J>$rKpDh64+^WmGXLp`ExjL>>W<Q8WRzAxz9r*FhNod3*9BYl<GQsi z2`eC|OJghp9SwKhJSqhW2Z~dR%SrFgXxv;cxNF#`^kMY>n40OGIKaaQeE{j9%-x$T z0g5u@Om=>Va6%tE#ZwwZJ5KlPX0Jmv14ljNm)vuy2#y6J#PWm+ZUpJV4cDir@H&eK zR?7eEHn$GgPSrf(K2doyu{c6~OS2MyRK-Flwu`QAU`4<lR9|e5KlsL~KFaKK%|g8l z4H^Gg9PJYtg4M8tf~?Jf-JkUH*V$OMQLC3&&B^7wFV50$S@ilSdF_bMb^YhURYHwr zdBQvd>OtjuOdK=;?_63tUgbNLoX2qzcePh_BK^}>s!rqQJvRA1Wb_so0`}XY8M``` z;4Qi~Wec8sN_&UXf2el;#s6(Qvs!8BP6V7Mn5?26>CW3Q`n+(dbe<9qTjJ(f--3AY z;ofGV+K0Ev#N0K6*n>+7Osj<j__bGzeRTJHCEt&0g)%pG`^^n$FwcZJMT*%wuWpqB zf2MI4oaLwH&wau-P!(xB5!VsOn$uohogU{BaUgO>N8WUe>gI|mJU3qc4q0K8L8YTn z-W~P$eS6Q#|17l^q6OK>j-<Y~*zNg#Q{2@~dRFgv^MHD}SaNIB{{=h+)b+}s*xAoY z_An?KCsGIIRZ{A$du7h=76umJ`>rDu@*Cb~WcFRb`28qkRP_0Yuu^nAW{Pj7e?*Z{ zZ*w^9IWVI?mXioAtoli0woXP#AYF-t=c}mdWI9=OjHB?&fd-FL!V3rZ=Ib;Of0vL2 zlT~Cv%nb9MJ=3>3ovA~GijVs?Ya^-kDOWE~N}ejPiQrxHah;&%g_k45zr4n3nq!~? z)hB_~VW-PZx^&3Ca(P;7Ri6HSs*FbgwRx4QAN!RyzJB<Wf>!4YFMk)``X&48B<)_; zQz5J~F&yd2&(yWNDX9qw;yJ7R8GROK_jS{1ZI=J}iM0=DOU{B^yS`Ki9n$&3jDV}T zbjZuL{wI#gAy2h=o)f(X$Lv%FcfaNYXn-xB#ePp9hIM7vJaaN3OKEKrhz$3>ijX0w z@ws`cLZVO@^FK2RAHIOgwHpNp{C|O!y-omoSknvDa*W#<C%;i9pJI;GL$+2(?JeY3 zwhZ#2!r#Y)w=|wY-r{k&;=V9R!^}r~<#*-$Pdy&KIXj1rd?F!%k4-zrE#nc)Z=QY! zYk#esSZ*9QS{#lM105t<mkc=6{0tov0*!i^hVC(SL6CI3m+DLp{y}Orke(;1NcE=q z=9wM+V#Y4LBMZpVKEA~#_aFAQFHMDi$b@Vq?EEe{{B6U^%Ar*<Z#t^^bN93(3oq<N zX=r?c&olpw@#aM9<8H@w+6~QnJq+3yOz8PUThgFdWjw*g&Ac$i-~Pv@$JM&Z<hXiV zPbRJSve*-@w0!0YZ@I|B(8f4Q?H%kJUgPF}rFcH}^$Vr2ZxRt|uc|Nu?K2;@7Qg#1 zDZ$B)8Q%_-9llhSVl@8DmN+4DS&d3x9z_O}m^z^LZ{ZVsi@PUP7kr%cV9rutv#<j| z2t)7nZBr^ijARxokm8_w#o7i><WK&TN<Oh^N3+MBo@m|pHv@grmDLR&<0jRIKMP7T z;^C4`Tv>hUegEj+O;oc_h&o5@S##}RaJ*(VrM`AOezL+sj$L&?xrp#>8P6K<*WXu$ ztYRt<Tx*@m(_1!U(aHfbMbwVCJY$Ur5+M=n`~{l%;ugAe1wl%#e=IF^&smTR*;<D2 z#=B$RIAa5~N;0z7)scF!tiE%eAeZMwyPwQwrl(KBKhp2->#v9Y;`omXIy+~bF{qfB z4bRgmG36V*d0kRky0EwtuQo7i+62B*?eAFA=nr)shj^`pT+*5NpcuRCcwSvNqj$Bj zA{v^CBuU{|U~7jFf`LCW9#W6t%s8*MCow?4)FKn>+6n=4@CP9x6)LcUAQ6S^k4Ysc zVTGX)Vst5<;hqq+W~b~E0roW8W(T;a)a<~!I!AA6xWQ{51N)lW!k3;T9t3^}A>z`X z@oqmW2QBsnCoaFPSD&prKX~A%gL9tY4f^+4NcoQAf3)8JUMLs(C8qvCx9!InccGyh zpZ+y{i-*(_K2BUIqsoY|tW47*-Pu32-k&!SVeEQrCK*CT_hj}u9z}^Qv4SDTY)y*g z1^+`K6_N%>G*G4DGCBezT9e&l)?D&~{~p|r-5I-9O%eA_O%knZQTB#`ZT!MX|9KAU zTEL8-;A<P18ot+%T4j(-hyWzLdbgIT>ow<TdrjpdpQ|wwY_pH+$<-t8l8hlDhGn51 zOX-l|ime`r_DT~h1>L>>U8b&@!pN)PxTNQ&#WOop_bs9J|E2c->$?2U26CUB9PqT2 zr1#UC-%2}Y1k9!7X|@d?Ct9mNXX@f+U`s2U5rBD=%rE4G=c#IM@&hWpPM%vhg)~K@ zY=n;<tZsTpXMM;}D#E<%mKI%rc(uO#_~mz>p1nTiW-f81+hhEMpOA}{llC9Wgh}<Y z{OBA0D+Q988O><QQA7Cjrnaa7r$v(NkLMQ(BvmsC?gDu!Zd|S>&oROV>|RN=m}<S5 zd6-J#N^ta86(8;WI%DZL%>^(QZ=zq5(h8c1y5y?f9I3|ulObN8tenjGzQG?J8YZVO zK7S&HQR2(PNS-hW#;P!OebJz@VmE!v&9ywedE>h<mdc5IM3@Fp1N{L;K}0BSoWz}y z1u4^}ydz{7yFz$I*Vwyr=&#fX4tbcm{;sFnxrR%Iq@kj%xqdu%<$4o_xHwK+@$Smb z?)5KJFqOE!{ftYxL20=Myjwi6g^XSFE2(JADgUTNiC&Rc8Vz9JiPs6Y0I0;2r9}{J zCKIA`AG$I8=z_JC^pd$1&-H|n>k-C>G|}4NsB5h&dFp^wrDVPeZS(atM1=2h66W22 zilCm*yR=9K4F5B!*PCT9?d{E!q)~(*rwG#+pCQ`{5y6(AbtT_mVFeU*<$z`2z}NO3 zq>(|rsuXAGv)6Ir%Wr=q@%5r1kCgjRV(Ppw+9Bi|78pLAv*)O+!PJ{;ONPgHWS<@Q z{P1zGnBUW;p!m+#tXH^Mk3QdUSx!Io9-q3yMc4h72=y1d-zdWo9a#-wRDiQ{DZm5K zySzX28%i8CMw3u1|DOQQ+5QvYD_+W97q#=>zkh!f`w+0k0hFdegR|7AK{Joj-bb?u zJvMTTi6*&88A~WEjgH-X(h8jM21^;M>8Y6jg*}=GIl2@Slg2q2C&v%YUk``=dwVXs zPeBEXt9b&QC^2r}o`~WrWgmrJwm@(Up=zk3PMmS9O|p?Gei<(8Y#zAhLGqbY_sF{b zEpW_Divwvi!H)FJPK9y+Ms2xiPyC+vX9`Y%d>Lk5?+c`2?C@=G(=YHzZj4bEauW0} z5x{UPftD1iN(;=9h5QslA`@}59=%0)K3OJ#S${0g-J+d@Ge4{S5~f@GPyW|84Uv{H zlR(X*!2-M#$I2L94j%KEGDD^XD{Gv>`~4s%{MZ_*Ctf*zM09y(p*#F4N~j9x5lje3 z?F0xhNO7`Aat!=n!;>5|No;OkNsFq`<j9QW7z0Kh#-<4mS^*S94}oXjZ+*srOznpp z$aWwC$y=<oZsyk)W(nLPvtbrP$FyvAJG`*RPlOf=BZC6}r1%>Ep6J>mh2FhSeVQ_` z&;-67jd=<m%J(!Mx`nPzx2pi8U=>I<4xX8Lu|Av#Nec#i&MNW%99#b#a(Q`kh6u#p z2g8gJ1b3Ip!oh1d2I19Jy!Y>mYF>x^&pyZf?H))C`I1{QLKhn7ijPB#Bf3km0zOt` zd<_yT4Y%{f)~qwW-Qr&f#ww$L8YpI%FK{&F|1xlFwAhz^*r)Q4!sPomyjI)|IuJg= zz~ojRu9PLADTe*?W4vpaPBy4B3{l?F+jj_j^&5saY?E5?Iy7;z4yaGGFB+$k0=DW? zic?DltFN(eeby~jtYsPNmxJRKVA#TDotfW*bQ>i0HI^f`uNJrKSIv(T#iMvghQ5h@ z15}h3k$!hCVP1eC8YFx_x3Yba8pF#Q5Rhq4eU#_fDLKbW6^8n;<M9XZZ>2N~5}ceG z<itsxknxv+Hmabs9xy2VQDUkB=NE91_BpJuMZu9F4X0or09EMsQDVG;U>A7Y?*&9w zK6XpjCuxO!7hneVKit=|dl#{rE9OcAqIpBax>Ys6%?5Z#l51<QP$oMKeDHb!3iSzc zBVZzFV`G+P<(1`*wWnS1CsVa|P$f_!l>%BiP@9wW@>>7i=3ol^k*YwzL)WK}nHBz~ zjST;#O}$09Vvw?eghJ!)okK9tPet@?VuOWv@lDFfm#1=51UHSfI^{_gj~G;z-s5ji zgPqsCT{ly>T=)oZt(`_Y0lsW<aM)DSRJkW_hYGwp!O{OBFrCENnw+8xB2J-g<S;oe zw-HQ~ojC-7p?=dcTEpl)nfbVm;bw_saqPT6p_{hyj@2hO22HQhpD~V(_C>WWcjPc4 zI|uw_#%5I?F>z_$Mnt2!s@q$i)(YIuqle)XrhL*`o;qvjZcK<mPjH%>cl9s4%b-mF z%cUjEBr+;6SBKIVoO)4w78yusO=ngWuZT(61hSaM_QX>gkZ}epcZ<sT2D{|OI%au( z<&cJ_TZ%l?!TeG08DqSU2(nK66_u2-wx=CpP{?%*T~X|A^7FG}(*UE2n9_P7e89-3 zTFw2X^l=;NLRqGLP+{*${HD@BSMwh&up{QL(kD3WrUH8$%@;W<kFpDhWNNsM?f!B0 zmV?tzEUz!clt+nOM-@>sx&qOTz<B?X^m_dUV2mv%-T|q#3KWv&Ej$CO)T(x7z!l2U zm}Q%9-eS?H>5^A5NO*xGt%G$5LGA-)>(yu5-@7$f`<|IvQ>o!F(e+BKez!JdCAYFC zh;d{cEzth{tKaL&xSnDD9S*zAujzwvN_GZQJR(}ytna?Zp8>{G&Zp0cImL)x3OY(I zG6!mE6m{$^EC=p-PL?}(0GkUS0l%oz_gtD;LZ)9FXHeu_$i?if-d#IvkbB(!M?rr^ zrQwIGu@17;{CQdVGoWwgVK|pd?)RCN(mq`Na37Ccx4ABYqKT-MmoZ~gPWjbhf9>*b zOhaOlVmuL~r}~{DLg=c?TD)!n1XZ`pv`TwZ(c$Jb38W-m(peRu3H2r+5oYh@0=C9D zHfjvx{Ra(2UsspU)YGh6_O-?Mk!%1axpFmSGrWb@Ec=jM;wIYkaeW6qJF}immQY^{ zcuj1)o)1(7F5xo$;t0=tyD(?^3)erEFtXv!H^SZeccBJNQ2uA~H0#PsK{~g0q#K%^ zHPHJ{qRBxB^^MV<y*Zo8(}((d#;*n}mfDg%=ghY&b9F{@=!X4&_g&)FG8*m~BZ1+s zz<<7qXv{t<oh-`iCb@p)X_I0Z8{-m$i)tK%R@FcwUYDNxH=;o7>k||W0Xg<ur!lUM z%?2;WNxa@q7*Pr^jYe~cLZ?g&7<uem><13qCV$v*M+>SA7ist-ER%cMU$uC5Cs&Op zP7i$p;WXD*1I17ExB%f~>R%1rzAgy!+;)iDZ4NX9>7+k`TS^eCUry|720s9LQ`#p` zrVnw`v}X6dut84_=Fk_fXe}dqvdR|tU@Ttsf{cDI1;gH#3|aoQf#N;#T+R)1mo=2m ze3PT|BKyoky-AM?#TM=R6jhgSNmL-$3H&DlB3C&pbFpB3pv1q*S};7!QuUZ5A#egO zcu6HP)`O&tvcP!hP3wVvg8$pyK2Tf$9oe&{>CtG-KZ@^JasnEE7_BCo0e1Tq5f%c= zTYU3u<I#$cKATe|RL~Ehto>wSL?B^Rr(Fv<w<WtinN<vi^~x4V<bVX;xMOcYc@NfQ zqio_2bua|I^c>BV1Oz_%4K&dl2v0<Dz$2mzSy@s_M9F4hETS+ceiO)ln`QKgn7>%I zf~~kB9-*^;E9~MspWQs2{ySnTJp2SD?Gb+2xw`yEs`iu}H{oH&e2eF6PH2cc%vv{8 zBiUbP|Cl{Y%`U69jh}%drHdMj8hNjMX>!F}O`&`_{lhpJ$CCFfT!-UZ;foJ7sC7Av zbC>#7<52QIGEfi}16kO&imKFesfIMXR7#i&wfnd{Ls^j=<Ni(!G%FXp7PLS~1d~_t z!42{N;e{`Ax85byp<+JQ3A5@Yk8B`e3hePI+a)hk!kOTxz}j!}b<Ox0)j}FTm>r(R zWu0;8%dgMX|1B!H7XC)`tC=a)nWTXAzy9QKHm+OiPV`nHU$5g+F-iR#!^8@DHn#C< z*dp1y4w#jx10by;$nFKg>I<8B_Y3htn_G*7o;8hbjwn<#5oY1#Txp9YKcv$@NF@!l zXR>ceK6Z2+Qd?h#iVmlk(P`LQF(U(ffZqpG%rZz(wBO$df-TejEB;@M{?9^&K5(Vg z>@N6G1wN2djye9)C{^;J-Mo)!z^NO^8e5hB)OLN_u^X7rqjK%Wsi$>rCAA|X03{$U zkj5L_^sHQUJyRyJ+B-I1uPr-X=E+ok?#>Fd)&Xce0ol90`|7`Ls@@m;xlH?W8$0Uf z<j_ah!ikuQ0lVtmdrIy!U@tlF6*UU<t~8}@uJ2C414yGpssmV#mTdSom_qZ(JX&vw zn-}Jvl1a<@nl#=g=NESo@RTbyX}x@)L02`OX_VqnT6zP68i}{P!F@oI6xX!r{dKGn zYlfD2#RuR5IDY`2sE(=*aQ}wZ2zf|Pd3AS1*DH<ZeEB=5IUL9WkYQ2qd0<kY)Q&IH zKRY!{lp$Fp=Mq~=P{b|(x>n>OCF2`>E}o7tDj=*~>FZwc3nq$215FF5gBy=YEc3e} zQjwY5?B?w28GKse1{Q!J>+o(jS|mTph=>6Kn@Jya1T5^S%*Oqqh|)wASQNY36hiYg z^iTQ(N#55h<MdtP#62;5W(v@MbZO?>WP^(RR=oj7MQaX19ndibeg4$>8Zve<v+by; zXmyqhet>pN#*9|oy<1e{OW_}q=`<XY0_qnk@YIBL!BiyB>uLV>A{4OA@r~P#0+t`p zfz?qC9b3rPwHi5g=;&7SJ0B#O@sAWhDc4<%5BMOrTNnvR?nDS-_%2gYNf@Ht%`~dX zKbj~^v};7yNX}aXX3-CHRQDn?#vq$AKCDgI9kssOR(F&15om`1BMA^dJ#Ivd9KZoc z(|5{2!lr_k5t8Li>H{2thIK)cBK87pdfwXA)Mg;D&<WJ0y01T1a@gCH+S)WErx>Uh z%xek+u_*}u;0NgFXBTqWA!1CEEAr#z0BXQlV4fDr0BtDz33&LBB)XOz)d~SVE_h}d zJ3UP|17(XFpd+aymZnDETb{lh10$g*nhiaJ@a!`!;J0$OsRA&z&FCcJ<5M6x6tSgu zH1{cs0U&ZLpk<WeXzc;*%tU(mwtrSK-(_GgA~EH*Bubg*`ScWsuF2y1Iw4?|?12Jj zc_%tDy_e;&j04ML;l56y$?8F7Bt>)qPwV1%0cqC?XB9Go8A~Lk^2Z{NP>CVNVw|q= z;FQh!%c&KmFOC#5JK$PsjxpMe_&DO#I<=H2WJ@Ad;YgFm3S*}_BE3}9Jhilc!{<E- zxm!>?fdWb9v}{@vyU3iG<pwkXB9oG;2I!ff-vFJ7bJxN3<Jq|NxkKR8pIqD=fHPWf zT7Izs<y{V5*at0AnrjYO7<yE1n+<_3m8>ixj;aFE|4syfuFFdv;+VJXu5@X<GiftR g)_AwSY|(rqBC#8+vDwV>;6JDwrmh37QME<<H|tshlK=n! literal 0 HcmV?d00001 diff --git a/doc/src/images/mainscreen.png b/doc/src/images/mainscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..e0c5e9796e0c36bdfcd507f03cc8e0484033709f GIT binary patch literal 7056 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 Q^pAGnP)+4(MT_A702C`b5C8xG literal 0 HcmV?d00001 diff --git a/examples/tutorials/alarms/AlarmDelegate.qml b/examples/tutorials/alarms/AlarmDelegate.qml new file mode 100644 index 00000000..97ffc867 --- /dev/null +++ b/examples/tutorials/alarms/AlarmDelegate.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.4 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 + +ItemDelegate { + id: root + width: parent.width + checkable: true + + onClicked: ListView.view.currentIndex = index + + contentItem: ColumnLayout { + spacing: 0 + + RowLayout { + ColumnLayout { + id: dateColumn + + readonly property date alarmDate: new Date( + model.year, model.month - 1, model.day, model.hour, model.minute) + + Label { + id: timeLabel + font.pixelSize: Qt.application.font.pixelSize * 2 + text: dateColumn.alarmDate.toLocaleTimeString(window.locale, Locale.ShortFormat) + } + RowLayout { + Label { + id: dateLabel + text: dateColumn.alarmDate.toLocaleDateString(window.locale, Locale.ShortFormat) + } + Label { + id: alarmAbout + text: "⸱ " + model.label + visible: model.label.length > 0 && !root.checked + } + } + } + Item { + Layout.fillWidth: true + } + Switch { + checked: model.activated + Layout.alignment: Qt.AlignTop + onClicked: model.activated = checked + } + } + CheckBox { + id: alarmRepeat + text: qsTr("Repeat") + checked: model.repeat + visible: root.checked + onToggled: model.repeat = checked + } + Flow { + visible: root.checked && model.repeat + Layout.fillWidth: true + + Repeater { + id: dayRepeater + model: daysToRepeat + delegate: RoundButton { + text: Qt.locale().dayName(model.dayOfWeek, Locale.NarrowFormat) + flat: true + checked: model.repeat + checkable: true + Material.background: checked ? Material.accent : "transparent" + onToggled: model.repeat = checked + } + } + } + + TextField { + id: alarmDescriptionTextField + placeholderText: qsTr("Enter description here") + cursorVisible: true + visible: root.checked + text: model.label + onTextEdited: model.label = text + } + Button { + id: deleteAlarmButton + text: qsTr("Delete") + width: 40 + height: 40 + visible: root.checked + onClicked: alarmModel.remove(alarmListView.currentIndex, 1) + } + } +} diff --git a/examples/tutorials/alarms/AlarmDialog.qml b/examples/tutorials/alarms/AlarmDialog.qml new file mode 100644 index 00000000..10e5a264 --- /dev/null +++ b/examples/tutorials/alarms/AlarmDialog.qml @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 + +Dialog { + id: alarmDialog + title: "Add new alarm" + modal: true + standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel + + property AlarmModel alarmModel + + function formatNumber(number) { + return number < 10 && number >= 0 ? "0" + number : number.toString() + } + + onAccepted: { + alarmModel.append({ + "hour": hoursTumbler.currentIndex, + "minute": minutesTumbler.currentIndex, + "day": dayTumbler.currentIndex + 1, + "month": monthTumbler.currentIndex + 1, + "year": yearTumbler.years[yearTumbler.currentIndex], + "activated": true, + "label": "", + "repeat": false, + "daysToRepeat": [ + { "dayOfWeek": 0, "repeat": false }, + { "dayOfWeek": 1, "repeat": false }, + { "dayOfWeek": 2, "repeat": false }, + { "dayOfWeek": 3, "repeat": false }, + { "dayOfWeek": 4, "repeat": false }, + { "dayOfWeek": 5, "repeat": false }, + { "dayOfWeek": 6, "repeat": false } + ], + }) + } + onRejected: alarmDialog.close() + + contentItem: RowLayout { + RowLayout { + id: rowTumbler + + Tumbler { + id: hoursTumbler + model: 24 + delegate: TumblerDelegate { + text: formatNumber(modelData) + } + } + Tumbler { + id: minutesTumbler + model: 60 + delegate: TumblerDelegate { + text: formatNumber(modelData) + } + } + } + + RowLayout { + id: datePicker + + Layout.leftMargin: 20 + + property alias dayTumbler: dayTumbler + property alias monthTumbler: monthTumbler + property alias yearTumbler: yearTumbler + + readonly property var days: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + Tumbler { + id: dayTumbler + + function updateModel() { + // Populate the model with days of the month. For example: [0, ..., 30] + var previousIndex = dayTumbler.currentIndex + var array = [] + var newDays = datePicker.days[monthTumbler.currentIndex] + for (var i = 1; i <= newDays; ++i) + array.push(i) + dayTumbler.model = array + dayTumbler.currentIndex = Math.min(newDays - 1, previousIndex) + } + + Component.onCompleted: updateModel() + + delegate: TumblerDelegate { + text: formatNumber(modelData) + } + } + Tumbler { + id: monthTumbler + + onCurrentIndexChanged: dayTumbler.updateModel() + + model: 12 + delegate: TumblerDelegate { + text: window.locale.standaloneMonthName(modelData, Locale.ShortFormat) + } + } + Tumbler { + id: yearTumbler + + // This array is populated with the next three years. For example: [2018, 2019, 2020] + readonly property var years: (function() { + var currentYear = new Date().getFullYear() + return [0, 1, 2].map(function(value) { return value + currentYear; }) + })() + + model: years + delegate: TumblerDelegate { + text: formatNumber(modelData) + } + } + } + } +} diff --git a/examples/tutorials/alarms/AlarmModel.qml b/examples/tutorials/alarms/AlarmModel.qml new file mode 100644 index 00000000..6afa5db7 --- /dev/null +++ b/examples/tutorials/alarms/AlarmModel.qml @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.11 + +// Populate the model with some sample data. +ListModel { + id: alarmModel + + ListElement { + hour: 6 + minute: 0 + day: 2 + month: 8 + year: 2018 + activated: true + label: "Wake up" + repeat: true + daysToRepeat: [ + ListElement { dayOfWeek: 0; repeat: false }, + ListElement { dayOfWeek: 1; repeat: false }, + ListElement { dayOfWeek: 2; repeat: false }, + ListElement { dayOfWeek: 3; repeat: false }, + ListElement { dayOfWeek: 4; repeat: false }, + ListElement { dayOfWeek: 5; repeat: false }, + ListElement { dayOfWeek: 6; repeat: false } + ] + } + ListElement { + hour: 6 + minute: 0 + day: 3 + month: 8 + year: 2018 + activated: true + label: "Wake up" + repeat: true + daysToRepeat: [ + ListElement { dayOfWeek: 0; repeat: true }, + ListElement { dayOfWeek: 1; repeat: true }, + ListElement { dayOfWeek: 2; repeat: true }, + ListElement { dayOfWeek: 3; repeat: true }, + ListElement { dayOfWeek: 4; repeat: true }, + ListElement { dayOfWeek: 5; repeat: false }, + ListElement { dayOfWeek: 6; repeat: false } + ] + } + ListElement { + hour: 7 + minute: 0 + day: 3 + month: 8 + year: 2018 + activated: false + label: "Exercise" + repeat: true + daysToRepeat: [ + ListElement { dayOfWeek: 0; repeat: true }, + ListElement { dayOfWeek: 1; repeat: true }, + ListElement { dayOfWeek: 2; repeat: true }, + ListElement { dayOfWeek: 3; repeat: true }, + ListElement { dayOfWeek: 4; repeat: true }, + ListElement { dayOfWeek: 5; repeat: true }, + ListElement { dayOfWeek: 6; repeat: true } + ] + } + ListElement { + hour: 5 + minute: 15 + day: 1 + month: 9 + year: 2018 + activated: true + label: "" + repeat: false + daysToRepeat: [ + ListElement { dayOfWeek: 0; repeat: false }, + ListElement { dayOfWeek: 1; repeat: false }, + ListElement { dayOfWeek: 2; repeat: false }, + ListElement { dayOfWeek: 3; repeat: false }, + ListElement { dayOfWeek: 4; repeat: false }, + ListElement { dayOfWeek: 5; repeat: false }, + ListElement { dayOfWeek: 6; repeat: false } + ] + } + ListElement { + hour: 5 + minute: 45 + day: 3 + month: 9 + year: 2018 + activated: false + label: "" + repeat: false + daysToRepeat: [ + ListElement { dayOfWeek: 0; repeat: false }, + ListElement { dayOfWeek: 1; repeat: false }, + ListElement { dayOfWeek: 2; repeat: false }, + ListElement { dayOfWeek: 3; repeat: false }, + ListElement { dayOfWeek: 4; repeat: false }, + ListElement { dayOfWeek: 5; repeat: false }, + ListElement { dayOfWeek: 6; repeat: false } + ] + } +} diff --git a/examples/tutorials/alarms/TumblerDelegate.qml b/examples/tutorials/alarms/TumblerDelegate.qml new file mode 100644 index 00000000..88a35a5b --- /dev/null +++ b/examples/tutorials/alarms/TumblerDelegate.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.4 + +Text { + text: modelData + color: Tumbler.tumbler.Material.foreground + font: Tumbler.tumbler.font + opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter +} diff --git a/examples/tutorials/alarms/alarms.pro b/examples/tutorials/alarms/alarms.pro new file mode 100644 index 00000000..6c54c7f8 --- /dev/null +++ b/examples/tutorials/alarms/alarms.pro @@ -0,0 +1,29 @@ +QT += qml quick + +CONFIG += c++11 + +SOURCES += main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = $$PWD/imports + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS +TARGET = Alarms +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/examples/tutorials/alarms/main.cpp b/examples/tutorials/alarms/main.cpp new file mode 100644 index 00000000..3e1bdd84 --- /dev/null +++ b/examples/tutorials/alarms/main.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/tutorials/alarms/main.qml b/examples/tutorials/alarms/main.qml new file mode 100644 index 00000000..acd54168 --- /dev/null +++ b/examples/tutorials/alarms/main.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Controls.Material 2.4 +import QtQuick.Layouts 1.11 +import QtQuick.Window 2.11 +import Qt.labs.calendar 1.0 + +ApplicationWindow { + id: window + width: 400 + height: 500 + visible: true + + ListView { + id: alarmListView + anchors.fill: parent + model: AlarmModel {} + delegate: AlarmDelegate {} + } + + RoundButton { + id: addAlarmButton + text: "+" + anchors.bottom: alarmListView.bottom + anchors.bottomMargin: 8 + anchors.horizontalCenter: parent.horizontalCenter + onClicked: alarmDialog.open() + } + + AlarmDialog { + id: alarmDialog + x: Math.round((parent.width - width) / 2) + y: Math.round((parent.height - height) / 2) + alarmModel: alarmListView.model + } +} diff --git a/examples/tutorials/alarms/qml.qrc b/examples/tutorials/alarms/qml.qrc new file mode 100644 index 00000000..ae9ac907 --- /dev/null +++ b/examples/tutorials/alarms/qml.qrc @@ -0,0 +1,10 @@ +<RCC> + <qresource prefix="/"> + <file>main.qml</file> + <file>qtquickcontrols2.conf</file> + <file>TumblerDelegate.qml</file> + <file>AlarmModel.qml</file> + <file>AlarmDelegate.qml</file> + <file>AlarmDialog.qml</file> + </qresource> +</RCC> diff --git a/examples/tutorials/alarms/qtquickcontrols2.conf b/examples/tutorials/alarms/qtquickcontrols2.conf new file mode 100644 index 00000000..3c676659 --- /dev/null +++ b/examples/tutorials/alarms/qtquickcontrols2.conf @@ -0,0 +1,5 @@ +[Controls] +Style=Material +[Material] +Theme=Dark +Accent=Red -- GitLab