├── .envrc ├── tests ├── CMakeLists.txt ├── Calendar - DayGrid - OutOfInterval.qml ├── CalendarDayPickerView_FromGreaterThanTo.qml ├── Loader │ └── CMakeLists.txt └── FindPackageTest │ └── main.cpp ├── docs ├── .gitignore ├── Display │ ├── List.md │ ├── Divider.md │ ├── Label.md │ ├── Charts.md │ ├── Typography.md │ └── ToolTip.md ├── Inputs │ ├── Radio.md │ ├── Select.md │ ├── Switch.md │ ├── Checkbox.md │ ├── ButtonGroup.md │ ├── TextField.md │ ├── Fab.md │ └── Colors.md ├── Navigation │ ├── Link.md │ ├── Menu.md │ ├── Drawer.md │ ├── Breadcrumbs.md │ ├── BottomNavigation.md │ ├── SideSquacleButton.md │ └── Tabs.md ├── Surfaces │ ├── Card.md │ ├── Paper.md │ ├── AppBar.md │ └── ExpansionPanel.md ├── fav-icon.png ├── Feedback │ ├── Backdrop.md │ ├── Dialog.md │ ├── Snackbar.md │ ├── Progress.md │ └── Popup.md ├── QaterialGallery.md ├── QaterialOnline.md ├── 404.md ├── _config.yml ├── Build.md ├── Readme.md ├── index.md ├── Gemfile ├── QaterialHotReload.md └── IO │ └── Clipboard.md ├── qml ├── Qaterial │ ├── ButtonGroup.qml │ ├── OutlinedCard.qml │ ├── ToggleButton.qml │ ├── ElevatedCard.qml │ ├── HslColorHueSlider.qml │ ├── HsvColorHueSlider.qml │ ├── HsvColorValueSlider.qml │ ├── HslColorLightnessSlider.qml │ ├── HsvColorSaturationSlider.qml │ ├── ColorMiniButton.qml │ ├── HslColorSaturationSlider.qml │ ├── Button.qml │ ├── DebugRectangle.qml │ ├── FlatButton.qml │ ├── MiniFlatFabButton.qml │ ├── PlaceholderText.qml │ ├── RaisedButton.qml │ ├── MiniOutlinedFabButton.qml │ ├── MiniFabButton.qml │ ├── Ripple.qml │ ├── VerticalLineSeparator.qml │ ├── FluidGrid.qml │ ├── ToolButton.qml │ ├── OutlineButton.qml │ ├── ScalableFlatFabButton.qml │ ├── ScalableOutlinedFabButton.qml │ ├── ColorButton.qml │ ├── TextFieldClearButton.qml │ ├── TextFieldAlertIcon.qml │ ├── DialogManagerSettings.qml │ ├── TextFieldPasswordButton.qml │ ├── CalendarWeekDayRow.qml │ ├── SnackbarManager.qml │ ├── TextFieldCopyButton.qml │ ├── AlertDialog.qml │ ├── CircularMinute.qml │ ├── RadioDialogDelegate.qml │ ├── CardSupportingText.qml │ ├── CalendarDayPicker.qml │ ├── GridLabelsX.qml │ ├── GridLabelsY.qml │ ├── OutlinedFabButton.qml │ ├── RoundImage.qml │ ├── AmCircularHour.qml │ ├── CalendarDateDisplay.qml │ ├── ErrorSequentialAnimation.qml │ ├── ClusteredTabBar.qml │ ├── SquacleImageButton.qml │ ├── GradientSlider.qml │ ├── ModalDialog.qml │ ├── TextFieldIcon.qml │ ├── TreeView.qml │ ├── ListSectionTitle.qml │ ├── ScrollablePage.qml │ ├── ExtendedFabButton.qml │ ├── ColorBlueSlider.qml │ ├── ColorCyanSlider.qml │ ├── ColorRedSlider.qml │ ├── ColorAlphaSlider.qml │ ├── ColorGreenSlider.qml │ ├── ColorMagentaSlider.qml │ ├── ColorYellowSlider.qml │ ├── TextFieldIconButton.qml │ ├── EnumDelegate.qml │ ├── FixedTabBar.qml │ ├── HorizontalLineSeparator.qml │ ├── TextFieldClockButton.qml │ ├── RadioMenuItem.qml │ ├── AppBarButton.qml │ ├── DebugGridOverlay.qml │ ├── ColorPaletteGrid.qml │ ├── CursorDelegate.qml │ ├── FixedGrid.qml │ ├── LatoTabBar.qml │ ├── TextFieldDatePicker.qml │ ├── CardMedia.qml │ ├── ColorSaturationSlider.qml │ ├── ColorValueSlider.qml │ ├── ScrollView.qml │ ├── ToolBar.qml │ ├── SplashScreenWindow.qml │ ├── SwipeView.qml │ ├── ColorHueSlider.qml │ ├── ScrollableTabBar.qml │ ├── DateFormat.qml │ ├── Pane.qml │ ├── CalendarMonthPickerView.qml │ ├── MenuBar.qml │ ├── BusyIndicatorDialog.qml │ ├── TextField2014.qml │ ├── TextAreaScrollView.qml │ ├── LabelBody1.qml │ ├── LabelBody2.qml │ ├── LabelButton.qml │ ├── LabelHeadline1.qml │ ├── LabelHeadline2.qml │ ├── LabelHeadline3.qml │ ├── LabelHeadline4.qml │ ├── LabelHeadline5.qml │ ├── LabelHeadline6.qml │ ├── LabelSubtitle1.qml │ ├── LabelSubtitle2.qml │ ├── CardRippleBackground.qml │ ├── ProgressBarDialog.qml │ ├── LabelHint1.qml │ ├── LabelHint2.qml │ ├── LabelCaption.qml │ ├── LabelOverline.qml │ ├── DebugGridOverlayHorizontal.qml │ ├── DebugGridOverlayVertical.qml │ ├── ListDelegateBackground.qml │ ├── EuCircularHour.qml │ ├── SideSquacleButton.qml │ ├── SideSquacleImageButton.qml │ ├── ScrollIndicator.qml │ ├── SplashScreen.qml │ ├── RadioDialog.qml │ ├── CaptionWithLabel.qml │ ├── OverlineWithLabel.qml │ ├── Icon.qml │ ├── ApplicationWindow.qml │ ├── TextFieldButtonContainer.qml │ ├── CardBackground.qml │ ├── FolderTreeView.qml │ ├── ClipRRect.qml │ └── Frame.qml └── CMakeLists.txt ├── examples ├── Feedback │ ├── Version.qml │ ├── Logger.qml │ └── PopupMenu.qml ├── Inputs │ ├── RaisedButton.qml │ ├── FlatButton.qml │ ├── OutlineButton.qml │ ├── AppBarButton.qml │ ├── RoundButton.qml │ ├── TextFieldDate.qml │ ├── CheckButton.qml │ ├── TextFieldClockButton.qml │ ├── TimePickerDialog.qml │ ├── TextFieldTimePicker.qml │ ├── MaterialColorPalette.qml │ ├── PopupMenuButton.qml │ ├── ContinuousSlider.qml │ └── TextFieldDialog.qml ├── Surface │ ├── SplashScreen.qml │ ├── WindowSaveLayout.qml │ ├── SplashScreenWindow.qml │ ├── RectangleAreaHandler - ReverseAllowed.qml │ ├── Card.qml │ └── RectangleAreaHandler - Customized.qml ├── Calendar │ ├── TextFieldDatePicker.qml │ ├── YearPickerView.qml │ ├── NavigationBar.qml │ ├── MonthPickerView.qml │ ├── View.qml │ ├── DatePickerDialog.qml │ ├── DayGrid.qml │ ├── DayPickerView.qml │ └── TextFieldDatePickerNoDialogManager.qml ├── IO │ ├── TextFile - Write.qml │ └── TextFile - Read.qml ├── Display │ ├── GridLabels.qml │ ├── Expandable - Animation.qml │ ├── LineChart.qml │ ├── Expandable - Simple.qml │ ├── LabelWithCaption - Variation.qml │ ├── ColorIcon.qml │ └── Expandable - Advanced.qml └── Navigation │ ├── Tabs - LatoTabButton.qml │ ├── FolderTreeView.qml │ ├── Tabs - LatoTabBar.qml │ └── Stepper - Simple.qml ├── scripts └── jsbeautify.sh ├── .gitignore ├── cmake ├── QaterialConfigShared.cmake.in ├── Dependencies.cmake ├── QaterialConfig.cmake.in ├── FetchGoogleFontCMake.cmake ├── FetchMaterialDesignIcons.cmake ├── FetchQOlm.cmake ├── Version.cmake └── CPM.cmake ├── .github └── workflows │ ├── remove-old-artifacts.yml │ ├── notify.yml │ ├── nix.yml │ └── clang-format.yml ├── nix ├── get-cpm-cmake-pkg-source-flag.nix ├── get-project-version.nix └── get-pkg-source-from-cmake.nix ├── .jsbeautifyrc ├── src └── Qaterial │ ├── Pch │ └── Pch.hpp │ ├── _Template.cpp │ ├── Display │ └── IconDescription.cpp │ ├── Qaterial.hpp │ ├── Navigation │ ├── StepperElement.cpp │ └── TreeElement.cpp │ ├── _Template.hpp │ └── Details │ └── Export.hpp └── Licence /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(Loader) -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | .jekyll-cache 3 | *.lock -------------------------------------------------------------------------------- /docs/Display/List.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: List 4 | --- 5 | 6 | # List -------------------------------------------------------------------------------- /docs/Inputs/Radio.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🔘 Radio 4 | --- 5 | 6 | # Radio -------------------------------------------------------------------------------- /docs/Inputs/Select.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Select 4 | --- 5 | 6 | # Select -------------------------------------------------------------------------------- /docs/Inputs/Switch.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Switch 4 | --- 5 | 6 | # Switch -------------------------------------------------------------------------------- /docs/Navigation/Link.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Link 4 | --- 5 | 6 | # Link -------------------------------------------------------------------------------- /docs/Navigation/Menu.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Menu 4 | --- 5 | 6 | # Menu -------------------------------------------------------------------------------- /docs/Surfaces/Card.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Card 4 | --- 5 | 6 | # Card -------------------------------------------------------------------------------- /docs/Surfaces/Paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Paper 4 | --- 5 | 6 | # Paper -------------------------------------------------------------------------------- /docs/Display/Divider.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Divider 4 | --- 5 | 6 | # Divider -------------------------------------------------------------------------------- /docs/Navigation/Drawer.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Drawer 4 | --- 5 | 6 | # Drawer -------------------------------------------------------------------------------- /docs/Surfaces/AppBar.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: App Bar 4 | --- 5 | 6 | # App Bar -------------------------------------------------------------------------------- /docs/fav-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OlivierLDff/Qaterial/HEAD/docs/fav-icon.png -------------------------------------------------------------------------------- /docs/Feedback/Backdrop.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Backdrop 4 | --- 5 | 6 | # Backdrop -------------------------------------------------------------------------------- /docs/Feedback/Dialog.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗨️ Dialog 4 | --- 5 | 6 | # 🗨️ Dialog -------------------------------------------------------------------------------- /docs/Feedback/Snackbar.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Snackbar 4 | --- 5 | 6 | # Snackbar -------------------------------------------------------------------------------- /docs/Feedback/Progress.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🔄 Progress 4 | --- 5 | 6 | # 🔄 Progress -------------------------------------------------------------------------------- /docs/Inputs/Checkbox.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: ✔️ Checkbox 4 | --- 5 | 6 | # ✔️ Checkbox -------------------------------------------------------------------------------- /docs/Inputs/ButtonGroup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Button Group 4 | --- 5 | 6 | # Button Group -------------------------------------------------------------------------------- /docs/Inputs/TextField.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🖹 Text Field 4 | --- 5 | 6 | # 🖹 Text Field -------------------------------------------------------------------------------- /docs/Navigation/Breadcrumbs.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Breadcrumbs 4 | --- 5 | 6 | # Breadcrumbs -------------------------------------------------------------------------------- /qml/Qaterial/ButtonGroup.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Templates as T 3 | 4 | T.ButtonGroup {} 5 | -------------------------------------------------------------------------------- /examples/Feedback/Version.qml: -------------------------------------------------------------------------------- 1 | import Qaterial 1.0 2 | 3 | Label 4 | { 5 | text: Version.readable 6 | } 7 | -------------------------------------------------------------------------------- /docs/Surfaces/ExpansionPanel.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Expansion Panel 4 | --- 5 | 6 | # Expansion Panel -------------------------------------------------------------------------------- /examples/Inputs/RaisedButton.qml: -------------------------------------------------------------------------------- 1 | import Qaterial 1.0 2 | 3 | RaisedButton 4 | { 5 | text: "Raised Button" 6 | } 7 | -------------------------------------------------------------------------------- /docs/Inputs/Fab.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Floatting Action Button 4 | --- 5 | 6 | # Floatting Action Button -------------------------------------------------------------------------------- /docs/QaterialGallery.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🎨 Gallery 4 | nav_order: 3 5 | --- 6 | 7 | # 🎨 Gallery 8 | -------------------------------------------------------------------------------- /docs/Navigation/BottomNavigation.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Bottom Navigation 4 | --- 5 | 6 | # Bottom Navigation -------------------------------------------------------------------------------- /examples/Inputs/FlatButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial 1.0 3 | 4 | FlatButton 5 | { 6 | text: "Flat Button" 7 | } 8 | -------------------------------------------------------------------------------- /docs/QaterialOnline.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🌍 Qaterial Online 4 | nav_order: 4 5 | --- 6 | 7 | # 🌍 Qaterial Online 8 | -------------------------------------------------------------------------------- /examples/Inputs/OutlineButton.qml: -------------------------------------------------------------------------------- 1 | import Qaterial as Qaterial 2 | 3 | Qaterial.OutlineButton 4 | { 5 | text: "Outline Button" 6 | } 7 | -------------------------------------------------------------------------------- /scripts/jsbeautify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | find ../qml -regex '.*\.\(qml\|js\)' -exec js-beautify -r --config $(pwd)/../.jsbeautifyrc {} \; 4 | -------------------------------------------------------------------------------- /docs/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Page not found 4 | permalink: /404.html 5 | nav_exclude: true 6 | search_exclude: true 7 | --- 8 | 9 |

404

10 | 11 |

Page not found

