mirror of
https://github.com/stemoretti/BaseUI.git
synced 2025-06-04 01:28:33 -04:00
First commit
This commit is contained in:
commit
32a567a950
94
CMakeLists.txt
Normal file
94
CMakeLists.txt
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(baseui VERSION 0.1 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
option(BASEUI_EMBED_QML "BaseUI embed qml" OFF)
|
||||||
|
option(BASEUI_EMBED_ICONS "BaseUI embed icons" OFF)
|
||||||
|
|
||||||
|
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Qml Quick Gui QuickControls2 REQUIRED)
|
||||||
|
|
||||||
|
add_library(${PROJECT_NAME} STATIC
|
||||||
|
include/BaseUI/core.h
|
||||||
|
src/core.cpp
|
||||||
|
src/iconprovider.h
|
||||||
|
src/icons.h
|
||||||
|
src/icons.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BASEUI_EMBED_QML)
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE "qml/BaseUI/baseui_qml.qrc")
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE BASEUI_EMBED_QML)
|
||||||
|
else()
|
||||||
|
file(GLOB QML_FILES "qml/BaseUI/*.qml" "qml/BaseUI/qmldir")
|
||||||
|
|
||||||
|
add_custom_target(copy_qml_to_binary_dir ALL
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_BINARY_DIR}/BaseUI"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${QML_FILES} "${CMAKE_BINARY_DIR}/BaseUI"
|
||||||
|
COMMENT "Copying QML files to binary directory"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BASEUI_EMBED_ICONS)
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE "icons/baseui_icons.qrc")
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE BASEUI_EMBED_ICONS)
|
||||||
|
else()
|
||||||
|
add_custom_target(copy_icons_to_binary_dir ALL
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_BINARY_DIR}/BaseUI/icons"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
|
"${PROJECT_SOURCE_DIR}/icons/codepoints.json"
|
||||||
|
"${PROJECT_SOURCE_DIR}/icons/MaterialIcons-Regular.ttf"
|
||||||
|
"${CMAKE_BINARY_DIR}/BaseUI/icons"
|
||||||
|
COMMENT "Copying icons files to binary directory"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC "${PROJECT_SOURCE_DIR}/include")
|
||||||
|
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
CXX_STANDARD 11
|
||||||
|
CXX_STANDARD_REQUIRED YES
|
||||||
|
CXX_EXTENSIONS NO
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:
|
||||||
|
QT_QML_DEBUG
|
||||||
|
# enable deprecated warnings for qt < 5.13
|
||||||
|
QT_DEPRECATED_WARNINGS
|
||||||
|
>
|
||||||
|
|
||||||
|
$<$<CONFIG:Release>:
|
||||||
|
# disable deprecated warnings for qt >= 5.13
|
||||||
|
QT_NO_DEPRECATED_WARNINGS
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wpedantic
|
||||||
|
>
|
||||||
|
|
||||||
|
$<$<CXX_COMPILER_ID:MSVC>:
|
||||||
|
/W4
|
||||||
|
>
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::Qml
|
||||||
|
Qt${QT_VERSION_MAJOR}::Quick
|
||||||
|
Qt${QT_VERSION_MAJOR}::Gui
|
||||||
|
Qt${QT_VERSION_MAJOR}::QuickControls2
|
||||||
|
)
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org>
|
2
README.rst
Normal file
2
README.rst
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
BaseUI
|
||||||
|
======
|
54
baseui.pri
Normal file
54
baseui.pri
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
QT += qml quick quickcontrols2
|
||||||
|
|
||||||
|
BASEUI_DIR = BaseUI
|
||||||
|
|
||||||
|
INCLUDEPATH += \
|
||||||
|
$$PWD/include
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/include/BaseUI/core.h \
|
||||||
|
$$PWD/src/iconprovider.h \
|
||||||
|
$$PWD/src/icons.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/src/core.cpp \
|
||||||
|
$$PWD/src/icons.cpp
|
||||||
|
|
||||||
|
QML_FILES = \
|
||||||
|
$$PWD/qml/BaseUI/qmldir \
|
||||||
|
$$files($$PWD/qml/BaseUI/*.qml)
|
||||||
|
|
||||||
|
OTHER_FILES += $$QML_FILES
|
||||||
|
|
||||||
|
contains(CONFIG, baseui_embed_qml) {
|
||||||
|
DEFINES += BASEUI_EMBED_QML
|
||||||
|
RESOURCES += $$PWD/qml/BaseUI/baseui_qml.qrc
|
||||||
|
} else {
|
||||||
|
qml_copy.path = $$BASEUI_DIR
|
||||||
|
qml_copy.files = $$QML_FILES
|
||||||
|
|
||||||
|
qml_install.path = $$DESTDIR/$$BASEUI_DIR
|
||||||
|
qml_install.files = $$QML_FILES
|
||||||
|
|
||||||
|
COPIES += qml_copy
|
||||||
|
INSTALLS += qml_install
|
||||||
|
}
|
||||||
|
|
||||||
|
contains(CONFIG, baseui_embed_icons) {
|
||||||
|
DEFINES += BASEUI_EMBED_ICONS
|
||||||
|
RESOURCES += $$PWD/icons/baseui_icons.qrc
|
||||||
|
} else {
|
||||||
|
BASEUI_ICONS_DIR = $$BASEUI_DIR/icons
|
||||||
|
ICONS_FILES = \
|
||||||
|
$$PWD/icons/codepoints.json \
|
||||||
|
$$PWD/icons/MaterialIcons-Regular.ttf
|
||||||
|
|
||||||
|
icons_copy.path = $$BASEUI_ICONS_DIR
|
||||||
|
icons_copy.files = $$ICONS_FILES
|
||||||
|
|
||||||
|
icons_install.path = $$DESTDIR/$$BASEUI_ICONS_DIR
|
||||||
|
icons_install.files = $$ICONS_FILES
|
||||||
|
|
||||||
|
COPIES += icons_copy
|
||||||
|
INSTALLS += icons_install
|
||||||
|
}
|
21
example/CMakeLists.txt
Normal file
21
example/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(example VERSION 0.1 LANGUAGES CXX)
|
||||||
|
|
||||||
|
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Qml Quick Gui QuickControls2 REQUIRED)
|
||||||
|
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} main.cpp qml.qrc)
|
||||||
|
|
||||||
|
add_subdirectory(baseui)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::Qml
|
||||||
|
Qt${QT_VERSION_MAJOR}::Quick
|
||||||
|
Qt${QT_VERSION_MAJOR}::Gui
|
||||||
|
Qt${QT_VERSION_MAJOR}::QuickControls2
|
||||||
|
baseui
|
||||||
|
)
|
7
example/example.pro
Normal file
7
example/example.pro
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
QT += quick quickcontrols2
|
||||||
|
|
||||||
|
include(baseui/baseui.pri)
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
|
|
||||||
|
RESOURCES += qml.qrc
|
23
example/main.cpp
Normal file
23
example/main.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QQmlApplicationEngine>
|
||||||
|
|
||||||
|
#include <BaseUI/core.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
|
BaseUI::init(&engine);
|
||||||
|
|
||||||
|
QUrl url("qrc:/main.qml");
|
||||||
|
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
|
||||||
|
&app, [url](QObject *obj, const QUrl &objUrl) {
|
||||||
|
if (!obj && url == objUrl)
|
||||||
|
QCoreApplication::exit(-1);
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
engine.load(url);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
302
example/main.qml
Normal file
302
example/main.qml
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
|
import BaseUI 1.0 as UI
|
||||||
|
|
||||||
|
UI.App {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: 360
|
||||||
|
height: 480
|
||||||
|
|
||||||
|
property string primary: Material.primary
|
||||||
|
property string accent: Material.accent
|
||||||
|
property bool theme: false
|
||||||
|
|
||||||
|
initialPage: UI.AppStackPage {
|
||||||
|
id: homePage
|
||||||
|
|
||||||
|
title: "HomePage"
|
||||||
|
|
||||||
|
leftButton: Action {
|
||||||
|
icon.source: UI.Icons.menu
|
||||||
|
onTriggered: navDrawer.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
rightButtons: [
|
||||||
|
Action {
|
||||||
|
icon.source: UI.Icons.more_vert
|
||||||
|
onTriggered: optionsMenu.open()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: mainPane
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
UI.LabelBody {
|
||||||
|
leftPadding: 10
|
||||||
|
rightPadding: 10
|
||||||
|
text: Qt.application.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Drawer {
|
||||||
|
id: navDrawer
|
||||||
|
|
||||||
|
interactive: homePage.stack.currentItem == homePage
|
||||||
|
width: Math.min(240, Math.min(parent.width, parent.height) / 3 * 2 )
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
onAboutToShow: menuColumn.enabled = true
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
anchors.fill: parent
|
||||||
|
contentHeight: menuColumn.implicitHeight
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: menuColumn
|
||||||
|
|
||||||
|
anchors { left: parent.left; right: parent.right }
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: topItem
|
||||||
|
|
||||||
|
height: 140
|
||||||
|
color: UI.Style.primaryColor
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: Qt.application.name
|
||||||
|
color: UI.Style.textOnPrimary
|
||||||
|
font.pixelSize: UI.Style.fontSizeHeadline
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
margins: 25
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: pageList
|
||||||
|
|
||||||
|
model: [
|
||||||
|
{ icon: UI.Icons.settings, text: "Settings", page: settingsPage },
|
||||||
|
{ icon: UI.Icons.info_outline, text: "About", page: aboutPage }
|
||||||
|
]
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
icon.source: modelData.icon
|
||||||
|
text: modelData.text
|
||||||
|
Layout.fillWidth: true
|
||||||
|
onClicked: {
|
||||||
|
// Disable, or a double click will push the page twice.
|
||||||
|
menuColumn.enabled = false
|
||||||
|
navDrawer.close()
|
||||||
|
pageStack.push(modelData.page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: optionsMenu
|
||||||
|
|
||||||
|
modal: true
|
||||||
|
dim: false
|
||||||
|
closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
|
||||||
|
x: parent.width - width - 6
|
||||||
|
y: -homePage.appToolBar.height + 6
|
||||||
|
transformOrigin: Menu.TopRight
|
||||||
|
|
||||||
|
onAboutToShow: enabled = true
|
||||||
|
onAboutToHide: currentIndex = -1 // reset highlighting
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Toast test"
|
||||||
|
onTriggered: toastPopup.start("Toast message.")
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: "Error test"
|
||||||
|
onTriggered: errorPopup.start("Error message.")
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: "Info test"
|
||||||
|
onTriggered: infoPopup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: settingsPage
|
||||||
|
|
||||||
|
UI.AppStackPage {
|
||||||
|
title: "Settings"
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
contentHeight: settingsPane.implicitHeight
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: settingsPane
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
UI.SettingsSectionTitle {
|
||||||
|
text: "Display"
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.SettingsItem {
|
||||||
|
title: "Dark Theme"
|
||||||
|
check.visible: true
|
||||||
|
check.checked: root.theme
|
||||||
|
check.onClicked: root.theme = !root.theme
|
||||||
|
onClicked: check.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.SettingsItem {
|
||||||
|
title: "Primary Color"
|
||||||
|
subtitle: primaryColorPopup.currentColorName
|
||||||
|
onClicked: primaryColorPopup.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.SettingsItem {
|
||||||
|
title: "Accent Color"
|
||||||
|
subtitle: accentColorPopup.currentColorName
|
||||||
|
onClicked: accentColorPopup.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: aboutPage
|
||||||
|
|
||||||
|
UI.AppStackPage {
|
||||||
|
title: "About"
|
||||||
|
padding: 10
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
contentHeight: aboutPane.implicitHeight
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: aboutPane
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
UI.LabelTitle {
|
||||||
|
text: Qt.application.name
|
||||||
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.LabelBody {
|
||||||
|
property string url: "http://github.com/stemoretti/baseui"
|
||||||
|
|
||||||
|
text: "<a href='" + url + "'>" + url + "</a>"
|
||||||
|
linkColor: UI.Style.isDarkTheme ? "lightblue" : "blue"
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.HorizontalDivider { }
|
||||||
|
|
||||||
|
UI.LabelSubheading {
|
||||||
|
text: "This app is based on the following software:"
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.LabelBody {
|
||||||
|
text: "Qt 6<br>"
|
||||||
|
+ "Copyright 2008-2021 The Qt Company Ltd."
|
||||||
|
+ " All rights reserved."
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.LabelBody {
|
||||||
|
text: "Qt is under the LGPLv3 license."
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.HorizontalDivider { }
|
||||||
|
|
||||||
|
UI.LabelBody {
|
||||||
|
text: "<a href='https://material.io/tools/icons/'"
|
||||||
|
+ "title='Material Design'>Material Design</a>"
|
||||||
|
+ " icons are under Apache license version 2.0"
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
linkColor: UI.Style.isDarkTheme ? "lightblue" : "blue"
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.PopupToast {
|
||||||
|
id: toastPopup
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.PopupError {
|
||||||
|
id: errorPopup
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.PopupInfo {
|
||||||
|
id: infoPopup
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
text: "Information message."
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.PopupColorSelection {
|
||||||
|
id: primaryColorPopup
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
currentColor: root.primary
|
||||||
|
onColorSelected: function(c) { root.primary = c }
|
||||||
|
}
|
||||||
|
|
||||||
|
UI.PopupColorSelection {
|
||||||
|
id: accentColorPopup
|
||||||
|
|
||||||
|
parent: Overlay.overlay
|
||||||
|
|
||||||
|
selectAccentColor: true
|
||||||
|
currentColor: root.accent
|
||||||
|
onColorSelected: function(c) { root.accent = c }
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
UI.Style.primaryColor = Qt.binding(function() { return root.primary })
|
||||||
|
UI.Style.accentColor = Qt.binding(function() { return root.accent })
|
||||||
|
UI.Style.isDarkTheme = Qt.binding(function() { return root.theme })
|
||||||
|
}
|
||||||
|
}
|
5
example/qml.qrc
Normal file
5
example/qml.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>main.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
202
icons/LICENSE
Normal file
202
icons/LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
BIN
icons/MaterialIcons-Regular.ttf
Normal file
BIN
icons/MaterialIcons-Regular.ttf
Normal file
Binary file not shown.
6
icons/baseui_icons.qrc
Normal file
6
icons/baseui_icons.qrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="imports/BaseUI/icons">
|
||||||
|
<file>MaterialIcons-Regular.ttf</file>
|
||||||
|
<file>codepoints.json</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
934
icons/codepoints.json
Normal file
934
icons/codepoints.json
Normal file
@ -0,0 +1,934 @@
|
|||||||
|
{
|
||||||
|
"3d_rotation": "\ue84d",
|
||||||
|
"ac_unit": "\ueb3b",
|
||||||
|
"access_alarm": "\ue190",
|
||||||
|
"access_alarms": "\ue191",
|
||||||
|
"access_time": "\ue192",
|
||||||
|
"accessibility": "\ue84e",
|
||||||
|
"accessible": "\ue914",
|
||||||
|
"account_balance": "\ue84f",
|
||||||
|
"account_balance_wallet": "\ue850",
|
||||||
|
"account_box": "\ue851",
|
||||||
|
"account_circle": "\ue853",
|
||||||
|
"adb": "\ue60e",
|
||||||
|
"add": "\ue145",
|
||||||
|
"add_a_photo": "\ue439",
|
||||||
|
"add_alarm": "\ue193",
|
||||||
|
"add_alert": "\ue003",
|
||||||
|
"add_box": "\ue146",
|
||||||
|
"add_circle": "\ue147",
|
||||||
|
"add_circle_outline": "\ue148",
|
||||||
|
"add_location": "\ue567",
|
||||||
|
"add_shopping_cart": "\ue854",
|
||||||
|
"add_to_photos": "\ue39d",
|
||||||
|
"add_to_queue": "\ue05c",
|
||||||
|
"adjust": "\ue39e",
|
||||||
|
"airline_seat_flat": "\ue630",
|
||||||
|
"airline_seat_flat_angled": "\ue631",
|
||||||
|
"airline_seat_individual_suite": "\ue632",
|
||||||
|
"airline_seat_legroom_extra": "\ue633",
|
||||||
|
"airline_seat_legroom_normal": "\ue634",
|
||||||
|
"airline_seat_legroom_reduced": "\ue635",
|
||||||
|
"airline_seat_recline_extra": "\ue636",
|
||||||
|
"airline_seat_recline_normal": "\ue637",
|
||||||
|
"airplanemode_active": "\ue195",
|
||||||
|
"airplanemode_inactive": "\ue194",
|
||||||
|
"airplay": "\ue055",
|
||||||
|
"airport_shuttle": "\ueb3c",
|
||||||
|
"alarm": "\ue855",
|
||||||
|
"alarm_add": "\ue856",
|
||||||
|
"alarm_off": "\ue857",
|
||||||
|
"alarm_on": "\ue858",
|
||||||
|
"album": "\ue019",
|
||||||
|
"all_inclusive": "\ueb3d",
|
||||||
|
"all_out": "\ue90b",
|
||||||
|
"android": "\ue859",
|
||||||
|
"announcement": "\ue85a",
|
||||||
|
"apps": "\ue5c3",
|
||||||
|
"archive": "\ue149",
|
||||||
|
"arrow_back": "\ue5c4",
|
||||||
|
"arrow_downward": "\ue5db",
|
||||||
|
"arrow_drop_down": "\ue5c5",
|
||||||
|
"arrow_drop_down_circle": "\ue5c6",
|
||||||
|
"arrow_drop_up": "\ue5c7",
|
||||||
|
"arrow_forward": "\ue5c8",
|
||||||
|
"arrow_upward": "\ue5d8",
|
||||||
|
"art_track": "\ue060",
|
||||||
|
"aspect_ratio": "\ue85b",
|
||||||
|
"assessment": "\ue85c",
|
||||||
|
"assignment": "\ue85d",
|
||||||
|
"assignment_ind": "\ue85e",
|
||||||
|
"assignment_late": "\ue85f",
|
||||||
|
"assignment_return": "\ue860",
|
||||||
|
"assignment_returned": "\ue861",
|
||||||
|
"assignment_turned_in": "\ue862",
|
||||||
|
"assistant": "\ue39f",
|
||||||
|
"assistant_photo": "\ue3a0",
|
||||||
|
"attach_file": "\ue226",
|
||||||
|
"attach_money": "\ue227",
|
||||||
|
"attachment": "\ue2bc",
|
||||||
|
"audiotrack": "\ue3a1",
|
||||||
|
"autorenew": "\ue863",
|
||||||
|
"av_timer": "\ue01b",
|
||||||
|
"backspace": "\ue14a",
|
||||||
|
"backup": "\ue864",
|
||||||
|
"battery_alert": "\ue19c",
|
||||||
|
"battery_charging_full": "\ue1a3",
|
||||||
|
"battery_full": "\ue1a4",
|
||||||
|
"battery_std": "\ue1a5",
|
||||||
|
"battery_unknown": "\ue1a6",
|
||||||
|
"beach_access": "\ueb3e",
|
||||||
|
"beenhere": "\ue52d",
|
||||||
|
"block": "\ue14b",
|
||||||
|
"bluetooth": "\ue1a7",
|
||||||
|
"bluetooth_audio": "\ue60f",
|
||||||
|
"bluetooth_connected": "\ue1a8",
|
||||||
|
"bluetooth_disabled": "\ue1a9",
|
||||||
|
"bluetooth_searching": "\ue1aa",
|
||||||
|
"blur_circular": "\ue3a2",
|
||||||
|
"blur_linear": "\ue3a3",
|
||||||
|
"blur_off": "\ue3a4",
|
||||||
|
"blur_on": "\ue3a5",
|
||||||
|
"book": "\ue865",
|
||||||
|
"bookmark": "\ue866",
|
||||||
|
"bookmark_border": "\ue867",
|
||||||
|
"border_all": "\ue228",
|
||||||
|
"border_bottom": "\ue229",
|
||||||
|
"border_clear": "\ue22a",
|
||||||
|
"border_color": "\ue22b",
|
||||||
|
"border_horizontal": "\ue22c",
|
||||||
|
"border_inner": "\ue22d",
|
||||||
|
"border_left": "\ue22e",
|
||||||
|
"border_outer": "\ue22f",
|
||||||
|
"border_right": "\ue230",
|
||||||
|
"border_style": "\ue231",
|
||||||
|
"border_top": "\ue232",
|
||||||
|
"border_vertical": "\ue233",
|
||||||
|
"branding_watermark": "\ue06b",
|
||||||
|
"brightness_1": "\ue3a6",
|
||||||
|
"brightness_2": "\ue3a7",
|
||||||
|
"brightness_3": "\ue3a8",
|
||||||
|
"brightness_4": "\ue3a9",
|
||||||
|
"brightness_5": "\ue3aa",
|
||||||
|
"brightness_6": "\ue3ab",
|
||||||
|
"brightness_7": "\ue3ac",
|
||||||
|
"brightness_auto": "\ue1ab",
|
||||||
|
"brightness_high": "\ue1ac",
|
||||||
|
"brightness_low": "\ue1ad",
|
||||||
|
"brightness_medium": "\ue1ae",
|
||||||
|
"broken_image": "\ue3ad",
|
||||||
|
"brush": "\ue3ae",
|
||||||
|
"bubble_chart": "\ue6dd",
|
||||||
|
"bug_report": "\ue868",
|
||||||
|
"build": "\ue869",
|
||||||
|
"burst_mode": "\ue43c",
|
||||||
|
"business": "\ue0af",
|
||||||
|
"business_center": "\ueb3f",
|
||||||
|
"cached": "\ue86a",
|
||||||
|
"cake": "\ue7e9",
|
||||||
|
"call": "\ue0b0",
|
||||||
|
"call_end": "\ue0b1",
|
||||||
|
"call_made": "\ue0b2",
|
||||||
|
"call_merge": "\ue0b3",
|
||||||
|
"call_missed": "\ue0b4",
|
||||||
|
"call_missed_outgoing": "\ue0e4",
|
||||||
|
"call_received": "\ue0b5",
|
||||||
|
"call_split": "\ue0b6",
|
||||||
|
"call_to_action": "\ue06c",
|
||||||
|
"camera": "\ue3af",
|
||||||
|
"camera_alt": "\ue3b0",
|
||||||
|
"camera_enhance": "\ue8fc",
|
||||||
|
"camera_front": "\ue3b1",
|
||||||
|
"camera_rear": "\ue3b2",
|
||||||
|
"camera_roll": "\ue3b3",
|
||||||
|
"cancel": "\ue5c9",
|
||||||
|
"card_giftcard": "\ue8f6",
|
||||||
|
"card_membership": "\ue8f7",
|
||||||
|
"card_travel": "\ue8f8",
|
||||||
|
"casino": "\ueb40",
|
||||||
|
"cast": "\ue307",
|
||||||
|
"cast_connected": "\ue308",
|
||||||
|
"center_focus_strong": "\ue3b4",
|
||||||
|
"center_focus_weak": "\ue3b5",
|
||||||
|
"change_history": "\ue86b",
|
||||||
|
"chat": "\ue0b7",
|
||||||
|
"chat_bubble": "\ue0ca",
|
||||||
|
"chat_bubble_outline": "\ue0cb",
|
||||||
|
"check": "\ue5ca",
|
||||||
|
"check_box": "\ue834",
|
||||||
|
"check_box_outline_blank": "\ue835",
|
||||||
|
"check_circle": "\ue86c",
|
||||||
|
"chevron_left": "\ue5cb",
|
||||||
|
"chevron_right": "\ue5cc",
|
||||||
|
"child_care": "\ueb41",
|
||||||
|
"child_friendly": "\ueb42",
|
||||||
|
"chrome_reader_mode": "\ue86d",
|
||||||
|
"class": "\ue86e",
|
||||||
|
"clear": "\ue14c",
|
||||||
|
"clear_all": "\ue0b8",
|
||||||
|
"close": "\ue5cd",
|
||||||
|
"closed_caption": "\ue01c",
|
||||||
|
"cloud": "\ue2bd",
|
||||||
|
"cloud_circle": "\ue2be",
|
||||||
|
"cloud_done": "\ue2bf",
|
||||||
|
"cloud_download": "\ue2c0",
|
||||||
|
"cloud_off": "\ue2c1",
|
||||||
|
"cloud_queue": "\ue2c2",
|
||||||
|
"cloud_upload": "\ue2c3",
|
||||||
|
"code": "\ue86f",
|
||||||
|
"collections": "\ue3b6",
|
||||||
|
"collections_bookmark": "\ue431",
|
||||||
|
"color_lens": "\ue3b7",
|
||||||
|
"colorize": "\ue3b8",
|
||||||
|
"comment": "\ue0b9",
|
||||||
|
"compare": "\ue3b9",
|
||||||
|
"compare_arrows": "\ue915",
|
||||||
|
"computer": "\ue30a",
|
||||||
|
"confirmation_number": "\ue638",
|
||||||
|
"contact_mail": "\ue0d0",
|
||||||
|
"contact_phone": "\ue0cf",
|
||||||
|
"contacts": "\ue0ba",
|
||||||
|
"content_copy": "\ue14d",
|
||||||
|
"content_cut": "\ue14e",
|
||||||
|
"content_paste": "\ue14f",
|
||||||
|
"control_point": "\ue3ba",
|
||||||
|
"control_point_duplicate": "\ue3bb",
|
||||||
|
"copyright": "\ue90c",
|
||||||
|
"create": "\ue150",
|
||||||
|
"create_new_folder": "\ue2cc",
|
||||||
|
"credit_card": "\ue870",
|
||||||
|
"crop": "\ue3be",
|
||||||
|
"crop_16_9": "\ue3bc",
|
||||||
|
"crop_3_2": "\ue3bd",
|
||||||
|
"crop_5_4": "\ue3bf",
|
||||||
|
"crop_7_5": "\ue3c0",
|
||||||
|
"crop_din": "\ue3c1",
|
||||||
|
"crop_free": "\ue3c2",
|
||||||
|
"crop_landscape": "\ue3c3",
|
||||||
|
"crop_original": "\ue3c4",
|
||||||
|
"crop_portrait": "\ue3c5",
|
||||||
|
"crop_rotate": "\ue437",
|
||||||
|
"crop_square": "\ue3c6",
|
||||||
|
"dashboard": "\ue871",
|
||||||
|
"data_usage": "\ue1af",
|
||||||
|
"date_range": "\ue916",
|
||||||
|
"dehaze": "\ue3c7",
|
||||||
|
"delete": "\ue872",
|
||||||
|
"delete_forever": "\ue92b",
|
||||||
|
"delete_sweep": "\ue16c",
|
||||||
|
"description": "\ue873",
|
||||||
|
"desktop_mac": "\ue30b",
|
||||||
|
"desktop_windows": "\ue30c",
|
||||||
|
"details": "\ue3c8",
|
||||||
|
"developer_board": "\ue30d",
|
||||||
|
"developer_mode": "\ue1b0",
|
||||||
|
"device_hub": "\ue335",
|
||||||
|
"devices": "\ue1b1",
|
||||||
|
"devices_other": "\ue337",
|
||||||
|
"dialer_sip": "\ue0bb",
|
||||||
|
"dialpad": "\ue0bc",
|
||||||
|
"directions": "\ue52e",
|
||||||
|
"directions_bike": "\ue52f",
|
||||||
|
"directions_boat": "\ue532",
|
||||||
|
"directions_bus": "\ue530",
|
||||||
|
"directions_car": "\ue531",
|
||||||
|
"directions_railway": "\ue534",
|
||||||
|
"directions_run": "\ue566",
|
||||||
|
"directions_subway": "\ue533",
|
||||||
|
"directions_transit": "\ue535",
|
||||||
|
"directions_walk": "\ue536",
|
||||||
|
"disc_full": "\ue610",
|
||||||
|
"dns": "\ue875",
|
||||||
|
"do_not_disturb": "\ue612",
|
||||||
|
"do_not_disturb_alt": "\ue611",
|
||||||
|
"do_not_disturb_off": "\ue643",
|
||||||
|
"do_not_disturb_on": "\ue644",
|
||||||
|
"dock": "\ue30e",
|
||||||
|
"domain": "\ue7ee",
|
||||||
|
"done": "\ue876",
|
||||||
|
"done_all": "\ue877",
|
||||||
|
"donut_large": "\ue917",
|
||||||
|
"donut_small": "\ue918",
|
||||||
|
"drafts": "\ue151",
|
||||||
|
"drag_handle": "\ue25d",
|
||||||
|
"drive_eta": "\ue613",
|
||||||
|
"dvr": "\ue1b2",
|
||||||
|
"edit": "\ue3c9",
|
||||||
|
"edit_location": "\ue568",
|
||||||
|
"eject": "\ue8fb",
|
||||||
|
"email": "\ue0be",
|
||||||
|
"enhanced_encryption": "\ue63f",
|
||||||
|
"equalizer": "\ue01d",
|
||||||
|
"error": "\ue000",
|
||||||
|
"error_outline": "\ue001",
|
||||||
|
"euro_symbol": "\ue926",
|
||||||
|
"ev_station": "\ue56d",
|
||||||
|
"event": "\ue878",
|
||||||
|
"event_available": "\ue614",
|
||||||
|
"event_busy": "\ue615",
|
||||||
|
"event_note": "\ue616",
|
||||||
|
"event_seat": "\ue903",
|
||||||
|
"exit_to_app": "\ue879",
|
||||||
|
"expand_less": "\ue5ce",
|
||||||
|
"expand_more": "\ue5cf",
|
||||||
|
"explicit": "\ue01e",
|
||||||
|
"explore": "\ue87a",
|
||||||
|
"exposure": "\ue3ca",
|
||||||
|
"exposure_neg_1": "\ue3cb",
|
||||||
|
"exposure_neg_2": "\ue3cc",
|
||||||
|
"exposure_plus_1": "\ue3cd",
|
||||||
|
"exposure_plus_2": "\ue3ce",
|
||||||
|
"exposure_zero": "\ue3cf",
|
||||||
|
"extension": "\ue87b",
|
||||||
|
"face": "\ue87c",
|
||||||
|
"fast_forward": "\ue01f",
|
||||||
|
"fast_rewind": "\ue020",
|
||||||
|
"favorite": "\ue87d",
|
||||||
|
"favorite_border": "\ue87e",
|
||||||
|
"featured_play_list": "\ue06d",
|
||||||
|
"featured_video": "\ue06e",
|
||||||
|
"feedback": "\ue87f",
|
||||||
|
"fiber_dvr": "\ue05d",
|
||||||
|
"fiber_manual_record": "\ue061",
|
||||||
|
"fiber_new": "\ue05e",
|
||||||
|
"fiber_pin": "\ue06a",
|
||||||
|
"fiber_smart_record": "\ue062",
|
||||||
|
"file_download": "\ue2c4",
|
||||||
|
"file_upload": "\ue2c6",
|
||||||
|
"filter": "\ue3d3",
|
||||||
|
"filter_1": "\ue3d0",
|
||||||
|
"filter_2": "\ue3d1",
|
||||||
|
"filter_3": "\ue3d2",
|
||||||
|
"filter_4": "\ue3d4",
|
||||||
|
"filter_5": "\ue3d5",
|
||||||
|
"filter_6": "\ue3d6",
|
||||||
|
"filter_7": "\ue3d7",
|
||||||
|
"filter_8": "\ue3d8",
|
||||||
|
"filter_9": "\ue3d9",
|
||||||
|
"filter_9_plus": "\ue3da",
|
||||||
|
"filter_b_and_w": "\ue3db",
|
||||||
|
"filter_center_focus": "\ue3dc",
|
||||||
|
"filter_drama": "\ue3dd",
|
||||||
|
"filter_frames": "\ue3de",
|
||||||
|
"filter_hdr": "\ue3df",
|
||||||
|
"filter_list": "\ue152",
|
||||||
|
"filter_none": "\ue3e0",
|
||||||
|
"filter_tilt_shift": "\ue3e2",
|
||||||
|
"filter_vintage": "\ue3e3",
|
||||||
|
"find_in_page": "\ue880",
|
||||||
|
"find_replace": "\ue881",
|
||||||
|
"fingerprint": "\ue90d",
|
||||||
|
"first_page": "\ue5dc",
|
||||||
|
"fitness_center": "\ueb43",
|
||||||
|
"flag": "\ue153",
|
||||||
|
"flare": "\ue3e4",
|
||||||
|
"flash_auto": "\ue3e5",
|
||||||
|
"flash_off": "\ue3e6",
|
||||||
|
"flash_on": "\ue3e7",
|
||||||
|
"flight": "\ue539",
|
||||||
|
"flight_land": "\ue904",
|
||||||
|
"flight_takeoff": "\ue905",
|
||||||
|
"flip": "\ue3e8",
|
||||||
|
"flip_to_back": "\ue882",
|
||||||
|
"flip_to_front": "\ue883",
|
||||||
|
"folder": "\ue2c7",
|
||||||
|
"folder_open": "\ue2c8",
|
||||||
|
"folder_shared": "\ue2c9",
|
||||||
|
"folder_special": "\ue617",
|
||||||
|
"font_download": "\ue167",
|
||||||
|
"format_align_center": "\ue234",
|
||||||
|
"format_align_justify": "\ue235",
|
||||||
|
"format_align_left": "\ue236",
|
||||||
|
"format_align_right": "\ue237",
|
||||||
|
"format_bold": "\ue238",
|
||||||
|
"format_clear": "\ue239",
|
||||||
|
"format_color_fill": "\ue23a",
|
||||||
|
"format_color_reset": "\ue23b",
|
||||||
|
"format_color_text": "\ue23c",
|
||||||
|
"format_indent_decrease": "\ue23d",
|
||||||
|
"format_indent_increase": "\ue23e",
|
||||||
|
"format_italic": "\ue23f",
|
||||||
|
"format_line_spacing": "\ue240",
|
||||||
|
"format_list_bulleted": "\ue241",
|
||||||
|
"format_list_numbered": "\ue242",
|
||||||
|
"format_paint": "\ue243",
|
||||||
|
"format_quote": "\ue244",
|
||||||
|
"format_shapes": "\ue25e",
|
||||||
|
"format_size": "\ue245",
|
||||||
|
"format_strikethrough": "\ue246",
|
||||||
|
"format_textdirection_l_to_r": "\ue247",
|
||||||
|
"format_textdirection_r_to_l": "\ue248",
|
||||||
|
"format_underlined": "\ue249",
|
||||||
|
"forum": "\ue0bf",
|
||||||
|
"forward": "\ue154",
|
||||||
|
"forward_10": "\ue056",
|
||||||
|
"forward_30": "\ue057",
|
||||||
|
"forward_5": "\ue058",
|
||||||
|
"free_breakfast": "\ueb44",
|
||||||
|
"fullscreen": "\ue5d0",
|
||||||
|
"fullscreen_exit": "\ue5d1",
|
||||||
|
"functions": "\ue24a",
|
||||||
|
"g_translate": "\ue927",
|
||||||
|
"gamepad": "\ue30f",
|
||||||
|
"games": "\ue021",
|
||||||
|
"gavel": "\ue90e",
|
||||||
|
"gesture": "\ue155",
|
||||||
|
"get_app": "\ue884",
|
||||||
|
"gif": "\ue908",
|
||||||
|
"golf_course": "\ueb45",
|
||||||
|
"gps_fixed": "\ue1b3",
|
||||||
|
"gps_not_fixed": "\ue1b4",
|
||||||
|
"gps_off": "\ue1b5",
|
||||||
|
"grade": "\ue885",
|
||||||
|
"gradient": "\ue3e9",
|
||||||
|
"grain": "\ue3ea",
|
||||||
|
"graphic_eq": "\ue1b8",
|
||||||
|
"grid_off": "\ue3eb",
|
||||||
|
"grid_on": "\ue3ec",
|
||||||
|
"group": "\ue7ef",
|
||||||
|
"group_add": "\ue7f0",
|
||||||
|
"group_work": "\ue886",
|
||||||
|
"hd": "\ue052",
|
||||||
|
"hdr_off": "\ue3ed",
|
||||||
|
"hdr_on": "\ue3ee",
|
||||||
|
"hdr_strong": "\ue3f1",
|
||||||
|
"hdr_weak": "\ue3f2",
|
||||||
|
"headset": "\ue310",
|
||||||
|
"headset_mic": "\ue311",
|
||||||
|
"healing": "\ue3f3",
|
||||||
|
"hearing": "\ue023",
|
||||||
|
"help": "\ue887",
|
||||||
|
"help_outline": "\ue8fd",
|
||||||
|
"high_quality": "\ue024",
|
||||||
|
"highlight": "\ue25f",
|
||||||
|
"highlight_off": "\ue888",
|
||||||
|
"history": "\ue889",
|
||||||
|
"home": "\ue88a",
|
||||||
|
"hot_tub": "\ueb46",
|
||||||
|
"hotel": "\ue53a",
|
||||||
|
"hourglass_empty": "\ue88b",
|
||||||
|
"hourglass_full": "\ue88c",
|
||||||
|
"http": "\ue902",
|
||||||
|
"https": "\ue88d",
|
||||||
|
"image": "\ue3f4",
|
||||||
|
"image_aspect_ratio": "\ue3f5",
|
||||||
|
"import_contacts": "\ue0e0",
|
||||||
|
"import_export": "\ue0c3",
|
||||||
|
"important_devices": "\ue912",
|
||||||
|
"inbox": "\ue156",
|
||||||
|
"indeterminate_check_box": "\ue909",
|
||||||
|
"info": "\ue88e",
|
||||||
|
"info_outline": "\ue88f",
|
||||||
|
"input": "\ue890",
|
||||||
|
"insert_chart": "\ue24b",
|
||||||
|
"insert_comment": "\ue24c",
|
||||||
|
"insert_drive_file": "\ue24d",
|
||||||
|
"insert_emoticon": "\ue24e",
|
||||||
|
"insert_invitation": "\ue24f",
|
||||||
|
"insert_link": "\ue250",
|
||||||
|
"insert_photo": "\ue251",
|
||||||
|
"invert_colors": "\ue891",
|
||||||
|
"invert_colors_off": "\ue0c4",
|
||||||
|
"iso": "\ue3f6",
|
||||||
|
"keyboard": "\ue312",
|
||||||
|
"keyboard_arrow_down": "\ue313",
|
||||||
|
"keyboard_arrow_left": "\ue314",
|
||||||
|
"keyboard_arrow_right": "\ue315",
|
||||||
|
"keyboard_arrow_up": "\ue316",
|
||||||
|
"keyboard_backspace": "\ue317",
|
||||||
|
"keyboard_capslock": "\ue318",
|
||||||
|
"keyboard_hide": "\ue31a",
|
||||||
|
"keyboard_return": "\ue31b",
|
||||||
|
"keyboard_tab": "\ue31c",
|
||||||
|
"keyboard_voice": "\ue31d",
|
||||||
|
"kitchen": "\ueb47",
|
||||||
|
"label": "\ue892",
|
||||||
|
"label_outline": "\ue893",
|
||||||
|
"landscape": "\ue3f7",
|
||||||
|
"language": "\ue894",
|
||||||
|
"laptop": "\ue31e",
|
||||||
|
"laptop_chromebook": "\ue31f",
|
||||||
|
"laptop_mac": "\ue320",
|
||||||
|
"laptop_windows": "\ue321",
|
||||||
|
"last_page": "\ue5dd",
|
||||||
|
"launch": "\ue895",
|
||||||
|
"layers": "\ue53b",
|
||||||
|
"layers_clear": "\ue53c",
|
||||||
|
"leak_add": "\ue3f8",
|
||||||
|
"leak_remove": "\ue3f9",
|
||||||
|
"lens": "\ue3fa",
|
||||||
|
"library_add": "\ue02e",
|
||||||
|
"library_books": "\ue02f",
|
||||||
|
"library_music": "\ue030",
|
||||||
|
"lightbulb_outline": "\ue90f",
|
||||||
|
"line_style": "\ue919",
|
||||||
|
"line_weight": "\ue91a",
|
||||||
|
"linear_scale": "\ue260",
|
||||||
|
"link": "\ue157",
|
||||||
|
"linked_camera": "\ue438",
|
||||||
|
"list": "\ue896",
|
||||||
|
"live_help": "\ue0c6",
|
||||||
|
"live_tv": "\ue639",
|
||||||
|
"local_activity": "\ue53f",
|
||||||
|
"local_airport": "\ue53d",
|
||||||
|
"local_atm": "\ue53e",
|
||||||
|
"local_bar": "\ue540",
|
||||||
|
"local_cafe": "\ue541",
|
||||||
|
"local_car_wash": "\ue542",
|
||||||
|
"local_convenience_store": "\ue543",
|
||||||
|
"local_dining": "\ue556",
|
||||||
|
"local_drink": "\ue544",
|
||||||
|
"local_florist": "\ue545",
|
||||||
|
"local_gas_station": "\ue546",
|
||||||
|
"local_grocery_store": "\ue547",
|
||||||
|
"local_hospital": "\ue548",
|
||||||
|
"local_hotel": "\ue549",
|
||||||
|
"local_laundry_service": "\ue54a",
|
||||||
|
"local_library": "\ue54b",
|
||||||
|
"local_mall": "\ue54c",
|
||||||
|
"local_movies": "\ue54d",
|
||||||
|
"local_offer": "\ue54e",
|
||||||
|
"local_parking": "\ue54f",
|
||||||
|
"local_pharmacy": "\ue550",
|
||||||
|
"local_phone": "\ue551",
|
||||||
|
"local_pizza": "\ue552",
|
||||||
|
"local_play": "\ue553",
|
||||||
|
"local_post_office": "\ue554",
|
||||||
|
"local_printshop": "\ue555",
|
||||||
|
"local_see": "\ue557",
|
||||||
|
"local_shipping": "\ue558",
|
||||||
|
"local_taxi": "\ue559",
|
||||||
|
"location_city": "\ue7f1",
|
||||||
|
"location_disabled": "\ue1b6",
|
||||||
|
"location_off": "\ue0c7",
|
||||||
|
"location_on": "\ue0c8",
|
||||||
|
"location_searching": "\ue1b7",
|
||||||
|
"lock": "\ue897",
|
||||||
|
"lock_open": "\ue898",
|
||||||
|
"lock_outline": "\ue899",
|
||||||
|
"looks": "\ue3fc",
|
||||||
|
"looks_3": "\ue3fb",
|
||||||
|
"looks_4": "\ue3fd",
|
||||||
|
"looks_5": "\ue3fe",
|
||||||
|
"looks_6": "\ue3ff",
|
||||||
|
"looks_one": "\ue400",
|
||||||
|
"looks_two": "\ue401",
|
||||||
|
"loop": "\ue028",
|
||||||
|
"loupe": "\ue402",
|
||||||
|
"low_priority": "\ue16d",
|
||||||
|
"loyalty": "\ue89a",
|
||||||
|
"mail": "\ue158",
|
||||||
|
"mail_outline": "\ue0e1",
|
||||||
|
"map": "\ue55b",
|
||||||
|
"markunread": "\ue159",
|
||||||
|
"markunread_mailbox": "\ue89b",
|
||||||
|
"memory": "\ue322",
|
||||||
|
"menu": "\ue5d2",
|
||||||
|
"merge_type": "\ue252",
|
||||||
|
"message": "\ue0c9",
|
||||||
|
"mic": "\ue029",
|
||||||
|
"mic_none": "\ue02a",
|
||||||
|
"mic_off": "\ue02b",
|
||||||
|
"mms": "\ue618",
|
||||||
|
"mode_comment": "\ue253",
|
||||||
|
"mode_edit": "\ue254",
|
||||||
|
"monetization_on": "\ue263",
|
||||||
|
"money_off": "\ue25c",
|
||||||
|
"monochrome_photos": "\ue403",
|
||||||
|
"mood": "\ue7f2",
|
||||||
|
"mood_bad": "\ue7f3",
|
||||||
|
"more": "\ue619",
|
||||||
|
"more_horiz": "\ue5d3",
|
||||||
|
"more_vert": "\ue5d4",
|
||||||
|
"motorcycle": "\ue91b",
|
||||||
|
"mouse": "\ue323",
|
||||||
|
"move_to_inbox": "\ue168",
|
||||||
|
"movie": "\ue02c",
|
||||||
|
"movie_creation": "\ue404",
|
||||||
|
"movie_filter": "\ue43a",
|
||||||
|
"multiline_chart": "\ue6df",
|
||||||
|
"music_note": "\ue405",
|
||||||
|
"music_video": "\ue063",
|
||||||
|
"my_location": "\ue55c",
|
||||||
|
"nature": "\ue406",
|
||||||
|
"nature_people": "\ue407",
|
||||||
|
"navigate_before": "\ue408",
|
||||||
|
"navigate_next": "\ue409",
|
||||||
|
"navigation": "\ue55d",
|
||||||
|
"near_me": "\ue569",
|
||||||
|
"network_cell": "\ue1b9",
|
||||||
|
"network_check": "\ue640",
|
||||||
|
"network_locked": "\ue61a",
|
||||||
|
"network_wifi": "\ue1ba",
|
||||||
|
"new_releases": "\ue031",
|
||||||
|
"next_week": "\ue16a",
|
||||||
|
"nfc": "\ue1bb",
|
||||||
|
"no_encryption": "\ue641",
|
||||||
|
"no_sim": "\ue0cc",
|
||||||
|
"not_interested": "\ue033",
|
||||||
|
"note": "\ue06f",
|
||||||
|
"note_add": "\ue89c",
|
||||||
|
"notifications": "\ue7f4",
|
||||||
|
"notifications_active": "\ue7f7",
|
||||||
|
"notifications_none": "\ue7f5",
|
||||||
|
"notifications_off": "\ue7f6",
|
||||||
|
"notifications_paused": "\ue7f8",
|
||||||
|
"offline_pin": "\ue90a",
|
||||||
|
"ondemand_video": "\ue63a",
|
||||||
|
"opacity": "\ue91c",
|
||||||
|
"open_in_browser": "\ue89d",
|
||||||
|
"open_in_new": "\ue89e",
|
||||||
|
"open_with": "\ue89f",
|
||||||
|
"pages": "\ue7f9",
|
||||||
|
"pageview": "\ue8a0",
|
||||||
|
"palette": "\ue40a",
|
||||||
|
"pan_tool": "\ue925",
|
||||||
|
"panorama": "\ue40b",
|
||||||
|
"panorama_fish_eye": "\ue40c",
|
||||||
|
"panorama_horizontal": "\ue40d",
|
||||||
|
"panorama_vertical": "\ue40e",
|
||||||
|
"panorama_wide_angle": "\ue40f",
|
||||||
|
"party_mode": "\ue7fa",
|
||||||
|
"pause": "\ue034",
|
||||||
|
"pause_circle_filled": "\ue035",
|
||||||
|
"pause_circle_outline": "\ue036",
|
||||||
|
"payment": "\ue8a1",
|
||||||
|
"people": "\ue7fb",
|
||||||
|
"people_outline": "\ue7fc",
|
||||||
|
"perm_camera_mic": "\ue8a2",
|
||||||
|
"perm_contact_calendar": "\ue8a3",
|
||||||
|
"perm_data_setting": "\ue8a4",
|
||||||
|
"perm_device_information": "\ue8a5",
|
||||||
|
"perm_identity": "\ue8a6",
|
||||||
|
"perm_media": "\ue8a7",
|
||||||
|
"perm_phone_msg": "\ue8a8",
|
||||||
|
"perm_scan_wifi": "\ue8a9",
|
||||||
|
"person": "\ue7fd",
|
||||||
|
"person_add": "\ue7fe",
|
||||||
|
"person_outline": "\ue7ff",
|
||||||
|
"person_pin": "\ue55a",
|
||||||
|
"person_pin_circle": "\ue56a",
|
||||||
|
"personal_video": "\ue63b",
|
||||||
|
"pets": "\ue91d",
|
||||||
|
"phone": "\ue0cd",
|
||||||
|
"phone_android": "\ue324",
|
||||||
|
"phone_bluetooth_speaker": "\ue61b",
|
||||||
|
"phone_forwarded": "\ue61c",
|
||||||
|
"phone_in_talk": "\ue61d",
|
||||||
|
"phone_iphone": "\ue325",
|
||||||
|
"phone_locked": "\ue61e",
|
||||||
|
"phone_missed": "\ue61f",
|
||||||
|
"phone_paused": "\ue620",
|
||||||
|
"phonelink": "\ue326",
|
||||||
|
"phonelink_erase": "\ue0db",
|
||||||
|
"phonelink_lock": "\ue0dc",
|
||||||
|
"phonelink_off": "\ue327",
|
||||||
|
"phonelink_ring": "\ue0dd",
|
||||||
|
"phonelink_setup": "\ue0de",
|
||||||
|
"photo": "\ue410",
|
||||||
|
"photo_album": "\ue411",
|
||||||
|
"photo_camera": "\ue412",
|
||||||
|
"photo_filter": "\ue43b",
|
||||||
|
"photo_library": "\ue413",
|
||||||
|
"photo_size_select_actual": "\ue432",
|
||||||
|
"photo_size_select_large": "\ue433",
|
||||||
|
"photo_size_select_small": "\ue434",
|
||||||
|
"picture_as_pdf": "\ue415",
|
||||||
|
"picture_in_picture": "\ue8aa",
|
||||||
|
"picture_in_picture_alt": "\ue911",
|
||||||
|
"pie_chart": "\ue6c4",
|
||||||
|
"pie_chart_outlined": "\ue6c5",
|
||||||
|
"pin_drop": "\ue55e",
|
||||||
|
"place": "\ue55f",
|
||||||
|
"play_arrow": "\ue037",
|
||||||
|
"play_circle_filled": "\ue038",
|
||||||
|
"play_circle_outline": "\ue039",
|
||||||
|
"play_for_work": "\ue906",
|
||||||
|
"playlist_add": "\ue03b",
|
||||||
|
"playlist_add_check": "\ue065",
|
||||||
|
"playlist_play": "\ue05f",
|
||||||
|
"plus_one": "\ue800",
|
||||||
|
"poll": "\ue801",
|
||||||
|
"polymer": "\ue8ab",
|
||||||
|
"pool": "\ueb48",
|
||||||
|
"portable_wifi_off": "\ue0ce",
|
||||||
|
"portrait": "\ue416",
|
||||||
|
"power": "\ue63c",
|
||||||
|
"power_input": "\ue336",
|
||||||
|
"power_settings_new": "\ue8ac",
|
||||||
|
"pregnant_woman": "\ue91e",
|
||||||
|
"present_to_all": "\ue0df",
|
||||||
|
"print": "\ue8ad",
|
||||||
|
"priority_high": "\ue645",
|
||||||
|
"public": "\ue80b",
|
||||||
|
"publish": "\ue255",
|
||||||
|
"query_builder": "\ue8ae",
|
||||||
|
"question_answer": "\ue8af",
|
||||||
|
"queue": "\ue03c",
|
||||||
|
"queue_music": "\ue03d",
|
||||||
|
"queue_play_next": "\ue066",
|
||||||
|
"radio": "\ue03e",
|
||||||
|
"radio_button_checked": "\ue837",
|
||||||
|
"radio_button_unchecked": "\ue836",
|
||||||
|
"rate_review": "\ue560",
|
||||||
|
"receipt": "\ue8b0",
|
||||||
|
"recent_actors": "\ue03f",
|
||||||
|
"record_voice_over": "\ue91f",
|
||||||
|
"redeem": "\ue8b1",
|
||||||
|
"redo": "\ue15a",
|
||||||
|
"refresh": "\ue5d5",
|
||||||
|
"remove": "\ue15b",
|
||||||
|
"remove_circle": "\ue15c",
|
||||||
|
"remove_circle_outline": "\ue15d",
|
||||||
|
"remove_from_queue": "\ue067",
|
||||||
|
"remove_red_eye": "\ue417",
|
||||||
|
"remove_shopping_cart": "\ue928",
|
||||||
|
"reorder": "\ue8fe",
|
||||||
|
"repeat": "\ue040",
|
||||||
|
"repeat_one": "\ue041",
|
||||||
|
"replay": "\ue042",
|
||||||
|
"replay_10": "\ue059",
|
||||||
|
"replay_30": "\ue05a",
|
||||||
|
"replay_5": "\ue05b",
|
||||||
|
"reply": "\ue15e",
|
||||||
|
"reply_all": "\ue15f",
|
||||||
|
"report": "\ue160",
|
||||||
|
"report_problem": "\ue8b2",
|
||||||
|
"restaurant": "\ue56c",
|
||||||
|
"restaurant_menu": "\ue561",
|
||||||
|
"restore": "\ue8b3",
|
||||||
|
"restore_page": "\ue929",
|
||||||
|
"ring_volume": "\ue0d1",
|
||||||
|
"room": "\ue8b4",
|
||||||
|
"room_service": "\ueb49",
|
||||||
|
"rotate_90_degrees_ccw": "\ue418",
|
||||||
|
"rotate_left": "\ue419",
|
||||||
|
"rotate_right": "\ue41a",
|
||||||
|
"rounded_corner": "\ue920",
|
||||||
|
"router": "\ue328",
|
||||||
|
"rowing": "\ue921",
|
||||||
|
"rss_feed": "\ue0e5",
|
||||||
|
"rv_hookup": "\ue642",
|
||||||
|
"satellite": "\ue562",
|
||||||
|
"save": "\ue161",
|
||||||
|
"scanner": "\ue329",
|
||||||
|
"schedule": "\ue8b5",
|
||||||
|
"school": "\ue80c",
|
||||||
|
"screen_lock_landscape": "\ue1be",
|
||||||
|
"screen_lock_portrait": "\ue1bf",
|
||||||
|
"screen_lock_rotation": "\ue1c0",
|
||||||
|
"screen_rotation": "\ue1c1",
|
||||||
|
"screen_share": "\ue0e2",
|
||||||
|
"sd_card": "\ue623",
|
||||||
|
"sd_storage": "\ue1c2",
|
||||||
|
"search": "\ue8b6",
|
||||||
|
"security": "\ue32a",
|
||||||
|
"select_all": "\ue162",
|
||||||
|
"send": "\ue163",
|
||||||
|
"sentiment_dissatisfied": "\ue811",
|
||||||
|
"sentiment_neutral": "\ue812",
|
||||||
|
"sentiment_satisfied": "\ue813",
|
||||||
|
"sentiment_very_dissatisfied": "\ue814",
|
||||||
|
"sentiment_very_satisfied": "\ue815",
|
||||||
|
"settings": "\ue8b8",
|
||||||
|
"settings_applications": "\ue8b9",
|
||||||
|
"settings_backup_restore": "\ue8ba",
|
||||||
|
"settings_bluetooth": "\ue8bb",
|
||||||
|
"settings_brightness": "\ue8bd",
|
||||||
|
"settings_cell": "\ue8bc",
|
||||||
|
"settings_ethernet": "\ue8be",
|
||||||
|
"settings_input_antenna": "\ue8bf",
|
||||||
|
"settings_input_component": "\ue8c0",
|
||||||
|
"settings_input_composite": "\ue8c1",
|
||||||
|
"settings_input_hdmi": "\ue8c2",
|
||||||
|
"settings_input_svideo": "\ue8c3",
|
||||||
|
"settings_overscan": "\ue8c4",
|
||||||
|
"settings_phone": "\ue8c5",
|
||||||
|
"settings_power": "\ue8c6",
|
||||||
|
"settings_remote": "\ue8c7",
|
||||||
|
"settings_system_daydream": "\ue1c3",
|
||||||
|
"settings_voice": "\ue8c8",
|
||||||
|
"share": "\ue80d",
|
||||||
|
"shop": "\ue8c9",
|
||||||
|
"shop_two": "\ue8ca",
|
||||||
|
"shopping_basket": "\ue8cb",
|
||||||
|
"shopping_cart": "\ue8cc",
|
||||||
|
"short_text": "\ue261",
|
||||||
|
"show_chart": "\ue6e1",
|
||||||
|
"shuffle": "\ue043",
|
||||||
|
"signal_cellular_4_bar": "\ue1c8",
|
||||||
|
"signal_cellular_connected_no_internet_4_bar": "\ue1cd",
|
||||||
|
"signal_cellular_no_sim": "\ue1ce",
|
||||||
|
"signal_cellular_null": "\ue1cf",
|
||||||
|
"signal_cellular_off": "\ue1d0",
|
||||||
|
"signal_wifi_4_bar": "\ue1d8",
|
||||||
|
"signal_wifi_4_bar_lock": "\ue1d9",
|
||||||
|
"signal_wifi_off": "\ue1da",
|
||||||
|
"sim_card": "\ue32b",
|
||||||
|
"sim_card_alert": "\ue624",
|
||||||
|
"skip_next": "\ue044",
|
||||||
|
"skip_previous": "\ue045",
|
||||||
|
"slideshow": "\ue41b",
|
||||||
|
"slow_motion_video": "\ue068",
|
||||||
|
"smartphone": "\ue32c",
|
||||||
|
"smoke_free": "\ueb4a",
|
||||||
|
"smoking_rooms": "\ueb4b",
|
||||||
|
"sms": "\ue625",
|
||||||
|
"sms_failed": "\ue626",
|
||||||
|
"snooze": "\ue046",
|
||||||
|
"sort": "\ue164",
|
||||||
|
"sort_by_alpha": "\ue053",
|
||||||
|
"spa": "\ueb4c",
|
||||||
|
"space_bar": "\ue256",
|
||||||
|
"speaker": "\ue32d",
|
||||||
|
"speaker_group": "\ue32e",
|
||||||
|
"speaker_notes": "\ue8cd",
|
||||||
|
"speaker_notes_off": "\ue92a",
|
||||||
|
"speaker_phone": "\ue0d2",
|
||||||
|
"spellcheck": "\ue8ce",
|
||||||
|
"star": "\ue838",
|
||||||
|
"star_border": "\ue83a",
|
||||||
|
"star_half": "\ue839",
|
||||||
|
"stars": "\ue8d0",
|
||||||
|
"stay_current_landscape": "\ue0d3",
|
||||||
|
"stay_current_portrait": "\ue0d4",
|
||||||
|
"stay_primary_landscape": "\ue0d5",
|
||||||
|
"stay_primary_portrait": "\ue0d6",
|
||||||
|
"stop": "\ue047",
|
||||||
|
"stop_screen_share": "\ue0e3",
|
||||||
|
"storage": "\ue1db",
|
||||||
|
"store": "\ue8d1",
|
||||||
|
"store_mall_directory": "\ue563",
|
||||||
|
"straighten": "\ue41c",
|
||||||
|
"streetview": "\ue56e",
|
||||||
|
"strikethrough_s": "\ue257",
|
||||||
|
"style": "\ue41d",
|
||||||
|
"subdirectory_arrow_left": "\ue5d9",
|
||||||
|
"subdirectory_arrow_right": "\ue5da",
|
||||||
|
"subject": "\ue8d2",
|
||||||
|
"subscriptions": "\ue064",
|
||||||
|
"subtitles": "\ue048",
|
||||||
|
"subway": "\ue56f",
|
||||||
|
"supervisor_account": "\ue8d3",
|
||||||
|
"surround_sound": "\ue049",
|
||||||
|
"swap_calls": "\ue0d7",
|
||||||
|
"swap_horiz": "\ue8d4",
|
||||||
|
"swap_vert": "\ue8d5",
|
||||||
|
"swap_vertical_circle": "\ue8d6",
|
||||||
|
"switch_camera": "\ue41e",
|
||||||
|
"switch_video": "\ue41f",
|
||||||
|
"sync": "\ue627",
|
||||||
|
"sync_disabled": "\ue628",
|
||||||
|
"sync_problem": "\ue629",
|
||||||
|
"system_update": "\ue62a",
|
||||||
|
"system_update_alt": "\ue8d7",
|
||||||
|
"tab": "\ue8d8",
|
||||||
|
"tab_unselected": "\ue8d9",
|
||||||
|
"tablet": "\ue32f",
|
||||||
|
"tablet_android": "\ue330",
|
||||||
|
"tablet_mac": "\ue331",
|
||||||
|
"tag_faces": "\ue420",
|
||||||
|
"tap_and_play": "\ue62b",
|
||||||
|
"terrain": "\ue564",
|
||||||
|
"text_fields": "\ue262",
|
||||||
|
"text_format": "\ue165",
|
||||||
|
"textsms": "\ue0d8",
|
||||||
|
"texture": "\ue421",
|
||||||
|
"theaters": "\ue8da",
|
||||||
|
"thumb_down": "\ue8db",
|
||||||
|
"thumb_up": "\ue8dc",
|
||||||
|
"thumbs_up_down": "\ue8dd",
|
||||||
|
"time_to_leave": "\ue62c",
|
||||||
|
"timelapse": "\ue422",
|
||||||
|
"timeline": "\ue922",
|
||||||
|
"timer": "\ue425",
|
||||||
|
"timer_10": "\ue423",
|
||||||
|
"timer_3": "\ue424",
|
||||||
|
"timer_off": "\ue426",
|
||||||
|
"title": "\ue264",
|
||||||
|
"toc": "\ue8de",
|
||||||
|
"today": "\ue8df",
|
||||||
|
"toll": "\ue8e0",
|
||||||
|
"tonality": "\ue427",
|
||||||
|
"touch_app": "\ue913",
|
||||||
|
"toys": "\ue332",
|
||||||
|
"track_changes": "\ue8e1",
|
||||||
|
"traffic": "\ue565",
|
||||||
|
"train": "\ue570",
|
||||||
|
"tram": "\ue571",
|
||||||
|
"transfer_within_a_station": "\ue572",
|
||||||
|
"transform": "\ue428",
|
||||||
|
"translate": "\ue8e2",
|
||||||
|
"trending_down": "\ue8e3",
|
||||||
|
"trending_flat": "\ue8e4",
|
||||||
|
"trending_up": "\ue8e5",
|
||||||
|
"tune": "\ue429",
|
||||||
|
"turned_in": "\ue8e6",
|
||||||
|
"turned_in_not": "\ue8e7",
|
||||||
|
"tv": "\ue333",
|
||||||
|
"unarchive": "\ue169",
|
||||||
|
"undo": "\ue166",
|
||||||
|
"unfold_less": "\ue5d6",
|
||||||
|
"unfold_more": "\ue5d7",
|
||||||
|
"update": "\ue923",
|
||||||
|
"usb": "\ue1e0",
|
||||||
|
"verified_user": "\ue8e8",
|
||||||
|
"vertical_align_bottom": "\ue258",
|
||||||
|
"vertical_align_center": "\ue259",
|
||||||
|
"vertical_align_top": "\ue25a",
|
||||||
|
"vibration": "\ue62d",
|
||||||
|
"video_call": "\ue070",
|
||||||
|
"video_label": "\ue071",
|
||||||
|
"video_library": "\ue04a",
|
||||||
|
"videocam": "\ue04b",
|
||||||
|
"videocam_off": "\ue04c",
|
||||||
|
"videogame_asset": "\ue338",
|
||||||
|
"view_agenda": "\ue8e9",
|
||||||
|
"view_array": "\ue8ea",
|
||||||
|
"view_carousel": "\ue8eb",
|
||||||
|
"view_column": "\ue8ec",
|
||||||
|
"view_comfy": "\ue42a",
|
||||||
|
"view_compact": "\ue42b",
|
||||||
|
"view_day": "\ue8ed",
|
||||||
|
"view_headline": "\ue8ee",
|
||||||
|
"view_list": "\ue8ef",
|
||||||
|
"view_module": "\ue8f0",
|
||||||
|
"view_quilt": "\ue8f1",
|
||||||
|
"view_stream": "\ue8f2",
|
||||||
|
"view_week": "\ue8f3",
|
||||||
|
"vignette": "\ue435",
|
||||||
|
"visibility": "\ue8f4",
|
||||||
|
"visibility_off": "\ue8f5",
|
||||||
|
"voice_chat": "\ue62e",
|
||||||
|
"voicemail": "\ue0d9",
|
||||||
|
"volume_down": "\ue04d",
|
||||||
|
"volume_mute": "\ue04e",
|
||||||
|
"volume_off": "\ue04f",
|
||||||
|
"volume_up": "\ue050",
|
||||||
|
"vpn_key": "\ue0da",
|
||||||
|
"vpn_lock": "\ue62f",
|
||||||
|
"wallpaper": "\ue1bc",
|
||||||
|
"warning": "\ue002",
|
||||||
|
"watch": "\ue334",
|
||||||
|
"watch_later": "\ue924",
|
||||||
|
"wb_auto": "\ue42c",
|
||||||
|
"wb_cloudy": "\ue42d",
|
||||||
|
"wb_incandescent": "\ue42e",
|
||||||
|
"wb_iridescent": "\ue436",
|
||||||
|
"wb_sunny": "\ue430",
|
||||||
|
"wc": "\ue63d",
|
||||||
|
"web": "\ue051",
|
||||||
|
"web_asset": "\ue069",
|
||||||
|
"weekend": "\ue16b",
|
||||||
|
"whatshot": "\ue80e",
|
||||||
|
"widgets": "\ue1bd",
|
||||||
|
"wifi": "\ue63e",
|
||||||
|
"wifi_lock": "\ue1e1",
|
||||||
|
"wifi_tethering": "\ue1e2",
|
||||||
|
"work": "\ue8f9",
|
||||||
|
"wrap_text": "\ue25b",
|
||||||
|
"youtube_searched_for": "\ue8fa",
|
||||||
|
"zoom_in": "\ue8ff",
|
||||||
|
"zoom_out": "\ue900",
|
||||||
|
"zoom_out_map": "\ue56b"
|
||||||
|
}
|
11
include/BaseUI/core.h
Normal file
11
include/BaseUI/core.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef BASEUI_CORE_H
|
||||||
|
#define BASEUI_CORE_H
|
||||||
|
|
||||||
|
class QQmlEngine;
|
||||||
|
|
||||||
|
namespace BaseUI
|
||||||
|
{
|
||||||
|
void init(QQmlEngine *engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
28
qml/BaseUI/App.qml
Normal file
28
qml/BaseUI/App.qml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
property alias pageStack: stackView
|
||||||
|
property alias initialPage: stackView.initialItem
|
||||||
|
|
||||||
|
visible: true
|
||||||
|
locale: Qt.locale("en_US")
|
||||||
|
|
||||||
|
header: stackView.currentItem ? stackView.currentItem.appToolBar : null
|
||||||
|
|
||||||
|
StackView {
|
||||||
|
id: stackView
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onCurrentItemChanged: {
|
||||||
|
// make sure that the phone physical back button will get key events
|
||||||
|
currentItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Material.primary: Style.primaryColor
|
||||||
|
Material.accent: Style.accentColor
|
||||||
|
Material.theme: Style.isDarkTheme ? Material.Dark : Material.Light
|
||||||
|
}
|
45
qml/BaseUI/AppStackPage.qml
Normal file
45
qml/BaseUI/AppStackPage.qml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
import BaseUI 1.0
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property StackView stack: StackView.view
|
||||||
|
property alias appToolBar: appToolBar
|
||||||
|
property alias leftButton: appToolBar.leftButton
|
||||||
|
property alias rightButtons: appToolBar.rightButtons
|
||||||
|
|
||||||
|
function pop(item, operation) {
|
||||||
|
if (stack.currentItem != root)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return stack.pop(item, operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
function back() {
|
||||||
|
pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onBackPressed: function(event) {
|
||||||
|
if (stack.depth > 1) {
|
||||||
|
event.accepted = true
|
||||||
|
back()
|
||||||
|
} else {
|
||||||
|
Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Action {
|
||||||
|
id: backAction
|
||||||
|
icon.source: Icons.arrow_back
|
||||||
|
onTriggered: root.back()
|
||||||
|
}
|
||||||
|
|
||||||
|
AppToolBar {
|
||||||
|
id: appToolBar
|
||||||
|
title: root.title
|
||||||
|
leftButton: stack && stack.depth > 1 ? backAction : null
|
||||||
|
}
|
||||||
|
}
|
42
qml/BaseUI/AppToolBar.qml
Normal file
42
qml/BaseUI/AppToolBar.qml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
ToolBar {
|
||||||
|
property Action leftButton
|
||||||
|
property list<Action> rightButtons
|
||||||
|
|
||||||
|
property alias title: titleLabel.text
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
focus: false
|
||||||
|
spacing: 0
|
||||||
|
anchors { fill: parent; leftMargin: 4; rightMargin: 4 }
|
||||||
|
|
||||||
|
ToolButton {
|
||||||
|
icon.source: leftButton ? leftButton.icon.source : ""
|
||||||
|
icon.color: Style.textOnPrimary
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
opacity: Style.opacityTitle
|
||||||
|
enabled: leftButton && leftButton.enabled
|
||||||
|
onClicked: leftButton.trigger()
|
||||||
|
}
|
||||||
|
LabelTitle {
|
||||||
|
id: titleLabel
|
||||||
|
elide: Label.ElideRight
|
||||||
|
color: Style.textOnPrimary
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Repeater {
|
||||||
|
model: rightButtons.length
|
||||||
|
delegate: ToolButton {
|
||||||
|
icon.source: rightButtons[index].icon.source
|
||||||
|
icon.color: Style.textOnPrimary
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
opacity: Style.opacityTitle
|
||||||
|
enabled: rightButtons[index].enabled
|
||||||
|
onClicked: rightButtons[index].trigger()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
qml/BaseUI/ButtonFlat.qml
Normal file
36
qml/BaseUI/ButtonFlat.qml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// ekke (Ekkehard Gentz) @ekkescorner
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
property alias textColor: buttonText.color
|
||||||
|
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
leftPadding: 6
|
||||||
|
rightPadding: 6
|
||||||
|
|
||||||
|
Layout.minimumWidth: 88
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
id: buttonText
|
||||||
|
text: button.text
|
||||||
|
opacity: enabled ? 1.0 : 0.3
|
||||||
|
color: Style.flatButtonTextColor
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.capitalization: Font.AllUppercase
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: buttonBackground
|
||||||
|
implicitHeight: 48
|
||||||
|
color: button.pressed ? buttonText.color : "transparent"
|
||||||
|
radius: 2
|
||||||
|
opacity: button.pressed ? 0.12 : 1.0
|
||||||
|
}
|
||||||
|
}
|
45
qml/BaseUI/ButtonRaised.qml
Normal file
45
qml/BaseUI/ButtonRaised.qml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
property alias textColor: buttonText.color
|
||||||
|
property alias buttonColor: buttonBackground.color
|
||||||
|
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
leftPadding: 6
|
||||||
|
rightPadding: 6
|
||||||
|
|
||||||
|
Layout.minimumWidth: 80
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
id: buttonText
|
||||||
|
text: button.text
|
||||||
|
opacity: enabled ? 1.0 : 0.3
|
||||||
|
color: Style.textOnPrimary
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
font.capitalization: Font.AllUppercase
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
id: buttonBackground
|
||||||
|
implicitHeight: 48
|
||||||
|
color: Style.primaryColor
|
||||||
|
radius: 2
|
||||||
|
opacity: button.pressed ? 0.75 : 1.0
|
||||||
|
/*
|
||||||
|
layer.enabled: true
|
||||||
|
layer.effect: DropShadow {
|
||||||
|
verticalOffset: 2
|
||||||
|
horizontalOffset: 1
|
||||||
|
color: dropShadow
|
||||||
|
samples: button.pressed ? 20 : 10
|
||||||
|
spread: 0.5
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
19
qml/BaseUI/HorizontalDivider.qml
Normal file
19
qml/BaseUI/HorizontalDivider.qml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// ekke (Ekkehard Gentz) @ekkescorner
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
Item {
|
||||||
|
height: 8
|
||||||
|
Layout.fillWidth: true
|
||||||
|
// anchors.left: parent.left
|
||||||
|
// anchors.right: parent.right
|
||||||
|
// anchors.margins: 6
|
||||||
|
// https://www.google.com/design/spec/components/dividers.html#dividers-types-of-dividers
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
height: 1
|
||||||
|
opacity: Style.dividerOpacity
|
||||||
|
color: Style.dividerColor
|
||||||
|
}
|
||||||
|
}
|
9
qml/BaseUI/LabelBody.qml
Normal file
9
qml/BaseUI/LabelBody.qml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// ekke (Ekkehard Gentz) @ekkescorner
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
opacity: Style.opacityBodyAndButton
|
||||||
|
}
|
10
qml/BaseUI/LabelSubheading.qml
Normal file
10
qml/BaseUI/LabelSubheading.qml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ekke (Ekkehard Gentz) @ekkescorner
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: Style.fontSizeSubheading
|
||||||
|
opacity: Style.opacitySubheading
|
||||||
|
}
|
10
qml/BaseUI/LabelTitle.qml
Normal file
10
qml/BaseUI/LabelTitle.qml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// ekke (Ekkehard Gentz) @ekkescorner
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pixelSize: Style.fontSizeTitle
|
||||||
|
opacity: Style.opacityTitle
|
||||||
|
}
|
84
qml/BaseUI/PopupColorSelection.qml
Normal file
84
qml/BaseUI/PopupColorSelection.qml
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
|
PopupModalBase {
|
||||||
|
property bool selectAccentColor: false
|
||||||
|
property color currentColor: Material.primary
|
||||||
|
property string currentColorName: colorModel.get(currentIndex).title
|
||||||
|
property int currentIndex: 0
|
||||||
|
|
||||||
|
signal colorSelected(color c)
|
||||||
|
|
||||||
|
implicitWidth: parent.width * 0.9
|
||||||
|
implicitHeight: Math.min(colorsList.contentHeight, parent.height * 0.9)
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: colorsList
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
width: colorsList.width
|
||||||
|
contentItem: RowLayout {
|
||||||
|
spacing: 0
|
||||||
|
Rectangle {
|
||||||
|
visible: selectAccentColor
|
||||||
|
color: Material.primary
|
||||||
|
Layout.margins: 0
|
||||||
|
Layout.minimumHeight: 32
|
||||||
|
Layout.minimumWidth: 48
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
color: Material.color(model.bg)
|
||||||
|
Layout.margins: 0
|
||||||
|
Layout.minimumHeight: 32
|
||||||
|
Layout.minimumWidth: 32
|
||||||
|
}
|
||||||
|
LabelBody {
|
||||||
|
text: model.title
|
||||||
|
Layout.leftMargin: 6
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
colorSelected(Material.color(model.bg))
|
||||||
|
currentIndex = index
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
id: colorModel
|
||||||
|
ListElement { title: "Material Red"; bg: Material.Red }
|
||||||
|
ListElement { title: "Material Pink"; bg: Material.Pink }
|
||||||
|
ListElement { title: "Material Purple"; bg: Material.Purple }
|
||||||
|
ListElement { title: "Material DeepPurple"; bg: Material.DeepPurple }
|
||||||
|
ListElement { title: "Material Indigo"; bg: Material.Indigo }
|
||||||
|
ListElement { title: "Material Blue"; bg: Material.Blue }
|
||||||
|
ListElement { title: "Material LightBlue"; bg: Material.LightBlue }
|
||||||
|
ListElement { title: "Material Cyan"; bg: Material.Cyan }
|
||||||
|
ListElement { title: "Material Teal"; bg: Material.Teal }
|
||||||
|
ListElement { title: "Material Green"; bg: Material.Green }
|
||||||
|
ListElement { title: "Material LightGreen"; bg: Material.LightGreen }
|
||||||
|
ListElement { title: "Material Lime"; bg: Material.Lime }
|
||||||
|
ListElement { title: "Material Yellow"; bg: Material.Yellow }
|
||||||
|
ListElement { title: "Material Amber"; bg: Material.Amber }
|
||||||
|
ListElement { title: "Material Orange"; bg: Material.Orange }
|
||||||
|
ListElement { title: "Material DeepOrange"; bg: Material.DeepOrange }
|
||||||
|
ListElement { title: "Material Brown"; bg: Material.Brown }
|
||||||
|
ListElement { title: "Material Grey"; bg: Material.Grey }
|
||||||
|
ListElement { title: "Material BlueGrey"; bg: Material.BlueGrey }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
for (var i = 0; i < colorModel.count; ++i) {
|
||||||
|
var tmp = colorModel.get(i)
|
||||||
|
if (Material.color(tmp.bg) === currentColor) {
|
||||||
|
currentIndex = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
qml/BaseUI/PopupError.qml
Normal file
69
qml/BaseUI/PopupError.qml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
|
import BaseUI 1.0
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
function start(errorText) {
|
||||||
|
errorLabel.text = errorText
|
||||||
|
if (!errorTimer.running)
|
||||||
|
open()
|
||||||
|
else
|
||||||
|
errorTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
closePolicy: Popup.CloseOnPressOutside
|
||||||
|
bottomMargin: Screen.primaryOrientation === Qt.LandscapeOrientation ? 24 : 80
|
||||||
|
implicitWidth: Screen.primaryOrientation === Qt.LandscapeOrientation ? parent.width * 0.50 : parent.width * 0.80
|
||||||
|
|
||||||
|
x: (parent.width - implicitWidth) / 2
|
||||||
|
y: (parent.height - height)
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Material.color(Material.Red, Style.isDarkTheme ? Material.Shade500 : Material.Shade800)
|
||||||
|
radius: 24
|
||||||
|
opacity: Style.toastOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToShow: errorTimer.start()
|
||||||
|
onAboutToHide: errorTimer.stop()
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: errorTimer
|
||||||
|
|
||||||
|
interval: 3000
|
||||||
|
repeat: false
|
||||||
|
|
||||||
|
onTriggered: root.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: alarmIcon
|
||||||
|
|
||||||
|
smooth: true
|
||||||
|
source: Icons.error + "color=white"
|
||||||
|
sourceSize.width: 36
|
||||||
|
sourceSize.height: 36
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: errorLabel
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredWidth: 1
|
||||||
|
|
||||||
|
rightPadding: 24
|
||||||
|
font.pixelSize: 16
|
||||||
|
color: "white"
|
||||||
|
wrapMode: Label.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
qml/BaseUI/PopupInfo.qml
Normal file
40
qml/BaseUI/PopupInfo.qml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
|
PopupModalBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias text: popupLabel.text
|
||||||
|
|
||||||
|
closePolicy: Popup.CloseOnEscape
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 10
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
LabelSubheading {
|
||||||
|
id: popupLabel
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
topPadding: 20
|
||||||
|
leftPadding: 8
|
||||||
|
rightPadding: 8
|
||||||
|
color: Style.popupTextColor
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
linkColor: Style.isDarkTheme ? "lightblue" : "blue"
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonFlat {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
text: "OK"
|
||||||
|
textColor: Style.accentColor
|
||||||
|
onClicked: root.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
qml/BaseUI/PopupList.qml
Normal file
32
qml/BaseUI/PopupList.qml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
PopupModalBase {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias model: internalList.model
|
||||||
|
property alias currentIndex: internalList.currentIndex
|
||||||
|
property var delegateFunction
|
||||||
|
|
||||||
|
signal clicked(var data, int index)
|
||||||
|
|
||||||
|
implicitWidth: parent.width * 0.9
|
||||||
|
implicitHeight: Math.min(internalList.contentHeight, parent.height * 0.9)
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: internalList
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: internalDelegate
|
||||||
|
width: parent.width
|
||||||
|
implicitHeight: 40
|
||||||
|
text: delegateFunction(modelData)
|
||||||
|
onClicked: root.clicked(modelData, index)
|
||||||
|
}
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
internalList.positionViewAtIndex(currentIndex, ListView.Center)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
qml/BaseUI/PopupModalBase.qml
Normal file
14
qml/BaseUI/PopupModalBase.qml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
modal: true
|
||||||
|
dim: true
|
||||||
|
padding: 0
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height) / 2
|
||||||
|
implicitWidth: Math.min(contentWidth, parent.width * 0.9)
|
||||||
|
implicitHeight: Math.min(contentHeight, parent.height * 0.9)
|
||||||
|
}
|
51
qml/BaseUI/PopupToast.qml
Normal file
51
qml/BaseUI/PopupToast.qml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Window 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
function start(toastText) {
|
||||||
|
toastLabel.text = toastText
|
||||||
|
if (!toastTimer.running)
|
||||||
|
open()
|
||||||
|
else
|
||||||
|
toastTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2
|
||||||
|
y: (parent.height - height)
|
||||||
|
|
||||||
|
closePolicy: Popup.CloseOnPressOutside
|
||||||
|
bottomMargin: Screen.primaryOrientation === Qt.LandscapeOrientation ? 24 : 80
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Style.toastColor
|
||||||
|
radius: 24
|
||||||
|
opacity: Style.toastOpacity
|
||||||
|
}
|
||||||
|
|
||||||
|
onAboutToShow: toastTimer.start()
|
||||||
|
onAboutToHide: toastTimer.stop()
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: toastTimer
|
||||||
|
|
||||||
|
interval: 3000
|
||||||
|
repeat: false
|
||||||
|
|
||||||
|
onTriggered: root.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: toastLabel
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
leftPadding: 16
|
||||||
|
rightPadding: 16
|
||||||
|
font.pixelSize: 16
|
||||||
|
color: "white"
|
||||||
|
wrapMode: Label.WordWrap
|
||||||
|
}
|
||||||
|
}
|
48
qml/BaseUI/SettingsItem.qml
Normal file
48
qml/BaseUI/SettingsItem.qml
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias title: titleLabel.text
|
||||||
|
property string subtitle
|
||||||
|
property string subtitlePlaceholder
|
||||||
|
property alias check: settingSwitch
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 2
|
||||||
|
|
||||||
|
LabelSubheading {
|
||||||
|
id: titleLabel
|
||||||
|
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
LabelBody {
|
||||||
|
id: subtitleLabel
|
||||||
|
|
||||||
|
visible: text.length > 0 || root.subtitlePlaceholder.length > 0
|
||||||
|
opacity: 0.6
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
elide: Text.ElideMiddle
|
||||||
|
text: root.subtitle.length > 0 ? root.subtitle : root.subtitlePlaceholder
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch {
|
||||||
|
id: settingSwitch
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
qml/BaseUI/SettingsSectionTitle.qml
Normal file
18
qml/BaseUI/SettingsSectionTitle.qml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls 2.12
|
||||||
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
|
Label {
|
||||||
|
leftPadding: 16
|
||||||
|
topPadding: 6
|
||||||
|
bottomPadding: 6
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: Style.fontSizeBodyAndButton
|
||||||
|
color: Style.isDarkTheme ? "white" : "black"
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: Style.isDarkTheme ? Qt.darker("gray") : "lightgray"
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
56
qml/BaseUI/Style.qml
Normal file
56
qml/BaseUI/Style.qml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Controls.Material 2.12
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
property bool isDarkTheme: false
|
||||||
|
|
||||||
|
property color primaryColor: Material.color(Material.BlueGrey)
|
||||||
|
property color accentColor: Material.color(Material.Orange)
|
||||||
|
property color primaryDarkColor: Qt.darker(primaryColor)
|
||||||
|
|
||||||
|
// ui constants
|
||||||
|
property color textOnPrimary: isDarkColor(primaryColor) ? "#FFFFFF" : "#000000"
|
||||||
|
property color textOnAccent: isDarkColor(accentColor) ? "#FFFFFF" : "#000000"
|
||||||
|
property color textOnPrimaryDark: textOnPrimary
|
||||||
|
|
||||||
|
property color dividerColor: isDarkTheme ? "#FFFFFF" : "#000000"
|
||||||
|
property real primaryTextOpacity: isDarkTheme ? 1.0 : 0.87
|
||||||
|
property real secondaryTextOpacity: isDarkTheme ? 0.7 : 0.54
|
||||||
|
property real dividerOpacity: isDarkTheme ? 0.12 : 0.12
|
||||||
|
property color flatButtonTextColor: isDarkTheme ? "#FFFFFF" : "#424242"
|
||||||
|
property color popupTextColor: isDarkTheme ? "#FFFFFF" : "#424242"
|
||||||
|
property color toastColor: isDarkTheme ? "Darkgrey" : "#323232"
|
||||||
|
property real toastOpacity: isDarkTheme ? 0.9 : 0.75
|
||||||
|
|
||||||
|
// font sizes - defaults from Google Material Design Guide
|
||||||
|
property int fontSizeDisplay4: 112
|
||||||
|
property int fontSizeDisplay3: 56
|
||||||
|
property int fontSizeDisplay2: 45
|
||||||
|
property int fontSizeDisplay1: 34
|
||||||
|
property int fontSizeHeadline: 24
|
||||||
|
property int fontSizeTitle: 20
|
||||||
|
property int fontSizeSubheading: 16
|
||||||
|
property int fontSizeBodyAndButton: 14 // is Default
|
||||||
|
property int fontSizeCaption: 12
|
||||||
|
// fonts are grouped into primary and secondary with different Opacity
|
||||||
|
// to make it easier to get the right property,
|
||||||
|
// here's the opacity per size:
|
||||||
|
property real opacityDisplay4: secondaryTextOpacity
|
||||||
|
property real opacityDisplay3: secondaryTextOpacity
|
||||||
|
property real opacityDisplay2: secondaryTextOpacity
|
||||||
|
property real opacityDisplay1: secondaryTextOpacity
|
||||||
|
property real opacityHeadline: primaryTextOpacity
|
||||||
|
property real opacityTitle: primaryTextOpacity
|
||||||
|
property real opacitySubheading: primaryTextOpacity
|
||||||
|
// body can be both: primary or secondary text
|
||||||
|
property real opacityBodyAndButton: primaryTextOpacity
|
||||||
|
property real opacityBodySecondary: secondaryTextOpacity
|
||||||
|
property real opacityCaption: secondaryTextOpacity
|
||||||
|
|
||||||
|
function isDarkColor(color) {
|
||||||
|
var a = 1.0 - (0.299 * color.r + 0.587 * color.g + 0.114 * color.b)
|
||||||
|
return color.a > 0.0 && a >= 0.3
|
||||||
|
}
|
||||||
|
}
|
23
qml/BaseUI/baseui_qml.qrc
Normal file
23
qml/BaseUI/baseui_qml.qrc
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/imports/BaseUI">
|
||||||
|
<file>qmldir</file>
|
||||||
|
<file>App.qml</file>
|
||||||
|
<file>AppStackPage.qml</file>
|
||||||
|
<file>AppToolBar.qml</file>
|
||||||
|
<file>ButtonFlat.qml</file>
|
||||||
|
<file>ButtonRaised.qml</file>
|
||||||
|
<file>HorizontalDivider.qml</file>
|
||||||
|
<file>LabelBody.qml</file>
|
||||||
|
<file>LabelSubheading.qml</file>
|
||||||
|
<file>LabelTitle.qml</file>
|
||||||
|
<file>PopupColorSelection.qml</file>
|
||||||
|
<file>PopupError.qml</file>
|
||||||
|
<file>PopupInfo.qml</file>
|
||||||
|
<file>PopupList.qml</file>
|
||||||
|
<file>PopupModalBase.qml</file>
|
||||||
|
<file>PopupToast.qml</file>
|
||||||
|
<file>SettingsItem.qml</file>
|
||||||
|
<file>SettingsSectionTitle.qml</file>
|
||||||
|
<file>Style.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
21
qml/BaseUI/qmldir
Normal file
21
qml/BaseUI/qmldir
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
module BaseUI
|
||||||
|
|
||||||
|
App 1.0 App.qml
|
||||||
|
AppStackPage 1.0 AppStackPage.qml
|
||||||
|
AppToolBar 1.0 AppToolBar.qml
|
||||||
|
ButtonFlat 1.0 ButtonFlat.qml
|
||||||
|
ButtonRaised 1.0 ButtonRaised.qml
|
||||||
|
HorizontalDivider 1.0 HorizontalDivider.qml
|
||||||
|
LabelBody 1.0 LabelBody.qml
|
||||||
|
LabelSubheading 1.0 LabelSubheading.qml
|
||||||
|
LabelTitle 1.0 LabelTitle.qml
|
||||||
|
PopupColorSelection 1.0 PopupColorSelection.qml
|
||||||
|
PopupError 1.0 PopupError.qml
|
||||||
|
PopupInfo 1.0 PopupInfo.qml
|
||||||
|
PopupList 1.0 PopupList.qml
|
||||||
|
PopupModalBase 1.0 PopupModalBase.qml
|
||||||
|
PopupToast 1.0 PopupToast.qml
|
||||||
|
SettingsItem 1.0 SettingsItem.qml
|
||||||
|
SettingsSectionTitle 1.0 SettingsSectionTitle.qml
|
||||||
|
|
||||||
|
singleton Style 1.0 Style.qml
|
41
src/core.cpp
Normal file
41
src/core.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <BaseUI/core.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQuickStyle>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "icons.h"
|
||||||
|
|
||||||
|
static void initialize(QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
#ifdef BASEUI_EMBED_QML
|
||||||
|
Q_INIT_RESOURCE(baseui_qml);
|
||||||
|
engine->addImportPath(":/imports");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QString path = "/BaseUI/icons/";
|
||||||
|
|
||||||
|
#ifdef BASEUI_EMBED_ICONS
|
||||||
|
Q_INIT_RESOURCE(baseui_icons);
|
||||||
|
path = ":/imports" + path;
|
||||||
|
#else
|
||||||
|
path = QCoreApplication::applicationDirPath() + path;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Icons::registerIcons(engine, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BaseUI
|
||||||
|
{
|
||||||
|
|
||||||
|
void init(QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
QQuickStyle::setStyle("Material");
|
||||||
|
|
||||||
|
initialize(engine);
|
||||||
|
|
||||||
|
qmlRegisterSingletonType<Icons>("BaseUI", 1, 0, "Icons", Icons::singletonProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
111
src/iconprovider.h
Normal file
111
src/iconprovider.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#ifndef ICONPROVIDER_H
|
||||||
|
#define ICONPROVIDER_H
|
||||||
|
|
||||||
|
#include <QQuickImageProvider>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
|
||||||
|
class IconProvider : public QQuickImageProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit IconProvider(const QString &family, const QString &codesPath)
|
||||||
|
: QQuickImageProvider(QQuickImageProvider::Image)
|
||||||
|
, font(family)
|
||||||
|
{
|
||||||
|
QFile file(codesPath);
|
||||||
|
if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
auto jd = QJsonDocument::fromJson(file.readAll());
|
||||||
|
if (!jd.isNull())
|
||||||
|
codepoints = jd.object();
|
||||||
|
else
|
||||||
|
qWarning() << "Invalid codepoints JSON file" << codesPath;
|
||||||
|
} else {
|
||||||
|
qWarning() << "Cannot open icon codes file" << codesPath;
|
||||||
|
qWarning() << file.errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override
|
||||||
|
{
|
||||||
|
int width = 48;
|
||||||
|
int height = 48;
|
||||||
|
|
||||||
|
if (requestedSize.width() > 0)
|
||||||
|
width = requestedSize.width();
|
||||||
|
|
||||||
|
if (requestedSize.height() > 0)
|
||||||
|
height = requestedSize.height();
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
*size = QSize(width, height);
|
||||||
|
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
QStringList args = id.split(",", QString::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList args = id.split(",", Qt::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QString iconChar("?");
|
||||||
|
if (!args.isEmpty()) {
|
||||||
|
QString name = args.takeFirst();
|
||||||
|
if (codepoints.value(name).isUndefined())
|
||||||
|
qWarning() << "Icon name" << name << "not found in" << font.family();
|
||||||
|
else
|
||||||
|
iconChar = codepoints[name].toString();
|
||||||
|
} else {
|
||||||
|
qWarning() << "Icon name empty";
|
||||||
|
}
|
||||||
|
|
||||||
|
font.setPixelSize(width < height ? width : height);
|
||||||
|
|
||||||
|
QFontMetrics fm(font);
|
||||||
|
double widthRatio = double(width) / fm.boundingRect(iconChar).width();
|
||||||
|
if (widthRatio < 1.0)
|
||||||
|
font.setPixelSize(font.pixelSize() * widthRatio);
|
||||||
|
|
||||||
|
QImage image(width, height, QImage::Format_RGBA8888);
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPainter painter(&image);
|
||||||
|
|
||||||
|
for (const QString &arg : args) {
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
|
||||||
|
QStringList attr = arg.split("=", QString::SkipEmptyParts);
|
||||||
|
#else
|
||||||
|
QStringList attr = arg.split("=", Qt::SkipEmptyParts);
|
||||||
|
#endif
|
||||||
|
if (attr.isEmpty() || attr.size() > 2) {
|
||||||
|
qWarning() << "Argument" << arg << "not valid.";
|
||||||
|
} else if (attr[0] == "color") {
|
||||||
|
if (attr.size() == 2)
|
||||||
|
painter.setPen(attr[1]);
|
||||||
|
else
|
||||||
|
qWarning() << "Attribute color needs a value";
|
||||||
|
} else if (attr[0] == "hflip") {
|
||||||
|
painter.setTransform(QTransform(-1, 0, 0, 0, 1, 0, width, 0, 1));
|
||||||
|
} else if (attr[0] == "vflip") {
|
||||||
|
painter.setTransform(QTransform(1, 0, 0, 0, -1, 0, 0, height, 1));
|
||||||
|
} else {
|
||||||
|
qWarning() << "Unknown attribute" << attr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter.setFont(font);
|
||||||
|
painter.drawText(QRect(0, 0, width, height), Qt::AlignCenter, iconChar);
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList keys() { return codepoints.keys(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QJsonObject codepoints;
|
||||||
|
QFont font;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ICONPROVIDER_H
|
55
src/icons.cpp
Normal file
55
src/icons.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "icons.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QFontDatabase>
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
#include "iconprovider.h"
|
||||||
|
|
||||||
|
Icons::Icons(QObject *parent)
|
||||||
|
: QQmlPropertyMap(this, parent)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
|
}
|
||||||
|
|
||||||
|
Icons *Icons::instance()
|
||||||
|
{
|
||||||
|
static Icons instance_;
|
||||||
|
|
||||||
|
return &instance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *Icons::singletonProvider(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
|
||||||
|
{
|
||||||
|
Q_UNUSED(qmlEngine)
|
||||||
|
Q_UNUSED(jsEngine)
|
||||||
|
|
||||||
|
return instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Icons::registerIcons(QQmlEngine *engine, const QString &path)
|
||||||
|
{
|
||||||
|
QString iconProviderName = "baseui_icons";
|
||||||
|
|
||||||
|
if (QFontDatabase::addApplicationFont(path + "MaterialIcons-Regular.ttf") == -1)
|
||||||
|
qWarning() << "Failed to load font Material";
|
||||||
|
|
||||||
|
auto iconProvider = new IconProvider("Material Icons", path + "codepoints.json");
|
||||||
|
|
||||||
|
engine->addImageProvider(iconProviderName, iconProvider);
|
||||||
|
|
||||||
|
#if (QT_VERSION < QT_VERSION_CHECK(6, 1, 0))
|
||||||
|
for (const QString &key : iconProvider->keys())
|
||||||
|
instance()->insert(key, QVariant("image://" + iconProviderName + "/" + key + ","));
|
||||||
|
#else
|
||||||
|
QVariantHash hash;
|
||||||
|
for (const QString &key : iconProvider->keys())
|
||||||
|
hash.insert(key, QVariant("image://" + iconProviderName + "/" + key + ","));
|
||||||
|
instance()->insert(hash);
|
||||||
|
#endif
|
||||||
|
}
|
28
src/icons.h
Normal file
28
src/icons.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef ICONS_H
|
||||||
|
#define ICONS_H
|
||||||
|
|
||||||
|
#include <QQmlPropertyMap>
|
||||||
|
|
||||||
|
class QQmlEngine;
|
||||||
|
class QJSEngine;
|
||||||
|
|
||||||
|
class Icons : public QQmlPropertyMap
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Icons(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
static Icons *instance();
|
||||||
|
static QObject *singletonProvider(QQmlEngine *qmlEngine, QJSEngine *jsEngine);
|
||||||
|
|
||||||
|
static void registerIcons(QQmlEngine *engine, const QString &path);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template <typename DerivedType>
|
||||||
|
explicit Icons(DerivedType *derived, QObject *parent = nullptr)
|
||||||
|
: QQmlPropertyMap(derived, parent)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user