12 | -------------------------------------------------------------------------------- /docs/Navigation/SideSquacleButton.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗂️ SquacleButton 4 | --- 5 | 6 | # 🗂️ SquacleButton 7 | 8 | ![squacleButton](https://user-images.githubusercontent.com/17255804/95100911-e4e5f600-0731-11eb-8101-369b387021d3.gif) 9 | -------------------------------------------------------------------------------- /qml/Qaterial/OutlinedCard.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.Card 10 | { 11 | outlined: true 12 | } // Card 13 | -------------------------------------------------------------------------------- /qml/Qaterial/ToggleButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ToolButton 10 | { 11 | outlined: true 12 | } // ToolButton 13 | -------------------------------------------------------------------------------- /qml/Qaterial/ElevatedCard.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.Card 10 | { 11 | elevation: Qaterial.Style.card.activeElevation 12 | } 13 | -------------------------------------------------------------------------------- /qml/Qaterial/HslColorHueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorHueSlider 10 | { 11 | id: control 12 | hsv: false 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/HsvColorHueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorHueSlider 10 | { 11 | id: control 12 | hsv: true 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/HsvColorValueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorValueSlider 10 | { 11 | id: control 12 | hsv: true 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/HslColorLightnessSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorValueSlider 10 | { 11 | id: control 12 | hsv: false 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/HsvColorSaturationSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorSaturationSlider 10 | { 11 | id: control 12 | hsv: true 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorMiniButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | 8 | // Qaterial 9 | import Qaterial as Qaterial 10 | 11 | Qaterial.ColorButton 12 | { 13 | type: Qaterial.Style.FabType.Mini 14 | } 15 | -------------------------------------------------------------------------------- /qml/Qaterial/HslColorSaturationSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.ColorSaturationSlider 10 | { 11 | id: control 12 | hsv: false 13 | } 14 | -------------------------------------------------------------------------------- /qml/Qaterial/Button.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.RawMaterialButton 10 | { 11 | highlighted: true 12 | flat: false 13 | } // RawMaterialButton 14 | -------------------------------------------------------------------------------- /qml/Qaterial/DebugRectangle.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | Rectangle 10 | { 11 | color: "transparent" 12 | border.width: 1 13 | border.color: "#E91E63" 14 | } // Rectangle 15 | -------------------------------------------------------------------------------- /qml/Qaterial/FlatButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.RawMaterialButton 10 | { 11 | flat: true 12 | highlighted: true 13 | } // RawMaterialButton 14 | -------------------------------------------------------------------------------- /qml/Qaterial/MiniFlatFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.FlatFabButton 10 | { 11 | type: Qaterial.Style.FabType.Mini 12 | } // FlatFabButton 13 | -------------------------------------------------------------------------------- /qml/Qaterial/PlaceholderText.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.Label 10 | { 11 | id: root 12 | color: Qaterial.Style.hintTextColor() 13 | } // Label 14 | -------------------------------------------------------------------------------- /qml/Qaterial/RaisedButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.RawMaterialButton 10 | { 11 | highlighted: true 12 | flat: false 13 | } // RawMaterialButton 14 | -------------------------------------------------------------------------------- /examples/Surface/SplashScreen.qml: -------------------------------------------------------------------------------- 1 | import Qaterial as Qaterial 2 | 3 | Qaterial.SplashScreen 4 | { 5 | width: 480 6 | height: 270 7 | image: "https://cdn.pixabay.com/photo/2018/11/14/20/50/hd-3816045_960_720.jpg" 8 | 9 | text: "Loading ..." 10 | version: Qaterial.Version.readable 11 | } 12 | -------------------------------------------------------------------------------- /qml/Qaterial/MiniOutlinedFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.OutlinedFabButton 10 | { 11 | type: Qaterial.Style.FabType.Mini 12 | } // OutlinedFabButton 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Allow in source build 2 | [Bb]uild*/ 3 | # Ignore qt files when importing CMakeLists 4 | *.users 5 | # Ignore CLion project files 6 | *.idea 7 | # For macOs users 8 | .DS_Store 9 | 10 | CMakeLists.txt.user 11 | 12 | # CPM cache 13 | .cpm 14 | 15 | # nix files 16 | result* 17 | .direnv 18 | -------------------------------------------------------------------------------- /cmake/QaterialConfigShared.cmake.in: -------------------------------------------------------------------------------- 1 | find_package(Qt6 COMPONENTS 2 | Core 3 | Gui 4 | Qml 5 | Quick 6 | QuickControls2 7 | Svg 8 | Xml 9 | Core5Compat 10 | REQUIRED 11 | ) 12 | find_package(QOlm REQUIRED) 13 | 14 | include("${CMAKE_CURRENT_LIST_DIR}/@QATERIAL_TARGET@Targets.cmake") 15 | -------------------------------------------------------------------------------- /examples/Inputs/AppBarButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Row 5 | { 6 | Qaterial.AppBarButton 7 | { 8 | icon.source: Qaterial.Icons.menu 9 | } 10 | Qaterial.AppBarButton 11 | { 12 | icon.source: Qaterial.Icons.clockOutline 13 | enabled: false 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /qml/Qaterial/MiniFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.FabButton 10 | { 11 | flat: true 12 | highlighted: false 13 | type: Qaterial.Style.FabType.Mini 14 | } // FabButton 15 | -------------------------------------------------------------------------------- /docs/Display/Label.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗠 Label 4 | --- 5 | 6 | # Label 7 | 8 | ## Deprecated: TextType Convertion 9 | 10 | | TextType | Control | 11 | | :------: | :------------: | 12 | | Title | LabelHeadline6 | 13 | | | | 14 | | | | 15 | 16 | -------------------------------------------------------------------------------- /cmake/Dependencies.cmake: -------------------------------------------------------------------------------- 1 | set(MDI_REPOSITORY 2 | "https://github.com/OlivierLDff/MaterialDesignSvgo" 3 | CACHE STRING "Repository of Qaterial" 4 | ) 5 | set(MDI_TAG 6 | # hash: sha256-Y3+7fnvP2Ye/2jUm7KyMiH+XTjSvwUC0VIJy2vo2xYg= 7 | "113d3f3cfa20a00f1103d4361e00945815316840" 8 | CACHE STRING "Git Tag of Mdi" 9 | ) 10 | -------------------------------------------------------------------------------- /examples/Inputs/RoundButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | Qaterial.RoundButton 7 | { 8 | text: "Button" 9 | //icon.source: Qaterial.Icons.alien 10 | } 11 | Qaterial.AppBarButton 12 | { 13 | text: "Button" 14 | //icon.source: Qaterial.Icons.alien 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/Calendar/TextFieldDatePicker.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | // Qaterial 4 | import Qaterial as Qaterial 5 | 6 | Qaterial.TextFieldDatePicker 7 | { 8 | id: root 9 | //Define the interval of dates 10 | from: new Date(2000, 0, 5) 11 | to: new Date(2001, 5, 12) 12 | 13 | //select a Date 14 | date: new Date(2000, 5, 14) 15 | } 16 | -------------------------------------------------------------------------------- /qml/Qaterial/Ripple.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Controls.impl 10 | import QtQuick.Controls.Material 11 | import QtQuick.Controls.Material.impl as QQuickMaterial 12 | 13 | QQuickMaterial.Ripple {} 14 | -------------------------------------------------------------------------------- /qml/Qaterial/VerticalLineSeparator.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.HorizontalLineSeparator 10 | { 11 | implicitHeight: Qaterial.Style.menu.separatorImplicitWidth 12 | implicitWidth: 1 13 | } // HorizontalLineSeparator 14 | -------------------------------------------------------------------------------- /qml/Qaterial/FluidGrid.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.Grid 5 | { 6 | id: root 7 | 8 | leftPadding: flow === Flow.LeftToRight ? padding : 0 9 | rightPadding: flow === Flow.LeftToRight ? padding : 0 10 | topPadding: flow === Flow.TopToBottom ? padding : 0 11 | bottomPadding: flow === Flow.TopToBottom ? padding : 0 12 | } 13 | -------------------------------------------------------------------------------- /examples/Inputs/TextFieldDate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.TextFieldDate 5 | { 6 | //choose a date Interval 7 | 8 | from: new Date(2001, 0, 2) 9 | to: new Date(2001, 11, 2) 10 | 11 | //Choose a predefined date 12 | date: new Date(2001, 5, 4) 13 | 14 | onAccepted: () => console.log(`Date Accepted : ${date}`) 15 | } 16 | -------------------------------------------------------------------------------- /qml/Qaterial/ToolButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.SquareButton 10 | { 11 | highlighted: checked || pressed 12 | forceRipple: checked 13 | accentRipple: highlighted 14 | checkable: true 15 | useSecondaryColor: true 16 | } // SquareButton 17 | -------------------------------------------------------------------------------- /examples/Calendar/YearPickerView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.CalendarYearPickerView 5 | { 6 | id: _view 7 | 8 | year: 1950 9 | startYear: 1900 10 | endYear: 2100 11 | 12 | //Clip to true for a better esthetic 13 | clip: true 14 | 15 | // Called when user pick a year 16 | onAccepted: (year) => console.log(`Accept year ${year}`) 17 | } 18 | -------------------------------------------------------------------------------- /qml/Qaterial/OutlineButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.RawMaterialButton 10 | { 11 | flat: true 12 | highlighted: true 13 | outlined: true 14 | //highlighted: checked || pressed 15 | 16 | accentRipple: checked || pressed 17 | } // RawMaterialButton 18 | -------------------------------------------------------------------------------- /qml/Qaterial/ScalableFlatFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.FlatFabButton 10 | { 11 | rippleClip: true 12 | scaleDuration: 100 13 | property bool isActive: hovered || down || visualFocus 14 | backgroundScale: isActive ? 1.0 : 0.9 15 | } // FlatFabButton 16 | -------------------------------------------------------------------------------- /qml/Qaterial/ScalableOutlinedFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.OutlinedFabButton 10 | { 11 | rippleClip: true 12 | scaleDuration: 100 13 | property bool isActive: hovered || down || visualFocus 14 | scale: isActive ? 1.0 : 0.9 15 | } // OutlinedFabButton 16 | -------------------------------------------------------------------------------- /examples/Calendar/NavigationBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.CalendarNavigationBar 5 | { 6 | month: Qaterial.Calendar.Month.February 7 | year: 2015 8 | 9 | onNextMonth: () => console.log(`Next Clicked`) 10 | onPreviousMonth: () => console.log(`Previous Clicked`) 11 | onMonthClicked: () => console.log(`Month Clicked`) 12 | onYearClicked: () => console.log(`Year Clicked`) 13 | } 14 | -------------------------------------------------------------------------------- /examples/Inputs/CheckButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | Qaterial.CheckButton 7 | { 8 | text: "CheckButton 1" 9 | checkState: Qt.Unchecked 10 | } 11 | Qaterial.CheckButton 12 | { 13 | id: button2 14 | text: "CheckButton 2" 15 | checkState: Qt.Checked 16 | } 17 | Qaterial.CheckButton 18 | { 19 | text: "CheckButton 3" 20 | checkState: button2.checkState 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.OutlinedFabButton 13 | { 14 | property color color 15 | backgroundColor: color 16 | 17 | borderWidth: 2 18 | borderColor: hovered || pressed ? Qaterial.Style.primaryTextColor() : Qaterial.Style.secondaryTextColor() 19 | } 20 | -------------------------------------------------------------------------------- /examples/IO/TextFile - Write.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.FlatButton 5 | { 6 | text: "Write text to file" 7 | 8 | onClicked: function() 9 | { 10 | textFile.open('foo.txt', Qaterial.TextFile.Write) 11 | textFile.write('Some Taaaext') 12 | textFile.close() 13 | } 14 | 15 | Qaterial.TextFile 16 | { 17 | id: textFile 18 | onErrorChanged: () => console.warn(`io error : ${error}`) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldClearButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.TextFieldIconButton 13 | { 14 | icon.source: Qaterial.Icons.closeCircle 15 | onClicked: function() 16 | { 17 | if(textField) textField.clear() 18 | if(textArea) textArea.clear() 19 | } 20 | } // TextFieldIconButton 21 | -------------------------------------------------------------------------------- /examples/Calendar/MonthPickerView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.CalendarMonthPickerView 5 | { 6 | month: Qaterial.Calendar.Month.April 7 | 8 | //Width min : 100; Height min : 35 9 | width: 200 10 | height: 150 11 | 12 | //Clip to true for a better esthetic 13 | clip: true 14 | 15 | // Called when user pick a date 16 | onAccepted: (month) => console.log(`Accept month ${Qaterial.Calendar.monthToString(month)}`) 17 | } 18 | -------------------------------------------------------------------------------- /examples/Display/GridLabels.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | height: 100 7 | width: 200 8 | 9 | Qaterial.GridLabelsX 10 | { 11 | y: parent.height 12 | numberOfLabels: 4 13 | axisMaxX: 100 14 | axisMinX: 0 15 | color: "blue" 16 | } 17 | 18 | Qaterial.GridLabelsY 19 | { 20 | x: parent.width 21 | numberOfLabels: 4 22 | axisMaxY: 100 23 | axisMinY: 0 24 | color: "red" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/remove-old-artifacts.yml: -------------------------------------------------------------------------------- 1 | name: 🔥 Remove old artifacts 2 | 3 | on: 4 | schedule: 5 | # Every day at 1am 6 | - cron: '0 1 * * *' 7 | 8 | jobs: 9 | remove-old-artifacts: 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 10 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Remove old artifacts 16 | uses: c-hive/gha-remove-artifacts@v1 17 | with: 18 | age: '1 day' 19 | skip-tags: true 20 | skip-recent: 2 21 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: Qaterial 2 | description: Collection of Material Components based on QtQuick/Controls2. 3 | remote_theme: https://github.com/carlosperate/jekyll-theme-rtd 4 | 5 | # Theme settings: 6 | site_author: Olivier LDff 7 | repo_url: "https://github.com/OlivierLDff/Qaterial" 8 | edit_on_github: true 9 | github_docs_folder: true 10 | sticky_navigation: true 11 | prev_next_buttons_location: bottom 12 | search_enabled: true 13 | hljs_style: github-gist 14 | 15 | plugins: 16 | - jekyll-remote-theme -------------------------------------------------------------------------------- /examples/IO/TextFile - Read.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.FlatButton 5 | { 6 | text: "Read text from file" 7 | 8 | onClicked: function() 9 | { 10 | textFile.open('foo.txt', Qaterial.TextFile.Read) 11 | const readText = textFile.readAll() 12 | textFile.close() 13 | 14 | console.log(`read text: ${readText}`) 15 | } 16 | 17 | Qaterial.TextFile 18 | { 19 | id: textFile 20 | onErrorChanged: () => console.warn(`io error : ${error}`) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /cmake/QaterialConfig.cmake.in: -------------------------------------------------------------------------------- 1 | find_package(Qt6 COMPONENTS 2 | Core 3 | Gui 4 | Qml 5 | Quick 6 | QuickControls2 7 | Svg 8 | Xml 9 | Core5Compat 10 | REQUIRED 11 | ) 12 | find_package(QOlm REQUIRED) 13 | 14 | include("${CMAKE_CURRENT_LIST_DIR}/@QATERIAL_TARGET@IconsTargets.cmake") 15 | include("${CMAKE_CURRENT_LIST_DIR}/@QATERIAL_TARGET@FontsTargets.cmake") 16 | include("${CMAKE_CURRENT_LIST_DIR}/@QATERIAL_TARGET@ComponentsTargets.cmake") 17 | include("${CMAKE_CURRENT_LIST_DIR}/@QATERIAL_TARGET@Targets.cmake") 18 | -------------------------------------------------------------------------------- /nix/get-cpm-cmake-pkg-source-flag.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Olivier Le Doeuff 2 | # SPDX-License-Identifier: MIT 3 | let 4 | getCpmCMakePkgSourceFlag = 5 | { file 6 | , cmakeVar 7 | , cpmPkg 8 | , private ? false 9 | , pkgs ? import { } 10 | }: 11 | let 12 | pkg = import ./get-pkg-source-from-cmake.nix { 13 | inherit file cmakeVar pkgs private; 14 | }; 15 | in 16 | "-DCPM_${cpmPkg}_SOURCE=${pkg}"; 17 | in 18 | getCpmCMakePkgSourceFlag 19 | -------------------------------------------------------------------------------- /cmake/FetchGoogleFontCMake.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # SPDX-FileCopyrightText: Naostage 3 | # SPDX-FileContributor: Olivier Le Doeuff 4 | # SPDX-License-Identifier: MIT 5 | # ~~~ 6 | 7 | if(COMMAND fetch_google_font) 8 | return() 9 | endif() 10 | 11 | include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) 12 | 13 | CPMAddPackage( 14 | NAME FetchGoogleFontCMake 15 | GIT_REPOSITORY "https://github.com/OlivierLDff/FetchGoogleFontCMake.git" 16 | GIT_TAG "c19d83a68eda83b9dd3033893dbb63d84c941196" 17 | ) 18 | -------------------------------------------------------------------------------- /examples/Inputs/TextFieldClockButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.TextFieldClockButton 5 | { 6 | // Default time showed when dialog is opened 7 | hour: 15 8 | minute: 30 9 | 10 | // Style of the clock, European by default 11 | styleAm: false 12 | // If Am/Pm style, time slot of the hour 13 | am: false // Pm 14 | 15 | // Listen to user changes 16 | onHourAccepted: (hour, minute, am) => console.log( 17 | `User picked ${hour}:${minute} ${styleAm ? (am ? "AM" : "PM") : ""}`) 18 | } 19 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldAlertIcon.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.TextFieldIcon 13 | { 14 | id: _control 15 | color: Qaterial.Style.errorColor 16 | source: Qaterial.Icons.alertCircle 17 | onVisibleChanged: function() 18 | { 19 | if(visible) 20 | _anim.start() 21 | } 22 | ErrorSequentialAnimation { id: _anim;target: _control; } 23 | } // TextFieldIcon 24 | -------------------------------------------------------------------------------- /cmake/FetchMaterialDesignIcons.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # SPDX-FileCopyrightText: Naostage 3 | # SPDX-FileContributor: Olivier Le Doeuff 4 | # SPDX-License-Identifier: MIT 5 | # ~~~ 6 | 7 | include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) 8 | include(${CMAKE_CURRENT_LIST_DIR}/Dependencies.cmake) 9 | 10 | CPMAddPackage( 11 | NAME MaterialDesignIcons 12 | GIT_REPOSITORY ${MDI_REPOSITORY} 13 | GIT_TAG ${MDI_TAG} 14 | ) 15 | 16 | set(MATERIALDESIGNICONS_ICONS_DIR "${MaterialDesignIcons_SOURCE_DIR}/svg") 17 | -------------------------------------------------------------------------------- /cmake/FetchQOlm.cmake: -------------------------------------------------------------------------------- 1 | # ~~~ 2 | # SPDX-FileCopyrightText: Naostage 3 | # SPDX-FileContributor: Olivier Le Doeuff 4 | # SPDX-License-Identifier: MIT 5 | # ~~~ 6 | 7 | if(TARGET QOlm::QOlm) 8 | return() 9 | endif() 10 | 11 | include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) 12 | 13 | CPMAddPackage( 14 | NAME QOlm 15 | GIT_REPOSITORY "https://github.com/OlivierLDff/QOlm.git" 16 | GIT_TAG "v3.2.0" 17 | OPTIONS "QOLM_ENABLE_INSTALL ${QATERIAL_ENABLE_INSTALL}" "QOLM_FOLDER_PREFIX Dependencies" 18 | ) 19 | -------------------------------------------------------------------------------- /qml/Qaterial/DialogManagerSettings.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | QtObject 10 | { 11 | property 12 | var acceptedCallback 13 | property 14 | var appliedCallback 15 | property 16 | var rejectedCallback 17 | property 18 | var helpRequestedCallback 19 | 20 | property string text 21 | property string title 22 | property string iconSource 23 | property color iconColor 24 | 25 | property int standardButtons 26 | } // QtObject 27 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldPasswordButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.TextFieldIconButton 13 | { 14 | icon.source: textField && (textField.echoMode !== TextInput.Password) ? Qaterial.Icons.eyeOff : Qaterial.Icons.eye 15 | onClicked: if(textField) textField.echoMode = (textField.echoMode !== TextInput.Password) ? TextInput.Password : 16 | TextInput.Normal 17 | } // TextFieldIconButton 18 | -------------------------------------------------------------------------------- /examples/Display/Expandable - Animation.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.Expandable 5 | { 6 | id: root 7 | 8 | header: Qaterial.ItemDelegate 9 | { 10 | height: 32 11 | backgroundColor: Qaterial.Style.orange 12 | onClicked: () => root.expanded = !root.expanded 13 | } 14 | 15 | delegate: Rectangle 16 | { 17 | height: 64 18 | color: Qaterial.Style.teal 19 | } 20 | 21 | animation: NumberAnimation 22 | { 23 | duration: 1000 24 | easing.type: Easing.OutCirc 25 | } 26 | } // Expandable 27 | -------------------------------------------------------------------------------- /qml/Qaterial/CalendarWeekDayRow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Row 5 | { 6 | id: root 7 | 8 | property int size: Qaterial.Style.roundIcon.size 9 | property 10 | var model: ["M", "T", "W", "T", "F", "S", "S"] 11 | 12 | Repeater 13 | { 14 | model: root.model 15 | delegate: Qaterial.LabelCaption 16 | { 17 | text: modelData 18 | 19 | width: root.size 20 | height: root.size 21 | 22 | horizontalAlignment: Text.AlignHCenter 23 | verticalAlignment: Text.AlignVCenter 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /qml/Qaterial/SnackbarManager.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | pragma Singleton 7 | 8 | // Qt 9 | import QtQuick 10 | 11 | QtObject 12 | { 13 | property 14 | var snackBarLoader 15 | 16 | function show(config) 17 | { 18 | if(typeof config === 'string') 19 | config = { text: config } 20 | if(snackBarLoader) 21 | snackBarLoader.show(config) 22 | } 23 | 24 | function popSnackBar() 25 | { 26 | if(snackBarLoader) 27 | snackBarLoader.popSnackBar() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/notify.yml: -------------------------------------------------------------------------------- 1 | name: 🔊 Notify QaterialOnline & Gallery 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | jobs: 8 | dispatch: 9 | 10 | strategy: 11 | matrix: 12 | repo: ['OlivierLDff/QaterialOnline', 'OlivierLDff/QaterialGallery'] 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Repository Dispatch 18 | uses: peter-evans/repository-dispatch@v1 19 | with: 20 | token: ${{ secrets.CI_TOKEN }} 21 | repository: ${{ matrix.repo }} 22 | event-type: qaterial-update 23 | -------------------------------------------------------------------------------- /examples/Calendar/View.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.CalendarView 5 | { 6 | id: _view 7 | 8 | year: 2000 9 | month: Qaterial.Calendar.Month.April 10 | 11 | from: new Date(2000, 1, 29) 12 | to: new Date(2001, 2, 1) 13 | 14 | // Called when user pick a year 15 | onAccepted: (date) => console.log(`Accepted date ${date}`) 16 | onMoved: (month, year) => console.log(`Year ${year} And Month ${month}`) 17 | onYearClicked: () => console.log(`YearButton clicked`) 18 | onMonthClicked: () => console.log(`MonthButton clicked`) 19 | } 20 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldCopyButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.TextFieldIconButton 13 | { 14 | icon.source: Qaterial.Icons.contentCopy 15 | onClicked: 16 | { 17 | if(textField) 18 | { 19 | if(textField.length > 0) 20 | textField.select(0, textField.length) 21 | textField.copy() 22 | textField.deselect() 23 | } // if 24 | } // onClicked 25 | } // TextFieldIconButton 26 | -------------------------------------------------------------------------------- /docs/Build.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🔨 Build 4 | nav_order: 2 5 | --- 6 | 7 | # 🔨 Build 8 | 9 | ## CMake integration 10 | 11 | ### Dependencies 12 | 13 | All dependencies are pull from git repository with CMake [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) mechanism. 14 | 15 | * [spdlog](https://github.com/gabime/spdlog): Can be customize with `SPDLOG_REPOSITORY` and `SPDLOG_TAG` 16 | * [QtStaticCMake](https://github.com/OlivierLDff/QtStaticCMake): Can be customize with `QTSTATICCMAKE_REPOSITORY` and `QTSTATICCMAKE_TAG` 17 | 18 | ## C++ Main 19 | -------------------------------------------------------------------------------- /qml/Qaterial/AlertDialog.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 2.12 8 | import QtQuick.Templates 2.12 as T 9 | import QtQuick.Controls 2.12 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | Qaterial.ModalDialog 15 | { 16 | id: _control 17 | 18 | property string text 19 | 20 | contentItem: Qaterial.Label 21 | { 22 | text: _control.text 23 | font: _control.font 24 | color: Qaterial.Style.secondaryTextColor() 25 | wrapMode: Text.Wrap 26 | } // Label 27 | } // ModalDialog 28 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": "2", 3 | "indent_char": " ", 4 | "max_preserve_newlines": "2", 5 | "preserve_newlines": true, 6 | "keep_array_indentation": false, 7 | "break_chained_methods": true, 8 | "indent_scripts": "normal", 9 | "brace_style": "expand,preserve-inline", 10 | "space_before_conditional": false, 11 | "unescape_strings": false, 12 | "jslint_happy": false, 13 | "end_with_newline": true, 14 | "wrap_line_length": "0", 15 | "comma_first": false, 16 | "e4x": false, 17 | "indent_empty_lines": false, 18 | "space_after_anon_function": false, 19 | "space_after_named_function": false 20 | } 21 | -------------------------------------------------------------------------------- /examples/Display/LineChart.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.LineChart 5 | { 6 | id: root 7 | width: 400 8 | height: 200 9 | 10 | thickness: 3 11 | color: Qaterial.Style.green 12 | 13 | series: [ 14 | Qt.vector2d(-10, -20), 15 | Qt.vector2d(10, 12), 16 | Qt.vector2d(20, 24), 17 | Qt.vector2d(30, 15), 18 | Qt.vector2d(40, -26), 19 | Qt.vector2d(50, 25), 20 | Qt.vector2d(60, 87), 21 | Qt.vector2d(70, 32) 22 | ] 23 | 24 | Qaterial.Label 25 | { 26 | text: `minX:${root.minX} | minY:${root.minY} | maxX:${root.maxX} | maxY:${root.maxY}` 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/Inputs/TimePickerDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.TimePickerDialog 5 | { 6 | // Default time showed when dialog is opened 7 | hour: 15 8 | minute: 30 9 | 10 | // Display the clock in Am/Pm style, or Eu style 11 | styleAm: false 12 | 13 | // Listen to user changes 14 | onHourChanged: () => console.log(`Hour Changed : ${hour}`) 15 | onMinuteChanged: () => console.log(`Minute Changed : ${minute}`) 16 | 17 | onAccepted: () => console.log(`User picked ${hour}:${minute}`) 18 | onRejected: () => console.log(`Rejected`) 19 | 20 | Component.onCompleted: open() 21 | } 22 | -------------------------------------------------------------------------------- /qml/Qaterial/CircularMinute.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | property int radius: 100 9 | property int minute 10 | 11 | property alias labelSize: _minutePath.labelSize 12 | 13 | implicitWidth: _minutePath.implicitWidth 14 | implicitHeight: _minutePath.implicitHeight 15 | 16 | CircularPathLabel 17 | { 18 | id: _minutePath 19 | anchors.centerIn: parent 20 | radius: parent.radius 21 | model: ["00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55"] 22 | currentIndex: root.minute % 5 === 0 ? root.minute / 5 : -1 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /qml/Qaterial/RadioDialogDelegate.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.RadioDelegate 14 | { 15 | onClicked: ListView.view.currentIndex = index 16 | checked: ListView.isCurrentItem 17 | backgroundColor: Qaterial.Style.dialogColor 18 | indicatorSpacing: Qaterial.Style.dialog.indicatorSpacing 19 | alignTextRight: true 20 | LayoutMirroring.enabled: true 21 | width: parent.width // Not sure if this should be here ? 22 | } // RadioDelegate 23 | -------------------------------------------------------------------------------- /qml/Qaterial/CardSupportingText.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Item 14 | { 15 | implicitHeight: _label.font.pixelSize * 3 16 | implicitWidth: 200 17 | property alias supportingText: _label.text 18 | 19 | Qaterial.LabelBody1 20 | { 21 | id: _label 22 | wrapMode: Text.WordWrap 23 | elide: Text.ElideRight 24 | maximumLineCount: 2 25 | verticalAlignment: Text.AlignVCenter 26 | anchors.fill: parent 27 | } // Label 28 | } // Item 29 | -------------------------------------------------------------------------------- /examples/Surface/WindowSaveLayout.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.ApplicationWindow 5 | { 6 | id: window 7 | 8 | width: 500 9 | height: 300 10 | 11 | minimumWidth: 100 12 | minimumHeight: 100 13 | 14 | // Save and restore x, y, width, height of window 15 | Qaterial.WindowLayoutSave { name: "MyCategory" } 16 | 17 | Column 18 | { 19 | anchors.centerIn: parent 20 | 21 | Qaterial.Label { text: `resolution : ${window.width}x${window.height}` } 22 | Qaterial.Label { text: `position : {${window.x},${window.y}}` } 23 | Qaterial.Label { text: `screen : ${window.screen.name}` } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /qml/Qaterial/CalendarDayPicker.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import Qaterial as Qaterial 4 | 5 | Column 6 | { 7 | id: root 8 | 9 | property alias date: _dayGrid.date 10 | property alias today: _dayGrid.today 11 | property alias month: _dayGrid.month 12 | property alias year: _dayGrid.year 13 | property alias enabled: _dayGrid.enabled 14 | property alias from: _dayGrid.from 15 | property alias to: _dayGrid.to 16 | 17 | signal accepted(date date) 18 | 19 | Qaterial.CalendarWeekDayRow {} 20 | 21 | Qaterial.CalendarDayGrid 22 | { 23 | id: _dayGrid 24 | onAccepted: (date) => root.accepted(date) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/Calendar/DatePickerDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.DatePickerDialog 5 | { 6 | // Default Grid showed when dialog is opened 7 | month: Qaterial.Calendar.Month.January 8 | year: 2015 9 | 10 | onMonthChanged: () => console.log( 11 | `Grid Changed : month :${Qaterial.Calendar.monthToString(month)} & year : ${year}`) 12 | onYearChanged: () => console.log(`Grid Changed : month :${Qaterial.Calendar.monthToString(month)} & year : ${year}`) 13 | 14 | onAccepted: (date) => console.log(`User picked ${date.toString()}`) 15 | onRejected: () => console.log(`Rejected`) 16 | 17 | Component.onCompleted: open() 18 | } 19 | -------------------------------------------------------------------------------- /docs/Navigation/Tabs.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗂️ Tabs 4 | --- 5 | 6 | # 🗂️ Tabs 7 | 8 | Tabs make it easy to explore and switch between different views. 9 | Tabs organize and allow navigation between groups of content that are related and at the same level of hierarchy. 10 | 11 | ## Simple tabs 12 | 13 | ## Fixed Tabs 14 | 15 | ## Anchored Tabs 16 | 17 | ### Left Anchored Tabs 18 | 19 | ### Center Anchored Tabs 20 | 21 | ### Right Anchored Tabs 22 | 23 | ## Scrollable Tabs 24 | 25 | ## NavTabs 26 | 27 | ## Icon Tab 28 | 29 | ## Lato Tabs 30 | 31 | ![latoTab](https://user-images.githubusercontent.com/17255804/95096322-66d32080-072c-11eb-85a2-35af03034bd2.gif) 32 | -------------------------------------------------------------------------------- /qml/Qaterial/GridLabelsX.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | implicitWidth: 200 9 | implicitHeight: 40 10 | 11 | property int axisMaxX: 100 12 | property int axisMinX: 0 13 | property int numberOfLabels: 10 14 | property color color: Qaterial.Style.foregroundColor 15 | 16 | Repeater 17 | { 18 | model: root.numberOfLabels 19 | Qaterial.Label 20 | { 21 | topPadding: 6 22 | bottomPadding: 6 23 | x: (index + 1) * root.width / root.numberOfLabels 24 | text: root.axisMinX + index * (root.axisMaxX - root.axisMinX) / root.numberOfLabels 25 | color: root.color 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /qml/Qaterial/GridLabelsY.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | implicitWidth: 50 9 | implicitHeight: 100 10 | 11 | property int numberOfLabels: 4 12 | property int axisMaxY: 100 13 | property int axisMinY: 0 14 | property color color: Qaterial.Style.foregroundColor 15 | 16 | Repeater 17 | { 18 | model: root.numberOfLabels 19 | Qaterial.Label 20 | { 21 | rightPadding: 10 22 | leftPadding: 10 23 | y: index * root.height / root.numberOfLabels - height / 2 24 | text: root.axisMaxY - index * (root.axisMaxY - root.axisMinY) / root.numberOfLabels 25 | color: root.color 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Qaterial/Pch/Pch.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __QATERIAL_PCH_HPP__ 2 | #define __QATERIAL_PCH_HPP__ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #ifdef major 26 | # undef major 27 | #endif 28 | #ifdef minor 29 | # undef minor 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /examples/Calendar/DayGrid.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | Qaterial.CalendarDayGrid 7 | { 8 | id: _grid 9 | // Choose displayed month 10 | month: Qaterial.Calendar.Month.April 11 | // Choose displayed year 12 | year: 2012 13 | // Called when user pick a date 14 | onAccepted: (date) => console.log(`Accept date ${date}`) 15 | } 16 | Qaterial.Label { text: `date : ${_grid.date}` } 17 | Qaterial.Label { text: `month : ${Qaterial.Calendar.monthToString(_grid.month)}` } 18 | Qaterial.Label { text: `year : ${_grid.year}` } 19 | Qaterial.Label { text: `from : ${_grid.from}` } 20 | Qaterial.Label { text: `to : ${_grid.to}` } 21 | } 22 | -------------------------------------------------------------------------------- /qml/Qaterial/OutlinedFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.FlatFabButton 14 | { 15 | id: _control 16 | 17 | backgroundColor: "transparent" 18 | borderColor: enabled ? (highlighted ? Qaterial.Style.accentColor : Qaterial.Style.dividersColor()) : Qaterial.Style 19 | .disabledDividersColor() 20 | outlined: true 21 | 22 | foregroundColor: !enabled ? Qaterial.Style.disabledTextColor() : highlighted ? Qaterial.Style.accentColor : Qaterial 23 | .Style.primaryTextColor() 24 | } // FlatFabButton 25 | -------------------------------------------------------------------------------- /examples/Inputs/TextFieldTimePicker.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.TextFieldTimePicker 5 | { 6 | width: 250 7 | // Default time showed when the TextFieldClockButton is clicked 8 | hour: 15 9 | minute: 30 10 | 11 | // Style of the clock, European by default 12 | styleAm: true 13 | // If Am/Pm style, time slot of the hour 14 | am: false // Pm 15 | 16 | // Listen to user changes 17 | onHourChanged: () => console.log(`Hour Changed : ${hour}`) 18 | onMinuteChanged: () => console.log(`Minute Changed : ${minute}`) 19 | 20 | onHourAccepted: (hour, minute, am) => console.log( 21 | `User picked ${hour}:${minute} ${styleAm ? (am ? "AM" : "PM") : ""}`) 22 | } 23 | -------------------------------------------------------------------------------- /qml/Qaterial/RoundImage.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import Qt5Compat.GraphicalEffects 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Image 14 | { 15 | id: _root 16 | fillMode: Image.PreserveAspectFit 17 | 18 | sourceSize.width: width 19 | sourceSize.height: height 20 | 21 | property bool rounded: true 22 | 23 | layer.enabled: rounded 24 | layer.effect: OpacityMask 25 | { 26 | maskSource: Rectangle 27 | { 28 | width: _root.width 29 | height: _root.height 30 | radius: _root.width / 2 31 | } // Rectangle 32 | } // OpacityMask 33 | } // Image 34 | -------------------------------------------------------------------------------- /.github/workflows/nix.yml: -------------------------------------------------------------------------------- 1 | name: 👷 Nix CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - v* 9 | pull_request: 10 | types: [opened, synchronize, labeled] 11 | workflow_dispatch: 12 | 13 | jobs: 14 | BuildNixFlake: 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - 19 | uses: naostage/nix-installer-action@ddfca32d6f9b28188dc2d139c0786e8e69fa8757 20 | - 21 | uses: naostage/magic-nix-cache-action@87b14cf437d03d37989d87f0fa5ce4f5dc1a330b 22 | with: 23 | use-flakehub: false 24 | - 25 | uses: actions/checkout@v4 26 | - 27 | name: 🔨 Build Qaterial 28 | run: | 29 | nix build .#qaterial --print-build-logs 30 | -------------------------------------------------------------------------------- /docs/Readme.md: -------------------------------------------------------------------------------- 1 | # Jekyll Documentation 2 | 3 | ## Setup environment 4 | 5 | ### Linux 6 | 7 | ```bash 8 | # Install ruby 9 | sudo apt install -y ruby-full build-essential zlib1g-dev 10 | # Setup environment 11 | echo '# Install Ruby Gems to ~/gems' >> ~/.zshrc 12 | echo 'export GEM_HOME="$HOME/gems"' >> ~/.zshrc 13 | echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.zshrc 14 | source ~/.zshrc 15 | # Install bundler and jekyll 16 | sudo gem install jekyll bundler 17 | # Build website in this folder and serve it at localhost:4000 18 | bundle exec jekyll serve --watch 19 | ``` 20 | 21 | ## Build Website 22 | 23 | ```bash 24 | # Build website in this folder and serve it at localhost:4000 25 | bundle exec jekyll serve --watch 26 | ``` 27 | -------------------------------------------------------------------------------- /qml/Qaterial/AmCircularHour.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | property int radius: 100 9 | property int hour: 0 10 | property alias labelSize: _amHour.labelSize 11 | 12 | implicitWidth: _amHour.implicitWidth 13 | implicitHeight: _amHour.implicitHeight 14 | 15 | CircularPathLabel 16 | { 17 | id: _amHour 18 | anchors.centerIn: parent 19 | radius: parent.radius 20 | model: ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] 21 | currentIndex: 22 | { 23 | if(root.hour === 12) 24 | return 0 25 | if(root.hour >= 1 && root.hour <= 11) 26 | return root.hour 27 | return -1 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/CalendarDateDisplay.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | 4 | import Qaterial as Qaterial 5 | 6 | Rectangle 7 | { 8 | id: root 9 | implicitWidth: 280 10 | implicitHeight: 80 11 | radius: Qaterial.Style.dialog.radius 12 | color: Qaterial.Style.accentColor 13 | 14 | property string text 15 | 16 | Rectangle 17 | { 18 | anchors.bottom: parent.bottom 19 | anchors.left: parent.left 20 | anchors.right: parent.right 21 | height: parent.height / 2 22 | color: parent.color 23 | } 24 | 25 | Qaterial.LabelHeadline4 26 | { 27 | leftPadding: 20 28 | anchors.verticalCenter: parent.verticalCenter 29 | text: root.text 30 | color: Qaterial.Style.textColorDark 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/Surface/SplashScreenWindow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.SplashScreenWindow 5 | { 6 | id: window 7 | 8 | width: 480 9 | height: 270 10 | image: "https://cdn.pixabay.com/photo/2018/11/14/20/50/hd-3816045_960_720.jpg" 11 | 12 | text: "Loading ..." 13 | version: Qaterial.Version.readable 14 | 15 | property int dots: 1 16 | 17 | Timer 18 | { 19 | interval: 1000;running: true;repeat: true 20 | onTriggered: function() 21 | { 22 | ++window.dots 23 | let text = "Loading " 24 | for(let i = 0; i < window.dots; ++i) 25 | text += '.' 26 | 27 | window.text = text 28 | if(window.dots == 3) 29 | window.dots = 0 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /qml/Qaterial/ErrorSequentialAnimation.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import Qt5Compat.GraphicalEffects 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | SequentialAnimation 14 | { 15 | id: _root 16 | property 17 | var target 18 | property double x: 0 19 | running: false 20 | NumberAnimation { target: _root.target;property: "x";to: _root.x + 4;duration: 50 } // NumberAnimation 21 | NumberAnimation { target: _root.target;property: "x";to: _root.x - 4;duration: 50 } // NumberAnimation 22 | NumberAnimation { target: _root.target;property: "x";to: _root.x;duration: 50 } // NumberAnimation 23 | } // SequentialAnimation 24 | -------------------------------------------------------------------------------- /qml/Qaterial/ClusteredTabBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.TabBar 14 | { 15 | id: _root 16 | property alias model: _repeater.model 17 | property int display: AbstractButton.TextBesideIcon 18 | width: implicitWidth 19 | 20 | Repeater 21 | { 22 | id: _repeater 23 | delegate: Qaterial.TabButton 24 | { 25 | display: _root.display 26 | text: model.text ? model.text : "" 27 | icon.source: model.source ? model.source : "" 28 | enabled: _root.enabled 29 | } // TabButton 30 | } // Repeater 31 | } // TabBar 32 | -------------------------------------------------------------------------------- /cmake/Version.cmake: -------------------------------------------------------------------------------- 1 | set(QATERIAL_VERSION_MAJOR 1) 2 | set(QATERIAL_VERSION_MINOR 5) 3 | set(QATERIAL_VERSION_PATCH 2) 4 | if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") 5 | execute_process( 6 | COMMAND git rev-parse --short HEAD 7 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 8 | OUTPUT_VARIABLE QATERIAL_VERSION_TAG 9 | OUTPUT_STRIP_TRAILING_WHITESPACE 10 | ) 11 | endif() 12 | if(NOT QATERIAL_VERSION_TAG) 13 | set(QATERIAL_VERSION_TAG 00000000) 14 | endif() 15 | set(QATERIAL_VERSION_TAG_HEX 0x${QATERIAL_VERSION_TAG}) 16 | set(QATERIAL_VERSION_TAG ${QATERIAL_VERSION_TAG} CACHE STRING "Git Tag of Qaterial") 17 | set(QATERIAL_VERSION ${QATERIAL_VERSION_MAJOR}.${QATERIAL_VERSION_MINOR}.${QATERIAL_VERSION_PATCH} CACHE STRING "Version of Qaterial") 18 | -------------------------------------------------------------------------------- /examples/Inputs/MaterialColorPalette.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.MaterialColorPalette 5 | { 6 | cellWidth: 48 7 | cellHeight: 48 8 | 9 | function camelize(str) 10 | { 11 | return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) 12 | { 13 | return index === 0 ? word.toLowerCase() : word.toUpperCase(); 14 | }) 15 | .replace(/\s+/g, ''); 16 | } 17 | 18 | onAccepted: function(color, name, shade) 19 | { 20 | console.log(`Accept ${name} ${shade} (${color})`) 21 | const colorProperty = `Qaterial.Colors.${camelize(name)}${shade}` 22 | Qaterial.Clipboard.text = colorProperty 23 | Qaterial.SnackbarManager.show(`Color copied! \n"${colorProperty}"`) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /nix/get-project-version.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Olivier Le Doeuff 2 | # SPDX-License-Identifier: MIT 3 | { file, prefix }: 4 | let 5 | versionFileContent = builtins.readFile file; 6 | versionMajorParse = builtins.match ".*set\\(${prefix}_VERSION_MAJOR ([0-9]+)\\).*" versionFileContent; 7 | versionMajor = builtins.elemAt versionMajorParse 0; 8 | versionMinorParse = builtins.match ".*set\\(${prefix}_VERSION_MINOR ([0-9]+)\\).*" versionFileContent; 9 | versionMinor = builtins.elemAt versionMinorParse 0; 10 | versionPatchParse = builtins.match ".*set\\(${prefix}_VERSION_PATCH ([0-9]+)\\).*" versionFileContent; 11 | versionPatch = builtins.elemAt versionPatchParse 0; 12 | in 13 | "${versionMajor}.${versionMinor}.${versionPatch}" 14 | -------------------------------------------------------------------------------- /qml/Qaterial/SquacleImageButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Templates as T 4 | import Qt5Compat.GraphicalEffects 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.SquacleButton 10 | { 11 | id: control 12 | 13 | padding: 8 14 | 15 | contentItem: Qaterial.ClipRRect 16 | { 17 | id: clipper 18 | 19 | radius: control.squared ? 16 : width / 2 20 | 21 | Behavior on radius { NumberAnimation { duration: 150;easing.type: Easing.InOutQuad } } 22 | 23 | Image 24 | { 25 | source: control.icon.source 26 | fillMode: Image.PreserveAspectFit 27 | anchors.centerIn: parent 28 | 29 | width: control.icon.width 30 | height: control.icon.height 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /qml/Qaterial/GradientSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import Qt5Compat.GraphicalEffects 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.LargeSlider 14 | { 15 | id: control 16 | 17 | backgroundColor: "white" 18 | property alias gradient: _gradient.gradient 19 | 20 | LinearGradient 21 | { 22 | id: _gradient 23 | visible: control.enabled 24 | 25 | x: background.x 26 | y: background.y 27 | width: background.width 28 | height: background.height 29 | 30 | start: Qt.point(0, control.horizontal ? 0 : height) 31 | end: Qt.point(control.horizontal ? width : 0, 0) 32 | 33 | source: background 34 | } 35 | } // Slider 36 | -------------------------------------------------------------------------------- /examples/Inputs/PopupMenuButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Row 5 | { 6 | Qaterial.PopupMenuItem 7 | { 8 | text: "Info" 9 | icon.source: Qaterial.Icons.informationOutline 10 | } 11 | Qaterial.PopupMenuItem 12 | { 13 | text: "Code" 14 | icon.source: Qaterial.Icons.qrcode 15 | } 16 | Qaterial.PopupMenuItem 17 | { 18 | id: customIcon 19 | text: "Delete" 20 | 21 | icon.source: Qaterial.Icons.trashCanOutline 22 | icon.color: Qaterial.Colors.red500 23 | } 24 | Qaterial.PopupMenuItem 25 | { 26 | id: imageItem 27 | text: "Image" 28 | icon.source: "https://www.flaticon.com/svg/static/icons/svg/3426/3426645.svg" 29 | 30 | iconItem: Image 31 | { 32 | source: imageItem.icon.source 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /qml/Qaterial/ModalDialog.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick.Controls 8 | import QtQuick.Window 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.Dialog 14 | { 15 | id: root 16 | modal: true 17 | focus: true 18 | 19 | x: Math.floor((parent.width - width) / 2) 20 | y: Math.floor((parent.height - (Qt.inputMethod && Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle 21 | .height / Screen.devicePixelRatio) : 0) - height) / 2) 22 | 23 | parent: Overlay.overlay 24 | property int dialogImplicitWidth: Qaterial.Style.dialog.implicitWidth 25 | implicitWidth: Math.floor(Math.min(parent.width - 2 * Qaterial.Style.card.horizontalPadding, dialogImplicitWidth)) 26 | } // Dialog 27 | -------------------------------------------------------------------------------- /docs/Feedback/Popup.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗨️ Popup 4 | --- 5 | 6 | # 🗨️ Popup 7 | 8 | ## Popup Menu 9 | 10 | Display a popup with a little arrow pointing to the origin. 11 | It should be opened with the `openAt(origin, transformOrigin)` function. 12 | * transformOrigin can be any of `Item.Top`, `Item.Bottom`, `Item.Right`, `Item.Left`. 13 | * origin must be the coordinate of the origin in `Overlay`. You should use the function `mapToItem(Overlay.overlay, x, y)` to get the origin. 14 | 15 | ![popupmenu](https://user-images.githubusercontent.com/17255804/93909825-81ef6a80-fd00-11ea-96fb-14fe1ee6a579.gif) 16 | 17 | ### Popup Menu Item 18 | 19 | Dedicated Button for popup menu. 20 | 21 | ![popupmenuitem](https://user-images.githubusercontent.com/17255804/93981917-de926a00-fd80-11ea-8de2-9160e69f422c.gif) 22 | -------------------------------------------------------------------------------- /docs/Inputs/Colors.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🎨 Color 4 | --- 5 | 6 | # 🎨 Color 7 | 8 | todo : predefined colors 9 | 10 | ## Color Picker 11 | 12 | todo 13 | 14 | ## 🎚️ Color Sliders 15 | 16 | ![colorsliders](https://user-images.githubusercontent.com/17255804/86588073-3fcd4d00-bf8b-11ea-9369-359875f19b1f.gif) 17 | 18 | ### Red/Green/Blue 19 | 20 | * `ColorRedSlider` 21 | * `ColorGreenSlider` 22 | * `ColorBlueSlider` 23 | 24 | ### Hue/Saturation/Value 25 | 26 | * `HsvColorHueSlider` 27 | * `HsvColorSaturationSlider` 28 | * `HsvColorValueSlider` 29 | 30 | ### Hue/Saturation/Lightness 31 | 32 | * `HslColorHueSlider` 33 | * `HslColorSaturationSlider` 34 | * `HslColorLightnessSlider` 35 | 36 | ### Alpha 37 | 38 | * `ColorAlphaSlider` 39 | 40 | ## 👈 Color Buttons 41 | 42 | `ColorButton` & `ColorMiniButton` -------------------------------------------------------------------------------- /examples/Surface/RectangleAreaHandler - ReverseAllowed.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.RectangleAreaHandler 5 | { 6 | id: root 7 | 8 | start: Qt.vector2d(0.25, 0.25) 9 | end: Qt.vector2d(0.75, 0.75) 10 | 11 | width: parent.width 12 | height: parent.height 13 | 14 | horizontalReverseAllowed: _horizontalReversedAllowed.checked 15 | verticalReverseAllowed: _verticalReversedAllowed.checked 16 | 17 | Column 18 | { 19 | anchors.centerIn: parent 20 | 21 | Qaterial.SwitchButton 22 | { 23 | id: _horizontalReversedAllowed 24 | text: "Allow horizontal reverse" 25 | checked: true 26 | } 27 | Qaterial.SwitchButton 28 | { 29 | id: _verticalReversedAllowed 30 | text: "Allow vertical reverse" 31 | checked: true 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldIcon.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.ColorIcon 13 | { 14 | id: _control 15 | property Qaterial.TextField textField 16 | property Qaterial.TextArea textArea 17 | property Qaterial.ComboBox comboBox 18 | iconSize: Qaterial.Style.textField.iconSize 19 | width: visible ? Qaterial.Style.textField.iconWidth : 0 //width: Qaterial.Style.textField.iconWidth 20 | height: Qaterial.Style.textField.iconWidth 21 | 22 | property bool drawline: Qaterial.Style.debug.drawDebugButton 23 | 24 | Qaterial.DebugRectangle 25 | { 26 | anchors.fill: parent 27 | border.color: "pink" 28 | visible: _control.drawline 29 | } // DebugRectangle 30 | } // ColorIcon 31 | -------------------------------------------------------------------------------- /qml/Qaterial/TreeView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQml 3 | import Qaterial as Qaterial 4 | 5 | ListView 6 | { 7 | id: root 8 | 9 | property Component itemDelegate 10 | 11 | property string modelRole: "model" 12 | property string depthRole: "depth" 13 | property string indexRole: "index" 14 | property string childrenRole: "children" 15 | 16 | readonly property int depth: -1 17 | 18 | Component 19 | { 20 | id: treeViewItemComponent 21 | 22 | Qaterial.TreeViewItem 23 | { 24 | id: expandable 25 | 26 | width: root.width 27 | 28 | modelRole: root.modelRole 29 | depthRole: root.depthRole 30 | indexRole: root.indexRole 31 | childrenRole: root.childrenRole 32 | 33 | header: root.itemDelegate 34 | treeViewItem: treeViewItemComponent 35 | } 36 | } 37 | 38 | delegate: treeViewItemComponent 39 | } 40 | -------------------------------------------------------------------------------- /tests/Calendar - DayGrid - OutOfInterval.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | Qaterial.CalendarDayGrid 7 | { 8 | id: _grid 9 | 10 | // Choose displayed month 11 | month: Qaterial.Calendar.Month.February 12 | 13 | // Choose displayed year 14 | year: 2008 15 | 16 | // Choose the interval of date for the calendar 17 | from: new Date(2010, 0, 3) 18 | to: new Date(2010, 0, 25) 19 | 20 | // Called when user pick a date 21 | onAccepted: (date) => console.log(`Accept date ${date}`) 22 | } 23 | 24 | Qaterial.Label { text: `date : ${_grid.date}` } 25 | Qaterial.Label { text: `month : ${Qaterial.Calendar.monthToString(_grid.month)}` } 26 | Qaterial.Label { text: `year : ${_grid.year}` } 27 | Qaterial.Label { text: `from : ${_grid.from}` } 28 | Qaterial.Label { text: `to : ${_grid.to}` } 29 | } 30 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Index 4 | nav_exclude: true 5 | --- 6 | 7 | # Qaterial Documentation 8 | 9 | [![](https://github.com/OlivierLDff/Qaterial/workflows/CI/badge.svg)](https://github.com/OlivierLDff/Qaterial/actions?query=workflow%3ACI) 10 | 11 | A collection Material Components to build UI using Qml. The project QaterialGallery demonstrate the use of the library and show example, how to use components. This library is still under development so big changes might happened. If you intend to use this in your project, you should use a stable version because master change often. 12 | 13 | ## Overview 14 | 15 | - Checkout [Qaterial Gallery](https://olivierldff.github.io/QaterialGallery/). 16 | - [Getting Start Guide](https://olivierldff.github.io/Qaterial/Quickstart.html). 17 | - Try it live with [Qaterial Online](https://olivierldff.github.io/QaterialOnline/). -------------------------------------------------------------------------------- /qml/Qaterial/ListSectionTitle.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.LabelOverline 14 | { 15 | id: _control 16 | property bool separatorVisible: false 17 | 18 | Qaterial.ToolSeparator 19 | { 20 | id: _separator 21 | width: parent.width 22 | y: Math.floor(Qaterial.Style.card.horizontalPadding / 2) 23 | verticalPadding: 0 24 | orientation: Qt.Horizontal 25 | visible: _control.separatorVisible 26 | } // ToolSeparator 27 | 28 | padding: Qaterial.Style.card.horizontalPadding 29 | bottomPadding: Qaterial.Style.card.verticalPadding 30 | topPadding: _separator.visible ? Qaterial.Style.card.horizontalPadding : Qaterial.Style.card.verticalPadding 31 | elide: Text.ElideRight 32 | } // Label 33 | -------------------------------------------------------------------------------- /qml/Qaterial/ScrollablePage.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Window 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | Qaterial.Page 15 | { 16 | id: _page 17 | 18 | default property alias content: _pane.contentItem 19 | property alias pane: _pane 20 | 21 | Flickable 22 | { 23 | anchors.fill: parent 24 | contentHeight: _pane.implicitHeight + (Qt.inputMethod && Qt.inputMethod.visible ? (Qt.inputMethod 25 | .keyboardRectangle.height / Screen.devicePixelRatio) : 0) 26 | flickableDirection: Flickable.AutoFlickIfNeeded 27 | 28 | Qaterial.Pane 29 | { 30 | id: _pane 31 | width: parent.width 32 | } // Pane 33 | 34 | ScrollIndicator.vertical: Qaterial.ScrollIndicator {} 35 | } // Flickable 36 | } // Page 37 | -------------------------------------------------------------------------------- /examples/Inputs/ContinuousSlider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQml 3 | import Qaterial as Qaterial 4 | 5 | Column 6 | { 7 | Qaterial.LabelHeadline6 8 | { 9 | text: "Volume" 10 | } 11 | Row 12 | { 13 | id: root 14 | spacing: 8 15 | Qaterial.ColorIcon 16 | { 17 | anchors.verticalCenter: parent.verticalCenter 18 | source: slider.value ? Qaterial.Icons.volumeMedium : Qaterial.Icons.volumeOff 19 | } 20 | Qaterial.Slider 21 | { 22 | id: slider 23 | width: 100 24 | value: 0.3 25 | } 26 | Qaterial.ColorIcon 27 | { 28 | anchors.verticalCenter: parent.verticalCenter 29 | source: Qaterial.Icons.volumeSource 30 | } 31 | } 32 | 33 | Qaterial.LabelHeadline6 34 | { 35 | text: "Disabled Slider" 36 | } 37 | 38 | Qaterial.Slider 39 | { 40 | x: -16 41 | value: slider.value 42 | enabled: false 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/Navigation/Tabs - LatoTabButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | implicitWidth: listView.width 9 | implicitHeight: listView.height 10 | 11 | ListView 12 | { 13 | id: listView 14 | 15 | width: contentWidth 16 | height: contentHeight 17 | 18 | contentWidth: contentItem.childrenRect.width;contentHeight: contentItem.childrenRect.height 19 | 20 | model: ["Overview", "Guides", "Reference", "Docs"] 21 | 22 | orientation: ListView.Horizontal 23 | boundsBehavior: Flickable.StopAtBounds 24 | flickableDirection: Flickable.AutoFlickIfNeeded 25 | snapMode: ListView.SnapToItem 26 | 27 | delegate: Qaterial.LatoTabButton 28 | { 29 | text: modelData 30 | 31 | onClicked: () => ListView.view.currentIndex = index 32 | } 33 | } 34 | 35 | Qaterial.DebugRectangle { anchors.fill: root } 36 | } 37 | -------------------------------------------------------------------------------- /qml/Qaterial/ExtendedFabButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.FabButton 10 | { 11 | id: _control 12 | flat: false 13 | highlighted: true 14 | 15 | leftPadding: Qaterial.Style.fab.padding 16 | rightPadding: Qaterial.Style.fab.padding 17 | 18 | contentItem: Qaterial.FabIconLabel 19 | { 20 | id: _iconLabel 21 | spacing: _control.spacing 22 | display: _control.display 23 | icon: _control.icon 24 | text: _control.text 25 | font: _control.font 26 | color: _control.foregroundColor 27 | } // FabIconLabel 28 | 29 | property bool extended: (!extendedOnHovered || extendedOnHovered && (hovered || down || visualFocus)) && text != "" 30 | 31 | type: extended ? Qaterial.Style.FabType.Extended : Qaterial.Style.FabType.Default 32 | } // FabButton 33 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorBlueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(color.r, color.g, value, color.a) 21 | } 22 | 23 | value: color.b 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(control.color.r, control.color.g, 0, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(control.color.r, control.color.g, 1, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorCyanSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(value, color.g, color.b, color.a) 21 | } 22 | 23 | value: color.r 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(0, control.color.g, control.color.b, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(1, control.color.g, control.color.b, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorRedSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(value, color.g, color.b, color.a) 21 | } 22 | 23 | value: color.r 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(0, control.color.g, control.color.b, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(1, control.color.g, control.color.b, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorAlphaSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(color.r, color.g, color.b, value) 21 | } 22 | 23 | value: color.a 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(control.color.r, control.color.g, control.color.b, 0) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(control.color.r, control.color.g, control.color.b, 1) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorGreenSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(color.r, value, color.b, color.a) 21 | } 22 | 23 | value: color.g 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(control.color.r, 0, control.color.b, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(control.color.r, 1, control.color.b, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorMagentaSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(value, color.g, color.b, color.a) 21 | } 22 | 23 | value: color.r 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(0, control.color.g, control.color.b, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(1, control.color.g, control.color.b, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorYellowSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return Qt.rgba(value, color.g, color.b, color.a) 21 | } 22 | 23 | value: color.r 24 | backgroundColor: "white" 25 | rippleColor: "transparent" 26 | inlineBorderWidth: 0 27 | handleRadius: 4 28 | 29 | gradient: Gradient 30 | { 31 | GradientStop 32 | { 33 | position: 0.000 34 | color: Qt.rgba(0, control.color.g, control.color.b, control.color.a) 35 | } 36 | GradientStop 37 | { 38 | position: 1.000 39 | color: Qt.rgba(1, control.color.g, control.color.b, control.color.a) 40 | } 41 | } 42 | } // Slider 43 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldIconButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.AppBarButton 13 | { 14 | property Qaterial.TextField textField 15 | property Qaterial.TextArea textArea 16 | property Qaterial.ComboBox comboBox 17 | backgroundImplicitHeight: Qaterial.Style.textField.iconWidth 18 | topInset: 0 19 | bottomInset: 0 20 | foregroundColor: 21 | { 22 | if(enabled) 23 | { 24 | if(colorReversed) 25 | return Qaterial.Style.secondaryTextColorReversed() 26 | return Qaterial.Style.secondaryTextColor() 27 | } 28 | if(colorReversed) 29 | return Qaterial.Style.disabledTextColorReversed() 30 | return Qaterial.Style.disabledTextColor() 31 | } 32 | 33 | width: visible ? implicitWidth : 0 34 | } // AppBarButton 35 | -------------------------------------------------------------------------------- /qml/Qaterial/EnumDelegate.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | // TO DO : improve that to use Qaterial.DialogManager 14 | Qaterial.ItemDelegate 15 | { 16 | id: _control 17 | 18 | signal accepted(int value) 19 | signal rejected() 20 | 21 | property alias model: _radioDialog.model 22 | property alias value: _radioDialog.currentIndex 23 | property alias delegate: _radioDialog.delegate 24 | property alias currentIndex: _radioDialog.currentIndex 25 | property alias title: _radioDialog.title 26 | 27 | Qaterial.RadioDialog 28 | { 29 | id: _radioDialog 30 | onAccepted: _control.accepted(currentIndex) 31 | onRejected: _control.rejected() 32 | } // RadioDialog 33 | 34 | onClicked: _radioDialog.open() 35 | } // ItemDelegate 36 | -------------------------------------------------------------------------------- /qml/Qaterial/FixedTabBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.TabBar 14 | { 15 | id: _root 16 | property alias model: _repeater.model 17 | property alias button: _repeater.delegate 18 | property int display: AbstractButton.TextUnderIcon 19 | implicitWidth: width 20 | 21 | Repeater 22 | { 23 | id: _repeater 24 | delegate: Qaterial.TabButton 25 | { 26 | width: implicitWidth 27 | implicitWidth: _root.width / model.count 28 | display: _root.display 29 | text: model.text ? model.text : "" 30 | icon.source: model.source ? model.source : "" 31 | onPrimary: _root.onPrimary 32 | spacing: _root.spacing 33 | enabled: _root.enabled 34 | } // TabButton 35 | } // Repeater 36 | } // TabBar 37 | -------------------------------------------------------------------------------- /examples/Display/Expandable - Simple.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.Expandable 5 | { 6 | id: root 7 | 8 | header: Qaterial.ItemDelegate 9 | { 10 | text: "Header" 11 | onClicked: () => root.expanded = !root.expanded 12 | 13 | contentItem: Qaterial.LabelHeadline6 14 | { 15 | text: parent.text 16 | horizontalAlignment: Text.AlignHCenter 17 | verticalAlignment: Text.AlignVCenter 18 | } 19 | 20 | Qaterial.DebugRectangle 21 | { 22 | anchors.fill: parent; 23 | border.color: Qaterial.Style.green 24 | } 25 | } 26 | 27 | delegate: Qaterial.LabelHeadline6 28 | { 29 | text: "Delegate" 30 | horizontalAlignment: Text.AlignHCenter 31 | verticalAlignment: Text.AlignVCenter 32 | height: 100 33 | 34 | Qaterial.DebugRectangle 35 | { 36 | anchors.fill: parent; 37 | border.color: Qaterial.Style.amber 38 | } 39 | } 40 | } // Expandable 41 | -------------------------------------------------------------------------------- /qml/Qaterial/HorizontalLineSeparator.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Rectangle 13 | { 14 | implicitWidth: Qaterial.Style.menu.separatorImplicitWidth 15 | implicitHeight: 1 16 | property bool enabled: true 17 | color: !enabled ? (colorReversed ? Qaterial.Style.disabledDividersColorReversed() : Qaterial.Style 18 | .disabledDividersColor()) : highlighted && accentColorAuthorized ? Qaterial.Style.accentColor : colorReversed ? 19 | Qaterial.Style.dividersColorReversed() : Qaterial.Style.dividersColor() 20 | 21 | property bool highlighted: false 22 | property bool onPrimary: false 23 | property bool colorReversed: onPrimary && Qaterial.Style.shouldReverseForegroundOnPrimary 24 | property bool accentColorAuthorized: onPrimary && Qaterial.Style.preferAccentOnPrimary 25 | } // Rectangle 26 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldClockButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.TextFieldIconButton 13 | { 14 | id: root 15 | 16 | property int hour 17 | property int minute 18 | property bool styleAm 19 | property bool am 20 | 21 | signal hourAccepted(int hour, int minute, bool am) 22 | 23 | icon.source: Qaterial.Icons.clockOutline 24 | onClicked: Qaterial.DialogManager.openFromComponent(_TimePickerDialog) 25 | 26 | Component 27 | { 28 | id: _TimePickerDialog 29 | Qaterial.TimePickerDialog 30 | { 31 | hour: root.hour 32 | minute: root.minute 33 | styleAm: root.styleAm 34 | am: root.am 35 | onAccepted: () => root.hourAccepted(hour, minute, am) 36 | Component.onCompleted: open() 37 | } 38 | } // Component 39 | } // TextFieldIconButton 40 | -------------------------------------------------------------------------------- /examples/Display/LabelWithCaption - Variation.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 1.15 3 | 4 | import Qaterial as Qaterial 5 | 6 | ColumnLayout 7 | { 8 | Qaterial.LabelWithCaption 9 | { 10 | Layout.preferredWidth: 150 11 | 12 | text: "text" 13 | caption: "caption" 14 | maximumLineCount: 1 15 | wrapMode: Text.WordWrap 16 | 17 | Qaterial.DebugRectangle { anchors.fill: parent } 18 | } 19 | 20 | Qaterial.CaptionWithLabel 21 | { 22 | Layout.preferredWidth: 150 23 | 24 | text: "text" 25 | caption: "caption" 26 | maximumLineCount: 1 27 | wrapMode: Text.WordWrap 28 | 29 | Qaterial.DebugRectangle { anchors.fill: parent } 30 | } 31 | 32 | Qaterial.OverlineWithLabel 33 | { 34 | Layout.preferredWidth: 150 35 | 36 | text: "text" 37 | caption: "caption" 38 | maximumLineCount: 1 39 | wrapMode: Text.WordWrap 40 | 41 | Qaterial.DebugRectangle { anchors.fill: parent } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docs/Display/Charts.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 🗠 Charts 4 | --- 5 | 6 | # Charts 7 | 8 | ## LineChart 9 | 10 | Display a graph from an array of `Qt.vector2d` called `series`. 11 | 12 | ## Example 13 | ![image](https://user-images.githubusercontent.com/66482761/87764698-14fab880-c817-11ea-8900-8f6156079cae.png) 14 | 15 | ``` js 16 | Qaterial.LineChart 17 | { 18 | id: _lineChart 19 | width: 400 20 | height: 200 21 | thickness: 3 22 | color: "cyan" 23 | 24 | series: 25 | [ 26 | Qt.vector2d(-10,-20), 27 | Qt.vector2d(10,12), 28 | Qt.vector2d(20,24), 29 | Qt.vector2d(30,15), 30 | Qt.vector2d(40,-26), 31 | Qt.vector2d(50,25), 32 | Qt.vector2d(60,87), 33 | Qt.vector2d(70,32) 34 | ] 35 | } 36 | ``` 37 | 38 | ## Properties 39 | 40 | `series`: a tab of `Qt.vector2d()` used to create the chartLine points 41 | `thickness`: define the color of the line *(default: 1)* 42 | `color`: define the color of the line *(default: `Qaterial.Style.AccentColor`)* 43 | -------------------------------------------------------------------------------- /qml/Qaterial/RadioMenuItem.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.MenuItem 13 | { 14 | id: _control 15 | 16 | property alias indicatorSource: _indicatorIcon.source 17 | 18 | icon.width: radioIcon.width 19 | icon.height: radioIcon.height 20 | icon.color: radioIcon.color 21 | icon.source: radioIcon.source 22 | 23 | checkable: true 24 | 25 | Qaterial.ColorIcon 26 | { 27 | id: _indicatorIcon 28 | x: parent.width - width - Qaterial.Style.card.horizontalPadding 29 | anchors.verticalCenter: parent.verticalCenter 30 | color: _control.enabled ? (_control.colorReversed ? Qaterial.Style.primaryTextColorReversed() : Qaterial.Style 31 | .primaryTextColor()) : (_control.colorReversed ? Qaterial.Style.hintTextColorReversed() : Qaterial.Style 32 | .hintTextColor()) 33 | } // ColorIcon 34 | } // MenuItem 35 | -------------------------------------------------------------------------------- /qml/Qaterial/AppBarButton.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qaterial 7 | import Qaterial as Qaterial 8 | 9 | Qaterial.RoundButton 10 | { 11 | leftPadding: 0 12 | rightPadding: 0 13 | 14 | topInset: Qaterial.Style.toolButton.padding 15 | bottomInset: Qaterial.Style.toolButton.padding 16 | leftInset: Qaterial.Style.toolButton.padding 17 | rightInset: Qaterial.Style.toolButton.padding 18 | 19 | backgroundImplicitWidth: Qaterial.Style.toolButton.appBarButtonWidth 20 | backgroundImplicitHeight: Qaterial.Style.toolButton.appBarButtonHeight 21 | 22 | foregroundColor: 23 | { 24 | if(!enabled) 25 | return colorReversed ? Qaterial.Style.disabledTextColorReversed() : Qaterial.Style.disabledTextColor() 26 | if(highlighted) 27 | return Qaterial.Style.accentColor 28 | return colorReversed ? Qaterial.Style.primaryTextColorReversed() : Qaterial.Style.primaryTextColor() 29 | } 30 | } // RoundButton 31 | -------------------------------------------------------------------------------- /qml/Qaterial/DebugGridOverlay.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Loader 5 | { 6 | id: root 7 | 8 | property real leftPadding 9 | property real rightPadding 10 | property real topPadding 11 | property real bottomPadding 12 | property real spacing 13 | property int columns 14 | property int flow 15 | 16 | sourceComponent: flow === Flow.LeftToRight ? verticalComponent : horizontalComponent 17 | opacity: 0.1 18 | 19 | Component 20 | { 21 | id: verticalComponent 22 | Qaterial.DebugGridOverlayVertical 23 | { 24 | leftPadding: root.leftPadding 25 | rightPadding: root.rightPadding 26 | spacing: root.spacing 27 | columns: root.columns 28 | } 29 | } 30 | 31 | Component 32 | { 33 | id: horizontalComponent 34 | Qaterial.DebugGridOverlayHorizontal 35 | { 36 | topPadding: root.topPadding 37 | bottomPadding: root.bottomPadding 38 | spacing: root.spacing 39 | columns: root.columns 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/Calendar/DayPickerView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | Qaterial.CalendarDayPickerView 7 | { 8 | id: _view 9 | 10 | // Choose displayed month 11 | month: Qaterial.Calendar.Month.May 12 | 13 | // Choose displayed year 14 | year: 2010 15 | 16 | // Choose the interval of date for the calendar 17 | from: new Date(2010, 3, 20) 18 | to: new Date(2010, 9, 1) 19 | 20 | // Can be required in order to show only current CalendarDayPicker 21 | clip: true 22 | 23 | // Called when user pick a date 24 | onAccepted: (date) => console.log(`Accept date ${date}`) 25 | 26 | // Called when user swip the view to go to another month/year 27 | onMoved: (month, year) => console.log(`Moved to month: ${month}, year: ${year}`) 28 | } 29 | 30 | Qaterial.Label { text: `date : ${_view.date}` } 31 | Qaterial.Label { text: `month : ${Qaterial.Calendar.monthToString(_view.month)}` } 32 | Qaterial.Label { text: `year : ${_view.year}` } 33 | } 34 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorPaletteGrid.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | import QtQuick 7 | 8 | import Qaterial as Qaterial 9 | 10 | GridView 11 | { 12 | id: root 13 | 14 | property int columns: 1 15 | property int rows: 1 16 | 17 | property bool showName: true 18 | property bool showShade: true 19 | 20 | signal accepted(color color, string name, string shade) 21 | 22 | implicitWidth: columns * cellWidth 23 | implicitHeight: rows * cellHeight 24 | 25 | interactive: false 26 | 27 | cellWidth: 24 28 | cellHeight: 24 29 | 30 | flow: GridView.FlowTopToBottom 31 | 32 | delegate: Qaterial.ColorPaletteButton 33 | { 34 | showName: root.showName 35 | showShade: root.showShade 36 | 37 | light: model.light 38 | name: model.name 39 | shade: model.shade 40 | color: model.color 41 | 42 | width: root.cellWidth 43 | height: root.cellHeight 44 | 45 | onClicked: () => root.accepted(color, name, shade) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/CalendarDayPickerView_FromGreaterThanTo.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | import Qaterial as Qaterial 4 | 5 | Column 6 | { 7 | Qaterial.CalendarDayPickerView 8 | { 9 | id: _view 10 | 11 | // Choose displayed month 12 | month: Qaterial.Calendar.Month.January 13 | 14 | // Choose displayed year 15 | year: 2019 16 | 17 | // Choose intervall of dates 18 | 19 | from: new Date(2020, 0, 1) 20 | to: new Date(2020, 3, 1) 21 | 22 | // Can be required in order to show only current CalendarDayPicker 23 | clip: true 24 | 25 | // Called when user pick a date 26 | onAccepted: (date) => console.log(`Accept date ${date}`) 27 | 28 | // Called when user swip the view to go to another month/year 29 | onMoved: (month, year) => console.log(`Moved to month: ${month}, year: ${year}`) 30 | } 31 | 32 | Qaterial.Label { text: `date : ${_view.date}` } 33 | Qaterial.Label { text: `month : ${Qaterial.Calendar.monthToString(_view.month)}` } 34 | Qaterial.Label { text: `year : ${_view.year}` } 35 | } 36 | -------------------------------------------------------------------------------- /examples/Navigation/FolderTreeView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQml 3 | 4 | import Qaterial as Qaterial 5 | 6 | Qaterial.FolderTreeView 7 | { 8 | id: treeView 9 | 10 | width: 300 11 | height: parent ? Math.min(contentHeight, parent.height) : contentHeight 12 | 13 | // sortField: Qaterial.FolderTreeModel.Type/Name/Size/Time 14 | // sortReversed: true 15 | // sortCaseSensitive: false 16 | // 17 | // showDotAndDotDot: true 18 | // showDrives: false 19 | // showDirs: false 20 | // showFiles: false 21 | // showHidden: true 22 | // showOnlyReadable: true 23 | // 24 | // nameFilters: [ "*.qml", "*.cpp" ] 25 | // caseSensitive: true 26 | // 27 | // path: file:///Path/To/Folder 28 | path: "" 29 | 30 | property QtObject selectedElement 31 | 32 | itemDelegate: Qaterial.FolderTreeViewItem 33 | { 34 | highlighted: treeView.selectedElement === model 35 | onAccepted: function(path) 36 | { 37 | console.log(`Accept path ${path}`) 38 | treeView.selectedElement = model 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /qml/Qaterial/CursorDelegate.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Rectangle 13 | { 14 | id: root 15 | 16 | color: Qaterial.Style.accentColor 17 | width: Qaterial.Style.textField.cursorWidth 18 | visible: parent.activeFocus && !parent.readOnly && parent.selectionStart === parent.selectionEnd 19 | 20 | Connections 21 | { 22 | target: root.parent 23 | function onCursorPositionChanged() 24 | { 25 | // keep a moving cursor visible 26 | root.opacity = 1 27 | _timer.restart() 28 | } 29 | } // Connections 30 | 31 | Timer 32 | { 33 | id: _timer 34 | running: root.parent.activeFocus && !root.parent.readOnly 35 | repeat: true 36 | interval: Qt.styleHints.cursorFlashTime / 2 37 | onTriggered: root.opacity = !root.opacity ? 1 : 0 38 | // force the cursor visible when gaining focus 39 | onRunningChanged: root.opacity = 1 40 | } // Timer 41 | } // Rectangle 42 | -------------------------------------------------------------------------------- /qml/Qaterial/FixedGrid.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.Grid 5 | { 6 | id: root 7 | 8 | readonly property real idealSize: 9 | { 10 | switch(type) 11 | { 12 | case Qaterial.Layout.ExtraLarge: 13 | return extraLargeBreakpoint 14 | case Qaterial.Layout.Large: 15 | return largeBreakpoint 16 | case Qaterial.Layout.Medium: 17 | return mediumBreakpoint 18 | case Qaterial.Layout.Small: 19 | return smallBreakpoint 20 | case Qaterial.Layout.ExtraSmall: 21 | return smallBreakpoint 22 | } 23 | } 24 | 25 | readonly property real idealSizePaddingLess: idealSize - padding * 2 26 | 27 | readonly property real fixedPadding: Math.floor(((flow === Flow.LeftToRight ? width : height) - 28 | idealSizePaddingLess) / 2) 29 | 30 | leftPadding: flow === Flow.LeftToRight ? fixedPadding : 0 31 | rightPadding: flow === Flow.LeftToRight ? fixedPadding : 0 32 | topPadding: flow === Flow.TopToBottom ? fixedPadding : 0 33 | bottomPadding: flow === Flow.TopToBottom ? fixedPadding : 0 34 | } 35 | -------------------------------------------------------------------------------- /qml/Qaterial/LatoTabBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Templates as T 10 | import Qt5Compat.GraphicalEffects 11 | 12 | // Qaterial 13 | import Qaterial as Qaterial 14 | 15 | T.TabBar 16 | { 17 | id: control 18 | 19 | implicitWidth: contentWidth + leftPadding + rightPadding 20 | implicitHeight: contentHeight + topPadding + bottomPadding 21 | 22 | contentItem: ListView 23 | { 24 | model: control.contentModel 25 | currentIndex: control.currentIndex 26 | 27 | spacing: control.spacing 28 | orientation: ListView.Horizontal 29 | boundsBehavior: Flickable.StopAtBounds 30 | flickableDirection: Flickable.AutoFlickIfNeeded 31 | snapMode: ListView.SnapToItem 32 | 33 | highlightMoveDuration: 250 34 | highlightResizeDuration: 0 35 | highlightFollowsCurrentItem: true 36 | highlightRangeMode: ListView.ApplyRange 37 | preferredHighlightBegin: 48 38 | preferredHighlightEnd: width - 48 39 | } // ListView 40 | } // TabBar 41 | -------------------------------------------------------------------------------- /examples/Inputs/TextFieldDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import Qaterial as Qaterial 4 | 5 | Qaterial.Button 6 | { 7 | text: "Show Text Field Dialog" 8 | icon.source: Qaterial.Icons.formTextbox 9 | 10 | onClicked: function() 11 | { 12 | Qaterial.DialogManager.showTextFieldDialog( 13 | { 14 | title: "title", 15 | textTitle: "textTitle", 16 | text: "text", 17 | placeholderText: "placeholderText", 18 | helperText: "helperText", 19 | validator: null, 20 | inputMethodHints: Qt.ImhSensitiveData, 21 | maximumLengthCount: 32, 22 | selectAllText: true, 23 | errorText: "Text is too long", 24 | echoMode: TextInput.Normal, 25 | standardButtons: Dialog.Ok | Dialog.Cancel, 26 | width: 400, 27 | onAccepted: function(text, acceptable) 28 | { 29 | if(acceptable) 30 | console.log(`Accept text ${text}`) 31 | else 32 | console.log(`Can't accept text ${text} because of error`) 33 | }, 34 | onRejected: () => console.log("Text Field Dialog rejected"), 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldDatePicker.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | // Qaterial 4 | import Qaterial as Qaterial 5 | 6 | Qaterial.TextFieldDate 7 | { 8 | id: root 9 | 10 | trailingVisible: true 11 | trailingInline: true 12 | trailingContent: Qaterial.TextFieldButtonContainer 13 | { 14 | Qaterial.TextFieldIconButton 15 | { 16 | icon.source: Qaterial.Icons.calendar 17 | onClicked: Qaterial.DialogManager.openFromComponent(_datePickerDialogComponent) 18 | 19 | Component 20 | { 21 | id: _datePickerDialogComponent 22 | Qaterial.DatePickerDialog 23 | { 24 | date: root.date 25 | month: isNaN(date) ? new Date() 26 | .getMonth() : root.date.getMonth() 27 | year: isNaN(date) ? new Date() 28 | .getFullYear() : root.date.getFullYear() 29 | 30 | from: root.from 31 | to: root.to 32 | 33 | onAccepted: function() 34 | { 35 | root.date = date 36 | root.accepted(date) 37 | } 38 | Component.onCompleted: open() 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /qml/Qaterial/CardMedia.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import Qt5Compat.GraphicalEffects 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Image 14 | { 15 | id: _control 16 | height: Qaterial.Style.card.mediaImplicitHeight 17 | width: Qaterial.Style.card.mediaImplicitWidth 18 | fillMode: Image.PreserveAspectCrop 19 | 20 | property bool clipTop: false 21 | property double radius: Qaterial.Style.card.radius 22 | 23 | layer.enabled: clipTop 24 | layer.effect: OpacityMask 25 | { 26 | maskSource: Rectangle 27 | { 28 | width: _control.width 29 | height: _control.height 30 | radius: _control.radius 31 | 32 | Rectangle 33 | { 34 | width: parent.width 35 | y: _control.radius 36 | height: parent.height - radius 37 | } // Rectangle 38 | } // Rectangle 39 | } // OpacityMask 40 | 41 | /*Qaterial.DebugRectangle 42 | { 43 | anchors.fill: _control 44 | border.color: "blue" 45 | z: 10 46 | } // DebugRectangle*/ 47 | } // Image 48 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorSaturationSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return hsv ? Qt.hsva(color.hsvHue, value, color.hsvValue, color.a) : 21 | Qt.hsla(color.hslHue, value, color.hslLightness, color.a) 22 | } 23 | 24 | value: hsv ? color.hsvSaturation : color.hslSaturation 25 | backgroundColor: "white" 26 | rippleColor: "transparent" 27 | inlineBorderWidth: 0 28 | handleRadius: 4 29 | 30 | gradient: Gradient 31 | { 32 | GradientStop 33 | { 34 | position: 0.000 35 | color: Qt.rgba(1, 1, 1, control.color.a) 36 | } 37 | GradientStop 38 | { 39 | position: 1.000 40 | color: control.hsv ? Qt.hsva(control.color.hsvHue, 1, control.color.hsvValue, control.color.a) : Qt.hsla( 41 | control.color.hslHue, 1, control.color.hslLightness, control.color.a) 42 | } 43 | } 44 | } // Slider 45 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorValueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return hsv ? Qt.hsva(color.hsvHue, color.hsvSaturation, value, color.a) : 21 | Qt.hsla(color.hslHue, color.hslSaturation, value, color.a) 22 | } 23 | 24 | value: hsv ? color.hsvValue : color.hslLightness 25 | backgroundColor: "white" 26 | rippleColor: "transparent" 27 | inlineBorderWidth: 0 28 | handleRadius: 4 29 | 30 | gradient: Gradient 31 | { 32 | GradientStop 33 | { 34 | position: 0.000 35 | color: Qt.rgba(0, 0, 0, control.color.a) 36 | } 37 | GradientStop 38 | { 39 | position: 1.000 40 | color: control.hsv ? Qt.hsva(control.color.hsvHue, control.color.hsvSaturation, 1, control.color.a) : Qt.hsla( 41 | control.color.hslHue, control.color.hslSaturation, 1, control.color.a) 42 | } 43 | } 44 | } // Slider 45 | -------------------------------------------------------------------------------- /Licence: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Olivier Le Doeuff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/Calendar/TextFieldDatePickerNoDialogManager.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | // Qaterial 4 | import Qaterial as Qaterial 5 | 6 | Qaterial.TextFieldDate 7 | { 8 | id: root 9 | 10 | // Select min & max in the picker 11 | from: new Date(2000, 0, 5) 12 | to: new Date(2001, 5, 12) 13 | 14 | //select a Date 15 | date: new Date(2000, 5, 14) 16 | 17 | trailingVisible: true 18 | trailingInline: true 19 | trailingContent: Qaterial.TextFieldButtonContainer 20 | { 21 | Qaterial.TextFieldIconButton 22 | { 23 | icon.source: Qaterial.Icons.calendar 24 | onClicked: () => dataDialog.open() 25 | 26 | Qaterial.DatePickerDialog 27 | { 28 | id: dataDialog 29 | 30 | date: root.date 31 | month: isNaN(date) ? new Date() 32 | .getMonth() : root.date.getMonth() 33 | year: isNaN(date) ? new Date() 34 | .getFullYear() : root.date.getFullYear() 35 | 36 | from: root.from 37 | to: root.to 38 | 39 | onAccepted: function() 40 | { 41 | root.date = date 42 | root.accepted(date) 43 | } 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/Feedback/Logger.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | width: 200 7 | Qaterial.RaisedButton 8 | { 9 | text: "Debug" 10 | width: parent.width 11 | backgroundColor: Qaterial.Style.blue 12 | onClicked: () => console.debug(`This is a debug message`) 13 | } 14 | Qaterial.RaisedButton 15 | { 16 | text: "Info" 17 | width: parent.width 18 | backgroundColor: Qaterial.Style.green 19 | onClicked: () => console.log(`This is a info message`) 20 | } 21 | Qaterial.RaisedButton 22 | { 23 | text: "Warning" 24 | width: parent.width 25 | backgroundColor: Qaterial.Style.orange 26 | onClicked: () => console.warn(`This is a warning message`) 27 | } 28 | Qaterial.RaisedButton 29 | { 30 | text: "Error" 31 | width: parent.width 32 | backgroundColor: Qaterial.Style.red 33 | onClicked: () => console.error(`This is a error message`) 34 | } 35 | Qaterial.RaisedButton 36 | { 37 | text: "Exception" 38 | width: parent.width 39 | backgroundColor: Qaterial.Colors.red900 40 | onClicked: () => console.exception(`This is a exception message`) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qml/Qaterial/ScrollView.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | import QtQuick.Controls 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.ScrollView 15 | { 16 | id: _control 17 | 18 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 19 | contentWidth + leftPadding + rightPadding) 20 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 21 | contentHeight + topPadding + bottomPadding) 22 | 23 | ScrollBar.vertical: Qaterial.ScrollBar 24 | { 25 | parent: _control 26 | x: _control.mirrored ? 0 : _control.width - width 27 | y: _control.topPadding 28 | height: _control.availableHeight 29 | active: _control.ScrollBar.horizontal.active 30 | } // ScrollBar 31 | 32 | ScrollBar.horizontal: Qaterial.ScrollBar 33 | { 34 | parent: _control 35 | x: _control.leftPadding 36 | y: _control.height - height 37 | width: _control.availableWidth 38 | active: _control.ScrollBar.vertical.active 39 | } // ScrollBar 40 | } // ScrollView 41 | -------------------------------------------------------------------------------- /qml/Qaterial/ToolBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | import QtQuick.Controls 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.ToolBar 15 | { 16 | id: _control 17 | 18 | property double elevation: Qaterial.Style.toolbar.elevation 19 | 20 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 21 | contentWidth + leftPadding + rightPadding) 22 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 23 | contentHeight + topPadding + bottomPadding) 24 | 25 | spacing: Qaterial.Style.card.horizontalPadding 26 | 27 | property color backgroundColor: Qaterial.Style.primaryColor 28 | 29 | background: Rectangle 30 | { 31 | implicitHeight: Qaterial.Style.toolbar.implicitHeight 32 | color: _control.backgroundColor 33 | 34 | layer.enabled: _control.elevation > 0 35 | layer.effect: Qaterial.ElevationEffect 36 | { 37 | elevation: _control.elevation 38 | fullWidth: true 39 | } // ElevationEffect 40 | } // Rectangle 41 | } // ToolBar 42 | -------------------------------------------------------------------------------- /qml/Qaterial/SplashScreenWindow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Window 3 | import Qaterial as Qaterial 4 | import QtQuick.Controls.Material 5 | 6 | Window 7 | { 8 | id: window 9 | 10 | property alias from: splashScreen.from 11 | property alias to: splashScreen.to 12 | property alias value: splashScreen.value 13 | property alias indeterminate: splashScreen.indeterminate 14 | 15 | property alias image: splashScreen.image 16 | property alias padding: splashScreen.padding 17 | property alias text: splashScreen.text 18 | property alias version: splashScreen.version 19 | 20 | width: 400 21 | height: 200 22 | 23 | color: Qaterial.Style.backgroundColor 24 | flags: Qt.SplashScreen 25 | 26 | // Ugly trick for now : todo remove 27 | Material.theme: Qaterial.Style.theme 28 | Material.primary: Qaterial.Style.primaryColor 29 | Material.background: Qaterial.Style.backgroundColor 30 | Material.accent: Qaterial.Style.accentColor 31 | Material.foreground: Qaterial.Style.foregroundColor 32 | 33 | Qaterial.SplashScreen 34 | { 35 | id: splashScreen 36 | anchors.fill: parent 37 | } 38 | 39 | Component.onCompleted: () => visible = true 40 | } 41 | -------------------------------------------------------------------------------- /examples/Display/ColorIcon.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Column 5 | { 6 | spacing: 10 7 | Qaterial.ColorIcon 8 | { 9 | source: Qaterial.Icons.rocketLaunchOutline 10 | outlined: false 11 | fill: false 12 | color: Qaterial.Style.accentColor 13 | roundColor: Qaterial.Style.primaryColor 14 | } 15 | Qaterial.ColorIcon 16 | { 17 | source: Qaterial.Icons.rocketLaunchOutline 18 | outlined: true 19 | fill: false 20 | color: Qaterial.Style.accentColor 21 | roundColor: Qaterial.Style.primaryColor 22 | roundBorderColor: Qaterial.Style.accentColor 23 | } 24 | Qaterial.ColorIcon 25 | { 26 | source: Qaterial.Icons.rocketLaunchOutline 27 | outlined: false 28 | fill: true 29 | color: Qaterial.Style.accentColor 30 | roundColor: Qaterial.Style.primaryColor 31 | roundBorderColor: Qaterial.Style.accentColor 32 | } 33 | Qaterial.ColorIcon 34 | { 35 | source: Qaterial.Icons.rocketLaunchOutline 36 | outlined: true 37 | fill: true 38 | color: Qaterial.Style.accentColor 39 | roundColor: Qaterial.Style.primaryColor 40 | roundBorderColor: Qaterial.Style.accentColor 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qml/Qaterial/SwipeView.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | T.SwipeView 14 | { 15 | id: _control 16 | 17 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 18 | contentWidth + leftPadding + rightPadding) 19 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 20 | contentHeight + topPadding + bottomPadding) 21 | 22 | contentItem: ListView 23 | { 24 | model: _control.contentModel 25 | interactive: _control.interactive 26 | currentIndex: _control.currentIndex 27 | 28 | spacing: _control.spacing 29 | orientation: _control.orientation 30 | snapMode: ListView.SnapOneItem 31 | boundsBehavior: Flickable.StopAtBounds 32 | 33 | highlightRangeMode: ListView.StrictlyEnforceRange 34 | preferredHighlightBegin: 0 35 | preferredHighlightEnd: 0 36 | highlightMoveDuration: 250 37 | maximumFlickVelocity: 4 * (_control.orientation === Qt.Horizontal ? width : height) 38 | } // ListView 39 | } // SwipeView 40 | -------------------------------------------------------------------------------- /qml/Qaterial/ColorHueSlider.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Qaterial.GradientSlider 13 | { 14 | id: control 15 | 16 | property bool hsv: true 17 | 18 | function getNewColor() 19 | { 20 | return hsv ? Qt.hsva(value, color.hsvSaturation, color.hsvValue, color.a) : 21 | Qt.hsla(value, color.hslSaturation, color.hslLightness, color.a) 22 | } 23 | 24 | value: hsv ? color.hsvHue : color.hslHue 25 | backgroundColor: "white" 26 | rippleColor: "transparent" 27 | inlineBorderWidth: 0 28 | handleRadius: 4 29 | 30 | gradient: Gradient 31 | { 32 | GradientStop { position: 0.000;color: Qt.rgba(1, 0, 0, 1) } 33 | GradientStop { position: 0.167;color: Qt.rgba(1, 1, 0, 1) } 34 | GradientStop { position: 0.333;color: Qt.rgba(0, 1, 0, 1) } 35 | GradientStop { position: 0.500;color: Qt.rgba(0, 1, 1, 1) } 36 | GradientStop { position: 0.667;color: Qt.rgba(0, 0, 1, 1) } 37 | GradientStop { position: 0.833;color: Qt.rgba(1, 0, 1, 1) } 38 | GradientStop { position: 1.000;color: Qt.rgba(1, 0, 0, 1) } 39 | } 40 | } // Slider 41 | -------------------------------------------------------------------------------- /qml/Qaterial/ScrollableTabBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.TabBar 14 | { 15 | id: _root 16 | property alias model: _repeater.model 17 | property int display: AbstractButton.TextOnly 18 | property double minWidth: Qaterial.Style.tabBar.minTabWidth 19 | property double maxWidth: Qaterial.Style.tabBar.maxTabWidth 20 | property int maxElement: 5 21 | implicitWidth: width 22 | 23 | leftPadding: !mirrored ? Qaterial.Style.tabBar.minLeftWidth : 0 24 | rightPadding: mirrored ? Qaterial.Style.tabBar.minLeftWidth : 0 25 | 26 | Repeater 27 | { 28 | id: _repeater 29 | delegate: Qaterial.TabButton 30 | { 31 | width: Math.max(_root.minWidth, Math.min(_root.width / _root.maxElement, _root.maxWidth)) 32 | implicitWidth: width 33 | display: _root.display 34 | text: model.text ? model.text : "" 35 | icon.source: model.source ? model.source : "" 36 | onPrimary: _root.onPrimary 37 | enabled: _root.enabled 38 | } // TabButton 39 | } // Repeater 40 | } // TabBar 41 | -------------------------------------------------------------------------------- /qml/Qaterial/DateFormat.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | pragma Singleton 10 | 11 | QtObject 12 | { 13 | /** 14 | * @brief Stringify a bytes count with the closest unit. 15 | * The count is also going to be round with 'decimals' 16 | * 17 | * @code 18 | * import Stringify.Formatter 1.0 as Formatter 19 | * 20 | * // ... 21 | * 22 | * const ms = 581293 23 | * const formatted = Formatter.Date.msToString(butes) 24 | * console.log("time : " + formatted) 25 | * // "time : 09:41:293" 26 | * 27 | * @endcode 28 | * 29 | * @param millis Milliseconds to transform into a timestamp 30 | * 31 | * @return Bytes string in form 'hour:minute:second:millisecond' 32 | */ 33 | function msToString(millis) 34 | { 35 | let ms = millis % 1000; 36 | let s = (millis - ms) / 1000; 37 | let secs = s % 60; 38 | s = (s - secs) / 60; 39 | let mins = s % 60; 40 | let hrs = (s - mins) / 60; 41 | 42 | ms = "00" + ms 43 | secs = "0" + secs 44 | mins = "0" + mins 45 | 46 | return (hrs ? hrs + ':' : '') + mins.substr(-2) + ':' + secs.substr(-2) + '.' + ms.substr(-3); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /qml/Qaterial/Pane.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Templates as T 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.Pane 15 | { 16 | id: control 17 | 18 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 19 | contentWidth + leftPadding + rightPadding) 20 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 21 | contentHeight + topPadding + bottomPadding) 22 | 23 | //padding: Qaterial.Style.card.horizontalPadding 24 | 25 | property bool onPrimary: false 26 | property bool colorReversed: onPrimary && Qaterial.Style.shouldReverseForegroundOnPrimary 27 | 28 | property double elevation: 0 29 | property color color: control.onPrimary ? Qaterial.Style.primaryColor : Qaterial.Style.backgroundColor 30 | property double radius: 0 31 | 32 | background: Rectangle 33 | { 34 | id: _back 35 | color: control.color 36 | radius: control.radius 37 | layer.enabled: control.enabled && control.elevation > 0 38 | layer.effect: Qaterial.ElevationEffect { elevation: control.elevation } // ElevationEffect 39 | } // Rectangle 40 | } // Pane 41 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | # Hello! This is where you manage which Jekyll version is used to run. 3 | # When you want to use a different version, change it below, save the 4 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so: 5 | # 6 | # bundle exec jekyll serve 7 | # 8 | # This will help ensure the proper Jekyll version is running. 9 | # Happy Jekylling! 10 | gem "jekyll", "~> 4.1.0" 11 | # This is the default theme for new Jekyll sites. You may change this to anything you like. 12 | gem "minima", "~> 2.5" 13 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and 14 | # uncomment the line below. To upgrade, run `bundle update github-pages`. 15 | # gem "github-pages", group: :jekyll_plugins 16 | # If you have any plugins, put them here! 17 | group :jekyll_plugins do 18 | gem "jekyll-feed", "~> 0.12" 19 | end 20 | 21 | # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem 22 | # and associated library. 23 | platforms :mingw, :x64_mingw, :mswin, :jruby do 24 | gem "tzinfo", "~> 1.2" 25 | gem "tzinfo-data" 26 | end 27 | 28 | # Performance-booster for watching directories on Windows 29 | gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] 30 | 31 | 32 | gem "jekyll-remote-theme" -------------------------------------------------------------------------------- /docs/QaterialHotReload.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: ♨️ Qaterial Hot Reload 4 | nav_order: 5 5 | --- 6 | 7 | # ♨️ Qaterial Hot Reload 8 | 9 | **QaterialHotReload** is an app that load a `.qml` file, and reloads it each time the file is saved on the system. 10 | 11 | ![QaterialHotReload](https://user-images.githubusercontent.com/17255804/85396672-6c787200-b552-11ea-814e-12ae2c6db0e9.gif) 12 | 13 | ## Position anchors 14 | 15 | Helpers button can apply anchors to your qml object. 16 | 17 | ![QaterialHotReloadAnchors](https://user-images.githubusercontent.com/17255804/85396675-6d110880-b552-11ea-80aa-fd79855346bc.gif) 18 | 19 | * FullScreen: `anchors.fill: parent` 20 | * Horizontal Center: `anchors.horizontalCenter: parent.horizontalCenter` 21 | * Vertical Center: `anchors.verticalCenter: parent.verticalCenter` 22 | * Left: `anchors.left: parent.left` 23 | * Right: `anchors.right: parent.right` 24 | * Bottom: `anchors.bottom: parent.bottom` 25 | * Top: `anchors.top: parent.top` 26 | 27 | ## Build & Execute 28 | 29 | Add the flag `-DQATERIAL_ENABLE_TOOLS=ON` when configuring the project with cmake to create the executable. 30 | 31 | ``` bash 32 | cmake -DQATERIAL_ENABLE_TOOLS=ON .. 33 | cmake --build . --target QaterialHotReload 34 | ./tools/HotReload/QaterialHotReload 35 | ``` -------------------------------------------------------------------------------- /tests/Loader/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(QATERIAL_TEST_LOADER QaterialTestLoader) 2 | message(STATUS "Add Test: ${QATERIAL_TEST_LOADER}") 3 | 4 | # Create our app 5 | qt_add_executable(${QATERIAL_TEST_LOADER} QaterialTestLoader.cpp) 6 | 7 | # We assume that Qaterial is available somewhere. You should have a look at 'cmake/FetchQaterial.cmake' 8 | target_link_libraries(${QATERIAL_TEST_LOADER} PRIVATE 9 | ${QATERIAL_TARGET}::${QATERIAL_TARGET} 10 | Qt::Core 11 | Qt::Gui 12 | Qt::Qml 13 | ) 14 | 15 | # AUTOMOC isn't necessary here, but it's a hello world 16 | # AUTORCC is to compile the .qrc files 17 | set_target_properties(${QATERIAL_TEST_LOADER} PROPERTIES FOLDER "${QATERIAL_FOLDER_PREFIX}/Test") 18 | 19 | file(GLOB_RECURSE QML_FILES ${PROJECT_SOURCE_DIR}/qml/*.qml) 20 | 21 | foreach(QML_FILE ${QML_FILES}) 22 | 23 | file(READ ${QML_FILE} QML_FILE_TXT) 24 | string(FIND "${QML_FILE_TXT}" "pragma Singleton" MATCH_SINGLETON) 25 | 26 | if(${MATCH_SINGLETON} EQUAL -1) 27 | 28 | get_filename_component(QML_FILE_NAME ${QML_FILE} NAME_WE) 29 | message(STATUS "Add test : ${QATERIAL_TEST_LOADER}_${QML_FILE_NAME}") 30 | add_test(NAME ${QATERIAL_TEST_LOADER}_${QML_FILE_NAME} COMMAND "$" "${QML_FILE}") 31 | 32 | endif() 33 | 34 | endforeach() 35 | -------------------------------------------------------------------------------- /qml/Qaterial/CalendarMonthPickerView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | 4 | import Qaterial as Qaterial 5 | 6 | GridView 7 | { 8 | id: root 9 | 10 | // Current selected month 11 | property int month: new Date() 12 | .getMonth() 13 | 14 | // Emitted when a month is clicked 15 | signal accepted(int month) 16 | 17 | implicitWidth: 280 18 | implicitHeight: 330 19 | 20 | cellHeight: Math.min(height / (Math.floor(height / 35)), height) 21 | cellWidth: Math.min(width / (Math.floor(width / 100)), width) 22 | 23 | model: Qaterial.Calendar.months 24 | 25 | delegate: Item 26 | { 27 | implicitWidth: root.cellWidth 28 | implicitHeight: root.cellHeight 29 | 30 | Qaterial.CalendarDateButton 31 | { 32 | id: _monthbutton 33 | 34 | anchors.fill: parent 35 | 36 | zoomLabelOnHovered: false 37 | horizontalPadding: Qaterial.Style.roundIcon.size / 3 38 | 39 | readonly property int month: index 40 | 41 | text: root.model[index] 42 | 43 | checked: root.month === index 44 | onClicked: function() 45 | { 46 | root.month = month 47 | root.accepted(month) 48 | } 49 | 50 | ToolTip.text: qsTr("Selected Month") 51 | ToolTip.visible: hovered && checked 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /qml/Qaterial/MenuBar.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Templates as T 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.MenuBar 15 | { 16 | id: _control 17 | 18 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 19 | contentWidth + leftPadding + rightPadding) 20 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 21 | contentHeight + topPadding + bottomPadding) 22 | 23 | delegate: Qaterial.MenuBarItem { onPrimary: _control.onPrimary;colorReversed: _control.colorReversed } 24 | 25 | contentItem: Row 26 | { 27 | spacing: _control.spacing 28 | Repeater 29 | { 30 | model: _control.contentModel 31 | } // Repeater 32 | } // Row 33 | 34 | property bool onPrimary: false 35 | property bool colorReversed: onPrimary && Qaterial.Style.shouldReverseForegroundOnPrimary 36 | 37 | property color backgroundColor: onPrimary ? Qaterial.Style.primaryColor : Qaterial.Style.dialogColor 38 | 39 | background: Rectangle 40 | { 41 | implicitHeight: Qaterial.Style.menu.implicitHeight 42 | color: _control.backgroundColor 43 | } // Rectangle 44 | } // MenuBar 45 | -------------------------------------------------------------------------------- /docs/Display/Typography.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 📜 Typography 4 | --- 5 | 6 | # 📜 Typography 7 | 8 | Use typography to present your design and content as clearly and efficiently as possible. 9 | 10 | Too many type sizes and styles at once can spoil any layout. A typographic scale has a limited set of type sizes that work well together along with the layout grid. 11 | 12 | `Qaterial.Style.TextType` is here to make life easier when you want to use text in a layout. 13 | 14 | ```js 15 | enum TextType 16 | { 17 | Display3, 18 | Display2, 19 | Display1, 20 | Heading, 21 | Title, 22 | Subheading, 23 | ListText, 24 | ListSecText, 25 | Overline, 26 | Body2, 27 | Body1, 28 | Caption, 29 | Hint, 30 | Button, 31 | Menu, 32 | MenuHint 33 | } // TextType 34 | ``` 35 | 36 | Several Type of typography are available with this `enum` : 37 | 38 | ![typo](https://user-images.githubusercontent.com/51703091/86353850-3f217780-bc68-11ea-86ec-3709fcac1129.png) 39 | 40 | Check it below, on [QaterialGallery](https://olivierldff.github.io/QaterialGallery/) or in [QaterialOnline](https://olivierldff.github.io/QaterialOnline/) 41 | 42 | ![typo](https://user-images.githubusercontent.com/51703091/86352630-6119fa80-bc66-11ea-9613-14abee8d7f55.gif) 43 | 44 | -------------------------------------------------------------------------------- /src/Qaterial/_Template.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include 24 | 25 | namespace qaterial { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /qml/Qaterial/BusyIndicatorDialog.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | import QtQuick.Controls 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | Qaterial.ModalDialog 15 | { 16 | id: root 17 | 18 | property alias text: _text.text 19 | width: undefined 20 | closePolicy: Popup.NoAutoClose 21 | 22 | contentItem: Item 23 | { 24 | implicitHeight: Math.floor(_busy.implicitHeight + _text.implicitHeight + Qaterial.Style.card.verticalPadding) 25 | 26 | implicitWidth: Qaterial.Style.dialog.implicitWidth - 2 * Qaterial.Style.card.horizontalPadding 27 | 28 | Qaterial.BusyIndicator 29 | { 30 | id: _busy 31 | anchors.horizontalCenter: parent.horizontalCenter 32 | } // BusyIndicator 33 | 34 | Qaterial.Label 35 | { 36 | id: _text 37 | 38 | text: root.text 39 | anchors.horizontalCenter: parent.horizontalCenter 40 | y: _busy.height + Qaterial.Style.card.verticalPadding 41 | width: parent.width 42 | font: root.font 43 | color: Qaterial.Style.secondaryTextColor() 44 | elide: Text.ElideRight 45 | horizontalAlignment: Text.AlignHCenter 46 | } // Label 47 | } // Item 48 | } // ModalDialog 49 | -------------------------------------------------------------------------------- /qml/Qaterial/TextField2014.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.TextField 26 | { 27 | id: root 28 | } 29 | -------------------------------------------------------------------------------- /src/Qaterial/Display/IconDescription.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include 24 | 25 | namespace qaterial { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /docs/IO/Clipboard.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 📋 Clipboard 4 | --- 5 | 6 | # 📋 Clipboard 7 | 8 | The clipboard offers a simple mechanism to copy and paste data between applications. 9 | 10 | `Clipboard` is provided as a Singleton. 11 | 12 | ## Copy Text 13 | 14 | The Clipboard have a `text` property that is used to read and write to the clipboard. An additional `owns` property tells if the text have been written by our application, or by an other application. 15 | 16 | ```js 17 | import QtQuick 18 | import Qaterial as Qaterial 19 | 20 | Qaterial.Label 21 | { 22 | // Read last text in clipboard 23 | text: Qaterial.Clipboard.text 24 | 25 | // React to clipboard text changed 26 | Connections 27 | { 28 | target: Qaterial.Clipboard 29 | function onTextChanged() 30 | { 31 | console.log(`new text in clipboard: ${Qaterial.Clipboard.text}`) 32 | } 33 | } 34 | 35 | // Write some text to the clipboard 36 | Component.onCompleted: () => Qaterial.Clipboard.text = "my text" 37 | } 38 | ``` 39 | 40 | The example `IO/Clipboard.qml` demonstrate how to copy text and how to list everything that have been copied. 41 | 42 | ## Copy Url 43 | 44 | > Not supported yet 45 | 46 | ## Copy Html 47 | 48 | > Not supported yet 49 | 50 | ## Copy Image 51 | 52 | > Not supported yet 53 | -------------------------------------------------------------------------------- /qml/Qaterial/TextAreaScrollView.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | import QtQuick.Controls 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.ScrollView 15 | { 16 | id: _view 17 | 18 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 19 | contentWidth + leftPadding + rightPadding) 20 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 21 | contentHeight + topPadding + bottomPadding) 22 | 23 | property double implicitTopPadding 24 | property double implicitBottomPadding 25 | 26 | ScrollBar.vertical: Qaterial.TextAreaScrollBar 27 | { 28 | parent: _view 29 | x: _view.mirrored ? 0 : _view.width - width 30 | y: _view.topPadding + _view.implicitTopPadding 31 | height: _view.availableHeight - _view.implicitBottomPadding - _view.implicitTopPadding 32 | active: _view.ScrollBar.horizontal.active 33 | } // TextAreaScrollBar 34 | 35 | ScrollBar.horizontal: Qaterial.TextAreaScrollBar 36 | { 37 | parent: _view 38 | x: _view.leftPadding 39 | y: _view.height - height 40 | width: _view.availableWidth 41 | active: _view.ScrollBar.vertical.active 42 | } // TextAreaScrollBar 43 | } // ScrollView 44 | -------------------------------------------------------------------------------- /src/Qaterial/Qaterial.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef __QATERIAL_HPP__ 24 | #define __QATERIAL_HPP__ 25 | 26 | #include 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /examples/Surface/Card.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 1.12 3 | import Qaterial as Qaterial 4 | 5 | Qaterial.Card 6 | { 7 | id: root 8 | media: "https://d1fmx1rbmqrxrr.cloudfront.net/cnet/optim/i/edit/2019/04/eso1644bsmall__w770.jpg" 9 | 10 | headerText: "This is a cool Image" 11 | subHeaderText: "Space is cool" 12 | supportingText: "Visit a blackHole will make you have a great day." 13 | button1.text: "Button 1" 14 | button2.text: "Button 2" 15 | 16 | property alias button1: _button1 17 | property alias button2: _button2 18 | 19 | contentItem: ColumnLayout 20 | { 21 | width: parent.width 22 | spacing: Qaterial.Style.card.horizontalPadding 23 | 24 | Qaterial.CardMedia { source: root.media;clipTop: true;Layout.preferredWidth: 300;Layout.preferredHeight: 200 } 25 | 26 | Qaterial.CardTitle 27 | { 28 | headerText: root.headerText 29 | subHeaderText: root.subHeaderText 30 | Layout.leftMargin: Qaterial.Style.card.horizontalPadding 31 | } 32 | 33 | Qaterial.CardSupportingText 34 | { 35 | supportingText: root.supportingText 36 | Layout.leftMargin: Qaterial.Style.card.horizontalPadding 37 | Layout.fillWidth: true 38 | } 39 | 40 | Row 41 | { 42 | Qaterial.FlatButton { id: _button1 } 43 | Qaterial.FlatButton { id: _button2 } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelBody1.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.body1 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelBody2.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.body2 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelButton.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.button 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline1.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline1 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline2.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline2 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline3.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline3 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline4.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline4 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline5.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline5 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHeadline6.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.headline6 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelSubtitle1.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.subtitle1 30 | } 31 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelSubtitle2.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.subtitle2 30 | } 31 | -------------------------------------------------------------------------------- /qml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Olivier Le Doeuff 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # Generate Qaterial::Fonts 24 | add_subdirectory(Qaterial/Fonts) 25 | # Generate Qaterial::Icons 26 | add_subdirectory(Qaterial/Icons) 27 | # Generate Qaterial::Components 28 | add_subdirectory(Qaterial) 29 | -------------------------------------------------------------------------------- /qml/Qaterial/CardRippleBackground.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import Qt5Compat.GraphicalEffects 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | Qaterial.CardBackground 15 | { 16 | id: _control 17 | 18 | property alias pressed: _ripple.pressed 19 | property alias rippleActive: _ripple.active 20 | property alias rippleColor: _ripple.color 21 | property alias rippleAnchor: _ripple.anchor 22 | property alias enabled: _ripple.enabled 23 | 24 | Qaterial.Ripple 25 | { 26 | id: _ripple 27 | width: parent.width - parent.border.width * 2 28 | height: parent.height - parent.border.width * 2 29 | x: parent.border.width 30 | y: parent.border.width 31 | 32 | clip: visible 33 | color: Qaterial.Style.rippleColor(parent.onPrimary ? Qaterial.Style.RippleBackground.Primary : Qaterial.Style 34 | .RippleBackground.Background) 35 | 36 | // trick because clipRadius isn't working in ripple private implementation (QTBUG-51894) 37 | layer.enabled: true 38 | layer.effect: OpacityMask 39 | { 40 | maskSource: Rectangle 41 | { 42 | width: _ripple.width 43 | height: _ripple.height 44 | radius: _control.radius 45 | } // Rectangle 46 | } // OpacityMask 47 | } // Ripple 48 | } // Rectangle 49 | -------------------------------------------------------------------------------- /.github/workflows/clang-format.yml: -------------------------------------------------------------------------------- 1 | name: 🎨 Run Linter 2 | 3 | on: [push] 4 | 5 | jobs: 6 | clang-format: 7 | runs-on: ubuntu-latest 8 | if: "!contains(github.event.head_commit.message, '🎨')" 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: DoozyX/clang-format-lint-action@v0.10 13 | name: "Run clang-format" 14 | with: 15 | source: '.' 16 | extensions: 'hpp,cpp' 17 | clangFormatVersion: 11 18 | inplace: True 19 | - uses: EndBug/add-and-commit@v4 20 | name: "Commit clang-format Change" 21 | with: 22 | author_name: Clang Robot 23 | author_email: robot@clang-format.com 24 | message: '🎨 Run clang-format' 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | 28 | js-beautify: 29 | needs: clang-format 30 | runs-on: ubuntu-latest 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | - name: "Install js-beautify" 35 | run: sudo npm -g install js-beautify 36 | - name: "🎨 Run js-beautify" 37 | run: find . -regex '.*\.\(qml\|js\)' -exec js-beautify -r {} \; 38 | - uses: EndBug/add-and-commit@v4 39 | name: "Commit js-beautify Change" 40 | with: 41 | author_name: Beautify Robot 42 | author_email: robot@js-beautify.com 43 | message: '🎨 Run js-beautify' 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | 47 | -------------------------------------------------------------------------------- /src/Qaterial/Navigation/StepperElement.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include 24 | 25 | namespace qaterial { 26 | 27 | StepperElement::StepperElement(QObject* parent) 28 | : QObject(parent) 29 | { 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/Qaterial/_Template.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef __QATERIAL_TEMPLATE_HPP__ 24 | #define __QATERIAL_TEMPLATE_HPP__ 25 | 26 | #include 27 | #include 28 | 29 | namespace qaterial { 30 | 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /nix/get-pkg-source-from-cmake.nix: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Olivier Le Doeuff 2 | # SPDX-License-Identifier: MIT 3 | let 4 | getPkgSourceFromCMake = 5 | { file 6 | , cmakeVar 7 | , private ? false 8 | , pkgs ? import { } 9 | }: 10 | let 11 | inherit (builtins) elemAt match; 12 | parse_repo = match ".*set\\(${cmakeVar}_REPOSITORY\n *\"([^\n]*)\"\n.*" 13 | (builtins.readFile file); 14 | parse_tag = match ".*set\\(${cmakeVar}_TAG\n *# hash: ([^\n]*)\n *\"([^\n]*)\"\n.*" 15 | (builtins.readFile file); 16 | pkg_url = elemAt parse_repo 0; 17 | pkg_hash = elemAt parse_tag 0; 18 | pkg_rev = elemAt parse_tag 1; 19 | parse_url = match ".*github\\.com/([a-zA-Z]+)/([a-zA-Z\\.0-9-]+)(/.*|$)" pkg_url; 20 | 21 | pkg_owner = elemAt parse_url 0; 22 | pkg_name_with_potential_extensions = elemAt parse_url 1; 23 | pkg_name = builtins.replaceStrings [ ".git" ".com" ] [ "" "" ] pkg_name_with_potential_extensions; 24 | in 25 | pkgs.fetchFromGitHub { 26 | owner = pkg_owner; 27 | repo = pkg_name; 28 | rev = pkg_rev; 29 | hash = pkg_hash; 30 | inherit private; 31 | # Calling github.com/owner/repo/archive/rev.tar.gz doesn't work with PAT... 32 | # I asked the question here: https://github.com/orgs/community/discussions/121881 33 | forceFetchGit = private; 34 | }; 35 | in 36 | getPkgSourceFromCMake 37 | -------------------------------------------------------------------------------- /qml/Qaterial/ProgressBarDialog.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | import QtQuick.Window 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | Qaterial.ModalDialog 15 | { 16 | id: _control 17 | 18 | width: undefined 19 | 20 | property alias from: _progressBar.from 21 | property alias to: _progressBar.to 22 | property alias value: _progressBar.value 23 | 24 | property alias text: _text.text 25 | property alias textColor: _text.color 26 | property alias textElide: _text.elide 27 | 28 | title: "Exporting Frames" 29 | 30 | contentItem: Item 31 | { 32 | implicitWidth: Qaterial.Style.dialog.implicitWidth - 2 * Qaterial.Style.card.horizontalPadding 33 | implicitHeight: Math.floor(_progressBar.implicitHeight + _text.implicitHeight + Qaterial.Style.card 34 | .verticalPadding) 35 | 36 | Qaterial.ProgressBar 37 | { 38 | id: _progressBar 39 | width: parent.width 40 | anchors.horizontalCenter: parent.horizontalCenter 41 | } // ProgressBar 42 | 43 | Qaterial.Label 44 | { 45 | id: _text 46 | 47 | width: parent.width 48 | y: _progressBar.height + Qaterial.Style.card.verticalPadding 49 | anchors.horizontalCenter: parent.horizontalCenter 50 | horizontalAlignment: Text.AlignHCenter 51 | } // Label 52 | } //Item 53 | } // ModalDialog 54 | -------------------------------------------------------------------------------- /examples/Feedback/PopupMenu.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | 4 | import Qaterial as Qaterial 5 | 6 | Item 7 | { 8 | id: root 9 | 10 | implicitWidth: 200 11 | implicitHeight: column.implicitHeight 12 | 13 | Column 14 | { 15 | id: column 16 | 17 | Qaterial.RaisedButton 18 | { 19 | width: 200 20 | text: "Show Top" 21 | onClicked: () => popup.openAt(mapToItem(Overlay.overlay, width / 2, 0), Item.Bottom) 22 | } 23 | 24 | Qaterial.RaisedButton 25 | { 26 | width: 200 27 | text: "Show Left" 28 | onClicked: () => popup.openAt(mapToItem(Overlay.overlay, width, height / 2), Item.Left) 29 | } 30 | 31 | Qaterial.RaisedButton 32 | { 33 | width: 200 34 | text: "Show Right" 35 | onClicked: () => popup.openAt(mapToItem(Overlay.overlay, 0, height / 2), Item.Right) 36 | } 37 | 38 | Qaterial.RaisedButton 39 | { 40 | width: 200 41 | text: "Show Bottom" 42 | onClicked: () => popup.openAt(mapToItem(Overlay.overlay, width / 2, height), Item.Top) 43 | } 44 | } 45 | 46 | Qaterial.PopupMenu 47 | { 48 | id: popup 49 | 50 | spacing: 8 51 | padding: 4 52 | 53 | contentItem: Qaterial.DebugRectangle 54 | { 55 | implicitWidth: 200 56 | implicitHeight: 50 57 | 58 | Qaterial.Label 59 | { 60 | anchors.centerIn: parent 61 | text: "Content Item" 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHint1.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.hint1 30 | color: enabled ? Qaterial.Style.colorTheme.secondaryText : Qaterial.Style.colorTheme.disabledText 31 | } 32 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelHint2.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.hint2 30 | color: enabled ? Qaterial.Style.colorTheme.secondaryText : Qaterial.Style.colorTheme.disabledText 31 | } 32 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelCaption.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.caption 30 | color: enabled ? Qaterial.Style.colorTheme.secondaryText : Qaterial.Style.colorTheme.disabledText 31 | } 32 | -------------------------------------------------------------------------------- /qml/Qaterial/LabelOverline.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import Qaterial as Qaterial 24 | 25 | Qaterial.Label 26 | { 27 | id: root 28 | 29 | font: Qaterial.Style.textTheme.overline 30 | color: enabled ? Qaterial.Style.colorTheme.secondaryText : Qaterial.Style.colorTheme.disabledText 31 | } 32 | -------------------------------------------------------------------------------- /examples/Display/Expandable - Advanced.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Qaterial.Expandable 5 | { 6 | id: root 7 | 8 | header: Qaterial.ItemDelegate 9 | { 10 | id: _header 11 | width: root.width 12 | 13 | icon.source: Qaterial.Icons.account 14 | text: "Header" 15 | secondaryText: `expanded: ${root.expanded}` 16 | 17 | onClicked: () => root.expanded = !root.expanded 18 | 19 | Qaterial.DebugRectangle 20 | { 21 | anchors.fill: parent; 22 | border.color: "#E91E63" 23 | } 24 | } // Rectangle 25 | 26 | delegate: Column 27 | { 28 | Repeater 29 | { 30 | id: _repeater 31 | 32 | model: ListModel 33 | { 34 | ListElement { icon: "numeric-1-circle-outline";color: "#2196F3" } 35 | ListElement { icon: "numeric-2-circle-outline";color: "#4CAF50" } 36 | ListElement { icon: "numeric-3-circle-outline";color: "#f44336" } 37 | } // ListModel 38 | 39 | delegate: Qaterial.ItemDelegate 40 | { 41 | width: root.width 42 | 43 | text: `Delegate ${index}` 44 | icon.source: `qrc:/Qaterial/Icons/${model.icon}.svg` 45 | 46 | Qaterial.DebugRectangle 47 | { 48 | anchors.fill: parent; 49 | border.color: model.color 50 | } 51 | 52 | onClicked: () => Qaterial.Logger.debug(`Element ${index+1} clicked`) 53 | } // ItemDelegate 54 | } // Repeater 55 | } // Item 56 | } // Expandable 57 | -------------------------------------------------------------------------------- /examples/Surface/RectangleAreaHandler - Customized.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | import QtQuick.Shapes 1.14 4 | 5 | Qaterial.RectangleAreaHandler 6 | { 7 | id: root 8 | 9 | start: Qt.vector2d(0.25, 0.25) 10 | end: Qt.vector2d(0.75, 0.75) 11 | 12 | width: parent.width 13 | height: parent.height 14 | 15 | handle: Rectangle 16 | { 17 | property bool hovered 18 | color: "#FF9800" 19 | 20 | width: 10 21 | height: 10 22 | 23 | scale: hovered ? 2 : 1 24 | Behavior on scale { NumberAnimation { duration: 100 } } 25 | 26 | rotation: 45 27 | antialiasing: true 28 | } 29 | 30 | handleLinker: Item 31 | { 32 | id: _linker 33 | property bool horizontal 34 | property bool hovered 35 | 36 | Shape 37 | { 38 | ShapePath 39 | { 40 | strokeWidth: hovered ? 4 : 2 41 | Behavior on strokeWidth { NumberAnimation { duration: 50 } } 42 | strokeColor: "#FF9800" 43 | strokeStyle: ShapePath.DashLine 44 | dashPattern: [1, 4] 45 | PathLine 46 | { 47 | x: horizontal ? _linker.width : 0 48 | y: horizontal ? 0 : _linker.height 49 | } 50 | } 51 | } 52 | } 53 | 54 | Column 55 | { 56 | anchors.centerIn: parent 57 | Qaterial.Label { text: `start: {${root.start.x.toFixed(2)},${root.start.y.toFixed(2)}}` } 58 | Qaterial.Label { text: `end: {${root.end.x.toFixed(2)},${root.end.y.toFixed(2)}}` } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /docs/Display/ToolTip.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: 💬 ToolTip 4 | --- 5 | 6 | # 💬 ToolTip 7 | 8 | **Tooltips** display informative text when users hover over, focus on, or tap an element. 9 | 10 | When activated, **Tooltips** display an element (default: label) such as a description of its function. 11 | 12 | ### Properties 13 | 14 | Inherited from `QtQuick.Templates`, `Qaterial.ToolTip` owns different properties. Most of them come from **Popup** and main others are : 15 | 16 | `QtQuick.Templates` properties 17 | 18 | - `text`: text shown by the `contentItem` (default: "") 19 | - `delay`: milliseconds before ToolTip apparition (default: 0) 20 | - `timeout`: milliseconds after which the ToolTip is hidden. A ToolTip with a negative timeout does not hide automatically (default: -1) 21 | - `contentItem`: default `Qaterial.Label` 22 | - `background`: default `Rectangle` 23 | 24 | `Qaterial` properties : 25 | 26 | - `backgroundRadius`: radius of the background Rectangle (default: 4) 27 | - `position`: ToolTip display position (default: on top of parent) 28 | 29 | ### ✏️ Position 30 | 31 | TooltTip `position` property holds from `Qaterial.Style.Position` enum. 32 | 33 | 17 position are available like TopStart, Top or TopEnd. Check **ToolTips** examples for more details : 34 | 35 | ![tooltip_position](https://user-images.githubusercontent.com/66482761/86573922-55377c80-bf75-11ea-87ec-da4450c610cb.gif) 36 | 37 | Or simply [check it live](https://tinyurl.com/yba5u44x) ! 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /qml/Qaterial/DebugGridOverlayHorizontal.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | property real topPadding 9 | property real bottomPadding 10 | property real spacing 11 | property int columns 12 | 13 | readonly property int paddingLessHeight: root.height - root.topPadding - root.bottomPadding 14 | readonly property real oneBlockSize: Math.floor(paddingLessHeight - (root.columns - 1) * root.spacing) / root.columns 15 | 16 | Repeater 17 | { 18 | anchors.fill: parent 19 | model: root.columns > 0 ? root.columns - 1 : 0 20 | delegate: Rectangle 21 | { 22 | y: root.topPadding + root.oneBlockSize * (index + 1) + root.spacing * index 23 | width: parent.width 24 | height: root.spacing 25 | color: Qaterial.Colors.cyan 26 | } 27 | } 28 | 29 | Repeater 30 | { 31 | anchors.fill: parent 32 | model: root.columns > 0 ? root.columns : 0 33 | delegate: Rectangle 34 | { 35 | y: root.topPadding + root.oneBlockSize * (index) + root.spacing * index 36 | width: parent.width 37 | height: root.oneBlockSize 38 | color: Qaterial.Colors.red 39 | } 40 | } 41 | 42 | Rectangle 43 | { 44 | width: parent.width 45 | height: root.topPadding 46 | color: Qaterial.Colors.green 47 | } 48 | 49 | Rectangle 50 | { 51 | y: parent.height - height 52 | width: parent.width 53 | height: root.topPadding 54 | color: Qaterial.Colors.green 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /qml/Qaterial/DebugGridOverlayVertical.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | property real leftPadding 9 | property real rightPadding 10 | property real spacing 11 | property int columns 12 | 13 | readonly property int paddingLessWidth: root.width - root.leftPadding - root.rightPadding 14 | readonly property real oneBlockSize: Math.floor(paddingLessWidth - (root.columns - 1) * root.spacing) / root.columns 15 | 16 | Repeater 17 | { 18 | anchors.fill: parent 19 | model: root.columns > 0 ? root.columns - 1 : 0 20 | delegate: Rectangle 21 | { 22 | x: root.leftPadding + root.oneBlockSize * (index + 1) + root.spacing * index 23 | height: parent.height 24 | width: root.spacing 25 | color: Qaterial.Colors.cyan 26 | } 27 | } 28 | 29 | Repeater 30 | { 31 | anchors.fill: parent 32 | model: root.columns > 0 ? root.columns : 0 33 | delegate: Rectangle 34 | { 35 | x: root.leftPadding + root.oneBlockSize * (index) + root.spacing * index 36 | height: parent.height 37 | width: root.oneBlockSize 38 | color: Qaterial.Colors.red 39 | } 40 | } 41 | 42 | Rectangle 43 | { 44 | height: parent.height 45 | width: root.leftPadding 46 | color: Qaterial.Colors.green 47 | } 48 | 49 | Rectangle 50 | { 51 | x: parent.width - width 52 | height: parent.height 53 | width: root.leftPadding 54 | color: Qaterial.Colors.green 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /qml/Qaterial/ListDelegateBackground.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Rectangle 13 | { 14 | implicitHeight: Qaterial.Style.delegate.implicitHeight(type, lines) 15 | implicitWidth: 200 16 | 17 | property alias rippleWidth: _ripple.width 18 | property alias rippleHeight: _ripple.height 19 | property alias rippleX: _ripple.x 20 | property alias rippleY: _ripple.y 21 | 22 | color: highlighted ? Qt.rgba(Qaterial.Style.accentColor.r, Qaterial.Style.accentColor.g, Qaterial.Style.accentColor.b, 23 | 0.2) : (transparentBackground ? "transparent" : Qaterial.Style.backgroundColor) 24 | 25 | property alias pressed: _ripple.pressed 26 | property alias rippleActive: _ripple.active 27 | property alias rippleColor: _ripple.color 28 | property alias rippleAnchor: _ripple.anchor 29 | property alias enabled: _ripple.enabled 30 | property bool transparentBackground: true 31 | property bool onPrimary: false 32 | property bool highlighted: false 33 | property int type 34 | property int lines 35 | 36 | Qaterial.Ripple 37 | { 38 | id: _ripple 39 | width: parent.width 40 | height: parent.height 41 | 42 | clip: visible 43 | color: Qaterial.Style.rippleColor(parent.onPrimary ? Qaterial.Style.RippleBackground.Primary : Qaterial.Style 44 | .RippleBackground.Background) 45 | } // Ripple 46 | } // Rectangle 47 | -------------------------------------------------------------------------------- /tests/FindPackageTest/main.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include 24 | #include 25 | 26 | int main(int argc, char* argv[]) 27 | { 28 | QGuiApplication app(argc, argv); 29 | qaterial::registerQmlTypes(); 30 | qaterial::loadQmlResources(); 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /src/Qaterial/Navigation/TreeElement.cpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #include 24 | 25 | namespace qaterial { 26 | 27 | TreeElement::TreeElement(QObject* parent) 28 | : TreeModel(parent) 29 | { 30 | } 31 | 32 | TreeElement* TreeElement::children() 33 | { 34 | return this; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /examples/Navigation/Tabs - LatoTabBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | id: root 7 | 8 | implicitWidth: column.width 9 | implicitHeight: column.height 10 | 11 | Column 12 | { 13 | id: column 14 | 15 | spacing: 8 16 | 17 | Qaterial.LatoTabBar 18 | { 19 | id: tabBar 20 | 21 | currentIndex: tabBarScroll.currentIndex 22 | 23 | Qaterial.LatoTabButton { text: "Overview" } 24 | Qaterial.LatoTabButton { text: "Guides" } 25 | Qaterial.LatoTabButton { text: "Reference" } 26 | Qaterial.LatoTabButton { text: "Docs" } 27 | Qaterial.LatoTabButton { text: "About" } 28 | } 29 | 30 | Qaterial.LatoTabBar 31 | { 32 | id: tabBarScroll 33 | 34 | currentIndex: tabBar.currentIndex 35 | 36 | width: 200 37 | clip: true 38 | 39 | Qaterial.LatoTabButton { text: "Overview";width: implicitWidth } 40 | Qaterial.LatoTabButton { text: "Guides";width: implicitWidth } 41 | Qaterial.LatoTabButton { text: "Reference";width: implicitWidth } 42 | Qaterial.LatoTabButton { text: "Docs";width: implicitWidth } 43 | Qaterial.LatoTabButton { text: "About";width: implicitWidth } 44 | } 45 | } 46 | 47 | Qaterial.DebugRectangle { width: tabBar.width;height: tabBar.height;x: tabBar.x;y: tabBar.y } 48 | Qaterial.DebugRectangle 49 | { 50 | width: tabBarScroll.width;height: tabBarScroll.height;x: tabBarScroll.x;y: tabBarScroll 51 | .y;border.color: Qaterial.Style.orange 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /qml/Qaterial/EuCircularHour.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | 9 | // Qaterial 10 | import Qaterial as Qaterial 11 | 12 | Item 13 | { 14 | id: root 15 | 16 | property int radius: 100 17 | property int hour: 0 18 | 19 | property alias labelSize: _amHour.labelSize 20 | readonly property int pmHourOffset: labelSize 21 | 22 | implicitWidth: Math.max(_amHour.implicitWidth, _pmHour.implicitWidth) 23 | implicitHeight: Math.max(_amHour.implicitHeight, _pmHour.implicitHeight) 24 | 25 | CircularPathLabel 26 | { 27 | id: _amHour 28 | anchors.centerIn: parent 29 | radius: parent.radius 30 | model: ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] 31 | currentIndex: 32 | { 33 | if(root.hour === 12) 34 | return 0 35 | if(root.hour >= 1 && root.hour <= 11) 36 | return root.hour 37 | return -1 38 | } 39 | } 40 | 41 | CircularPathLabel 42 | { 43 | id: _pmHour 44 | anchors.centerIn: parent 45 | radius: parent.radius - root.pmHourOffset 46 | font: Qaterial.Style.textTheme.caption 47 | model: ["00", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"] 48 | currentIndex: 49 | { 50 | if(root.hour === 24 || root.hour === 0) 51 | return 0 52 | if(root.hour >= 13 && root.hour <= 23) 53 | return root.hour - 12 54 | return -1 55 | } 56 | labelSize: _amHour.labelSize 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /qml/Qaterial/SideSquacleButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | 4 | // Qaterial 5 | import Qaterial as Qaterial 6 | 7 | Qaterial.SquacleButton 8 | { 9 | id: control 10 | readonly property bool horizontal: indicatorPosition === Qaterial.Style.Position.Top || indicatorPosition === 11 | Qaterial.Style.Position.Bottom 12 | 13 | property int indicatorPosition: Qaterial.Style.Position.Left 14 | 15 | topInset: horizontal ? 8 : 8 16 | bottomInset: horizontal ? 8 : 8 17 | leftInset: horizontal ? 8 : 12 18 | rightInset: horizontal ? 8 : 12 19 | 20 | Qaterial.SideSelectIndicator 21 | { 22 | x: 23 | { 24 | if(control.indicatorPosition === Qaterial.Style.Position.Left) 25 | return -width / 2 26 | if(control.indicatorPosition === Qaterial.Style.Position.Right) 27 | return parent.width - width / 2 28 | 29 | return parent.width / 2 - width / 2 30 | } 31 | 32 | y: 33 | { 34 | if(control.indicatorPosition === Qaterial.Style.Position.Top) 35 | return -height / 2 36 | if(control.indicatorPosition === Qaterial.Style.Position.Bottom) 37 | return parent.height - height / 2 38 | 39 | return parent.height / 2 - height / 2 40 | } 41 | 42 | color: control.color 43 | 44 | active: control.active 45 | pressed: control.highlighted || control.pressed 46 | hovered: control.hovered 47 | horizontal: control.horizontal 48 | } 49 | 50 | //Qaterial.DebugRectangle { anchors.fill: parent; border.color: "pink" } 51 | } 52 | -------------------------------------------------------------------------------- /qml/Qaterial/SideSquacleImageButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | 4 | // Qaterial 5 | import Qaterial as Qaterial 6 | 7 | Qaterial.SquacleImageButton 8 | { 9 | id: control 10 | readonly property bool horizontal: indicatorPosition === Qaterial.Style.Position.Top || indicatorPosition === 11 | Qaterial.Style.Position.Bottom 12 | 13 | property int indicatorPosition: Qaterial.Style.Position.Left 14 | 15 | topInset: horizontal ? 8 : 8 16 | bottomInset: horizontal ? 8 : 8 17 | leftInset: horizontal ? 8 : 12 18 | rightInset: horizontal ? 8 : 12 19 | 20 | Qaterial.SideSelectIndicator 21 | { 22 | x: 23 | { 24 | if(control.indicatorPosition === Qaterial.Style.Position.Left) 25 | return -width / 2 26 | if(control.indicatorPosition === Qaterial.Style.Position.Right) 27 | return parent.width - width / 2 28 | 29 | return parent.width / 2 - width / 2 30 | } 31 | 32 | y: 33 | { 34 | if(control.indicatorPosition === Qaterial.Style.Position.Top) 35 | return -height / 2 36 | if(control.indicatorPosition === Qaterial.Style.Position.Bottom) 37 | return parent.height - height / 2 38 | 39 | return parent.height / 2 - height / 2 40 | } 41 | 42 | color: control.color 43 | 44 | active: control.active 45 | pressed: control.highlighted || control.pressed 46 | hovered: control.hovered 47 | horizontal: control.horizontal 48 | } 49 | 50 | //Qaterial.DebugRectangle { anchors.fill: parent; border.color: "pink" } 51 | } 52 | -------------------------------------------------------------------------------- /qml/Qaterial/ScrollIndicator.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | T.ScrollIndicator 14 | { 15 | id: _control 16 | 17 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 18 | implicitContentWidth + leftPadding + rightPadding) 19 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 20 | implicitContentHeight + topPadding + bottomPadding) 21 | 22 | padding: 2 23 | 24 | contentItem: Rectangle 25 | { 26 | implicitWidth: 4 27 | implicitHeight: 4 28 | radius: 2 29 | 30 | color: Qaterial.Style.hintTextColor() 31 | visible: _control.size < 1.0 32 | opacity: 0.0 33 | 34 | states: State 35 | { 36 | name: "active" 37 | when: _control.active 38 | PropertyChanges { target: _control.contentItem;opacity: 0.75 } 39 | } // State 40 | 41 | transitions: [ 42 | Transition 43 | { 44 | from: "active" 45 | SequentialAnimation 46 | { 47 | PauseAnimation { duration: 450 } // PauseAnimation 48 | NumberAnimation 49 | { 50 | target: _control 51 | .contentItem;duration: 200;property: "opacity";to: 0.0 52 | } // NumberAnimation 53 | } // SequentialAnimation 54 | } // Transition 55 | ] // transitions 56 | } // Rectangle 57 | } // ScrollIndicator 58 | -------------------------------------------------------------------------------- /qml/Qaterial/SplashScreen.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Rectangle 5 | { 6 | id: root 7 | 8 | property real from 9 | property real to 10 | property real value 11 | property bool indeterminate: true 12 | 13 | property real padding 14 | property url image 15 | property string text 16 | property string version 17 | 18 | implicitWidth: 400 19 | implicitHeight: 200 20 | 21 | color: Qaterial.Style.backgroundColor 22 | 23 | Image 24 | { 25 | id: logo 26 | source: root.image 27 | width: parent.width - root.padding * 2 28 | anchors.centerIn: parent 29 | fillMode: Image.PreserveAspectFit 30 | } 31 | 32 | Qaterial.LabelCaption 33 | { 34 | id: stateText 35 | 36 | anchors.bottom: progressBar.top 37 | anchors.left: parent.left 38 | anchors.bottomMargin: Qaterial.Style.card.verticalPadding 39 | anchors.leftMargin: Qaterial.Style.card.horizontalPadding 40 | 41 | text: root.text 42 | } 43 | 44 | Qaterial.LabelCaption 45 | { 46 | id: hintText 47 | 48 | anchors.right: parent.right 49 | anchors.baseline: stateText.baseline 50 | anchors.rightMargin: Qaterial.Style.card.horizontalPadding 51 | 52 | text: root.version 53 | } 54 | 55 | Qaterial.ProgressBar 56 | { 57 | id: progressBar 58 | 59 | anchors.bottom: parent.bottom 60 | anchors.right: parent.right 61 | anchors.left: parent.left 62 | 63 | from: root.from 64 | to: root.to 65 | value: root.value 66 | indeterminate: root.indeterminate 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /qml/Qaterial/RadioDialog.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Qaterial.ModalDialog 14 | { 15 | id: _root 16 | 17 | property 18 | var model: null 19 | property int currentIndex: 0 20 | 21 | property 22 | var delegate: defaultDelegate 23 | readonly property 24 | var defaultDelegate: _defaultDelegate 25 | 26 | Component 27 | { 28 | id: _defaultDelegate 29 | Qaterial.RadioDialogDelegate 30 | { 31 | text: model.text ? model.text : "" 32 | secondaryText: model.secondaryText ? model.secondaryText : "" 33 | } // RadioDialogDelegate 34 | } // Component 35 | 36 | horizontalPadding: 0 37 | bottomPadding: 1 38 | drawSeparator: _list.height < _list.contentHeight 39 | property double maxHeight: Qaterial.Style.dialog.maxHeight 40 | 41 | standardButtons: Dialog.Ok | Dialog.Cancel 42 | contentItem: ListView 43 | { 44 | implicitHeight: Math.min(_root.maxHeight, _list.contentHeight) 45 | //height: 200 46 | interactive: contentHeight > height 47 | id: _list 48 | clip: true 49 | model: _root.model 50 | delegate: _root.delegate 51 | highlightFollowsCurrentItem: true 52 | currentIndex: _root.currentIndex 53 | 54 | onCurrentIndexChanged: 55 | { 56 | if(_root.currentIndex !== currentIndex) 57 | _root.currentIndex = currentIndex 58 | } 59 | } // ListView 60 | } // ModelDialog 61 | -------------------------------------------------------------------------------- /qml/Qaterial/CaptionWithLabel.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import QtQuick 24 | import Qaterial as Qaterial 25 | 26 | Qaterial.LabelWithCaption 27 | { 28 | id: root 29 | 30 | textColor: Qaterial.Style.colorTheme.secondaryText 31 | captionColor: Qaterial.Style.colorTheme.primaryText 32 | 33 | textFont: Qaterial.Style.textTheme.caption 34 | captionFont: Qaterial.Style.textTheme.body1 35 | } 36 | -------------------------------------------------------------------------------- /qml/Qaterial/OverlineWithLabel.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import QtQuick 24 | import Qaterial as Qaterial 25 | 26 | Qaterial.LabelWithCaption 27 | { 28 | id: root 29 | 30 | textColor: Qaterial.Style.colorTheme.secondaryText 31 | captionColor: Qaterial.Style.colorTheme.primaryText 32 | 33 | textFont: Qaterial.Style.textTheme.overline 34 | captionFont: Qaterial.Style.textTheme.body1 35 | } 36 | -------------------------------------------------------------------------------- /qml/Qaterial/Icon.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import Qt5Compat.GraphicalEffects as QGE 9 | 10 | import Qaterial as Qaterial 11 | 12 | Item 13 | { 14 | id: root 15 | 16 | property color color: Qaterial.Style.colorTheme.primaryText 17 | property alias icon: dummyImage.source 18 | property real size: Qaterial.Style.smallIcon 19 | property bool cached: true 20 | 21 | readonly property real _implicitSize: icon.toString() ? size : 0 22 | readonly property bool isImage: color.a === 0 23 | 24 | implicitWidth: _implicitSize 25 | implicitHeight: _implicitSize 26 | 27 | Image 28 | { 29 | id: dummyImage 30 | 31 | anchors.fill: parent 32 | 33 | fillMode: Image.PreserveAspectFit 34 | sourceSize: Qt.size(root.width, root.height) 35 | visible: root.isImage && root.enabled 36 | } // Image 37 | 38 | QGE.ColorOverlay 39 | { 40 | anchors.fill: parent 41 | 42 | source: dummyImage 43 | readonly property color implicitColor: enabled ? root.color : Qaterial.Style.colorTheme.disabledText 44 | color: Qt.rgba(implicitColor.r, implicitColor.g, implicitColor.b, implicitColor.a) 45 | 46 | cached: root.cached 47 | visible: !root.isImage 48 | } // ColorOverlay 49 | 50 | QGE.Colorize 51 | { 52 | anchors.fill: parent 53 | 54 | source: dummyImage 55 | hue: 0 56 | saturation: 0 57 | lightness: -0.2 58 | 59 | cached: root.cached 60 | visible: root.isImage && !root.enabled 61 | } // Colorize 62 | } // Item 63 | -------------------------------------------------------------------------------- /qml/Qaterial/ApplicationWindow.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | import QtQuick.Controls.Material 10 | 11 | // Qaterial 12 | import Qaterial as Qaterial 13 | 14 | T.ApplicationWindow 15 | { 16 | id: _window 17 | 18 | color: Qaterial.Style.backgroundColor 19 | property color overlayColor: Qaterial.Style.overlayColor 20 | 21 | Overlay.modal: Rectangle 22 | { 23 | color: _window.overlayColor 24 | Behavior on opacity { NumberAnimation { duration: 150 } } 25 | } // Rectangle 26 | 27 | Overlay.modeless: Rectangle 28 | { 29 | color: _window.overlayColor 30 | Behavior on opacity { NumberAnimation { duration: 150 } } 31 | } // Rectangle 32 | 33 | // Ugly trick for now : todo remove 34 | Material.theme: Qaterial.Style.theme 35 | Material.primary: Qaterial.Style.primaryColor 36 | Material.background: Qaterial.Style.backgroundColor 37 | Material.accent: Qaterial.Style.accentColor 38 | Material.foreground: Qaterial.Style.foregroundColor 39 | 40 | Qaterial.SnackbarLoader 41 | { 42 | id: _snackBarLoader 43 | } 44 | 45 | Qaterial.DialogLoader 46 | { 47 | id: _dialogLoader 48 | } 49 | 50 | Component.onCompleted: 51 | { 52 | if(!Qaterial.SnackbarManager.snackBarLoader) 53 | Qaterial.SnackbarManager.snackBarLoader = _snackBarLoader 54 | 55 | if(!Qaterial.DialogManager.dialogLoader) 56 | Qaterial.DialogManager.dialogLoader = _dialogLoader 57 | } // Component 58 | } // ApplicationWindow 59 | -------------------------------------------------------------------------------- /qml/Qaterial/TextFieldButtonContainer.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Container 14 | { 15 | id: _container 16 | property Qaterial.TextField textField 17 | property Qaterial.TextArea textArea 18 | property Qaterial.ComboBox comboBox 19 | width: list.contentWidth 20 | 21 | contentItem: ListView 22 | { 23 | id: list 24 | model: _container.contentModel 25 | snapMode: ListView.SnapOneItem 26 | orientation: ListView.Horizontal 27 | } 28 | 29 | function assignTextFieldToContentItem() 30 | { 31 | if(textField) 32 | { 33 | for(var i = 0; i < count; i++) 34 | { 35 | var item = itemAt(i) 36 | if(item && ((typeof item.textField) == "object")) 37 | item.textField = _container.textField 38 | } 39 | } 40 | if(textArea) 41 | { 42 | for(var i = 0; i < count; i++) 43 | { 44 | var item = itemAt(i) 45 | if(item && ((typeof item.textArea) == "object")) 46 | item.textArea = _container.textArea 47 | } 48 | } 49 | if(comboBox) 50 | { 51 | for(var i = 0; i < count; i++) 52 | { 53 | var item = itemAt(i) 54 | if(item && ((typeof item.comboBox) == "object")) 55 | item.comboBox = _container.comboBox 56 | } 57 | } 58 | } // function assignTextFieldToContentItem() 59 | onTextFieldChanged: assignTextFieldToContentItem() 60 | } // Container 61 | -------------------------------------------------------------------------------- /qml/Qaterial/CardBackground.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Controls 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | Rectangle 14 | { 15 | id: control 16 | property bool enabled: true 17 | property bool outlined: false 18 | property bool isActive: false 19 | property double elevation: 20 | { 21 | if(isActive) 22 | return Qaterial.Style.card.activeElevation 23 | return outlined ? 0 : Qaterial.Style.card.defaultElevation 24 | } 25 | 26 | property bool onPrimary: false 27 | property bool colorReversed: onPrimary && Qaterial.Style.shouldReverseForegroundOnPrimary 28 | 29 | color: onPrimary ? Qaterial.Style.primaryColor : Qaterial.Style.cardColor 30 | property color borderColor: enabled ? Qaterial.Style.dividersColor() : Qaterial.Style.disabledDividersColor() 31 | radius: Qaterial.Style.card.radius 32 | border.width: outlined ? 1 : 0 33 | border.color: isActive ? "transparent" : borderColor 34 | 35 | Behavior on border.color 36 | { 37 | ColorAnimation 38 | { 39 | duration: 250 40 | easing.type: Easing.OutCubic 41 | } // ColorAnimation 42 | } // Behavior 43 | 44 | Behavior on elevation 45 | { 46 | NumberAnimation 47 | { 48 | duration: 250 49 | easing.type: Easing.OutCubic 50 | } // NumberAnimation 51 | } // Behavior 52 | 53 | layer.enabled: control.enabled && control.elevation > 0 54 | layer.effect: Qaterial.ElevationEffect { elevation: control.elevation } 55 | } // Rectangle 56 | -------------------------------------------------------------------------------- /qml/Qaterial/FolderTreeView.qml: -------------------------------------------------------------------------------- 1 | // Copyright Olivier Le Doeuff 2020 (C) 2 | 3 | import QtQml 4 | import QtQuick 5 | 6 | import Qaterial as Qaterial 7 | 8 | Qaterial.TreeView 9 | { 10 | id: treeView 11 | 12 | property alias path: folderTreeModel.path 13 | property alias nameFilters: folderTreeModel.nameFilters 14 | property alias caseSensitive: folderTreeModel.caseSensitive 15 | property alias showDrives: folderTreeModel.showDrives 16 | property alias showDirs: folderTreeModel.showDirs 17 | property alias showFiles: folderTreeModel.showFiles 18 | property alias showDirsFirst: folderTreeModel.showDirsFirst 19 | property alias showDot: folderTreeModel.showDot 20 | property alias showDotDot: folderTreeModel.showDotDot 21 | property alias showDotAndDotDot: folderTreeModel.showDotAndDotDot 22 | property alias showHidden: folderTreeModel.showHidden 23 | property alias showOnlyReadable: folderTreeModel.showOnlyReadable 24 | property alias sortCaseSensitive: folderTreeModel.sortCaseSensitive 25 | property alias sortReversed: folderTreeModel.sortReversed 26 | property alias sortField: folderTreeModel.sortField 27 | property alias status: folderTreeModel.status 28 | 29 | implicitWidth: 300 30 | implicitHeight: contentHeight 31 | 32 | model: folderTreeModel 33 | itemDelegate: Qaterial.FolderTreeViewItem {} 34 | 35 | Qaterial.FolderTreeModel 36 | { 37 | id: folderTreeModel 38 | 39 | onPathChanged: function() { if(treeView.model === folderTreeModel) fetch() } 40 | Component.onCompleted: function() { if(treeView.model === folderTreeModel) fetch() } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /cmake/CPM.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: MIT 2 | # 3 | # SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors 4 | 5 | # Heuristic to check if file have already been found 6 | if(COMMAND CpmAddPackage) 7 | return() 8 | endif() 9 | 10 | if(QATERIAL_USE_LOCAL_CPM_FILE) 11 | find_file(CPM_LOCAL_FILE 12 | CPM.cmake 13 | PATH_SUFFIXES share/cpm/ 14 | ) 15 | 16 | if(EXISTS ${CPM_LOCAL_FILE}) 17 | message(STATUS "Using local CPM.cmake: ${CPM_LOCAL_FILE}") 18 | include(${CPM_LOCAL_FILE}) 19 | return() 20 | endif() 21 | endif() 22 | 23 | # Now the original from the release that can be found at 24 | # https://github.com/cpm-cmake/CPM.cmake/releases 25 | 26 | set(CPM_DOWNLOAD_VERSION 0.40.2) 27 | set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d") 28 | 29 | if(CPM_SOURCE_CACHE) 30 | set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 31 | elseif(DEFINED ENV{CPM_SOURCE_CACHE}) 32 | set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 33 | else() 34 | set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") 35 | endif() 36 | 37 | # Expand relative path. This is important if the provided path contains a tilde (~) 38 | get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) 39 | 40 | file(DOWNLOAD 41 | https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake 42 | ${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} 43 | ) 44 | 45 | include(${CPM_DOWNLOAD_LOCATION}) 46 | -------------------------------------------------------------------------------- /examples/Navigation/Stepper - Simple.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Qaterial as Qaterial 3 | 4 | Item 5 | { 6 | width: stepper.width 7 | height: stepper.height 8 | 9 | Qaterial.Stepper 10 | { 11 | id: stepper 12 | 13 | // Stepper has implicitWidth / Height 14 | 15 | // Dimension properties 16 | indicatorWidth: 64 17 | indicatorHeight: indicatorWidth 18 | 19 | contentItemWidth: 150 20 | contentItemHeight: 32 21 | 22 | separatorHeight: 10 23 | separatorWidth: 10 24 | 25 | // Clickable property which allow the user to click on the step to display it 26 | clickable: false 27 | // Vertical property which display vertically the stepper instead of horizontally 28 | vertical: false 29 | 30 | // HorizontalStepper model is a StepperModel Item which is a list of StepperElement 31 | // Those StepperElement can have properties like text, done, alertMessage, etc ... 32 | model: Qaterial.StepperModel 33 | { 34 | Qaterial.StepperElement {} 35 | Qaterial.StepperElement {} 36 | Qaterial.StepperElement {} 37 | } // StepperModel 38 | 39 | // Separator, Indicator and ContentItem are 3 customizable Components 40 | separator: Rectangle 41 | { 42 | color: Qaterial.Style.accentColor 43 | height: 10 44 | width: 10 45 | } 46 | indicator: Rectangle 47 | { 48 | color: "pink" 49 | width: 64 50 | height: 64 51 | } 52 | contentItem: Rectangle 53 | { 54 | color: Qaterial.Style.blue 55 | width: 150 56 | height: 32 57 | } 58 | } // HorizontalStepper 59 | } // Item 60 | -------------------------------------------------------------------------------- /qml/Qaterial/ClipRRect.qml: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import QtQuick as QQ 24 | import Qt5Compat.GraphicalEffects as QGE 25 | 26 | QQ.Item 27 | { 28 | id: root 29 | 30 | property real radius: 8 31 | 32 | layer.enabled: radius > 0 33 | layer.effect: QGE.OpacityMask 34 | { 35 | maskSource: QQ.Rectangle 36 | { 37 | width: root.width 38 | height: root.height 39 | radius: root.radius 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /qml/Qaterial/Frame.qml: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) Olivier Le Doeuff 2019 3 | * Contact: olivier.ldff@gmail.com 4 | */ 5 | 6 | // Qt 7 | import QtQuick 8 | import QtQuick.Templates as T 9 | 10 | // Qaterial 11 | import Qaterial as Qaterial 12 | 13 | T.Frame 14 | { 15 | id: _control 16 | 17 | implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, 18 | contentWidth + leftPadding + rightPadding) 19 | implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, 20 | contentHeight + topPadding + bottomPadding) 21 | 22 | horizontalPadding: Qaterial.Style.card.horizontalPadding 23 | verticalPadding: Qaterial.Style.card.verticalPadding 24 | 25 | property bool onPrimary: false 26 | property bool colorReversed: onPrimary && Qaterial.Style.shouldReverseForegroundOnPrimary 27 | 28 | property color color: onPrimary ? Qaterial.Style.primaryColor : Qaterial.Style.backgroundColor 29 | property color borderColor: enabled ? Qaterial.Style.dividersColor() : Qaterial.Style.disabledDividersColor() 30 | property alias radius: _rect.radius 31 | 32 | property double elevation 33 | 34 | background: Rectangle 35 | { 36 | id: _rect 37 | implicitWidth: 200 38 | radius: Qaterial.Style.card.radius 39 | color: _control.elevation > 0 ? _control.color : "transparent" 40 | border.color: _control.borderColor 41 | border.width: 1 42 | 43 | layer.enabled: _control.enabled && _control.elevation > 0 44 | layer.effect: Qaterial.ElevationEffect 45 | { 46 | elevation: _control.elevation 47 | } // ElevationEffect 48 | } // Rectangle 49 | } // Frame 50 | -------------------------------------------------------------------------------- /src/Qaterial/Details/Export.hpp: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright (c) 2020 Olivier Le Doeuff 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #ifndef __QATERIAL_EXPORT_HPP__ 24 | #define __QATERIAL_EXPORT_HPP__ 25 | 26 | #ifdef WIN32 27 | # ifdef QATERIAL_SHARED 28 | # define QATERIAL_API_ __declspec(dllexport) 29 | # elif QATERIAL_STATIC 30 | # define QATERIAL_API_ 31 | # else 32 | # define QATERIAL_API_ __declspec(dllimport) 33 | # endif 34 | #else 35 | # define QATERIAL_API_ 36 | #endif 37 | 38 | #endif 39 | --------------------------------------------------------------------------------