mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-15 05:22:53 +08:00
Format code, update to Qt 6.7.0 & attend issue #189
This commit is contained in:
parent
d4f7fbc0e3
commit
2684acaec5
@ -1,39 +1,24 @@
|
||||
# Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com>
|
||||
#
|
||||
# You may use this file under the terms of the 3-clause BSD license.
|
||||
# See the file LICENSE from this package for details.
|
||||
BasedOnStyle: LLVM
|
||||
Standard: Cpp11
|
||||
CommentPragmas: "^!|^:"
|
||||
PointerBindsToType: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
ConstructorInitializerIndentWidth: 2
|
||||
NamespaceIndentation: None
|
||||
AlignAfterOpenBracket: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
SortIncludes: false
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: AfterHash
|
||||
AccessModifierOffset: -2
|
||||
IndentWidth: 2
|
||||
ColumnLimit: 80
|
||||
|
||||
# This is the clang-format configuration style to be used by Qt,
|
||||
# based on the rules from https://wiki.qt.io/Qt_Coding_Style and
|
||||
# https://wiki.qt.io/Coding_Conventions
|
||||
|
||||
---
|
||||
# Webkit style was loosely based on the Qt style
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
Standard: Cpp11
|
||||
|
||||
# Leave the line breaks up to the user.
|
||||
# Note that this may be changed at some point in the future.
|
||||
ColumnLimit: 0
|
||||
# How much weight do extra characters after the line length limit have.
|
||||
# PenaltyExcessCharacter: 4
|
||||
|
||||
# Disable reflow of qdoc comments: indentation rules are different.
|
||||
# Translation comments are also excluded.
|
||||
CommentPragmas: "^!|^:"
|
||||
|
||||
# We want a space between the type and the star for pointer types.
|
||||
PointerBindsToType: false
|
||||
|
||||
# We use template< without space.
|
||||
SpaceAfterTemplateKeyword: false
|
||||
|
||||
# We want to break before the operators, but not before a '='.
|
||||
BreakBeforeBinaryOperators: All
|
||||
|
||||
# Braces are usually attached, but not after functions or class declarations.
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
@ -47,48 +32,7 @@ BraceWrapping:
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
|
||||
BreakBeforeTernaryOperators: true
|
||||
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
|
||||
# Indent initializers by 3 spaces
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
|
||||
# No indentation for namespaces.
|
||||
NamespaceIndentation: None
|
||||
|
||||
# Horizontally align arguments after an open bracket.
|
||||
# The coding style does not specify the following, but this is what gives
|
||||
# results closest to the existing code.
|
||||
AlignAfterOpenBracket: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
|
||||
# Ideally we should also allow less short function in a single line, but
|
||||
# clang-format does not handle that.
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
|
||||
# The coding style specifies some include order categories, but also tells to
|
||||
# separate categories with an empty line. It does not specify the order within
|
||||
# the categories. Since the SortInclude feature of clang-format does not
|
||||
# re-order includes separated by empty lines, the feature is not used.
|
||||
SortIncludes: false
|
||||
|
||||
# macros for which the opening brace stays attached.
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
|
||||
|
||||
IndentCaseLabels: true
|
||||
|
||||
IndentPPDirectives: AfterHash
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
|
||||
AccessModifierOffset: -4
|
||||
|
||||
IndentWidth: 4
|
||||
|
||||
#StatementMacros ['Q_OBJECT', 'Q_UNUSED']
|
||||
|
||||
ColumnLimit: 90
|
||||
|
||||
|
||||
|
||||
|
56
.clang-tidy
Normal file
56
.clang-tidy
Normal file
@ -0,0 +1,56 @@
|
||||
---
|
||||
Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm-*,-llvmlibc-*'
|
||||
CheckOptions: [{ key: misc-non-private-member-variables-in-classes, value: IgnoreClassesWithAllMemberVariablesBeingPublic }]
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
||||
|
||||
CheckOptions:
|
||||
- key: readability-identifier-naming.ClassCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ClassMemberCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.ConstexprVariableCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ConstexprVariablePrefix
|
||||
value: k
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.EnumConstantCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.EnumConstantPrefix
|
||||
value: k
|
||||
- key: readability-identifier-naming.FunctionCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.GlobalConstantCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.GlobalConstantPrefix
|
||||
value: k
|
||||
- key: readability-identifier-naming.StaticConstantCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.StaticConstantPrefix
|
||||
value: k
|
||||
- key: readability-identifier-naming.StaticVariableCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.MacroDefinitionCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.MacroDefinitionIgnoredRegexp
|
||||
value: '^[A-Z]+(_[A-Z]+)*_$'
|
||||
- key: readability-identifier-naming.MemberCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.PrivateMemberSuffix
|
||||
value: _
|
||||
- key: readability-identifier-naming.PublicMemberSuffix
|
||||
value: ''
|
||||
- key: readability-identifier-naming.NamespaceCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.ParameterCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.TypeAliasCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.TypedefCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.IgnoreMainLikeFunctions
|
||||
value: 1
|
79
.github/workflows/deploy.yml
vendored
79
.github/workflows/deploy.yml
vendored
@ -1,6 +1,6 @@
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Workflow configuration
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
name: Deploy
|
||||
on:
|
||||
@ -12,9 +12,9 @@ on:
|
||||
paths-ignore: # File-patterns to ignore
|
||||
- '**.md' # Ignore changes to *.md files
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Define application name & version
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
env:
|
||||
VERSION: "2.0.0"
|
||||
@ -26,14 +26,14 @@ env:
|
||||
QML_DIR_WIN: "assets\\qml"
|
||||
PUBLISHER: "Alex Spataru"
|
||||
REPO_DIR: "/home/runner/work/Serial-Studio"
|
||||
QT_VERSION: 6.6.2
|
||||
QT_MODULES: qtserialport qtconnectivity qt5compat qtpositioning qtlocation
|
||||
QT_VERSION: 6.7.0
|
||||
QT_MODULES: qtserialport qtconnectivity qtpositioning qtlocation
|
||||
QMAKE: qmake6
|
||||
CORES: 16
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Workflow jobs (GNU/Linux, macOS & Windows)
|
||||
#--------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
jobs:
|
||||
#
|
||||
@ -60,12 +60,15 @@ jobs:
|
||||
- name: '⚙️ Install dependencies'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install libgl1-mesa-dev libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libzstd-dev libxcb-image0-dev libxcb-util0-dev libxcb-cursor-dev
|
||||
sudo apt-get install libgl1-mesa-dev libxkbcommon-x11-0 libxcb-icccm4 \
|
||||
libxcb-image0 libxcb-keysyms1 libxcb-render-util0 \
|
||||
libxcb-xinerama0 libzstd-dev libxcb-image0-dev \
|
||||
libxcb-util0-dev libxcb-cursor-dev
|
||||
|
||||
- name: '🚧 Compile application'
|
||||
run: |
|
||||
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr
|
||||
make -j${{env.CORES}}
|
||||
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr
|
||||
make -j${{env.CORES}}
|
||||
|
||||
- name: '⚙️ Install linuxdeploy'
|
||||
run: |
|
||||
@ -109,24 +112,58 @@ jobs:
|
||||
version: ${{env.QT_VERSION}}
|
||||
modules: ${{env.QT_MODULES}}
|
||||
cache: true
|
||||
arch: clang_64
|
||||
install-deps: 'true'
|
||||
|
||||
- name: '⚙️ Install Node'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
|
||||
- name: '🚧 Compile application'
|
||||
run: |
|
||||
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr
|
||||
make -j${{env.CORES}}
|
||||
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release
|
||||
make -j${{env.CORES}}
|
||||
|
||||
- name: '📦 Package application (macdeployqt and zipfile)'
|
||||
- name: '📦 Package application'
|
||||
run: |
|
||||
macdeployqt ${{env.EXECUTABLE}}.app -qmldir="${{env.QML_DIR_NIX}}"
|
||||
mv "${{env.EXECUTABLE}}.app" "${{env.APPLICATION}}.app"
|
||||
ditto -c -k --sequesterRsrc --keepParent "${{env.APPLICATION}}.app" ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip
|
||||
|
||||
- name: '📤 Upload artifact: ZIP'
|
||||
uses: actions/upload-artifact@v2
|
||||
- name: '🪪 Import Code Signing Certificate'
|
||||
uses: apple-actions/import-codesign-certs@v2
|
||||
with:
|
||||
name: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip
|
||||
path: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip
|
||||
p12-file-base64: ${{secrets.CERTIFICATES_P12}}
|
||||
p12-password: ${{secrets.CERTIFICATES_P12_PASSWORD}}
|
||||
|
||||
- name: '✍🏻 Sign Application'
|
||||
run: codesign --force --deep --options runtime --sign "${{secrets.DEVELOPER_ID}}" "${{env.APPLICATION}}.app"
|
||||
|
||||
- name: '💽 Create nice DMG'
|
||||
run: |
|
||||
npm install --global create-dmg
|
||||
rm LICENSE.md
|
||||
create-dmg "${{env.APPLICATION}}.app" --dmg-title="${{env.APPLICATION}}"
|
||||
mv "${{env.APPLICATION}} ${{env.VERSION}}.dmg" "${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg"
|
||||
|
||||
- name: '📋 Notarize'
|
||||
uses: alex-spataru/xcode-notarize@v2
|
||||
with:
|
||||
product-path: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg
|
||||
appstore-connect-username: ${{secrets.NOTARIZATION_USERNAME}}
|
||||
appstore-connect-teamid: ${{secrets.NOTARIZATION_TEAMID}}
|
||||
appstore-connect-password: ${{secrets.NOTARIZATION_PASSWORD}}
|
||||
|
||||
- name: '📌 Staple'
|
||||
uses: BoundfoxStudios/action-xcode-staple@v1
|
||||
with:
|
||||
product-path: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg
|
||||
|
||||
- name: '📤 Upload artifact: DMG'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg
|
||||
path: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg
|
||||
|
||||
#
|
||||
# Windows build
|
||||
@ -259,7 +296,9 @@ jobs:
|
||||
name: msys2-pkgs
|
||||
path: msys2/*.zst
|
||||
|
||||
#
|
||||
# Test Windows MSYS2 packages
|
||||
#
|
||||
msys2-test:
|
||||
if: ${{false}}
|
||||
needs: msys2-makepkg
|
||||
@ -324,6 +363,6 @@ jobs:
|
||||
wget -q https://github.com/TheAssassin/pyuploadtool/releases/download/continuous/pyuploadtool-x86_64.AppImage
|
||||
chmod +x pyuploadtool-x86_64.AppImage
|
||||
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-Linux.AppImage
|
||||
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip
|
||||
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.dmg
|
||||
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-Windows.exe
|
||||
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-Windows.zip
|
||||
|
12
.gitignore
vendored
12
.gitignore
vendored
@ -4,8 +4,11 @@
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# SciTools understand
|
||||
Serial-Studio.und
|
||||
# Build & IDEs
|
||||
*.kdev*
|
||||
build/*
|
||||
*.vscode
|
||||
*.layout
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
@ -31,3 +34,8 @@ Temporary Items
|
||||
|
||||
# Qt project file
|
||||
*.pro.user
|
||||
*.user
|
||||
|
||||
# Clion
|
||||
.idea/*
|
||||
cmake-build-*
|
||||
|
@ -20,9 +20,9 @@
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Make options
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
UI_DIR = uic
|
||||
MOC_DIR = moc
|
||||
@ -33,15 +33,15 @@ isEmpty(PREFIX) {
|
||||
PREFIX = /usr
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Qt configuration
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
TEMPLATE = app # Project template
|
||||
TARGET = serial-studio # Set default target name
|
||||
CONFIG += qtquickcompiler # Pre-compile QML interface
|
||||
CONFIG += utf8_source # Source code encoding
|
||||
QTPLUGIN += qsvg # Fixes issues with windeployqt
|
||||
TEMPLATE = app
|
||||
TARGET = serial-studio
|
||||
CONFIG += qtquickcompiler
|
||||
CONFIG += utf8_source
|
||||
QTPLUGIN += qsvg
|
||||
|
||||
QT += xml
|
||||
QT += svg
|
||||
@ -56,15 +56,9 @@ QT += printsupport
|
||||
|
||||
QT += quickcontrols2
|
||||
|
||||
equals(QT_MAJOR_VERSION, 6) {
|
||||
QT += core5compat
|
||||
}
|
||||
|
||||
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Compiler options
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
CONFIG += c++11
|
||||
CONFIG += silent
|
||||
@ -79,68 +73,64 @@ CONFIG(release, debug|release) {
|
||||
}
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Serial Studio compile-time settings
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
DEFINES += SERIAL_STUDIO_INCLUDE_MOC
|
||||
#DEFINES += DISABLE_QS # If enabled, QSimpleUpdater shall not be used by the app
|
||||
# This is the default behaviour for MinGW.
|
||||
|
||||
#DEFINES += DISABLE_QSU # If enabled, QSimpleUpdater shall not be used by the app.
|
||||
# This is the default behaviour for MinGW.
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Libraries
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
include(libs/Libraries.pri)
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Assets
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
include(assets/Assets.pri)
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Deploy options
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
win32* {
|
||||
TARGET = SerialStudio # Change target name
|
||||
RC_FILE = deploy/windows/resources/info.rc # Set applicaiton icon
|
||||
OTHER_FILES += deploy/windows/nsis/setup.nsi # Setup script
|
||||
TARGET = SerialStudio
|
||||
RC_FILE = deploy/windows/resources/info.rc
|
||||
OTHER_FILES += deploy/windows/nsis/setup.nsi
|
||||
}
|
||||
|
||||
macx* {
|
||||
TARGET = SerialStudio # Change target name
|
||||
ICON = deploy/macOS/icon.icns # icon file
|
||||
RC_FILE = deploy/macOS/icon.icns # icon file
|
||||
QMAKE_INFO_PLIST = deploy/macOS/info.plist # Add info.plist file
|
||||
CONFIG += sdk_no_version_check # Avoid warnings with Big Sur
|
||||
TARGET = SerialStudio
|
||||
ICON = deploy/macOS/icon.icns
|
||||
RC_FILE = deploy/macOS/icon.icns
|
||||
QMAKE_INFO_PLIST = deploy/macOS/info.plist
|
||||
CONFIG += sdk_no_version_check
|
||||
}
|
||||
|
||||
linux:!android {
|
||||
PKGCONFIG += libssl # Add OpenSSL library
|
||||
target.path = $$PREFIX/bin # Set binary installation path
|
||||
icon.path = $$PREFIX/share/pixmaps # icon instalation path
|
||||
desktop.path = $$PREFIX/share/applications # *.desktop instalation path
|
||||
icon.files += deploy/linux/serial-studio.png # Add application icon
|
||||
desktop.files += deploy/linux/serial-studio.desktop # Add *.desktop file
|
||||
copyright.files += deploy/linux/copyright # Libc6 file for linuxdeployqt
|
||||
copyright.path = $$PREFIX/share/doc/libc6 # libc6 copyright path
|
||||
INSTALLS += target copyright desktop icon # make install targets
|
||||
PKGCONFIG += libssl
|
||||
target.path = $$PREFIX/bin
|
||||
icon.path = $$PREFIX/share/pixmaps
|
||||
desktop.path = $$PREFIX/share/applications
|
||||
icon.files += deploy/linux/serial-studio.png
|
||||
desktop.files += deploy/linux/serial-studio.desktop
|
||||
INSTALLS += target copyright desktop icon
|
||||
}
|
||||
|
||||
mingw {
|
||||
target.path = $$PREFIX/bin
|
||||
license.path = $$PREFIX/share/licenses/$$TARGET # Set license install path
|
||||
license.files += LICENSE.md # Add LICENSE.md file
|
||||
INSTALLS += target license # Install target+licence (MSYS2)
|
||||
DEFINES += DISABLE_QSU # Disable QSimpleUpdater (MSYS2)
|
||||
license.path = $$PREFIX/share/licenses/$$TARGET
|
||||
license.files += LICENSE.md
|
||||
INSTALLS += target license
|
||||
DEFINES += DISABLE_QSU
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Import source code
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
INCLUDEPATH += src
|
||||
|
||||
@ -161,7 +151,6 @@ HEADERS += \
|
||||
src/JSON/Generator.h \
|
||||
src/JSON/Group.h \
|
||||
src/MQTT/Client.h \
|
||||
src/Misc/MacExtras.h \
|
||||
src/Misc/ModuleManager.h \
|
||||
src/Misc/ThemeManager.h \
|
||||
src/Misc/TimerEvents.h \
|
||||
@ -205,7 +194,6 @@ SOURCES += \
|
||||
src/JSON/Generator.cpp \
|
||||
src/JSON/Group.cpp \
|
||||
src/MQTT/Client.cpp \
|
||||
src/Misc/MacExtras.cpp \
|
||||
src/Misc/ModuleManager.cpp \
|
||||
src/Misc/ThemeManager.cpp \
|
||||
src/Misc/TimerEvents.cpp \
|
||||
@ -236,9 +224,9 @@ SOURCES += \
|
||||
src/UI/Widgets/Terminal.cpp \
|
||||
src/main.cpp
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Import QML source code
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
DISTFILES += \
|
||||
assets/qml/*.qml \
|
||||
@ -252,9 +240,9 @@ DISTFILES += \
|
||||
assets/qml/PlatformDependent/*.qml \
|
||||
assets/qml/Panes/SetupPanes/Devices/*.qml \
|
||||
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# Deploy files
|
||||
#-----------------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
OTHER_FILES += \
|
||||
deploy/linux/* \
|
||||
|
@ -57,6 +57,7 @@
|
||||
<file>icons/multiplot.svg</file>
|
||||
<file>icons/new.svg</file>
|
||||
<file>icons/open.svg</file>
|
||||
<file>icons/paste.svg</file>
|
||||
<file>icons/plot.svg</file>
|
||||
<file>icons/points.svg</file>
|
||||
<file>icons/power.svg</file>
|
||||
@ -131,6 +132,7 @@
|
||||
<file>qml/ProjectEditor/JsonDatasetDelegate.qml</file>
|
||||
<file>qml/ProjectEditor/JsonGroupDelegate.qml</file>
|
||||
<file>qml/ProjectEditor/TreeView.qml</file>
|
||||
<file>qml/Widgets/GpsMap.qml</file>
|
||||
<file>qml/Widgets/Icon.qml</file>
|
||||
<file>qml/Widgets/JSONDropArea.qml</file>
|
||||
<file>qml/Widgets/Shadow.qml</file>
|
||||
@ -144,15 +146,13 @@
|
||||
<file>qml/Windows/MQTTConfiguration.qml</file>
|
||||
<file>qml/Windows/ProjectEditor.qml</file>
|
||||
<file>qml/main.qml</file>
|
||||
<file>scripts/frame-parser.js</file>
|
||||
<file>themes/1_Flat.json</file>
|
||||
<file>themes/2_Dark.json</file>
|
||||
<file>themes/3_Classic.json</file>
|
||||
<file>themes/4_Midnight.json</file>
|
||||
<file>themes/5_Noir.json</file>
|
||||
<file>themes/6_Mathworks.json</file>
|
||||
<file>touchbar/console.png</file>
|
||||
<file>touchbar/dashboard.png</file>
|
||||
<file>touchbar/setup.png</file>
|
||||
<file>translations/de.qm</file>
|
||||
<file>translations/de.ts</file>
|
||||
<file>translations/en.qm</file>
|
||||
@ -178,8 +178,5 @@
|
||||
<file>window-border/minimize.svg</file>
|
||||
<file>window-border/restore.svg</file>
|
||||
<file>window-border/unmaximize.svg</file>
|
||||
<file>icons/paste.svg</file>
|
||||
<file>scripts/frame-parser.js</file>
|
||||
<file>qml/Widgets/GpsMap.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -74,26 +74,6 @@ 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.
|
||||
|
||||
## QMapControl
|
||||
|
||||
Copyright (C) 2007 - 2008 Kai Winter
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with QMapControl. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Contact e-mail: kaiwinter@gmx.de
|
||||
Program URL : http://qmapcontrol.sourceforge.net/
|
||||
|
||||
## qtcsv
|
||||
|
||||
Copyright © 2015 Antony Cherepanov (antony.cherepanov@gmail.com)
|
||||
@ -731,13 +711,6 @@ Everyone is permitted to copy and distribute copies of this Agreement, but in or
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
|
||||
|
||||
## KDMacTouchBar
|
||||
|
||||
KDMacTouchBar is Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB.
|
||||
|
||||
You may use, distribute and copy KDMacTouchBar under the terms of GNU Lesser General Public License version 3, which is displayed below.
|
||||
|
||||
You may even contact us at info@kdab.com for different licensing options.
|
||||
|
||||
### GNU Lesser General Public License
|
||||
|
||||
|
@ -24,5 +24,5 @@ MCU-Projekten, lesen Sie bitte das Wiki:
|
||||
|
||||
→ https://github.com/Serial-Studio/Serial-Studio/wiki
|
||||
|
||||
Tipp: Verwenden Sie den JSON-Editor zum Erstellen und Bearbeiten von
|
||||
Tipp: Verwenden Sie den Projekt-Editor zum Erstellen und Bearbeiten von
|
||||
Serial Studio-Projektdateien.
|
||||
|
@ -22,4 +22,4 @@ the wiki:
|
||||
|
||||
→ https://github.com/Serial-Studio/Serial-Studio/wiki
|
||||
|
||||
Tip: use the JSON Editor to create and edit Serial Studio project files.
|
||||
Tip: use the Project Editor to create and edit Serial Studio project files.
|
||||
|
@ -22,4 +22,4 @@ actuales, por favor lea la wiki:
|
||||
|
||||
→ https://github.com/Serial-Studio/Serial-Studio/wiki
|
||||
|
||||
Consejo: utilice el Editor JSON para crear y editar proyectos de Serial Studio.
|
||||
Consejo: utilice el Editor de Proyectos para crear y editar proyectos de Serial Studio.
|
||||
|
@ -28,69 +28,69 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
radius: 5
|
||||
id: root
|
||||
radius: 5
|
||||
|
||||
property alias consoleChecked: consoleBt.checked
|
||||
property alias consoleChecked: consoleBt.checked
|
||||
|
||||
Settings {
|
||||
property alias consoleVisible: root.consoleChecked
|
||||
Settings {
|
||||
property alias consoleVisible: root.consoleChecked
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: Cpp_ThemeManager.windowGradient1
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: Cpp_ThemeManager.windowGradient1
|
||||
}
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: Cpp_ThemeManager.windowGradient2
|
||||
}
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: Cpp_ThemeManager.windowGradient2
|
||||
}
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
anchors {
|
||||
margins: 0
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: app.spacing
|
||||
rightMargin: app.spacing
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
anchors {
|
||||
margins: 0
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: app.spacing
|
||||
rightMargin: app.spacing
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Widgets.Icon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/icons/arrow-right.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
color: palette.brightText
|
||||
font.family: app.monoFont
|
||||
text: Cpp_UI_Dashboard.title
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
id: consoleBt
|
||||
checkable: true
|
||||
font.bold: true
|
||||
text: qsTr("Console")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.windowGradient1
|
||||
palette.window: Cpp_ThemeManager.windowGradient1
|
||||
}
|
||||
Widgets.Icon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/icons/arrow-right.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
color: palette.brightText
|
||||
font.family: app.monoFont
|
||||
text: Cpp_UI_Dashboard.title
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
id: consoleBt
|
||||
checkable: true
|
||||
font.bold: true
|
||||
text: qsTr("Console")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.windowGradient1
|
||||
palette.window: Cpp_ThemeManager.windowGradient1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,307 +28,307 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Widgets.Window {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
gradient: true
|
||||
title: qsTr("View")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/visibility.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal widgetSizeChanged(var maxSize)
|
||||
|
||||
//
|
||||
// Maps the slider position to points
|
||||
// https://stackoverflow.com/a/846249
|
||||
//
|
||||
function logslider(position) {
|
||||
var minp = 0
|
||||
var maxp = 100
|
||||
var minv = Math.log(10)
|
||||
var maxv = Math.log(10000)
|
||||
var scale = (maxv - minv) / (maxp - minp);
|
||||
return Math.exp(minv + scale * (position - minp)).toFixed(0);
|
||||
}
|
||||
|
||||
//
|
||||
// Maps the points value to the slider position
|
||||
// https://stackoverflow.com/a/846249
|
||||
//
|
||||
function logposition(value) {
|
||||
var minp = 0
|
||||
var maxp = 100
|
||||
var minv = Math.log(10)
|
||||
var maxv = Math.log(10000)
|
||||
var scale = (maxv - minv) / (maxp - minp)
|
||||
var result = (Math.log(value) - minv) / scale + minp;
|
||||
return result.toFixed(0)
|
||||
}
|
||||
|
||||
//
|
||||
// Settings
|
||||
//
|
||||
Settings {
|
||||
property alias points: plotPoints.value
|
||||
property alias widgetSize: widgetSize.value
|
||||
property alias decimalPlaces: decimalPlaces.value
|
||||
}
|
||||
|
||||
//
|
||||
// Put all items inside a scrollview
|
||||
//
|
||||
ScrollView {
|
||||
clip: true
|
||||
contentWidth: -1
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
anchors.topMargin: root.borderWidth
|
||||
anchors.bottomMargin: root.borderWidth
|
||||
|
||||
//
|
||||
// Window properties
|
||||
// Main layout
|
||||
//
|
||||
gradient: true
|
||||
title: qsTr("View")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/visibility.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
x: app.spacing
|
||||
spacing: app.spacing / 2
|
||||
width: parent.width - 10 - 2 * app.spacing
|
||||
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal widgetSizeChanged(var maxSize)
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Maps the slider position to points
|
||||
// https://stackoverflow.com/a/846249
|
||||
//
|
||||
function logslider(position) {
|
||||
var minp = 0
|
||||
var maxp = 100
|
||||
var minv = Math.log(10)
|
||||
var maxv = Math.log(10000)
|
||||
var scale = (maxv - minv) / (maxp - minp);
|
||||
return Math.exp(minv + scale * (position - minp)).toFixed(0);
|
||||
}
|
||||
//
|
||||
// View options title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
|
||||
//
|
||||
// Maps the points value to the slider position
|
||||
// https://stackoverflow.com/a/846249
|
||||
//
|
||||
function logposition(value) {
|
||||
var minp = 0
|
||||
var maxp = 100
|
||||
var minv = Math.log(10)
|
||||
var maxv = Math.log(10000)
|
||||
var scale = (maxv - minv) / (maxp - minp)
|
||||
var result = (Math.log(value) - minv) / scale + minp;
|
||||
return result.toFixed(0)
|
||||
}
|
||||
|
||||
//
|
||||
// Settings
|
||||
//
|
||||
Settings {
|
||||
property alias points: plotPoints.value
|
||||
property alias widgetSize: widgetSize.value
|
||||
property alias decimalPlaces: decimalPlaces.value
|
||||
}
|
||||
|
||||
//
|
||||
// Put all items inside a scrollview
|
||||
//
|
||||
ScrollView {
|
||||
clip: true
|
||||
contentWidth: -1
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
anchors.topMargin: root.borderWidth
|
||||
anchors.bottomMargin: root.borderWidth
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
x: app.spacing
|
||||
spacing: app.spacing / 2
|
||||
width: parent.width - 10 - 2 * app.spacing
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// View options title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: palette.text
|
||||
source: "qrc:/icons/visibility.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: qsTr("Visualization options")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Visualization controls
|
||||
//
|
||||
GridLayout {
|
||||
columns: 3
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Number of plot points slider
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Points:")
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
} Slider {
|
||||
id: plotPoints
|
||||
from: 0
|
||||
to: 100
|
||||
Layout.fillWidth: true
|
||||
value: logposition(100)
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
onValueChanged: {
|
||||
var log = logslider(value)
|
||||
if (Cpp_UI_Dashboard.points !== log)
|
||||
Cpp_UI_Dashboard.points = log
|
||||
}
|
||||
} Label {
|
||||
text: logslider(plotPoints.value)
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
}
|
||||
|
||||
//
|
||||
// Number of decimal places
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Decimal places:")
|
||||
} Slider {
|
||||
id: decimalPlaces
|
||||
to: 6
|
||||
from: 0
|
||||
value: 2
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: Cpp_UI_Dashboard.precision = value
|
||||
} Label {
|
||||
text: Cpp_UI_Dashboard.precision
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Number of plot points slider
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Widget size:")
|
||||
} Slider {
|
||||
id: widgetSize
|
||||
to: 720
|
||||
from: 400
|
||||
value: 480
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: widgetSizeChanged(value)
|
||||
} Item {}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Groups
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Datasets")
|
||||
icon: "qrc:/icons/group.svg"
|
||||
count: Cpp_UI_Dashboard.groupCount
|
||||
titles: Cpp_UI_Dashboard.groupTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGroupVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Multiplots
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Multiple data plots")
|
||||
icon: "qrc:/icons/multiplot.svg"
|
||||
count: Cpp_UI_Dashboard.multiPlotCount
|
||||
titles: Cpp_UI_Dashboard.multiPlotTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setMultiplotVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// LEDs
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("LED Panels")
|
||||
icon: "qrc:/icons/led.svg"
|
||||
count: Cpp_UI_Dashboard.ledCount
|
||||
titles: Cpp_UI_Dashboard.ledTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setLedVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// FFT
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("FFT plots")
|
||||
icon: "qrc:/icons/fft.svg"
|
||||
count: Cpp_UI_Dashboard.fftCount
|
||||
titles: Cpp_UI_Dashboard.fftTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setFFTVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Plots
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Data plots")
|
||||
icon: "qrc:/icons/plot.svg"
|
||||
count: Cpp_UI_Dashboard.plotCount
|
||||
titles: Cpp_UI_Dashboard.plotTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setPlotVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Bars
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Bars")
|
||||
icon: "qrc:/icons/bar.svg"
|
||||
count: Cpp_UI_Dashboard.barCount
|
||||
titles: Cpp_UI_Dashboard.barTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setBarVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Gauges
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Gauges")
|
||||
icon: "qrc:/icons/gauge.svg"
|
||||
count: Cpp_UI_Dashboard.gaugeCount
|
||||
titles: Cpp_UI_Dashboard.gaugeTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGaugeVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Compasses
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Compasses")
|
||||
icon: "qrc:/icons/compass.svg"
|
||||
count: Cpp_UI_Dashboard.compassCount
|
||||
titles: Cpp_UI_Dashboard.compassTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setCompassVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Gyroscopes
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Gyroscopes")
|
||||
icon: "qrc:/icons/gyro.svg"
|
||||
count: Cpp_UI_Dashboard.gyroscopeCount
|
||||
titles: Cpp_UI_Dashboard.gyroscopeTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGyroscopeVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Accelerometers
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Accelerometers")
|
||||
icon: "qrc:/icons/accelerometer.svg"
|
||||
count: Cpp_UI_Dashboard.accelerometerCount
|
||||
titles: Cpp_UI_Dashboard.accelerometerTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setAccelerometerVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Maps
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("GPS")
|
||||
icon: "qrc:/icons/gps.svg"
|
||||
count: Cpp_UI_Dashboard.gpsCount
|
||||
titles: Cpp_UI_Dashboard.gpsTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGpsVisible(index, checked)
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: palette.text
|
||||
source: "qrc:/icons/visibility.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: qsTr("Visualization options")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Visualization controls
|
||||
//
|
||||
GridLayout {
|
||||
columns: 3
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Number of plot points slider
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Points:")
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
} Slider {
|
||||
id: plotPoints
|
||||
from: 0
|
||||
to: 100
|
||||
Layout.fillWidth: true
|
||||
value: logposition(100)
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
onValueChanged: {
|
||||
var log = logslider(value)
|
||||
if (Cpp_UI_Dashboard.points !== log)
|
||||
Cpp_UI_Dashboard.points = log
|
||||
}
|
||||
} Label {
|
||||
text: logslider(plotPoints.value)
|
||||
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
|
||||
}
|
||||
|
||||
//
|
||||
// Number of decimal places
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Decimal places:")
|
||||
} Slider {
|
||||
id: decimalPlaces
|
||||
to: 6
|
||||
from: 0
|
||||
value: 2
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: Cpp_UI_Dashboard.precision = value
|
||||
} Label {
|
||||
text: Cpp_UI_Dashboard.precision
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Number of plot points slider
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Widget size:")
|
||||
} Slider {
|
||||
id: widgetSize
|
||||
to: 720
|
||||
from: 400
|
||||
value: 480
|
||||
Layout.fillWidth: true
|
||||
onValueChanged: widgetSizeChanged(value)
|
||||
} Item {}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Groups
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Datasets")
|
||||
icon: "qrc:/icons/group.svg"
|
||||
count: Cpp_UI_Dashboard.groupCount
|
||||
titles: Cpp_UI_Dashboard.groupTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGroupVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Multiplots
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Multiple data plots")
|
||||
icon: "qrc:/icons/multiplot.svg"
|
||||
count: Cpp_UI_Dashboard.multiPlotCount
|
||||
titles: Cpp_UI_Dashboard.multiPlotTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setMultiplotVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// LEDs
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("LED Panels")
|
||||
icon: "qrc:/icons/led.svg"
|
||||
count: Cpp_UI_Dashboard.ledCount
|
||||
titles: Cpp_UI_Dashboard.ledTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setLedVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// FFT
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("FFT plots")
|
||||
icon: "qrc:/icons/fft.svg"
|
||||
count: Cpp_UI_Dashboard.fftCount
|
||||
titles: Cpp_UI_Dashboard.fftTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setFFTVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Plots
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Data plots")
|
||||
icon: "qrc:/icons/plot.svg"
|
||||
count: Cpp_UI_Dashboard.plotCount
|
||||
titles: Cpp_UI_Dashboard.plotTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setPlotVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Bars
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Bars")
|
||||
icon: "qrc:/icons/bar.svg"
|
||||
count: Cpp_UI_Dashboard.barCount
|
||||
titles: Cpp_UI_Dashboard.barTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setBarVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Gauges
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Gauges")
|
||||
icon: "qrc:/icons/gauge.svg"
|
||||
count: Cpp_UI_Dashboard.gaugeCount
|
||||
titles: Cpp_UI_Dashboard.gaugeTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGaugeVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Compasses
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Compasses")
|
||||
icon: "qrc:/icons/compass.svg"
|
||||
count: Cpp_UI_Dashboard.compassCount
|
||||
titles: Cpp_UI_Dashboard.compassTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setCompassVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Gyroscopes
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Gyroscopes")
|
||||
icon: "qrc:/icons/gyro.svg"
|
||||
count: Cpp_UI_Dashboard.gyroscopeCount
|
||||
titles: Cpp_UI_Dashboard.gyroscopeTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGyroscopeVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Accelerometers
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("Accelerometers")
|
||||
icon: "qrc:/icons/accelerometer.svg"
|
||||
count: Cpp_UI_Dashboard.accelerometerCount
|
||||
titles: Cpp_UI_Dashboard.accelerometerTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setAccelerometerVisible(index, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Maps
|
||||
//
|
||||
ViewOptionsDelegate {
|
||||
title: qsTr("GPS")
|
||||
icon: "qrc:/icons/gps.svg"
|
||||
count: Cpp_UI_Dashboard.gpsCount
|
||||
titles: Cpp_UI_Dashboard.gpsTitles
|
||||
onCheckedChanged: Cpp_UI_Dashboard.setGpsVisible(index, checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,76 +5,76 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
visible: count > 0
|
||||
id: root
|
||||
visible: count > 0
|
||||
spacing: app.spacing
|
||||
|
||||
property int count: 0
|
||||
property var titles:[""]
|
||||
property string icon: ""
|
||||
property string title: ""
|
||||
|
||||
signal checkedChanged(var index, var checked)
|
||||
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onDataReset() {
|
||||
hideAll.checked = false
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: root.count > 0
|
||||
|
||||
property int count: 0
|
||||
property var titles:[""]
|
||||
property string icon: ""
|
||||
property string title: ""
|
||||
|
||||
signal checkedChanged(var index, var checked)
|
||||
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onDataReset() {
|
||||
hideAll.checked = false
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
source: root.icon
|
||||
color: palette.text
|
||||
opacity: hideAll.checked ? 0.5 : 1
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: root.count > 0
|
||||
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
source: root.icon
|
||||
color: palette.text
|
||||
opacity: hideAll.checked ? 0.5 : 1
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: root.title
|
||||
opacity: hideAll.checked ? 0.5 : 1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: hideAll
|
||||
width: 24
|
||||
height: 24
|
||||
flat: true
|
||||
checkable: true
|
||||
icon.color: palette.text
|
||||
Layout.rightMargin: -app.spacing
|
||||
icon.source: checked ? "qrc:/icons/show-all.svg" : "qrc:/icons/hide-all.svg"
|
||||
onCheckedChanged: {
|
||||
for (var i = 0; i < root.count; ++i)
|
||||
root.checkedChanged(i, !checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: hideAll.checked ? 0 : root.count
|
||||
delegate: Switch {
|
||||
checked: true
|
||||
Layout.fillWidth: true
|
||||
text: root.titles[index]
|
||||
onCheckedChanged: root.checkedChanged(index, checked)
|
||||
palette.highlight: Cpp_ThemeManager.alternativeHighlight
|
||||
}
|
||||
Label {
|
||||
font.bold: true
|
||||
text: root.title
|
||||
opacity: hideAll.checked ? 0.5 : 1
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
visible: !hideAll.checked && count > 0
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
id: hideAll
|
||||
width: 24
|
||||
height: 24
|
||||
flat: true
|
||||
checkable: true
|
||||
icon.color: palette.text
|
||||
Layout.rightMargin: -app.spacing
|
||||
icon.source: checked ? "qrc:/icons/show-all.svg" : "qrc:/icons/hide-all.svg"
|
||||
onCheckedChanged: {
|
||||
for (var i = 0; i < root.count; ++i)
|
||||
root.checkedChanged(i, !checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: hideAll.checked ? 0 : root.count
|
||||
delegate: Switch {
|
||||
checked: true
|
||||
Layout.fillWidth: true
|
||||
text: root.titles[index]
|
||||
onCheckedChanged: root.checkedChanged(index, checked)
|
||||
palette.highlight: Cpp_ThemeManager.alternativeHighlight
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
visible: !hideAll.checked && count > 0
|
||||
}
|
||||
}
|
||||
|
@ -30,125 +30,125 @@ import "../Widgets" as Widgets
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property int widgetIndex: -1
|
||||
property FramelessWindow.CustomWindow externalWindow: null
|
||||
property int widgetIndex: -1
|
||||
property FramelessWindow.CustomWindow externalWindow: null
|
||||
|
||||
Widgets.Window {
|
||||
id: window
|
||||
Widgets.Window {
|
||||
id: window
|
||||
anchors.fill: parent
|
||||
title: widget.widgetTitle
|
||||
icon.source: widget.widgetIcon
|
||||
headerDoubleClickEnabled: true
|
||||
borderColor: Cpp_ThemeManager.widgetWindowBorder
|
||||
onHeaderDoubleClicked: {
|
||||
if (root.externalWindow !== null)
|
||||
root.externalWindow.showNormal()
|
||||
else
|
||||
externalWindowLoader.active = true
|
||||
}
|
||||
|
||||
DashboardWidget {
|
||||
id: widget
|
||||
widgetIndex: root.widgetIndex
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: window.borderWidth
|
||||
rightMargin: window.borderWidth
|
||||
bottomMargin: window.borderWidth
|
||||
}
|
||||
|
||||
//
|
||||
// Hack: render a GPS map using QML code instead of QtWidgets
|
||||
//
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
title: widget.widgetTitle
|
||||
icon.source: widget.widgetIcon
|
||||
headerDoubleClickEnabled: true
|
||||
borderColor: Cpp_ThemeManager.widgetWindowBorder
|
||||
onHeaderDoubleClicked: {
|
||||
if (root.externalWindow !== null)
|
||||
root.externalWindow.showNormal()
|
||||
else
|
||||
externalWindowLoader.active = true
|
||||
asynchronous: true
|
||||
active: widget.isGpsMap
|
||||
visible: widget.isGpsMap && status == Loader.Ready
|
||||
sourceComponent: Widgets.GpsMap {
|
||||
altitude: widget.gpsAltitude
|
||||
latitude: widget.gpsLatitude
|
||||
longitude: widget.gpsLongitude
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: externalWindowLoader
|
||||
|
||||
active: false
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: FramelessWindow.CustomWindow {
|
||||
id: _window
|
||||
minimumWidth: 640 + shadowMargin
|
||||
minimumHeight: 480 + shadowMargin
|
||||
title: externalWidget.widgetTitle
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
titlebarColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
backgroundColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
borderColor: isMaximized ? backgroundColor : Cpp_ThemeManager.highlight
|
||||
extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 200
|
||||
onTriggered: _window.showNormal()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.externalWindow = this
|
||||
timer.start()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
radius: _window.radius
|
||||
anchors.margins: _window.shadowMargin
|
||||
color: Cpp_ThemeManager.widgetWindowBackground
|
||||
anchors.topMargin: _window.titlebar.height + _window.shadowMargin
|
||||
|
||||
Rectangle {
|
||||
height: _window.radius
|
||||
color: Cpp_ThemeManager.widgetWindowBackground
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
DashboardWidget {
|
||||
id: widget
|
||||
widgetIndex: root.widgetIndex
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: window.borderWidth
|
||||
rightMargin: window.borderWidth
|
||||
bottomMargin: window.borderWidth
|
||||
}
|
||||
id: externalWidget
|
||||
anchors.fill: parent
|
||||
isExternalWindow: true
|
||||
widgetIndex: root.widgetIndex
|
||||
widgetVisible: _window.visible
|
||||
anchors.margins: _window.radius
|
||||
|
||||
//
|
||||
// Hack: render a GPS map using QML code instead of QtWidgets
|
||||
//
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
active: widget.isGpsMap
|
||||
visible: widget.isGpsMap && status == Loader.Ready
|
||||
sourceComponent: Widgets.GpsMap {
|
||||
altitude: widget.gpsAltitude
|
||||
latitude: widget.gpsLatitude
|
||||
longitude: widget.gpsLongitude
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: externalWindowLoader
|
||||
|
||||
active: false
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: FramelessWindow.CustomWindow {
|
||||
id: _window
|
||||
minimumWidth: 640 + shadowMargin
|
||||
minimumHeight: 480 + shadowMargin
|
||||
title: externalWidget.widgetTitle
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
titlebarColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
backgroundColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
borderColor: isMaximized ? backgroundColor : Cpp_ThemeManager.highlight
|
||||
extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 200
|
||||
onTriggered: _window.showNormal()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.externalWindow = this
|
||||
timer.start()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
radius: _window.radius
|
||||
anchors.margins: _window.shadowMargin
|
||||
color: Cpp_ThemeManager.widgetWindowBackground
|
||||
anchors.topMargin: _window.titlebar.height + _window.shadowMargin
|
||||
|
||||
Rectangle {
|
||||
height: _window.radius
|
||||
color: Cpp_ThemeManager.widgetWindowBackground
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
DashboardWidget {
|
||||
id: externalWidget
|
||||
anchors.fill: parent
|
||||
isExternalWindow: true
|
||||
widgetIndex: root.widgetIndex
|
||||
widgetVisible: _window.visible
|
||||
anchors.margins: _window.radius
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
active: externalWidget.isGpsMap
|
||||
visible: externalWidget.isGpsMap && status == Loader.Ready
|
||||
sourceComponent: Widgets.GpsMap {
|
||||
altitude: externalWidget.gpsAltitude
|
||||
latitude: externalWidget.gpsLatitude
|
||||
longitude: externalWidget.gpsLongitude
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FramelessWindow.ResizeHandles {
|
||||
window: _window
|
||||
anchors.fill: parent
|
||||
handleSize: _window.handleSize
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
active: externalWidget.isGpsMap
|
||||
visible: externalWidget.isGpsMap && status == Loader.Ready
|
||||
sourceComponent: Widgets.GpsMap {
|
||||
altitude: externalWidget.gpsAltitude
|
||||
latitude: externalWidget.gpsLatitude
|
||||
longitude: externalWidget.gpsLongitude
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FramelessWindow.ResizeHandles {
|
||||
window: _window
|
||||
anchors.fill: parent
|
||||
handleSize: _window.handleSize
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,101 +27,101 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Widgets.Window {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
gradient: true
|
||||
title: qsTr("Data")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/dataset.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
gradient: true
|
||||
title: qsTr("Data")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/dataset.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
// Hacks for calculating cell width
|
||||
property int maxSize: 480
|
||||
readonly property int minSize: maxSize * 356/480
|
||||
readonly property int cellHeight: cellWidth * (2/3)
|
||||
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth)
|
||||
readonly property int cellWidth: cWidth + ((grid.width - 2 * scroll.width) - (cWidth) * columns) / columns
|
||||
readonly property int cWidth: Math.min(Math.max(minSize, (grid.width - 2 * scroll.width) / model.count), maxSize)
|
||||
// Hacks for calculating cell width
|
||||
property int maxSize: 480
|
||||
readonly property int minSize: maxSize * 356/480
|
||||
readonly property int cellHeight: cellWidth * (2/3)
|
||||
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth)
|
||||
readonly property int cellWidth: cWidth + ((grid.width - 2 * scroll.width) - (cWidth) * columns) / columns
|
||||
readonly property int cWidth: Math.min(Math.max(minSize, (grid.width - 2 * scroll.width) / model.count), maxSize)
|
||||
|
||||
//
|
||||
// Put everything into a flickable to enable scrolling
|
||||
//
|
||||
Item {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
//
|
||||
// Put everything into a flickable to enable scrolling
|
||||
//
|
||||
Item {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
|
||||
Flickable {
|
||||
contentWidth: width
|
||||
contentHeight: grid.height
|
||||
Flickable {
|
||||
contentWidth: width
|
||||
contentHeight: grid.height
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: app.spacing * 2
|
||||
rightMargin: app.spacing
|
||||
}
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: app.spacing * 2
|
||||
rightMargin: app.spacing
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scroll
|
||||
}
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scroll
|
||||
}
|
||||
|
||||
Grid {
|
||||
id: grid
|
||||
width: parent.width
|
||||
columns: root.columns
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
height: childrenRect.height
|
||||
Grid {
|
||||
id: grid
|
||||
width: parent.width
|
||||
columns: root.columns
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
height: childrenRect.height
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 200
|
||||
onTriggered: transition.enabled = false
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
function onWidgetVisibilityChanged() {
|
||||
transition.enabled = true
|
||||
timer.start()
|
||||
}
|
||||
}
|
||||
|
||||
move: Transition {
|
||||
id: transition
|
||||
enabled: false
|
||||
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
properties: "x,y"
|
||||
easing.type: Easing.OutSine
|
||||
}
|
||||
}
|
||||
|
||||
WidgetModel {
|
||||
id: model
|
||||
cellWidth: root.cellWidth
|
||||
cellHeight: root.cellHeight
|
||||
model: Cpp_UI_Dashboard.totalWidgetCount
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 200
|
||||
onTriggered: transition.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Redraw bottom window border over flickable items
|
||||
//
|
||||
Rectangle {
|
||||
height: root.borderWidth
|
||||
color: root.gradientColor1
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
leftMargin: root.radius
|
||||
rightMargin: root.radius
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
function onWidgetVisibilityChanged() {
|
||||
transition.enabled = true
|
||||
timer.start()
|
||||
}
|
||||
}
|
||||
|
||||
move: Transition {
|
||||
id: transition
|
||||
enabled: false
|
||||
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
properties: "x,y"
|
||||
easing.type: Easing.OutSine
|
||||
}
|
||||
}
|
||||
|
||||
WidgetModel {
|
||||
id: model
|
||||
cellWidth: root.cellWidth
|
||||
cellHeight: root.cellHeight
|
||||
model: Cpp_UI_Dashboard.totalWidgetCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Redraw bottom window border over flickable items
|
||||
//
|
||||
Rectangle {
|
||||
height: root.borderWidth
|
||||
color: root.gradientColor1
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
leftMargin: root.radius
|
||||
rightMargin: root.radius
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,27 +23,27 @@
|
||||
import QtQuick
|
||||
|
||||
Repeater {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property real cellWidth: 0
|
||||
property real cellHeight: 0
|
||||
property real cellWidth: 0
|
||||
property real cellHeight: 0
|
||||
|
||||
delegate: Loader {
|
||||
id: loader
|
||||
asynchronous: true
|
||||
width: root.cellWidth
|
||||
height: root.cellHeight
|
||||
delegate: Loader {
|
||||
id: loader
|
||||
asynchronous: true
|
||||
width: root.cellWidth
|
||||
height: root.cellHeight
|
||||
|
||||
sourceComponent: WidgetDelegate {
|
||||
widgetIndex: index
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onWidgetVisibilityChanged() {
|
||||
loader.visible = Cpp_UI_Dashboard.widgetVisible(index)
|
||||
}
|
||||
}
|
||||
sourceComponent: WidgetDelegate {
|
||||
widgetIndex: index
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onWidgetVisibilityChanged() {
|
||||
loader.visible = Cpp_UI_Dashboard.widgetVisible(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,304 +26,304 @@ import QtQuick.Window as QtWindow
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
QtWindow.Window {
|
||||
id: root
|
||||
id: root
|
||||
color: "transparent"
|
||||
flags: (Cpp_ThemeManager.customWindowDecorations ? root.customFlags : Qt.Window) | root.extraFlags
|
||||
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal closed()
|
||||
signal minimized()
|
||||
signal maximized()
|
||||
signal unmaximized()
|
||||
|
||||
//
|
||||
// Connections with the theme manager for enabling/disabling frameless window
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_ThemeManager
|
||||
|
||||
function onCustomWindowDecorationsChanged() {
|
||||
if (Cpp_ThemeManager.customWindowDecorations)
|
||||
root.flags = root.customFlags | root.extraFlags
|
||||
else
|
||||
root.flags = Qt.Window | root.extraFlags
|
||||
|
||||
var prevVisible = root.visible
|
||||
root.visible = false
|
||||
root.visible = prevVisible
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window radius control
|
||||
//
|
||||
property int borderWidth: Cpp_ThemeManager.customWindowDecorations ? 2 : 0
|
||||
readonly property int handleSize: radius > 0 ? radius + shadowMargin + 10 : 0
|
||||
readonly property int radius: Cpp_ThemeManager.customWindowDecorations ?
|
||||
(((root.visibility === QtWindow.Window.Maximized &&
|
||||
maximizeEnabled) || isFullscreen) ? 0 : 10) : 0
|
||||
|
||||
//
|
||||
// Visibility properties
|
||||
//
|
||||
property int extraFlags: 0
|
||||
property bool firstChange: true
|
||||
property bool isMaximized: false
|
||||
property bool isMinimized: false
|
||||
property alias showIcon: _title.showIcon
|
||||
property alias isFullscreen: _title.isFullscreen
|
||||
readonly property int customFlags: {
|
||||
// Setup frameless window flags
|
||||
var flags = Qt.Window |
|
||||
Qt.CustomizeWindowHint |
|
||||
Qt.FramelessWindowHint |
|
||||
Qt.WindowSystemMenuHint |
|
||||
Qt.WindowMinMaxButtonsHint
|
||||
|
||||
//
|
||||
// The macOS window manager is able to generate shadows for Qt frameless
|
||||
// windows. Other operating systems have varied mileage, so we draw the
|
||||
// shadow ourselves to avoid ugly surprises.
|
||||
//
|
||||
// Also, disabling the custom shadow on macOS is a good idea so that users can
|
||||
// move the window freely over all the desktop without being blocked by the
|
||||
// menubar or dock due to the custom shadow border.
|
||||
//
|
||||
if (!Cpp_IsMac)
|
||||
flags |= Qt.NoDropShadowWindowHint
|
||||
|
||||
// Return "calculated" window flags
|
||||
return flags
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle fullscreen state
|
||||
//
|
||||
function toggleFullscreen() {
|
||||
root.isFullscreen = !root.isFullscreen
|
||||
if (root.isFullscreen)
|
||||
root.showFullScreen()
|
||||
else
|
||||
root.showNormal()
|
||||
}
|
||||
|
||||
//
|
||||
// Alias to the titlebar
|
||||
//
|
||||
property alias titlebar: _title
|
||||
|
||||
//
|
||||
// Size of the shadow object
|
||||
//
|
||||
property int shadowMargin: (Cpp_IsMac | !Cpp_ThemeManager.customWindowDecorations) ?
|
||||
0 : (root.radius > 0 ? 20 : 0)
|
||||
|
||||
//
|
||||
// Titlebar left/right margins for custom controls
|
||||
//
|
||||
property alias showMacControls: _title.showMacControls
|
||||
readonly property real leftTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.leftMargin : 0
|
||||
readonly property real rightTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.rightMargin : 0
|
||||
|
||||
//
|
||||
// Background color of the window & the titlebar
|
||||
//
|
||||
property color borderColor: Cpp_ThemeManager.highlight
|
||||
property color backgroundColor: Cpp_ThemeManager.window
|
||||
property color titlebarText: Cpp_ThemeManager.menubarText
|
||||
property color titlebarColor: Cpp_ThemeManager.toolbarGradient2
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
property alias closeEnabled: _title.closeEnabled
|
||||
property alias minimizeEnabled: _title.minimizeEnabled
|
||||
property alias maximizeEnabled: _title.maximizeEnabled
|
||||
|
||||
//
|
||||
// Ensure that window size & position is valid upon showing
|
||||
//
|
||||
Component.onCompleted: {
|
||||
// Reset window size for whatever reason
|
||||
if (root.width <= 0 || root.height <= 0) {
|
||||
root.width = root.minimumWidth
|
||||
root.height = root.minimumHeight
|
||||
}
|
||||
|
||||
// Startup verifications to ensure that app is displayed inside the screen
|
||||
if (root.x < 0 || root.x >= QtWindow.Screen.desktopAvailableWidth)
|
||||
root.x = 100
|
||||
if (root.y < 0 || root.y >= QtWindow.Screen.desktopAvailableHeight)
|
||||
root.y = 100
|
||||
|
||||
// Startup verifications to ensure that app fits in current screen
|
||||
if (root.width > QtWindow.Screen.desktopAvailableWidth) {
|
||||
root.x = 100
|
||||
root.width = QtWindow.Screen.desktopAvailableWidth - root.x
|
||||
}
|
||||
|
||||
// Startup verifications to ensure that app fits in current screen
|
||||
if (root.height > QtWindow.Screen.desktopAvailableHeight) {
|
||||
root.y = 100
|
||||
root.height = QtWindow.Screen.desktopAvailableHeight - root.y
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom shadow implementation for non-macOS systems. The shadow shall be disabled
|
||||
// when the window is maximized.
|
||||
//
|
||||
Widgets.Shadow {
|
||||
border.top: 50
|
||||
border.left: 50
|
||||
border.right: 50
|
||||
border.bottom: 50
|
||||
anchors.fill: bg
|
||||
shadowOpacity: 1.0
|
||||
visible: root.shadowMargin > 0
|
||||
topMargin: -1 * root.shadowMargin
|
||||
leftMargin: -1 * root.shadowMargin
|
||||
rightMargin: -1 * root.shadowMargin
|
||||
bottomMargin: -1 * root.shadowMargin
|
||||
source: "qrc:/images/window-shadow.png"
|
||||
} Rectangle {
|
||||
id: bg
|
||||
color: "transparent"
|
||||
flags: (Cpp_ThemeManager.customWindowDecorations ? root.customFlags : Qt.Window) | root.extraFlags
|
||||
radius: root.radius
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal closed()
|
||||
signal minimized()
|
||||
signal maximized()
|
||||
signal unmaximized()
|
||||
//
|
||||
// Window border
|
||||
//
|
||||
Rectangle {
|
||||
opacity: 0.8
|
||||
z: titlebar.z + 1
|
||||
radius: root.radius
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
border.color: root.borderColor
|
||||
border.width: root.borderWidth
|
||||
anchors.margins: root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Connections with the theme manager for enabling/disabling frameless window
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_ThemeManager
|
||||
//
|
||||
// Global mouse area to set cursor shape while resizing
|
||||
//
|
||||
MouseArea {
|
||||
z: titlebar.z - 1
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
enabled: Cpp_ThemeManager.customWindowDecorations
|
||||
cursorShape: {
|
||||
const p = Qt.point(mouseX, mouseY)
|
||||
const b = root.handleSize / 2
|
||||
|
||||
function onCustomWindowDecorationsChanged() {
|
||||
if (Cpp_ThemeManager.customWindowDecorations)
|
||||
root.flags = root.customFlags | root.extraFlags
|
||||
else
|
||||
root.flags = Qt.Window | root.extraFlags
|
||||
if (p.x < b && p.y < b)
|
||||
return Qt.SizeFDiagCursor
|
||||
|
||||
var prevVisible = root.visible
|
||||
root.visible = false
|
||||
root.visible = prevVisible
|
||||
}
|
||||
if (p.x >= width - b && p.y >= height - b)
|
||||
return Qt.SizeFDiagCursor
|
||||
|
||||
if (p.x >= width - b && p.y < b)
|
||||
return Qt.SizeBDiagCursor
|
||||
|
||||
if (p.x < b && p.y >= height - b)
|
||||
return Qt.SizeBDiagCursor
|
||||
|
||||
if (p.x < b || p.x >= width - b)
|
||||
return Qt.SizeHorCursor
|
||||
|
||||
if (p.y < b || p.y >= height - b)
|
||||
return Qt.SizeVerCursor
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window radius control
|
||||
//
|
||||
property int borderWidth: Cpp_ThemeManager.customWindowDecorations ? 2 : 0
|
||||
readonly property int handleSize: radius > 0 ? radius + shadowMargin + 10 : 0
|
||||
readonly property int radius: Cpp_ThemeManager.customWindowDecorations ?
|
||||
(((root.visibility === QtWindow.Window.Maximized &&
|
||||
maximizeEnabled) || isFullscreen) ? 0 : 10) : 0
|
||||
//
|
||||
// Titlebar control
|
||||
//
|
||||
Titlebar {
|
||||
z: 2000
|
||||
id: _title
|
||||
window: root
|
||||
radius: root.radius
|
||||
color: root.titlebarColor
|
||||
textColor: root.titlebarText
|
||||
|
||||
//
|
||||
// Visibility properties
|
||||
//
|
||||
property int extraFlags: 0
|
||||
property bool firstChange: true
|
||||
property bool isMaximized: false
|
||||
property bool isMinimized: false
|
||||
property alias showIcon: _title.showIcon
|
||||
property alias isFullscreen: _title.isFullscreen
|
||||
readonly property int customFlags: {
|
||||
// Setup frameless window flags
|
||||
var flags = Qt.Window |
|
||||
Qt.CustomizeWindowHint |
|
||||
Qt.FramelessWindowHint |
|
||||
Qt.WindowSystemMenuHint |
|
||||
Qt.WindowMinMaxButtonsHint
|
||||
onClosed: root.closed()
|
||||
onMinimized: root.minimized()
|
||||
onMaximized: root.maximized()
|
||||
onUnmaximized: root.unmaximized()
|
||||
|
||||
//
|
||||
// The macOS window manager is able to generate shadows for Qt frameless
|
||||
// windows. Other operating systems have varied mileage, so we draw the
|
||||
// shadow ourselves to avoid ugly surprises.
|
||||
//
|
||||
// Also, disabling the custom shadow on macOS is a good idea so that users can
|
||||
// move the window freely over all the desktop without being blocked by the
|
||||
// menubar or dock due to the custom shadow border.
|
||||
//
|
||||
if (!Cpp_IsMac)
|
||||
flags |= Qt.NoDropShadowWindowHint
|
||||
|
||||
// Return "calculated" window flags
|
||||
return flags
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: root.shadowMargin
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle fullscreen state
|
||||
//
|
||||
function toggleFullscreen() {
|
||||
root.isFullscreen = !root.isFullscreen
|
||||
if (root.isFullscreen)
|
||||
root.showFullScreen()
|
||||
else
|
||||
root.showNormal()
|
||||
}
|
||||
//
|
||||
// Maximize window fixes
|
||||
//
|
||||
onVisibilityChanged: (visibility) => {
|
||||
// Ensure that correct window flags are still used
|
||||
if (Cpp_ThemeManager.customWindowDecorations) {
|
||||
// Hard-reset window flags on macOS to fix most glitches
|
||||
if (Cpp_IsMac)
|
||||
root.flags = Qt.Window
|
||||
|
||||
//
|
||||
// Alias to the titlebar
|
||||
//
|
||||
property alias titlebar: _title
|
||||
// Apply custom flags
|
||||
root.flags = root.customFlags | root.extraFlags
|
||||
}
|
||||
|
||||
//
|
||||
// Size of the shadow object
|
||||
//
|
||||
property int shadowMargin: (Cpp_IsMac | !Cpp_ThemeManager.customWindowDecorations) ?
|
||||
0 : (root.radius > 0 ? 20 : 0)
|
||||
// Apply basic flags
|
||||
else
|
||||
root.flags = Qt.Window | root.extraFlags
|
||||
|
||||
//
|
||||
// Titlebar left/right margins for custom controls
|
||||
//
|
||||
property alias showMacControls: _title.showMacControls
|
||||
readonly property real leftTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.leftMargin : 0
|
||||
readonly property real rightTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.rightMargin : 0
|
||||
// Window has been just maximized, update internal variables
|
||||
if (visibility === QtWindow.Window.Maximized) {
|
||||
if (!root.isMaximized)
|
||||
root.firstChange = false
|
||||
|
||||
//
|
||||
// Background color of the window & the titlebar
|
||||
//
|
||||
property color borderColor: Cpp_ThemeManager.highlight
|
||||
property color backgroundColor: Cpp_ThemeManager.window
|
||||
property color titlebarText: Cpp_ThemeManager.menubarText
|
||||
property color titlebarColor: Cpp_ThemeManager.toolbarGradient2
|
||||
root.isMaximized = true
|
||||
root.isFullscreen = false
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
property alias closeEnabled: _title.closeEnabled
|
||||
property alias minimizeEnabled: _title.minimizeEnabled
|
||||
property alias maximizeEnabled: _title.maximizeEnabled
|
||||
// Window has been just minimized, update internal variables
|
||||
else if (visibility === QtWindow.Window.Minimized) {
|
||||
root.isFullscreen = false
|
||||
root.isMaximized = false
|
||||
}
|
||||
|
||||
//
|
||||
// Ensure that window size & position is valid upon showing
|
||||
//
|
||||
Component.onCompleted: {
|
||||
// Reset window size for whatever reason
|
||||
if (root.width <= 0 || root.height <= 0) {
|
||||
root.width = root.minimumWidth
|
||||
root.height = root.minimumHeight
|
||||
}
|
||||
// Window has been just switched to full-screen, update internal variables
|
||||
else if (visibility === QtWindow.Window.FullScreen) {
|
||||
if (!root.isFullscreen)
|
||||
root.firstChange = false
|
||||
|
||||
// Startup verifications to ensure that app is displayed inside the screen
|
||||
if (root.x < 0 || root.x >= QtWindow.Screen.desktopAvailableWidth)
|
||||
root.x = 100
|
||||
if (root.y < 0 || root.y >= QtWindow.Screen.desktopAvailableHeight)
|
||||
root.y = 100
|
||||
root.isFullscreen = true
|
||||
root.isMaximized = false
|
||||
}
|
||||
|
||||
// Startup verifications to ensure that app fits in current screen
|
||||
if (root.width > QtWindow.Screen.desktopAvailableWidth) {
|
||||
root.x = 100
|
||||
root.width = QtWindow.Screen.desktopAvailableWidth - root.x
|
||||
}
|
||||
// Window was just restored to "normal" mode, recover previous geometry
|
||||
else if (visibility !== QtWindow.Window.Hidden) {
|
||||
if (isMaximized || isFullscreen && firstChange) {
|
||||
root.width = root.minimumWidth
|
||||
root.height = root.minimumHeight
|
||||
root.x = (QtWindow.Screen.desktopAvailableWidth - root.width) / 2
|
||||
root.y = (QtWindow.Screen.desktopAvailableHeight - root.height) / 2
|
||||
}
|
||||
|
||||
// Startup verifications to ensure that app fits in current screen
|
||||
if (root.height > QtWindow.Screen.desktopAvailableHeight) {
|
||||
root.y = 100
|
||||
root.height = QtWindow.Screen.desktopAvailableHeight - root.y
|
||||
}
|
||||
}
|
||||
root.isMaximized = false
|
||||
root.isFullscreen = false
|
||||
|
||||
//
|
||||
// Custom shadow implementation for non-macOS systems. The shadow shall be disabled
|
||||
// when the window is maximized.
|
||||
//
|
||||
Widgets.Shadow {
|
||||
border.top: 50
|
||||
border.left: 50
|
||||
border.right: 50
|
||||
border.bottom: 50
|
||||
anchors.fill: bg
|
||||
shadowOpacity: 1.0
|
||||
visible: root.shadowMargin > 0
|
||||
topMargin: -1 * root.shadowMargin
|
||||
leftMargin: -1 * root.shadowMargin
|
||||
rightMargin: -1 * root.shadowMargin
|
||||
bottomMargin: -1 * root.shadowMargin
|
||||
source: "qrc:/images/window-shadow.png"
|
||||
} Rectangle {
|
||||
id: bg
|
||||
color: "transparent"
|
||||
radius: root.radius
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Window border
|
||||
//
|
||||
Rectangle {
|
||||
opacity: 0.8
|
||||
z: titlebar.z + 1
|
||||
radius: root.radius
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
border.color: root.borderColor
|
||||
border.width: root.borderWidth
|
||||
anchors.margins: root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Global mouse area to set cursor shape while resizing
|
||||
//
|
||||
MouseArea {
|
||||
z: titlebar.z - 1
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
enabled: Cpp_ThemeManager.customWindowDecorations
|
||||
cursorShape: {
|
||||
const p = Qt.point(mouseX, mouseY)
|
||||
const b = root.handleSize / 2
|
||||
|
||||
if (p.x < b && p.y < b)
|
||||
return Qt.SizeFDiagCursor
|
||||
|
||||
if (p.x >= width - b && p.y >= height - b)
|
||||
return Qt.SizeFDiagCursor
|
||||
|
||||
if (p.x >= width - b && p.y < b)
|
||||
return Qt.SizeBDiagCursor
|
||||
|
||||
if (p.x < b && p.y >= height - b)
|
||||
return Qt.SizeBDiagCursor
|
||||
|
||||
if (p.x < b || p.x >= width - b)
|
||||
return Qt.SizeHorCursor
|
||||
|
||||
if (p.y < b || p.y >= height - b)
|
||||
return Qt.SizeVerCursor
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Titlebar control
|
||||
//
|
||||
Titlebar {
|
||||
z: 2000
|
||||
id: _title
|
||||
window: root
|
||||
radius: root.radius
|
||||
color: root.titlebarColor
|
||||
textColor: root.titlebarText
|
||||
|
||||
onClosed: root.closed()
|
||||
onMinimized: root.minimized()
|
||||
onMaximized: root.maximized()
|
||||
onUnmaximized: root.unmaximized()
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: root.shadowMargin
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Maximize window fixes
|
||||
//
|
||||
onVisibilityChanged: (visibility) => {
|
||||
// Ensure that correct window flags are still used
|
||||
if (Cpp_ThemeManager.customWindowDecorations) {
|
||||
// Hard-reset window flags on macOS to fix most glitches
|
||||
if (Cpp_IsMac)
|
||||
root.flags = Qt.Window
|
||||
|
||||
// Apply custom flags
|
||||
root.flags = root.customFlags | root.extraFlags
|
||||
}
|
||||
|
||||
// Apply basic flags
|
||||
else
|
||||
root.flags = Qt.Window | root.extraFlags
|
||||
|
||||
// Window has been just maximized, update internal variables
|
||||
if (visibility === QtWindow.Window.Maximized) {
|
||||
if (!root.isMaximized)
|
||||
root.firstChange = false
|
||||
|
||||
root.isMaximized = true
|
||||
root.isFullscreen = false
|
||||
}
|
||||
|
||||
// Window has been just minimized, update internal variables
|
||||
else if (visibility === QtWindow.Window.Minimized) {
|
||||
root.isFullscreen = false
|
||||
root.isMaximized = false
|
||||
}
|
||||
|
||||
// Window has been just switched to full-screen, update internal variables
|
||||
else if (visibility === QtWindow.Window.FullScreen) {
|
||||
if (!root.isFullscreen)
|
||||
root.firstChange = false
|
||||
|
||||
root.isFullscreen = true
|
||||
root.isMaximized = false
|
||||
}
|
||||
|
||||
// Window was just restored to "normal" mode, recover previous geometry
|
||||
else if (visibility !== QtWindow.Window.Hidden) {
|
||||
if (isMaximized || isFullscreen && firstChange) {
|
||||
root.width = root.minimumWidth
|
||||
root.height = root.minimumHeight
|
||||
root.x = (QtWindow.Screen.desktopAvailableWidth - root.width) / 2
|
||||
root.y = (QtWindow.Screen.desktopAvailableHeight - root.height) / 2
|
||||
}
|
||||
|
||||
root.isMaximized = false
|
||||
root.isFullscreen = false
|
||||
|
||||
// Force active focus
|
||||
root.requestActivate()
|
||||
root.requestUpdate()
|
||||
}
|
||||
}
|
||||
// Force active focus
|
||||
root.requestActivate()
|
||||
root.requestUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,216 +24,216 @@ import QtQuick
|
||||
import QtQuick.Window
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Pointer to window to control
|
||||
//
|
||||
property Window window
|
||||
property int handleSize
|
||||
//
|
||||
// Pointer to window to control
|
||||
//
|
||||
property Window window
|
||||
property int handleSize
|
||||
|
||||
//
|
||||
// Disable handles if window size is fixed or window is maximized
|
||||
//
|
||||
enabled: ((window.minimumWidth !== window.maximumWidth) ||
|
||||
(window.minimumHeight !== window.maximumHeight)) &&
|
||||
(window.visibility !== Window.Maximized)
|
||||
//
|
||||
// Disable handles if window size is fixed or window is maximized
|
||||
//
|
||||
enabled: ((window.minimumWidth !== window.maximumWidth) ||
|
||||
(window.minimumHeight !== window.maximumHeight)) &&
|
||||
(window.visibility !== Window.Maximized)
|
||||
|
||||
//
|
||||
// Right resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
//
|
||||
// Right resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
topMargin: titlebar.height
|
||||
}
|
||||
|
||||
width: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
|
||||
onMouseXChanged: {
|
||||
if (dragging) {
|
||||
var dx = mouseX + lastMousePos.x
|
||||
var width = window.width + dx
|
||||
if (width < window.minimumWidth)
|
||||
width = window.minimumWidth
|
||||
else if (width > window.maximumWidth)
|
||||
width = window.maximumWidth
|
||||
|
||||
window.setGeometry(window.x, window.y, width, window.height)
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
topMargin: titlebar.height
|
||||
}
|
||||
|
||||
//
|
||||
// Left resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
width: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
topMargin: titlebar.height
|
||||
}
|
||||
onMouseXChanged: {
|
||||
if (dragging) {
|
||||
var dx = mouseX + lastMousePos.x
|
||||
var width = window.width + dx
|
||||
if (width < window.minimumWidth)
|
||||
width = window.minimumWidth
|
||||
else if (width > window.maximumWidth)
|
||||
width = window.maximumWidth
|
||||
|
||||
width: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
window.setGeometry(window.x, window.y, width, window.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMouseXChanged: {
|
||||
if (dragging) {
|
||||
var dx = mouseX - lastMousePos.x
|
||||
var y = window.y
|
||||
var x = window.x + dx
|
||||
var height = window.height
|
||||
var width = window.width - dx
|
||||
//
|
||||
// Left resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
if (x > window.x) {
|
||||
width = window.width - dx / 2
|
||||
if (width < window.minimumWidth) {
|
||||
width = window.minimumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
else if (width > window.maximumWidth) {
|
||||
width = window.maximumWidth
|
||||
x = window.x
|
||||
}
|
||||
}
|
||||
|
||||
window.setGeometry(x, y, width, height)
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
topMargin: titlebar.height
|
||||
}
|
||||
|
||||
//
|
||||
// Bottom resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
width: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
onMouseXChanged: {
|
||||
if (dragging) {
|
||||
var dx = mouseX - lastMousePos.x
|
||||
var y = window.y
|
||||
var x = window.x + dx
|
||||
var height = window.height
|
||||
var width = window.width - dx
|
||||
|
||||
if (x > window.x) {
|
||||
width = window.width - dx / 2
|
||||
if (width < window.minimumWidth) {
|
||||
width = window.minimumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
else if (width > window.maximumWidth) {
|
||||
width = window.maximumWidth
|
||||
x = window.x
|
||||
}
|
||||
}
|
||||
|
||||
height: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
onMouseYChanged: {
|
||||
if (dragging) {
|
||||
var dy = mouseY - lastMousePos.y
|
||||
var height = window.height + dy
|
||||
if (height < window.minimumHeight)
|
||||
height = window.minimumHeight
|
||||
else if (height > window.maximumHeight)
|
||||
height = window.maximumHeight
|
||||
window.setGeometry(x, y, width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.setGeometry(window.x, window.y, window.width, height)
|
||||
}
|
||||
}
|
||||
//
|
||||
// Bottom resize handle
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
//
|
||||
// Bottom right corner
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
height: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
onMouseYChanged: {
|
||||
if (dragging) {
|
||||
var dy = mouseY - lastMousePos.y
|
||||
var height = window.height + dy
|
||||
if (height < window.minimumHeight)
|
||||
height = window.minimumHeight
|
||||
else if (height > window.maximumHeight)
|
||||
height = window.maximumHeight
|
||||
|
||||
function updateWindowPosition() {
|
||||
if (dragging) {
|
||||
var dy = mouseY - lastMousePos.y
|
||||
var dx = mouseX + lastMousePos.x
|
||||
var width = window.width + dx
|
||||
var height = window.height + dy
|
||||
window.setGeometry(window.x, window.y, window.width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (width < window.minimumWidth)
|
||||
width = window.minimumWidth
|
||||
else if (width > window.maximumWidth)
|
||||
width = window.maximumWidth
|
||||
//
|
||||
// Bottom right corner
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
if (height < window.minimumHeight)
|
||||
height = window.minimumHeight
|
||||
else if (height > window.maximumHeight)
|
||||
height = window.maximumHeight
|
||||
function updateWindowPosition() {
|
||||
if (dragging) {
|
||||
var dy = mouseY - lastMousePos.y
|
||||
var dx = mouseX + lastMousePos.x
|
||||
var width = window.width + dx
|
||||
var height = window.height + dy
|
||||
|
||||
window.setGeometry(window.x, window.y, width, height)
|
||||
}
|
||||
}
|
||||
if (width < window.minimumWidth)
|
||||
width = window.minimumWidth
|
||||
else if (width > window.maximumWidth)
|
||||
width = window.maximumWidth
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
if (height < window.minimumHeight)
|
||||
height = window.minimumHeight
|
||||
else if (height > window.maximumHeight)
|
||||
height = window.maximumHeight
|
||||
|
||||
width: handleSize
|
||||
height: handleSize
|
||||
enabled: Cpp_IsMac
|
||||
onPressedChanged: dragging = pressed
|
||||
onMouseXChanged: updateWindowPosition()
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
window.setGeometry(window.x, window.y, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bottom left corner
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
function updateWindowPosition() {
|
||||
if (dragging) {
|
||||
var dx = mouseX - lastMousePos.x
|
||||
var dy = mouseY - lastMousePos.y
|
||||
|
||||
var y = window.y
|
||||
var x = window.x + dx
|
||||
var width = window.width - dx
|
||||
var height = window.height + dy
|
||||
|
||||
if (x > window.x)
|
||||
width = window.width - dx / 2
|
||||
|
||||
if (width < window.minimumWidth) {
|
||||
width = window.minimumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
else if (width > window.maximumWidth) {
|
||||
width = window.maximumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
if (height < minimumHeight)
|
||||
height = minimumHeight
|
||||
else if (height > maximumHeight)
|
||||
height = maximumHeight
|
||||
|
||||
window.setGeometry(x, y, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
width: handleSize
|
||||
height: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onMouseXChanged: updateWindowPosition()
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
width: handleSize
|
||||
height: handleSize
|
||||
enabled: Cpp_IsMac
|
||||
onPressedChanged: dragging = pressed
|
||||
onMouseXChanged: updateWindowPosition()
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
}
|
||||
|
||||
//
|
||||
// Bottom left corner
|
||||
//
|
||||
MouseArea {
|
||||
property bool dragging: false
|
||||
property point lastMousePos: Qt.point(0, 0)
|
||||
|
||||
function updateWindowPosition() {
|
||||
if (dragging) {
|
||||
var dx = mouseX - lastMousePos.x
|
||||
var dy = mouseY - lastMousePos.y
|
||||
|
||||
var y = window.y
|
||||
var x = window.x + dx
|
||||
var width = window.width - dx
|
||||
var height = window.height + dy
|
||||
|
||||
if (x > window.x)
|
||||
width = window.width - dx / 2
|
||||
|
||||
if (width < window.minimumWidth) {
|
||||
width = window.minimumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
else if (width > window.maximumWidth) {
|
||||
width = window.maximumWidth
|
||||
x = window.x
|
||||
}
|
||||
|
||||
if (height < minimumHeight)
|
||||
height = minimumHeight
|
||||
else if (height > maximumHeight)
|
||||
height = maximumHeight
|
||||
|
||||
window.setGeometry(x, y, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
width: handleSize
|
||||
height: handleSize
|
||||
onPressedChanged: dragging = pressed
|
||||
onMouseXChanged: updateWindowPosition()
|
||||
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
|
||||
}
|
||||
}
|
||||
|
@ -28,312 +28,312 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal closed()
|
||||
signal minimized()
|
||||
signal maximized()
|
||||
signal unmaximized()
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal closed()
|
||||
signal minimized()
|
||||
signal maximized()
|
||||
signal unmaximized()
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
property Window window
|
||||
property bool showIcon: false
|
||||
property bool closeEnabled: true
|
||||
property bool isFullscreen: false
|
||||
property bool minimizeEnabled: true
|
||||
property bool maximizeEnabled: true
|
||||
property color textColor: palette.text
|
||||
property bool showMacControls: Cpp_IsMac
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
property Window window
|
||||
property bool showIcon: false
|
||||
property bool closeEnabled: true
|
||||
property bool isFullscreen: false
|
||||
property bool minimizeEnabled: true
|
||||
property bool maximizeEnabled: true
|
||||
property color textColor: palette.text
|
||||
property bool showMacControls: Cpp_IsMac
|
||||
|
||||
//
|
||||
// Access to left titlebar button widths (e.g. for implementing custom controls over
|
||||
// the window titlebar, such as the main window menubar)
|
||||
//
|
||||
readonly property real leftMargin: {
|
||||
var margin = 0
|
||||
//
|
||||
// Access to left titlebar button widths (e.g. for implementing custom controls over
|
||||
// the window titlebar, such as the main window menubar)
|
||||
//
|
||||
readonly property real leftMargin: {
|
||||
var margin = 0
|
||||
|
||||
// Calculations for macOS layout
|
||||
if (showMacControls) {
|
||||
// Default spacer
|
||||
margin = 4
|
||||
// Calculations for macOS layout
|
||||
if (showMacControls) {
|
||||
// Default spacer
|
||||
margin = 4
|
||||
|
||||
// Add space for close button
|
||||
if (closeEnabled)
|
||||
margin += 20
|
||||
// Add space for close button
|
||||
if (closeEnabled)
|
||||
margin += 20
|
||||
|
||||
// Add space for minimize button
|
||||
if (minimizeEnabled && !root.isFullscreen)
|
||||
margin += 20
|
||||
// Add space for minimize button
|
||||
if (minimizeEnabled && !root.isFullscreen)
|
||||
margin += 20
|
||||
|
||||
// Add space for maximize button
|
||||
if (maximizeEnabled && !root.isFullscreen)
|
||||
margin += 20
|
||||
// Add space for maximize button
|
||||
if (maximizeEnabled && !root.isFullscreen)
|
||||
margin += 20
|
||||
|
||||
// Add extra spacer if at least one button is visible
|
||||
if (margin > 4)
|
||||
margin += 4
|
||||
}
|
||||
|
||||
// Calculations for Windows/Linux layout
|
||||
else {
|
||||
margin = 8
|
||||
|
||||
if (root.showIcon)
|
||||
margin += 24
|
||||
|
||||
if (margin > 8)
|
||||
margin += 6
|
||||
}
|
||||
|
||||
// Return result
|
||||
return margin
|
||||
// Add extra spacer if at least one button is visible
|
||||
if (margin > 4)
|
||||
margin += 4
|
||||
}
|
||||
|
||||
//
|
||||
// Access to right titlebar button widths (e.g. for implementing custom controls over
|
||||
// the window titlebar, such as the main window menubar)
|
||||
//
|
||||
readonly property real rightMargin: {
|
||||
var margin
|
||||
// Calculations for Windows/Linux layout
|
||||
else {
|
||||
margin = 8
|
||||
|
||||
// Calculations for macOS layout
|
||||
if (showMacControls)
|
||||
margin = 8
|
||||
if (root.showIcon)
|
||||
margin += 24
|
||||
|
||||
// Calculations for Windows/Linux layout
|
||||
else {
|
||||
// Default spacer
|
||||
margin = 8
|
||||
if (margin > 8)
|
||||
margin += 6
|
||||
}
|
||||
|
||||
// Add space for close button
|
||||
if (closeEnabled)
|
||||
margin += 24
|
||||
// Return result
|
||||
return margin
|
||||
}
|
||||
|
||||
// Add space for minimize button
|
||||
if (minimizeEnabled && !root.isFullscreen)
|
||||
margin += 24
|
||||
//
|
||||
// Access to right titlebar button widths (e.g. for implementing custom controls over
|
||||
// the window titlebar, such as the main window menubar)
|
||||
//
|
||||
readonly property real rightMargin: {
|
||||
var margin
|
||||
|
||||
// Add space for maximize button
|
||||
if (maximizeEnabled && !root.isFullscreen)
|
||||
margin += 24
|
||||
// Calculations for macOS layout
|
||||
if (showMacControls)
|
||||
margin = 8
|
||||
|
||||
// Add extra spacer if at least one button is visible
|
||||
if (margin > 8)
|
||||
margin += 8
|
||||
// Calculations for Windows/Linux layout
|
||||
else {
|
||||
// Default spacer
|
||||
margin = 8
|
||||
|
||||
// Add space for close button
|
||||
if (closeEnabled)
|
||||
margin += 24
|
||||
|
||||
// Add space for minimize button
|
||||
if (minimizeEnabled && !root.isFullscreen)
|
||||
margin += 24
|
||||
|
||||
// Add space for maximize button
|
||||
if (maximizeEnabled && !root.isFullscreen)
|
||||
margin += 24
|
||||
|
||||
// Add extra spacer if at least one button is visible
|
||||
if (margin > 8)
|
||||
margin += 8
|
||||
}
|
||||
|
||||
// Return result
|
||||
return margin
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle maximized
|
||||
//
|
||||
function toggleMaximized() {
|
||||
if (window.visibility === Window.Maximized) {
|
||||
window.showNormal()
|
||||
root.unmaximized()
|
||||
}
|
||||
|
||||
else {
|
||||
window.showMaximized()
|
||||
root.maximized()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle fullscreen state
|
||||
//
|
||||
function toggleFullscreen() {
|
||||
root.isFullscreen = !root.isFullscreen
|
||||
if (root.isFullscreen)
|
||||
window.showFullScreen()
|
||||
else
|
||||
window.showNormal()
|
||||
}
|
||||
|
||||
//
|
||||
// Height calculation
|
||||
//
|
||||
height: Cpp_ThemeManager.customWindowDecorations ? (!showMacControls ? 38 : 32) : 0
|
||||
|
||||
//
|
||||
// Radius compensator rectangle
|
||||
//
|
||||
Rectangle {
|
||||
color: parent.color
|
||||
height: parent.radius
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler & maximize by double click
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
enabled: Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
onDoubleClicked: {
|
||||
if (root.maximizeEnabled)
|
||||
root.toggleMaximized()
|
||||
}
|
||||
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
window.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// macOS layout
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
enabled: showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
width: 4
|
||||
}
|
||||
|
||||
WindowButtonMacOS {
|
||||
name: "close"
|
||||
enabled: root.closeEnabled
|
||||
visible: root.closeEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
window.close()
|
||||
root.closed()
|
||||
}
|
||||
|
||||
// Return result
|
||||
return margin
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle maximized
|
||||
//
|
||||
function toggleMaximized() {
|
||||
if (window.visibility === Window.Maximized) {
|
||||
window.showNormal()
|
||||
root.unmaximized()
|
||||
WindowButtonMacOS {
|
||||
name: "minimize"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.minimizeEnabled && !root.isFullscreen
|
||||
visible: root.minimizeEnabled && !root.isFullscreen
|
||||
onClicked: {
|
||||
// Workaround for QTBUG-64994
|
||||
if (Cpp_IsMac)
|
||||
window.flags = Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint
|
||||
|
||||
window.showMinimized()
|
||||
root.minimized()
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
window.showMaximized()
|
||||
root.maximized()
|
||||
WindowButtonMacOS {
|
||||
name: "maximize"
|
||||
onClicked: root.toggleMaximized()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.maximizeEnabled && !root.isFullscreen
|
||||
visible: root.maximizeEnabled && !root.isFullscreen
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Windows & Linux layout
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: !showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
enabled: !showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
width: 8
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
visible: root.showIcon
|
||||
enabled: root.showIcon
|
||||
textColor: root.textColor
|
||||
pressedColor: root.textColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/images/icon-window.svg"
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
name: "minimize"
|
||||
textColor: root.textColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.minimizeEnabled && !root.isFullscreen
|
||||
visible: root.minimizeEnabled && !root.isFullscreen
|
||||
onClicked: {
|
||||
// Workaround for QTBUG-64994
|
||||
if (Cpp_IsMac)
|
||||
window.flags = Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint
|
||||
|
||||
window.showMinimized()
|
||||
root.minimized()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toggle fullscreen state
|
||||
//
|
||||
function toggleFullscreen() {
|
||||
root.isFullscreen = !root.isFullscreen
|
||||
if (root.isFullscreen)
|
||||
window.showFullScreen()
|
||||
else
|
||||
window.showNormal()
|
||||
}
|
||||
WindowButton {
|
||||
textColor: root.textColor
|
||||
onClicked: root.toggleMaximized()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.maximizeEnabled && !root.isFullscreen
|
||||
visible: root.maximizeEnabled && !root.isFullscreen
|
||||
name: window.visibility === Window.Maximized ? "unmaximize" : "maximize"
|
||||
}
|
||||
|
||||
//
|
||||
// Height calculation
|
||||
//
|
||||
height: Cpp_ThemeManager.customWindowDecorations ? (!showMacControls ? 38 : 32) : 0
|
||||
|
||||
//
|
||||
// Radius compensator rectangle
|
||||
//
|
||||
Rectangle {
|
||||
color: parent.color
|
||||
height: parent.radius
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
WindowButton {
|
||||
name: "close"
|
||||
pressedColor: "#f00"
|
||||
textColor: root.textColor
|
||||
enabled: root.closeEnabled
|
||||
visible: root.closeEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
window.close()
|
||||
root.closed()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler & maximize by double click
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
enabled: Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
onDoubleClicked: {
|
||||
if (root.maximizeEnabled)
|
||||
root.toggleMaximized()
|
||||
}
|
||||
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
window.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// macOS layout
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
enabled: showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
width: 4
|
||||
}
|
||||
|
||||
WindowButtonMacOS {
|
||||
name: "close"
|
||||
enabled: root.closeEnabled
|
||||
visible: root.closeEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
window.close()
|
||||
root.closed()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WindowButtonMacOS {
|
||||
name: "minimize"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.minimizeEnabled && !root.isFullscreen
|
||||
visible: root.minimizeEnabled && !root.isFullscreen
|
||||
onClicked: {
|
||||
// Workaround for QTBUG-64994
|
||||
if (Cpp_IsMac)
|
||||
window.flags = Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint
|
||||
|
||||
window.showMinimized()
|
||||
root.minimized()
|
||||
}
|
||||
}
|
||||
|
||||
WindowButtonMacOS {
|
||||
name: "maximize"
|
||||
onClicked: root.toggleMaximized()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.maximizeEnabled && !root.isFullscreen
|
||||
visible: root.maximizeEnabled && !root.isFullscreen
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Windows & Linux layout
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
visible: !showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
enabled: !showMacControls && Cpp_ThemeManager.customWindowDecorations
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Item {
|
||||
width: 8
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
visible: root.showIcon
|
||||
enabled: root.showIcon
|
||||
textColor: root.textColor
|
||||
pressedColor: root.textColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/images/icon-window.svg"
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
name: "minimize"
|
||||
textColor: root.textColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.minimizeEnabled && !root.isFullscreen
|
||||
visible: root.minimizeEnabled && !root.isFullscreen
|
||||
onClicked: {
|
||||
// Workaround for QTBUG-64994
|
||||
if (Cpp_IsMac)
|
||||
window.flags = Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint
|
||||
|
||||
window.showMinimized()
|
||||
root.minimized()
|
||||
}
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
textColor: root.textColor
|
||||
onClicked: root.toggleMaximized()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
enabled: root.maximizeEnabled && !root.isFullscreen
|
||||
visible: root.maximizeEnabled && !root.isFullscreen
|
||||
name: window.visibility === Window.Maximized ? "unmaximize" : "maximize"
|
||||
}
|
||||
|
||||
WindowButton {
|
||||
name: "close"
|
||||
pressedColor: "#f00"
|
||||
textColor: root.textColor
|
||||
enabled: root.closeEnabled
|
||||
visible: root.closeEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: {
|
||||
window.close()
|
||||
root.closed()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
text: window.title
|
||||
color: root.textColor
|
||||
anchors.centerIn: parent
|
||||
visible: Cpp_ThemeManager.customWindowDecorations
|
||||
}
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
text: window.title
|
||||
color: root.textColor
|
||||
anchors.centerIn: parent
|
||||
visible: Cpp_ThemeManager.customWindowDecorations
|
||||
}
|
||||
}
|
||||
|
@ -24,26 +24,26 @@ import QtQuick
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Widgets.Icon {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
signal clicked()
|
||||
property string name
|
||||
property color textColor
|
||||
property color pressedColor: Cpp_ThemeManager.highlight
|
||||
signal clicked()
|
||||
property string name
|
||||
property color textColor
|
||||
property color pressedColor: Cpp_ThemeManager.highlight
|
||||
|
||||
width: 24
|
||||
height: 24
|
||||
color: root.textColor
|
||||
source: "qrc:/window-border/" + name + ".svg"
|
||||
width: 24
|
||||
height: 24
|
||||
color: root.textColor
|
||||
source: "qrc:/window-border/" + name + ".svg"
|
||||
|
||||
Behavior on color { ColorAnimation{} }
|
||||
Behavior on color { ColorAnimation{} }
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onClicked: root.clicked()
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onContainsMouseChanged: root.color = containsMouse ? root.pressedColor : root.textColor
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onClicked: root.clicked()
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onContainsMouseChanged: root.color = containsMouse ? root.pressedColor : root.textColor
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,23 @@
|
||||
import QtQuick
|
||||
|
||||
Image {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
signal clicked()
|
||||
property string name
|
||||
property string variant: "normal"
|
||||
signal clicked()
|
||||
property string name
|
||||
property string variant: "normal"
|
||||
|
||||
width: sourceSize.width
|
||||
height: sourceSize.height
|
||||
sourceSize: Qt.size(20, 20)
|
||||
source: ("qrc:/window-border/macOS/" + name + "-" + variant + ".svg")
|
||||
width: sourceSize.width
|
||||
height: sourceSize.height
|
||||
sourceSize: Qt.size(20, 20)
|
||||
source: ("qrc:/window-border/macOS/" + name + "-" + variant + ".svg")
|
||||
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onReleased: root.clicked()
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onPressedChanged: root.variant = (pressed ? "active" : "normal")
|
||||
onContainsMouseChanged: root.variant = (containsMouse ? "hover" : "normal")
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onReleased: root.clicked()
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onPressedChanged: root.variant = (pressed ? "active" : "normal")
|
||||
onContainsMouseChanged: root.variant = (containsMouse ? "hover" : "normal")
|
||||
}
|
||||
}
|
||||
|
@ -27,61 +27,61 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property alias vt100emulation: terminal.vt100emulation
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property alias vt100emulation: terminal.vt100emulation
|
||||
|
||||
//
|
||||
// Utility functions between terminal widget & main window
|
||||
//
|
||||
function sendData() {
|
||||
terminal.sendData()
|
||||
} function clear() {
|
||||
terminal.clear()
|
||||
} function copy() {
|
||||
terminal.copy()
|
||||
} function selectAll() {
|
||||
terminal.selectAll()
|
||||
//
|
||||
// Utility functions between terminal widget & main window
|
||||
//
|
||||
function sendData() {
|
||||
terminal.sendData()
|
||||
} function clear() {
|
||||
terminal.clear()
|
||||
} function copy() {
|
||||
terminal.copy()
|
||||
} function selectAll() {
|
||||
terminal.selectAll()
|
||||
}
|
||||
|
||||
//
|
||||
// Load welcome guide
|
||||
//
|
||||
function showWelcomeGuide() {
|
||||
clear()
|
||||
Cpp_IO_Console.append(Cpp_Misc_Translator.welcomeConsoleText() + "\n")
|
||||
}
|
||||
|
||||
//
|
||||
// Re-load welcome text when the language is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
root.showWelcomeGuide()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Load welcome guide
|
||||
//
|
||||
function showWelcomeGuide() {
|
||||
clear()
|
||||
Cpp_IO_Console.append(Cpp_Misc_Translator.welcomeConsoleText() + "\n")
|
||||
}
|
||||
|
||||
//
|
||||
// Re-load welcome text when the language is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
root.showWelcomeGuide()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console window
|
||||
//
|
||||
Widgets.Window {
|
||||
id: window
|
||||
gradient: true
|
||||
anchors.fill: parent
|
||||
title: qsTr("Console")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
Widgets.Terminal {
|
||||
id: terminal
|
||||
widgetEnabled: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
//
|
||||
// Console window
|
||||
//
|
||||
Widgets.Window {
|
||||
id: window
|
||||
gradient: true
|
||||
anchors.fill: parent
|
||||
title: qsTr("Console")
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
Widgets.Terminal {
|
||||
id: terminal
|
||||
widgetEnabled: true
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,94 +28,94 @@ import "../Widgets" as Widgets
|
||||
import "../Dashboard" as DashboardItems
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
|
||||
//
|
||||
// Main layout
|
||||
// Widget selector + widgets
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
//
|
||||
// Widget selector + widgets
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
//
|
||||
// View options window
|
||||
//
|
||||
DashboardItems.ViewOptions {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 280
|
||||
onWidgetSizeChanged:(maxSize) => widgetGrid.maxSize = maxSize
|
||||
}
|
||||
|
||||
//
|
||||
// View options window
|
||||
//
|
||||
DashboardItems.ViewOptions {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 280
|
||||
onWidgetSizeChanged:(maxSize) => widgetGrid.maxSize = maxSize
|
||||
}
|
||||
//
|
||||
// Widget grid + console
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: terminalView.enabled ? app.spacing : 0
|
||||
|
||||
//
|
||||
// Widget grid + console
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: terminalView.enabled ? app.spacing : 0
|
||||
|
||||
DashboardItems.WidgetGrid {
|
||||
id: widgetGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 240
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
enabled: false
|
||||
id: terminalView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
Layout.maximumHeight: 280
|
||||
Layout.minimumHeight: 280
|
||||
visible: Layout.bottomMargin > -Layout.minimumHeight
|
||||
Layout.bottomMargin: enabled ? 0 : -Layout.minimumHeight
|
||||
|
||||
Behavior on Layout.bottomMargin { NumberAnimation{} }
|
||||
|
||||
Widgets.Window {
|
||||
id: terminal
|
||||
gradient: true
|
||||
anchors.fill: parent
|
||||
title: qsTr("Console")
|
||||
altButtonEnabled: true
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
altButtonIcon.source: "qrc:/icons/scroll-down.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
onAltButtonClicked: {
|
||||
terminalView.enabled = false
|
||||
dbTitle.consoleChecked = false
|
||||
}
|
||||
|
||||
Widgets.Terminal {
|
||||
anchors.fill: parent
|
||||
widgetEnabled: terminalView.enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DashboardItems.WidgetGrid {
|
||||
id: widgetGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 240
|
||||
}
|
||||
|
||||
//
|
||||
// Dashboard title window
|
||||
//
|
||||
DashboardItems.DashboardTitle {
|
||||
id: dbTitle
|
||||
height: 32
|
||||
Layout.fillWidth: true
|
||||
onConsoleCheckedChanged: {
|
||||
if (terminalView.enabled != consoleChecked)
|
||||
terminalView.enabled = consoleChecked
|
||||
|
||||
Item {
|
||||
enabled: false
|
||||
id: terminalView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
Layout.maximumHeight: 280
|
||||
Layout.minimumHeight: 280
|
||||
visible: Layout.bottomMargin > -Layout.minimumHeight
|
||||
Layout.bottomMargin: enabled ? 0 : -Layout.minimumHeight
|
||||
|
||||
Behavior on Layout.bottomMargin { NumberAnimation{} }
|
||||
|
||||
Widgets.Window {
|
||||
id: terminal
|
||||
gradient: true
|
||||
anchors.fill: parent
|
||||
title: qsTr("Console")
|
||||
altButtonEnabled: true
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
altButtonIcon.source: "qrc:/icons/scroll-down.svg"
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
onAltButtonClicked: {
|
||||
terminalView.enabled = false
|
||||
dbTitle.consoleChecked = false
|
||||
}
|
||||
|
||||
Widgets.Terminal {
|
||||
anchors.fill: parent
|
||||
widgetEnabled: terminalView.enabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dashboard title window
|
||||
//
|
||||
DashboardItems.DashboardTitle {
|
||||
id: dbTitle
|
||||
height: 32
|
||||
Layout.fillWidth: true
|
||||
onConsoleCheckedChanged: {
|
||||
if (terminalView.enabled != consoleChecked)
|
||||
terminalView.enabled = consoleChecked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,259 +29,259 @@ import "../Widgets" as Widgets
|
||||
import "SetupPanes" as SetupPanes
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int setupMargin: 0
|
||||
property int displayedWidth: 380 + app.spacing * 1.5
|
||||
readonly property int maxItemWidth: column.width - 2 * spacing
|
||||
|
||||
//
|
||||
// Displays the setup panel
|
||||
//
|
||||
function show() {
|
||||
setupMargin = 0
|
||||
}
|
||||
|
||||
//
|
||||
// Hides the setup panel
|
||||
//
|
||||
function hide() {
|
||||
setupMargin = -1 * displayedWidth
|
||||
}
|
||||
|
||||
//
|
||||
// Animations
|
||||
//
|
||||
visible: setupMargin > -1 * displayedWidth
|
||||
Behavior on setupMargin {NumberAnimation{}}
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
//
|
||||
// Misc settings
|
||||
//
|
||||
property alias auto: commAuto.checked
|
||||
property alias manual: commManual.checked
|
||||
property alias tabIndex: tab.currentIndex
|
||||
property alias csvExport: csvLogging.checked
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
// MQTT settings
|
||||
//
|
||||
property int setupMargin: 0
|
||||
property int displayedWidth: 380 + app.spacing * 1.5
|
||||
readonly property int maxItemWidth: column.width - 2 * spacing
|
||||
property alias mqttHost: mqtt.host
|
||||
property alias mqttPort: mqtt.port
|
||||
property alias mqttUser: mqtt.user
|
||||
property alias mqttMode: mqtt.mode
|
||||
property alias mqttTopic: mqtt.topic
|
||||
property alias mqttVersion: mqtt.version
|
||||
property alias mqttPassword: mqtt.password
|
||||
|
||||
//
|
||||
// Displays the setup panel
|
||||
// App settings
|
||||
//
|
||||
function show() {
|
||||
setupMargin = 0
|
||||
property alias language: settings.language
|
||||
property alias tcpPlugins: settings.tcpPlugins
|
||||
property alias windowShadows: settings.windowShadows
|
||||
}
|
||||
|
||||
//
|
||||
// Update manual/auto checkboxes
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_JSON_Generator
|
||||
function onOperationModeChanged() {
|
||||
commAuto.checked = (Cpp_JSON_Generator.operationMode === 1)
|
||||
commManual.checked = (Cpp_JSON_Generator.operationMode === 0)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window
|
||||
//
|
||||
Widgets.Window {
|
||||
gradient: true
|
||||
title: qsTr("Setup")
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 0
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
//
|
||||
// Hides the setup panel
|
||||
// Control arrangement
|
||||
//
|
||||
function hide() {
|
||||
setupMargin = -1 * displayedWidth
|
||||
}
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing / 2
|
||||
anchors.margins: app.spacing * 1.5
|
||||
|
||||
//
|
||||
// Animations
|
||||
//
|
||||
visible: setupMargin > -1 * displayedWidth
|
||||
Behavior on setupMargin {NumberAnimation{}}
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
//
|
||||
// Misc settings
|
||||
//
|
||||
property alias auto: commAuto.checked
|
||||
property alias manual: commManual.checked
|
||||
property alias tabIndex: tab.currentIndex
|
||||
property alias csvExport: csvLogging.checked
|
||||
|
||||
//
|
||||
// MQTT settings
|
||||
//
|
||||
property alias mqttHost: mqtt.host
|
||||
property alias mqttPort: mqtt.port
|
||||
property alias mqttUser: mqtt.user
|
||||
property alias mqttMode: mqtt.mode
|
||||
property alias mqttTopic: mqtt.topic
|
||||
property alias mqttVersion: mqtt.version
|
||||
property alias mqttPassword: mqtt.password
|
||||
|
||||
//
|
||||
// App settings
|
||||
//
|
||||
property alias language: settings.language
|
||||
property alias tcpPlugins: settings.tcpPlugins
|
||||
property alias windowShadows: settings.windowShadows
|
||||
}
|
||||
|
||||
//
|
||||
// Update manual/auto checkboxes
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_JSON_Generator
|
||||
function onOperationModeChanged() {
|
||||
commAuto.checked = (Cpp_JSON_Generator.operationMode === 1)
|
||||
commManual.checked = (Cpp_JSON_Generator.operationMode === 0)
|
||||
//
|
||||
// Comm mode selector
|
||||
//
|
||||
Label {
|
||||
font.bold: true
|
||||
text: qsTr("Communication Mode") + ":"
|
||||
} RadioButton {
|
||||
id: commAuto
|
||||
checked: true
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
text: qsTr("No parsing (device sends JSON data)")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
Cpp_JSON_Generator.setOperationMode(1)
|
||||
else
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window
|
||||
//
|
||||
Widgets.Window {
|
||||
gradient: true
|
||||
title: qsTr("Setup")
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 0
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
anchors.margins: (app.spacing * 1.5) - 5
|
||||
backgroundColor: Cpp_ThemeManager.paneWindowBackground
|
||||
|
||||
//
|
||||
// Control arrangement
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing / 2
|
||||
anchors.margins: app.spacing * 1.5
|
||||
|
||||
//
|
||||
// Comm mode selector
|
||||
//
|
||||
Label {
|
||||
font.bold: true
|
||||
text: qsTr("Communication Mode") + ":"
|
||||
} RadioButton {
|
||||
id: commAuto
|
||||
checked: true
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
text: qsTr("No parsing (device sends JSON data)")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
Cpp_JSON_Generator.setOperationMode(1)
|
||||
else
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
}
|
||||
} RadioButton {
|
||||
id: commManual
|
||||
checked: false
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
text: qsTr("Parse via JSON project file")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
else
|
||||
Cpp_JSON_Generator.setOperationMode(1)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Map file selector button
|
||||
//
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: commManual.checked
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
onClicked: Cpp_JSON_Generator.loadJsonMap()
|
||||
text: (Cpp_JSON_Generator.jsonMapFilename.length ? qsTr("Change project file (%1)").arg(Cpp_JSON_Generator.jsonMapFilename) :
|
||||
qsTr("Select project file") + "...")
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Enable/disable CSV logging
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Switch {
|
||||
id: csvLogging
|
||||
text: qsTr("Create CSV file")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
palette.highlight: Cpp_ThemeManager.csvCheckbox
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_CSV_Export.exportEnabled !== checked)
|
||||
Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/help.svg"
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Tab bar
|
||||
//
|
||||
TabBar {
|
||||
height: 24
|
||||
id: tab
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Device")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("MQTT")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Settings")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab bar contents
|
||||
//
|
||||
StackLayout {
|
||||
id: stack
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tab.currentIndex
|
||||
Layout.topMargin: -parent.spacing - 1
|
||||
|
||||
SetupPanes.Hardware {
|
||||
id: hardware
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
SetupPanes.MQTT {
|
||||
id: mqtt
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
SetupPanes.Settings {
|
||||
id: settings
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
}
|
||||
} RadioButton {
|
||||
id: commManual
|
||||
checked: false
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
text: qsTr("Parse via JSON project file")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
else
|
||||
Cpp_JSON_Generator.setOperationMode(1)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Map file selector button
|
||||
//
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: commManual.checked
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
onClicked: Cpp_JSON_Generator.loadJsonMap()
|
||||
text: (Cpp_JSON_Generator.jsonMapFilename.length ? qsTr("Change project file (%1)").arg(Cpp_JSON_Generator.jsonMapFilename) :
|
||||
qsTr("Select project file") + "...")
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Enable/disable CSV logging
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Switch {
|
||||
id: csvLogging
|
||||
text: qsTr("Create CSV file")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
palette.highlight: Cpp_ThemeManager.csvCheckbox
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_CSV_Export.exportEnabled !== checked)
|
||||
Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/help.svg"
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Tab bar
|
||||
//
|
||||
TabBar {
|
||||
height: 24
|
||||
id: tab
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.maxItemWidth
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Device")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("MQTT")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Settings")
|
||||
height: tab.height + 3
|
||||
width: implicitWidth + 2 * app.spacing
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab bar contents
|
||||
//
|
||||
StackLayout {
|
||||
id: stack
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tab.currentIndex
|
||||
Layout.topMargin: -parent.spacing - 1
|
||||
|
||||
SetupPanes.Hardware {
|
||||
id: hardware
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
SetupPanes.MQTT {
|
||||
id: mqtt
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
SetupPanes.Settings {
|
||||
id: settings
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,150 +25,150 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Start BLE scanning 2 seconds after the control is created
|
||||
//
|
||||
Component.onCompleted: timer.start()
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 2000
|
||||
onTriggered: Cpp_IO_Bluetooth_LE.startDiscovery()
|
||||
}
|
||||
|
||||
//
|
||||
// Control layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Start BLE scanning 2 seconds after the control is created
|
||||
// Device selector + refresh button
|
||||
//
|
||||
Component.onCompleted: timer.start()
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 2000
|
||||
onTriggered: Cpp_IO_Bluetooth_LE.startDiscovery()
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount > 0 ? 1 : 0
|
||||
|
||||
Label {
|
||||
id: devLabel
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Device") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth)
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: _deviceCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
model: Cpp_IO_Bluetooth_LE.deviceNames
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Bluetooth_LE.currentDevice)
|
||||
Cpp_IO_Bluetooth_LE.selectDevice(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
width: 24
|
||||
height: 24
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
icon.source: "qrc:/icons/refresh.svg"
|
||||
onClicked: Cpp_IO_Bluetooth_LE.startDiscovery()
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control layout
|
||||
// Service selector
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && serviceNames.count > 1 ? 1 : 0
|
||||
|
||||
//
|
||||
// Device selector + refresh button
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount > 0 ? 1 : 0
|
||||
Label {
|
||||
id: servLabel
|
||||
text: qsTr("Service") + ":"
|
||||
Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth)
|
||||
}
|
||||
|
||||
Label {
|
||||
id: devLabel
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Device") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth)
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: _deviceCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
model: Cpp_IO_Bluetooth_LE.deviceNames
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Bluetooth_LE.currentDevice)
|
||||
Cpp_IO_Bluetooth_LE.selectDevice(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
width: 24
|
||||
height: 24
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
icon.source: "qrc:/icons/refresh.svg"
|
||||
onClicked: Cpp_IO_Bluetooth_LE.startDiscovery()
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Service selector
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && serviceNames.count > 1 ? 1 : 0
|
||||
|
||||
Label {
|
||||
id: servLabel
|
||||
text: qsTr("Service") + ":"
|
||||
Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth)
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: serviceNames
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Bluetooth_LE.serviceNames
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: Cpp_IO_Bluetooth_LE.selectService(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Scanning indicator
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount < 1 ? 1 : 0
|
||||
|
||||
BusyIndicator {
|
||||
running: parent.visible
|
||||
Layout.minimumWidth: 16
|
||||
Layout.minimumHeight: 16
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Scanning....")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// OS not supported indicator
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: !Cpp_IO_Bluetooth_LE.operatingSystemSupported
|
||||
|
||||
ToolButton {
|
||||
flat: true
|
||||
enabled: false
|
||||
icon.width: 32
|
||||
icon.height: 32
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/heart-broken.svg"
|
||||
icon.color: Cpp_ThemeManager.connectButtonChecked
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WordWrap
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: qsTr("Sorry, this version of %1 is not supported yet. " +
|
||||
"We'll update Serial Studio to work with this operating " +
|
||||
"system as soon as Qt officially supports it.").arg(Cpp_OSName);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
ComboBox {
|
||||
id: serviceNames
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Bluetooth_LE.serviceNames
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: Cpp_IO_Bluetooth_LE.selectService(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Scanning indicator
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount < 1 ? 1 : 0
|
||||
|
||||
BusyIndicator {
|
||||
running: parent.visible
|
||||
Layout.minimumWidth: 16
|
||||
Layout.minimumHeight: 16
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Scanning....")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// OS not supported indicator
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
visible: opacity > 0
|
||||
opacity: !Cpp_IO_Bluetooth_LE.operatingSystemSupported
|
||||
|
||||
ToolButton {
|
||||
flat: true
|
||||
enabled: false
|
||||
icon.width: 32
|
||||
icon.height: 32
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/heart-broken.svg"
|
||||
icon.color: Cpp_ThemeManager.connectButtonChecked
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WordWrap
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: qsTr("Sorry, this version of %1 is not supported yet. " +
|
||||
"We'll update Serial Studio to work with this operating " +
|
||||
"system as soon as Qt officially supports it.").arg(Cpp_OSName);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,259 +25,259 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias address: _address.text
|
||||
property alias tcpPort: _tcpPort.text
|
||||
property alias udpLocalPort: _udpLocalPort.text
|
||||
property alias udpRemotePort: _udpRemotePort.text
|
||||
property alias socketType: _typeCombo.currentIndex
|
||||
property alias udpMulticastEnabled: _udpMulticast.checked
|
||||
property alias udpProcessDatagramsDirectly: _udpProcessDatagrams.checked
|
||||
|
||||
//
|
||||
// React to network manager events
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_IO_Network
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias address: _address.text
|
||||
property alias tcpPort: _tcpPort.text
|
||||
property alias udpLocalPort: _udpLocalPort.text
|
||||
property alias udpRemotePort: _udpRemotePort.text
|
||||
property alias socketType: _typeCombo.currentIndex
|
||||
property alias udpMulticastEnabled: _udpMulticast.checked
|
||||
property alias udpProcessDatagramsDirectly: _udpProcessDatagrams.checked
|
||||
|
||||
function onAddressChanged() {
|
||||
if (_address.text.length > 0)
|
||||
_address.text = Cpp_IO_Network.remoteAddress
|
||||
//
|
||||
// React to network manager events
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_IO_Network
|
||||
|
||||
function onAddressChanged() {
|
||||
if (_address.text.length > 0)
|
||||
_address.text = Cpp_IO_Network.remoteAddress
|
||||
}
|
||||
|
||||
function onPortChanged() {
|
||||
if (_tcpPort.text.length > 0)
|
||||
_tcpPort.text = Cpp_IO_Network.tcpPort
|
||||
|
||||
if (_udpLocalPort.text.length > 0)
|
||||
_udpLocalPort.text = Cpp_IO_Network.udpLocalPort
|
||||
|
||||
if (_udpRemotePort.text.length > 0)
|
||||
_udpRemotePort.text = Cpp_IO_Network.udpRemotePort
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Socket type
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Socket type") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
} ComboBox {
|
||||
id: _typeCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
model: Cpp_IO_Network.socketTypes
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
currentIndex: Cpp_IO_Network.socketTypeIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Network.socketTypeIndex)
|
||||
Cpp_IO_Network.socketTypeIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Address
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
text: qsTr("Remote address") + ":"
|
||||
} TextField {
|
||||
id: _address
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
placeholderText: Cpp_IO_Network.defaultAddress
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.remoteAddress
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.remoteAddress !== text && text.length > 0)
|
||||
Cpp_IO_Network.remoteAddress = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.remoteAddress = Cpp_IO_Network.defaultAddress
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TCP port
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Port") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 0
|
||||
} TextField {
|
||||
id: _tcpPort
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
placeholderText: Cpp_IO_Network.defaultTcpPort
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.tcpPort
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.tcpPort !== text && text.length > 0)
|
||||
Cpp_IO_Network.tcpPort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.port = Cpp_IO_Network.defaultTcpPort
|
||||
}
|
||||
|
||||
function onPortChanged() {
|
||||
if (_tcpPort.text.length > 0)
|
||||
_tcpPort.text = Cpp_IO_Network.tcpPort
|
||||
|
||||
if (_udpLocalPort.text.length > 0)
|
||||
_udpLocalPort.text = Cpp_IO_Network.udpLocalPort
|
||||
|
||||
if (_udpRemotePort.text.length > 0)
|
||||
_udpRemotePort.text = Cpp_IO_Network.udpRemotePort
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
|
||||
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 0
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TCP port
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Local port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} TextField {
|
||||
id: _udpLocalPort
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Type 0 for automatic port")
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.udpLocalPort
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.udpLocalPort !== text && text.length > 0)
|
||||
Cpp_IO_Network.udpLocalPort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.udpLocalPort = Cpp_IO_Network.defaultUdpLocalPort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
}
|
||||
|
||||
//
|
||||
// Output port
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Remote port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
|
||||
} TextField {
|
||||
id: _udpRemotePort
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
placeholderText: Cpp_IO_Network.defaultUdpRemotePort
|
||||
Component.onCompleted: text = Cpp_IO_Network.udpRemotePort
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.udpRemotePort !== text && text.length > 0)
|
||||
Cpp_IO_Network.udpRemotePort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.udpRemotePort = Cpp_IO_Network.defaultUdpRemotePort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UDP multicast checkbox
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Multicast") + ":"
|
||||
opacity: _udpMulticast.enabled ? 1 : 0.5
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} CheckBox {
|
||||
id: _udpMulticast
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_IO_Network.udpMulticast
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Network.udpMulticast !== checked)
|
||||
Cpp_IO_Network.udpMulticast = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UDP multicast checkbox
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Ignore data delimiters") + ":"
|
||||
opacity: _udpProcessDatagrams.enabled ? 1 : 0.5
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} CheckBox {
|
||||
id: _udpProcessDatagrams
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
checked: Cpp_IO_Network.udpIgnoreFrameSequences
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Network.udpIgnoreFrameSequences !== checked)
|
||||
Cpp_IO_Network.udpIgnoreFrameSequences = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Layout
|
||||
// Spacer
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Socket type
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Socket type") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
} ComboBox {
|
||||
id: _typeCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
model: Cpp_IO_Network.socketTypes
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
currentIndex: Cpp_IO_Network.socketTypeIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Network.socketTypeIndex)
|
||||
Cpp_IO_Network.socketTypeIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Address
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
text: qsTr("Remote address") + ":"
|
||||
} TextField {
|
||||
id: _address
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
placeholderText: Cpp_IO_Network.defaultAddress
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.remoteAddress
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.remoteAddress !== text && text.length > 0)
|
||||
Cpp_IO_Network.remoteAddress = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.remoteAddress = Cpp_IO_Network.defaultAddress
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TCP port
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Port") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 0
|
||||
} TextField {
|
||||
id: _tcpPort
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
placeholderText: Cpp_IO_Network.defaultTcpPort
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.tcpPort
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.tcpPort !== text && text.length > 0)
|
||||
Cpp_IO_Network.tcpPort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.port = Cpp_IO_Network.defaultTcpPort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
|
||||
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 0
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TCP port
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Local port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} TextField {
|
||||
id: _udpLocalPort
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Type 0 for automatic port")
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
Component.onCompleted: text = Cpp_IO_Network.udpLocalPort
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.udpLocalPort !== text && text.length > 0)
|
||||
Cpp_IO_Network.udpLocalPort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.udpLocalPort = Cpp_IO_Network.defaultUdpLocalPort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
}
|
||||
|
||||
//
|
||||
// Output port
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Remote port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
|
||||
} TextField {
|
||||
id: _udpRemotePort
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
placeholderText: Cpp_IO_Network.defaultUdpRemotePort
|
||||
Component.onCompleted: text = Cpp_IO_Network.udpRemotePort
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1 && !udpMulticastEnabled
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_IO_Network.udpRemotePort !== text && text.length > 0)
|
||||
Cpp_IO_Network.udpRemotePort = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_IO_Network.udpRemotePort = Cpp_IO_Network.defaultUdpRemotePort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UDP multicast checkbox
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Multicast") + ":"
|
||||
opacity: _udpMulticast.enabled ? 1 : 0.5
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} CheckBox {
|
||||
id: _udpMulticast
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_IO_Network.udpMulticast
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Network.udpMulticast !== checked)
|
||||
Cpp_IO_Network.udpMulticast = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UDP multicast checkbox
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Ignore data delimiters") + ":"
|
||||
opacity: _udpProcessDatagrams.enabled ? 1 : 0.5
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
} CheckBox {
|
||||
id: _udpProcessDatagrams
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
visible: Cpp_IO_Network.socketTypeIndex === 1
|
||||
checked: Cpp_IO_Network.udpIgnoreFrameSequences
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
enabled: Cpp_IO_Network.socketTypeIndex === 1 && !Cpp_IO_Manager.connected
|
||||
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Network.udpIgnoreFrameSequences !== checked)
|
||||
Cpp_IO_Network.udpIgnoreFrameSequences = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,207 +25,207 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias port: _portCombo.currentIndex
|
||||
property alias baudRate: _baudCombo.currentIndex
|
||||
property alias dataBits: _dataCombo.currentIndex
|
||||
property alias parity: _parityCombo.currentIndex
|
||||
property alias flowControl: _flowCombo.currentIndex
|
||||
property alias stopBits: _stopBitsCombo.currentIndex
|
||||
property alias autoReconnect: _autoreconnect.checked
|
||||
|
||||
//
|
||||
// Update listbox models when translation is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
var oldParityIndex = _parityCombo.currentIndex
|
||||
var oldFlowControlIndex = _flowCombo.currentIndex
|
||||
|
||||
_parityCombo.model = Cpp_IO_Serial.parityList
|
||||
_flowCombo.model = Cpp_IO_Serial.flowControlList
|
||||
|
||||
_parityCombo.currentIndex = oldParityIndex
|
||||
_flowCombo.currentIndex = oldFlowControlIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control layout
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
// Controls
|
||||
//
|
||||
property alias port: _portCombo.currentIndex
|
||||
property alias baudRate: _baudCombo.currentIndex
|
||||
property alias dataBits: _dataCombo.currentIndex
|
||||
property alias parity: _parityCombo.currentIndex
|
||||
property alias flowControl: _flowCombo.currentIndex
|
||||
property alias stopBits: _stopBitsCombo.currentIndex
|
||||
property alias autoReconnect: _autoreconnect.checked
|
||||
GridLayout {
|
||||
id: layout
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Update listbox models when translation is changed
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_Translator
|
||||
function onLanguageChanged() {
|
||||
var oldParityIndex = _parityCombo.currentIndex
|
||||
var oldFlowControlIndex = _flowCombo.currentIndex
|
||||
|
||||
_parityCombo.model = Cpp_IO_Serial.parityList
|
||||
_flowCombo.model = Cpp_IO_Serial.flowControlList
|
||||
|
||||
_parityCombo.currentIndex = oldParityIndex
|
||||
_flowCombo.currentIndex = oldFlowControlIndex
|
||||
//
|
||||
// COM port selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("COM Port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
} ComboBox {
|
||||
id: _portCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
model: Cpp_IO_Serial.portList
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
currentIndex: Cpp_IO_Serial.portIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Serial.portIndex)
|
||||
Cpp_IO_Serial.portIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Baud rate selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Baud Rate") + ":"
|
||||
} ComboBox {
|
||||
id: _baudCombo
|
||||
editable: true
|
||||
currentIndex: 4
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.baudRateList
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (find(editText) === -1)
|
||||
Cpp_IO_Serial.appendBaudRate(editText)
|
||||
}
|
||||
|
||||
onCurrentTextChanged: {
|
||||
var value = currentText
|
||||
Cpp_IO_Serial.baudRate = value
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Auto-reconnect
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Auto-reconnect") + ":"
|
||||
} CheckBox {
|
||||
id: _autoreconnect
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_IO_Serial.autoReconnect
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Serial.autoReconnect !== checked)
|
||||
Cpp_IO_Serial.autoReconnect = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
} Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Data bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Data Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _dataCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.dataBitsList
|
||||
currentIndex: Cpp_IO_Serial.dataBitsIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.dataBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.dataBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Parity selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Parity") + ":"
|
||||
} ComboBox {
|
||||
id: _parityCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.parityList
|
||||
currentIndex: Cpp_IO_Serial.parityIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.parityIndex !== currentIndex)
|
||||
Cpp_IO_Serial.parityIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Stop bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Stop Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _stopBitsCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.stopBitsList
|
||||
currentIndex: Cpp_IO_Serial.stopBitsIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.stopBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.stopBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Flow control selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Flow Control") + ":"
|
||||
} ComboBox {
|
||||
id: _flowCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.flowControlList
|
||||
currentIndex: Cpp_IO_Serial.flowControlIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.flowControlIndex !== currentIndex)
|
||||
Cpp_IO_Serial.flowControlIndex = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control layout
|
||||
// Vertical spacer
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
GridLayout {
|
||||
id: layout
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// COM port selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("COM Port") + ":"
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
} ComboBox {
|
||||
id: _portCombo
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
model: Cpp_IO_Serial.portList
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
currentIndex: Cpp_IO_Serial.portIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Serial.portIndex)
|
||||
Cpp_IO_Serial.portIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Baud rate selector
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Baud Rate") + ":"
|
||||
} ComboBox {
|
||||
id: _baudCombo
|
||||
editable: true
|
||||
currentIndex: 4
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.baudRateList
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
if (find(editText) === -1)
|
||||
Cpp_IO_Serial.appendBaudRate(editText)
|
||||
}
|
||||
|
||||
onCurrentTextChanged: {
|
||||
var value = currentText
|
||||
Cpp_IO_Serial.baudRate = value
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Auto-reconnect
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Auto-reconnect") + ":"
|
||||
} CheckBox {
|
||||
id: _autoreconnect
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_IO_Serial.autoReconnect
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Serial.autoReconnect !== checked)
|
||||
Cpp_IO_Serial.autoReconnect = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
} Item {
|
||||
Layout.minimumHeight: app.spacing / 2
|
||||
Layout.maximumHeight: app.spacing / 2
|
||||
}
|
||||
|
||||
//
|
||||
// Data bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Data Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _dataCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.dataBitsList
|
||||
currentIndex: Cpp_IO_Serial.dataBitsIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.dataBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.dataBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Parity selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Parity") + ":"
|
||||
} ComboBox {
|
||||
id: _parityCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.parityList
|
||||
currentIndex: Cpp_IO_Serial.parityIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.parityIndex !== currentIndex)
|
||||
Cpp_IO_Serial.parityIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Stop bits selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Stop Bits") + ":"
|
||||
} ComboBox {
|
||||
id: _stopBitsCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.stopBitsList
|
||||
currentIndex: Cpp_IO_Serial.stopBitsIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.stopBitsIndex !== currentIndex)
|
||||
Cpp_IO_Serial.stopBitsIndex = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Flow control selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Flow Control") + ":"
|
||||
} ComboBox {
|
||||
id: _flowCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_IO_Serial.flowControlList
|
||||
currentIndex: Cpp_IO_Serial.flowControlIndex
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_IO_Serial.flowControlIndex !== currentIndex)
|
||||
Cpp_IO_Serial.flowControlIndex = currentIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -29,90 +29,90 @@ import "Devices" as Devices
|
||||
import "../../Windows" as Windows
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
QtSettings.Settings {
|
||||
property alias driver: _driverCombo.currentIndex
|
||||
property alias parity: serial.parity
|
||||
property alias baudRate: serial.baudRate
|
||||
property alias dataBits: serial.dataBits
|
||||
property alias stopBits: serial.stopBits
|
||||
property alias flowControl: serial.flowControl
|
||||
property alias autoReconnect: serial.autoReconnect
|
||||
property alias address: network.address
|
||||
property alias tcpPort: network.tcpPort
|
||||
property alias socketType: network.socketType
|
||||
property alias udpLocalPort: network.udpLocalPort
|
||||
property alias udpRemotePort: network.udpRemotePort
|
||||
property alias udpMulticastEnabled: network.udpMulticastEnabled
|
||||
property alias udpProcessDatagramsDirectly: network.udpProcessDatagramsDirectly
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Save settings
|
||||
// Device type selector
|
||||
//
|
||||
QtSettings.Settings {
|
||||
property alias driver: _driverCombo.currentIndex
|
||||
property alias parity: serial.parity
|
||||
property alias baudRate: serial.baudRate
|
||||
property alias dataBits: serial.dataBits
|
||||
property alias stopBits: serial.stopBits
|
||||
property alias flowControl: serial.flowControl
|
||||
property alias autoReconnect: serial.autoReconnect
|
||||
property alias address: network.address
|
||||
property alias tcpPort: network.tcpPort
|
||||
property alias socketType: network.socketType
|
||||
property alias udpLocalPort: network.udpLocalPort
|
||||
property alias udpRemotePort: network.udpRemotePort
|
||||
property alias udpMulticastEnabled: network.udpMulticastEnabled
|
||||
property alias udpProcessDatagramsDirectly: network.udpProcessDatagramsDirectly
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("Data source") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: _driverCombo
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Manager.availableDrivers()
|
||||
onCurrentIndexChanged: Cpp_IO_Manager.selectedDriver = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
//
|
||||
// Device configuration
|
||||
//
|
||||
StackLayout {
|
||||
id: stack
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: Cpp_IO_Manager.selectedDriver
|
||||
|
||||
//
|
||||
// Device type selector
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("Data source") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: _driverCombo
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Manager.availableDrivers()
|
||||
onCurrentIndexChanged: Cpp_IO_Manager.selectedDriver = currentIndex
|
||||
}
|
||||
Devices.Serial {
|
||||
id: serial
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Device configuration
|
||||
//
|
||||
StackLayout {
|
||||
id: stack
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: Cpp_IO_Manager.selectedDriver
|
||||
|
||||
Devices.Serial {
|
||||
id: serial
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
Devices.Network {
|
||||
id: network
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
Devices.BluetoothLE {
|
||||
id: bluetoothLE
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
Devices.Network {
|
||||
id: network
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
Devices.BluetoothLE {
|
||||
id: bluetoothLE
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,274 +27,274 @@ import QtQuick.Controls
|
||||
import "../../Windows" as Windows
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
property alias host: _host.text
|
||||
property alias port: _port.text
|
||||
property alias topic: _topic.text
|
||||
property alias user: _user.text
|
||||
property alias password: _password.text
|
||||
property alias version: _version.currentIndex
|
||||
property alias mode: _mode.currentIndex
|
||||
|
||||
//
|
||||
// React to events from MQTT module
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_MQTT_Client
|
||||
|
||||
function onHostChanged() {
|
||||
if (_host.text.length > 0)
|
||||
_host.text = Cpp_MQTT_Client.host
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
property alias host: _host.text
|
||||
property alias port: _port.text
|
||||
property alias topic: _topic.text
|
||||
property alias user: _user.text
|
||||
property alias password: _password.text
|
||||
property alias version: _version.currentIndex
|
||||
property alias mode: _mode.currentIndex
|
||||
|
||||
//
|
||||
// React to events from MQTT module
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_MQTT_Client
|
||||
|
||||
function onHostChanged() {
|
||||
if (_host.text.length > 0)
|
||||
_host.text = Cpp_MQTT_Client.host
|
||||
}
|
||||
|
||||
function onPortChanged() {
|
||||
if (_port.text.length > 0)
|
||||
_port.text = Cpp_MQTT_Client.port
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// MQTT version
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Version") + ":"
|
||||
} ComboBox {
|
||||
id: _version
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_MQTT_Client.mqttVersions
|
||||
currentIndex: Cpp_MQTT_Client.mqttVersion
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_MQTT_Client.mqttVersion !== currentIndex)
|
||||
Cpp_MQTT_Client.mqttVersion = currentIndex
|
||||
}
|
||||
|
||||
function onPortChanged() {
|
||||
if (_port.text.length > 0)
|
||||
_port.text = Cpp_MQTT_Client.port
|
||||
}
|
||||
|
||||
//
|
||||
// Client mode version
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Mode") + ":"
|
||||
} ComboBox {
|
||||
id: _mode
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_MQTT_Client.clientModes
|
||||
currentIndex: Cpp_MQTT_Client.clientMode
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_MQTT_Client.clientMode !== currentIndex)
|
||||
Cpp_MQTT_Client.clientMode = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Host
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Host") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _host
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
placeholderText: Cpp_MQTT_Client.defaultHost
|
||||
Component.onCompleted: text = Cpp_MQTT_Client.host
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.host !== text && text.length > 0)
|
||||
Cpp_MQTT_Client.host = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_MQTT_Client.host = Cpp_MQTT_Client.defaultHost
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Port
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Port") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _port
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
placeholderText: Cpp_MQTT_Client.defaultPort
|
||||
Component.onCompleted: text = Cpp_MQTT_Client.port
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.port !== text && text.length > 0)
|
||||
Cpp_MQTT_Client.port = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_MQTT_Client.port = Cpp_MQTT_Client.defaultPort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Topic
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Topic") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _topic
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: Cpp_MQTT_Client.topic
|
||||
placeholderText: qsTr("MQTT topic")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.topic !== text)
|
||||
Cpp_MQTT_Client.topic = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Username
|
||||
//
|
||||
Label {
|
||||
text: qsTr("User") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _user
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: Cpp_MQTT_Client.username
|
||||
placeholderText: qsTr("MQTT username")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.username !== text)
|
||||
Cpp_MQTT_Client.username = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Password
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Password") + ":"
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: app.spacing / 2
|
||||
|
||||
TextField {
|
||||
id: _password
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
echoMode: TextField.Password
|
||||
text: Cpp_MQTT_Client.password
|
||||
placeholderText: qsTr("MQTT password")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.password !== text)
|
||||
Cpp_MQTT_Client.password = text
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
checkable: true
|
||||
icon.color: palette.text
|
||||
Layout.maximumWidth: height
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/visibility.svg"
|
||||
onCheckedChanged: _password.echoMode = (checked ? TextField.Normal :
|
||||
TextField.Password)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Layout
|
||||
// Spacer
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// MQTT version
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Version") + ":"
|
||||
} ComboBox {
|
||||
id: _version
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_MQTT_Client.mqttVersions
|
||||
currentIndex: Cpp_MQTT_Client.mqttVersion
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_MQTT_Client.mqttVersion !== currentIndex)
|
||||
Cpp_MQTT_Client.mqttVersion = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Client mode version
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Mode") + ":"
|
||||
} ComboBox {
|
||||
id: _mode
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_MQTT_Client.clientModes
|
||||
currentIndex: Cpp_MQTT_Client.clientMode
|
||||
onCurrentIndexChanged: {
|
||||
if (Cpp_MQTT_Client.clientMode !== currentIndex)
|
||||
Cpp_MQTT_Client.clientMode = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Host
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Host") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _host
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
placeholderText: Cpp_MQTT_Client.defaultHost
|
||||
Component.onCompleted: text = Cpp_MQTT_Client.host
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.host !== text && text.length > 0)
|
||||
Cpp_MQTT_Client.host = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_MQTT_Client.host = Cpp_MQTT_Client.defaultHost
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Port
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Port") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _port
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
placeholderText: Cpp_MQTT_Client.defaultPort
|
||||
Component.onCompleted: text = Cpp_MQTT_Client.port
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.port !== text && text.length > 0)
|
||||
Cpp_MQTT_Client.port = text
|
||||
|
||||
if (text.length === 0)
|
||||
Cpp_MQTT_Client.port = Cpp_MQTT_Client.defaultPort
|
||||
}
|
||||
|
||||
validator: IntValidator {
|
||||
bottom: 0
|
||||
top: 65535
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Topic
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Topic") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _topic
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: Cpp_MQTT_Client.topic
|
||||
placeholderText: qsTr("MQTT topic")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.topic !== text)
|
||||
Cpp_MQTT_Client.topic = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Username
|
||||
//
|
||||
Label {
|
||||
text: qsTr("User") + ":"
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} TextField {
|
||||
id: _user
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: Cpp_MQTT_Client.username
|
||||
placeholderText: qsTr("MQTT username")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.username !== text)
|
||||
Cpp_MQTT_Client.username = text
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Password
|
||||
//
|
||||
Label {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Password") + ":"
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
} RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: app.spacing / 2
|
||||
|
||||
TextField {
|
||||
id: _password
|
||||
Layout.fillWidth: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
echoMode: TextField.Password
|
||||
text: Cpp_MQTT_Client.password
|
||||
placeholderText: qsTr("MQTT password")
|
||||
enabled: !Cpp_MQTT_Client.isConnectedToHost
|
||||
|
||||
onTextChanged: {
|
||||
if (Cpp_MQTT_Client.password !== text)
|
||||
Cpp_MQTT_Client.password = text
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
checkable: true
|
||||
icon.color: palette.text
|
||||
Layout.maximumWidth: height
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: "qrc:/icons/visibility.svg"
|
||||
onCheckedChanged: _password.echoMode = (checked ? TextField.Normal :
|
||||
TextField.Password)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
//
|
||||
// Advanced setup & connect/disconnect button
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
onClicked: mqttSetup.show()
|
||||
icon.color: palette.buttonText
|
||||
text: qsTr("Advanced setup") + " "
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
icon.color: Cpp_ThemeManager.mqttButton
|
||||
checked: Cpp_MQTT_Client.isConnectedToHost
|
||||
palette.buttonText: Cpp_ThemeManager.mqttButton
|
||||
onClicked: Cpp_MQTT_Client.toggleConnection()
|
||||
text: (checked ? qsTr("Disconnect") :
|
||||
qsTr("Connect to broker")) + " "
|
||||
icon.source: checked ? "qrc:/icons/disconnect.svg" :
|
||||
"qrc:/icons/connect.svg"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumHeight: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// MQTT setup dialog
|
||||
// Spacer
|
||||
//
|
||||
Windows.MQTTConfiguration {
|
||||
id: mqttSetup
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
//
|
||||
// Advanced setup & connect/disconnect button
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
onClicked: mqttSetup.show()
|
||||
icon.color: palette.buttonText
|
||||
text: qsTr("Advanced setup") + " "
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
icon.color: Cpp_ThemeManager.mqttButton
|
||||
checked: Cpp_MQTT_Client.isConnectedToHost
|
||||
palette.buttonText: Cpp_ThemeManager.mqttButton
|
||||
onClicked: Cpp_MQTT_Client.toggleConnection()
|
||||
text: (checked ? qsTr("Disconnect") :
|
||||
qsTr("Connect to broker")) + " "
|
||||
icon.source: checked ? "qrc:/icons/disconnect.svg" :
|
||||
"qrc:/icons/connect.svg"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MQTT setup dialog
|
||||
//
|
||||
Windows.MQTTConfiguration {
|
||||
id: mqttSetup
|
||||
}
|
||||
}
|
||||
|
@ -25,131 +25,115 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
//
|
||||
property alias tcpPlugins: _tcpPlugins.checked
|
||||
property alias language: _langCombo.currentIndex
|
||||
property alias windowShadows: _windowShadows.checked
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Access to properties
|
||||
// Controls
|
||||
//
|
||||
property alias tcpPlugins: _tcpPlugins.checked
|
||||
property alias language: _langCombo.currentIndex
|
||||
property alias windowShadows: _windowShadows.checked
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
GridLayout {
|
||||
columns: 2
|
||||
Layout.fillWidth: true
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
|
||||
//
|
||||
// Language selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Language") + ":"
|
||||
} ComboBox {
|
||||
id: _langCombo
|
||||
Layout.fillWidth: true
|
||||
currentIndex: Cpp_Misc_Translator.language
|
||||
model: Cpp_Misc_Translator.availableLanguages
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_Misc_Translator.language)
|
||||
Cpp_Misc_Translator.setLanguage(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Theme selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Theme") + ":"
|
||||
} ComboBox {
|
||||
id: _themeCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_ThemeManager.availableThemes
|
||||
currentIndex: Cpp_ThemeManager.themeId
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_ThemeManager.themeId)
|
||||
Cpp_ThemeManager.setTheme(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Plugins enabled
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Plugin system") + ": "
|
||||
} Switch {
|
||||
id: _tcpPlugins
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
checked: Cpp_Plugins_Bridge.enabled
|
||||
onCheckedChanged: {
|
||||
if (checked !== Cpp_Plugins_Bridge.enabled)
|
||||
Cpp_Plugins_Bridge.enabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom window decorations
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Custom window decorations") + ": "
|
||||
} Switch {
|
||||
id: _windowShadows
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
checked: Cpp_ThemeManager.customWindowDecorations
|
||||
onCheckedChanged: {
|
||||
if (checked != Cpp_ThemeManager.customWindowDecorations)
|
||||
Cpp_ThemeManager.customWindowDecorations = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Software rendering
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Software rendering") + ": "
|
||||
} Switch {
|
||||
id: _softwareRendering
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
checked: Cpp_ModuleManager.softwareRendering
|
||||
onCheckedChanged: {
|
||||
if (checked !== Cpp_ModuleManager.softwareRendering)
|
||||
Cpp_ModuleManager.setSoftwareRenderingEnabled(checked)
|
||||
}
|
||||
}
|
||||
//
|
||||
// Language selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Language") + ":"
|
||||
} ComboBox {
|
||||
id: _langCombo
|
||||
Layout.fillWidth: true
|
||||
currentIndex: Cpp_Misc_Translator.language
|
||||
model: Cpp_Misc_Translator.availableLanguages
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_Misc_Translator.language)
|
||||
Cpp_Misc_Translator.setLanguage(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Plugins label
|
||||
//
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("Applications/plugins can interact with %1 by " +
|
||||
"establishing a TCP connection on port 7777.").arg(Cpp_AppName)
|
||||
//
|
||||
// Theme selector
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Theme") + ":"
|
||||
} ComboBox {
|
||||
id: _themeCombo
|
||||
Layout.fillWidth: true
|
||||
model: Cpp_ThemeManager.availableThemes
|
||||
currentIndex: Cpp_ThemeManager.themeId
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_ThemeManager.themeId)
|
||||
Cpp_ThemeManager.setTheme(currentIndex)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
//
|
||||
// Plugins enabled
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Plugin system") + ": "
|
||||
} Switch {
|
||||
id: _tcpPlugins
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
checked: Cpp_Plugins_Bridge.enabled
|
||||
onCheckedChanged: {
|
||||
if (checked !== Cpp_Plugins_Bridge.enabled)
|
||||
Cpp_Plugins_Bridge.enabled = checked
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Custom window decorations
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Custom window decorations") + ": "
|
||||
} Switch {
|
||||
id: _windowShadows
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
checked: Cpp_ThemeManager.customWindowDecorations
|
||||
onCheckedChanged: {
|
||||
if (checked != Cpp_ThemeManager.customWindowDecorations)
|
||||
Cpp_ThemeManager.customWindowDecorations = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Plugins label
|
||||
//
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("Applications/plugins can interact with %1 by " +
|
||||
"establishing a TCP connection on port 7777.").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,322 +28,296 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Control {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Reference to parent window to be able to drag it with the toolbar
|
||||
//
|
||||
property Window window
|
||||
//
|
||||
// Reference to parent window to be able to drag it with the toolbar
|
||||
//
|
||||
property Window window
|
||||
|
||||
//
|
||||
// Dummy string to increase width of buttons
|
||||
//
|
||||
readonly property string _btSpacer: " "
|
||||
//
|
||||
// Dummy string to increase width of buttons
|
||||
//
|
||||
readonly property string _btSpacer: " "
|
||||
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal setupClicked()
|
||||
signal consoleClicked()
|
||||
signal dashboardClicked()
|
||||
signal projectEditorClicked()
|
||||
//
|
||||
// Custom signals
|
||||
//
|
||||
signal setupClicked()
|
||||
signal consoleClicked()
|
||||
signal dashboardClicked()
|
||||
signal projectEditorClicked()
|
||||
|
||||
//
|
||||
// Aliases to button check status
|
||||
//
|
||||
property alias setupChecked: setupBt.checked
|
||||
property alias consoleChecked: consoleBt.checked
|
||||
property alias dashboardChecked: dashboardBt.checked
|
||||
//
|
||||
// Aliases to button check status
|
||||
//
|
||||
property alias setupChecked: setupBt.checked
|
||||
property alias consoleChecked: consoleBt.checked
|
||||
property alias dashboardChecked: dashboardBt.checked
|
||||
|
||||
//
|
||||
// Connections with mac touchbar
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Misc_MacExtras
|
||||
//
|
||||
// Toolbar shadow
|
||||
//
|
||||
Widgets.Shadow {
|
||||
anchors.fill: bg
|
||||
}
|
||||
|
||||
function onSetupClicked() {
|
||||
setupBt.clicked()
|
||||
Cpp_Misc_MacExtras.setSetupChecked(setupBt.checked)
|
||||
}
|
||||
//
|
||||
// Background gradient + border
|
||||
//
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
|
||||
function onConsoleClicked() {
|
||||
consoleBt.clicked()
|
||||
Cpp_Misc_MacExtras.setConsoleChecked(consoleBt.checked)
|
||||
}
|
||||
|
||||
function onDashboardClicked() {
|
||||
dashboardBt.clicked()
|
||||
Cpp_Misc_MacExtras.setDashboardChecked(dashboardBt.checked)
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0; color: Cpp_ThemeManager.toolbarGradient1 }
|
||||
GradientStop { position: 1; color: Cpp_ThemeManager.toolbarGradient2 }
|
||||
}
|
||||
|
||||
//
|
||||
// Toolbar shadow
|
||||
//
|
||||
Widgets.Shadow {
|
||||
anchors.fill: bg
|
||||
}
|
||||
|
||||
//
|
||||
// Background gradient + border
|
||||
//
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
border.width: 1
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0; color: Cpp_ThemeManager.toolbarGradient1 }
|
||||
GradientStop { position: 1; color: Cpp_ThemeManager.toolbarGradient2 }
|
||||
}
|
||||
Rectangle {
|
||||
height: 1
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toolbar icons
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
Button {
|
||||
id: setupBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
onClicked: root.setupClicked()
|
||||
text: qsTr("Setup") + _btSpacer
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: consoleBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
enabled: dashboardBt.enabled
|
||||
onClicked: root.consoleClicked()
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
text: qsTr("Console") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: dashboardBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: root.dashboardClicked()
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
text: qsTr("Dashboard") + _btSpacer
|
||||
icon.source: "qrc:/icons/dashboard.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Toolbar icons
|
||||
// Window drag handler
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Item {
|
||||
height: parent.height
|
||||
Layout.fillWidth: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
Button {
|
||||
id: setupBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
onClicked: root.setupClicked()
|
||||
text: qsTr("Setup") + _btSpacer
|
||||
icon.source: "qrc:/icons/settings.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
onCheckedChanged: Cpp_Misc_MacExtras.setSetupChecked(checked)
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: consoleBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
enabled: dashboardBt.enabled
|
||||
onClicked: root.consoleClicked()
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
text: qsTr("Console") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
onCheckedChanged: Cpp_Misc_MacExtras.setConsoleChecked(checked)
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: dashboardBt
|
||||
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: root.dashboardClicked()
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
text: qsTr("Dashboard") + _btSpacer
|
||||
icon.source: "qrc:/icons/dashboard.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
onCheckedChanged: Cpp_Misc_MacExtras.setDashboardChecked(checked)
|
||||
onEnabledChanged: Cpp_Misc_MacExtras.setDashboardEnabled(enabled)
|
||||
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
height: parent.height
|
||||
Layout.fillWidth: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
window.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
icon.source: "qrc:/icons/json.svg"
|
||||
onClicked: root.projectEditorClicked()
|
||||
text: qsTr("Project Editor") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_CSV_Player.isOpen
|
||||
icon.source: "qrc:/icons/open.svg"
|
||||
text: qsTr("Open CSV") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
onClicked: {
|
||||
if (Cpp_CSV_Export.isOpen)
|
||||
Cpp_CSV_Export.openCurrentCsv()
|
||||
else
|
||||
Cpp_CSV_Player.openFile()
|
||||
}
|
||||
|
||||
background: Item{}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: connectBt
|
||||
|
||||
//
|
||||
// Button properties
|
||||
//
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
font.bold: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
//
|
||||
// Connection-dependent
|
||||
//
|
||||
checked: Cpp_IO_Manager.connected
|
||||
text: (checked ? qsTr("Disconnect") :
|
||||
qsTr("Connect")) + _btSpacer
|
||||
icon.source: checked ? "qrc:/icons/disconnect.svg" :
|
||||
"qrc:/icons/connect.svg"
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
icon.color: checked ? Cpp_ThemeManager.connectButtonChecked :
|
||||
Cpp_ThemeManager.connectButtonUnchecked
|
||||
palette.buttonText: checked ? Cpp_ThemeManager.connectButtonChecked :
|
||||
Cpp_ThemeManager.connectButtonUnchecked
|
||||
|
||||
//
|
||||
// Only enable button if it can be clicked
|
||||
//
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: Cpp_IO_Manager.configurationOk
|
||||
|
||||
//
|
||||
// Connect/disconnect device when button is clicked
|
||||
//
|
||||
onClicked: Cpp_IO_Manager.toggleConnection()
|
||||
|
||||
//
|
||||
// Custom button background
|
||||
//
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
window.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
icon.source: "qrc:/icons/json.svg"
|
||||
onClicked: root.projectEditorClicked()
|
||||
text: qsTr("Project Editor") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
background: Item {}
|
||||
}
|
||||
|
||||
Button {
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillHeight: true
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: !Cpp_CSV_Player.isOpen
|
||||
icon.source: "qrc:/icons/open.svg"
|
||||
text: qsTr("Open CSV") + _btSpacer
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
|
||||
onClicked: {
|
||||
if (Cpp_CSV_Export.isOpen)
|
||||
Cpp_CSV_Export.openCurrentCsv()
|
||||
else
|
||||
Cpp_CSV_Player.openFile()
|
||||
}
|
||||
|
||||
background: Item{}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: connectBt
|
||||
|
||||
//
|
||||
// Button properties
|
||||
//
|
||||
flat: true
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
font.bold: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
//
|
||||
// Connection-dependent
|
||||
//
|
||||
checked: Cpp_IO_Manager.connected
|
||||
text: (checked ? qsTr("Disconnect") :
|
||||
qsTr("Connect")) + _btSpacer
|
||||
icon.source: checked ? "qrc:/icons/disconnect.svg" :
|
||||
"qrc:/icons/connect.svg"
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
icon.color: checked ? Cpp_ThemeManager.connectButtonChecked :
|
||||
Cpp_ThemeManager.connectButtonUnchecked
|
||||
palette.buttonText: checked ? Cpp_ThemeManager.connectButtonChecked :
|
||||
Cpp_ThemeManager.connectButtonUnchecked
|
||||
|
||||
//
|
||||
// Only enable button if it can be clicked
|
||||
//
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: Cpp_IO_Manager.configurationOk
|
||||
|
||||
//
|
||||
// Connect/disconnect device when button is clicked
|
||||
//
|
||||
onClicked: Cpp_IO_Manager.toggleConnection()
|
||||
|
||||
//
|
||||
// Custom button background
|
||||
//
|
||||
background: Rectangle {
|
||||
radius: 3
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
border.color: "#040600"
|
||||
opacity: parent.checked ? 0.2 : 0.0
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "#626262"
|
||||
anchors.fill: parent
|
||||
border.color: "#c2c2c2"
|
||||
radius: parent.radius - 1
|
||||
anchors.margins: parent.border.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,45 +25,45 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
MenuItem {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property alias sequence: _shortcut.sequence
|
||||
property bool indicatorVisible: root.icon.source.length > 0 || root.checkable
|
||||
property alias sequence: _shortcut.sequence
|
||||
property bool indicatorVisible: root.icon.source.length > 0 || root.checkable
|
||||
|
||||
Shortcut {
|
||||
id: _shortcut
|
||||
enabled: root.enabled
|
||||
onActivated: root.triggered()
|
||||
Shortcut {
|
||||
id: _shortcut
|
||||
enabled: root.enabled
|
||||
onActivated: root.triggered()
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
width: root.width
|
||||
opacity: root.enabled ? 1 : 0.5
|
||||
|
||||
Item {
|
||||
width: root.indicatorVisible ? 18 : 0
|
||||
}
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 0
|
||||
width: root.width
|
||||
opacity: root.enabled ? 1 : 0.5
|
||||
|
||||
Item {
|
||||
width: root.indicatorVisible ? 18 : 0
|
||||
}
|
||||
|
||||
Label {
|
||||
id: _titleLabel
|
||||
text: root.text
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
color: root.highlighted ? Cpp_ThemeManager.highlightedText : palette.text
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: _shortcutLabel
|
||||
opacity: 0.8
|
||||
text: _shortcut.nativeText
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
color: root.highlighted ? Cpp_ThemeManager.highlightedText : palette.text
|
||||
}
|
||||
Label {
|
||||
id: _titleLabel
|
||||
text: root.text
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
color: root.highlighted ? Cpp_ThemeManager.highlightedText : palette.text
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: _shortcutLabel
|
||||
opacity: 0.8
|
||||
text: _shortcut.nativeText
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
color: root.highlighted ? Cpp_ThemeManager.highlightedText : palette.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,325 +24,325 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
MenuBar {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Set background color
|
||||
//
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
//
|
||||
// Set background color
|
||||
//
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
//
|
||||
// Palette
|
||||
//
|
||||
palette.text: Cpp_ThemeManager.menubarText
|
||||
palette.base: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient2
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
|
||||
//
|
||||
// File menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+j"
|
||||
text: qsTr("Select JSON file") + "..."
|
||||
onTriggered: Cpp_JSON_Generator.loadJsonMap()
|
||||
}
|
||||
|
||||
//
|
||||
// Palette
|
||||
//
|
||||
palette.text: Cpp_ThemeManager.menubarText
|
||||
palette.base: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient2
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
MenuSeparator {}
|
||||
|
||||
//
|
||||
// File menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
title: qsTr("CSV export")
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+j"
|
||||
text: qsTr("Select JSON file") + "..."
|
||||
onTriggered: Cpp_JSON_Generator.loadJsonMap()
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Enable CSV export")
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
onTriggered: Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
Menu {
|
||||
title: qsTr("CSV export")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Enable CSV export")
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
onTriggered: Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+shift+o"
|
||||
enabled: Cpp_CSV_Export.isOpen
|
||||
text: qsTr("Show CSV in explorer")
|
||||
onTriggered: Cpp_CSV_Export.openCurrentCsv()
|
||||
}
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+o"
|
||||
text: qsTr("Replay CSV") + "..."
|
||||
onTriggered: Cpp_CSV_Player.openFile()
|
||||
enabled: Cpp_JSON_Generator.operationMode === 0
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+p"
|
||||
text: qsTr("Print") + "..."
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+s"
|
||||
onClicked: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
text: qsTr("Export console output") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Quit")
|
||||
onTriggered: Qt.quit()
|
||||
sequence: "ctrl+q"
|
||||
}
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+shift+o"
|
||||
enabled: Cpp_CSV_Export.isOpen
|
||||
text: qsTr("Show CSV in explorer")
|
||||
onTriggered: Cpp_CSV_Export.openCurrentCsv()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Edit menu
|
||||
//
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+o"
|
||||
text: qsTr("Replay CSV") + "..."
|
||||
onTriggered: Cpp_CSV_Player.openFile()
|
||||
enabled: Cpp_JSON_Generator.operationMode === 0
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+p"
|
||||
text: qsTr("Print") + "..."
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+s"
|
||||
onClicked: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
text: qsTr("Export console output") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Quit")
|
||||
onTriggered: Qt.quit()
|
||||
sequence: "ctrl+q"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Edit menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Copy")
|
||||
sequence: "ctrl+c"
|
||||
onTriggered: mainWindow.consoleCopy()
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+a"
|
||||
text: qsTr("Select all") + "..."
|
||||
onTriggered: mainWindow.consoleSelectAll()
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+d"
|
||||
onTriggered: mainWindow.consoleClear()
|
||||
text: qsTr("Clear console output")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
title: qsTr("Communication mode")
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Copy")
|
||||
sequence: "ctrl+c"
|
||||
onTriggered: mainWindow.consoleCopy()
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Device sends JSON")
|
||||
checked: Cpp_JSON_Generator.operationMode === 1
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+a"
|
||||
text: qsTr("Select all") + "..."
|
||||
onTriggered: mainWindow.consoleSelectAll()
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Load JSON from computer")
|
||||
checked: Cpp_JSON_Generator.operationMode === 0
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 0 : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "ctrl+d"
|
||||
onTriggered: mainWindow.consoleClear()
|
||||
text: qsTr("Clear console output")
|
||||
}
|
||||
//
|
||||
// View menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("View")
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Communication mode")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Device sends JSON")
|
||||
checked: Cpp_JSON_Generator.operationMode === 1
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Load JSON from computer")
|
||||
checked: Cpp_JSON_Generator.operationMode === 0
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 0 : 1
|
||||
}
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+t"
|
||||
text: qsTr("Console")
|
||||
checked: mainWindow.consoleVisible
|
||||
onTriggered: mainWindow.showConsole()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.consoleVisible !== checked)
|
||||
checked = mainWindow.consoleVisible
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// View menu
|
||||
//
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+d"
|
||||
text: qsTr("Dashboard")
|
||||
checked: mainWindow.dashboardVisible
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
onTriggered: mainWindow.showDashboard()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.dashboardVisible !== checked)
|
||||
checked = mainWindow.dashboardVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+,"
|
||||
checked: mainWindow.setupVisible
|
||||
text: qsTr("Show setup pane")
|
||||
onTriggered: mainWindow.showSetup()
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "f11"
|
||||
onTriggered: mainWindow.toggleFullscreen()
|
||||
text: mainWindow.isFullscreen ? qsTr("Exit full screen") :
|
||||
qsTr("Enter full screen")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console format
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Console")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Autoscroll")
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onTriggered: Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Show timestamp")
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onTriggered: Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
checked: mainWindow.vt100emulation
|
||||
text: qsTr("VT-100 emulation")
|
||||
onTriggered: mainWindow.vt100emulation = checked
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Echo user commands")
|
||||
checked: Cpp_IO_Console.echo
|
||||
onTriggered: Cpp_IO_Console.echo = checked
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("View")
|
||||
title: qsTr("Display mode")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+t"
|
||||
text: qsTr("Console")
|
||||
checked: mainWindow.consoleVisible
|
||||
onTriggered: mainWindow.showConsole()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.consoleVisible !== checked)
|
||||
checked = mainWindow.consoleVisible
|
||||
}
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Normal (plain text)")
|
||||
checked: Cpp_IO_Console.displayMode === 0
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 0 : 1
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+d"
|
||||
text: qsTr("Dashboard")
|
||||
checked: mainWindow.dashboardVisible
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
onTriggered: mainWindow.showDashboard()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.dashboardVisible !== checked)
|
||||
checked = mainWindow.dashboardVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
sequence: "ctrl+,"
|
||||
checked: mainWindow.setupVisible
|
||||
text: qsTr("Show setup pane")
|
||||
onTriggered: mainWindow.showSetup()
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "f11"
|
||||
onTriggered: mainWindow.toggleFullscreen()
|
||||
text: mainWindow.isFullscreen ? qsTr("Exit full screen") :
|
||||
qsTr("Enter full screen")
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Binary (hexadecimal)")
|
||||
checked: Cpp_IO_Console.displayMode === 1
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console format
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Console")
|
||||
title: qsTr("Line ending character")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Autoscroll")
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onTriggered: Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[0]
|
||||
checked: Cpp_IO_Console.lineEnding === 0
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 0
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Show timestamp")
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onTriggered: Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[1]
|
||||
checked: Cpp_IO_Console.lineEnding === 1
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 1
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
checked: mainWindow.vt100emulation
|
||||
text: qsTr("VT-100 emulation")
|
||||
onTriggered: mainWindow.vt100emulation = checked
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[2]
|
||||
checked: Cpp_IO_Console.lineEnding === 2
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 2
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Echo user commands")
|
||||
checked: Cpp_IO_Console.echo
|
||||
onTriggered: Cpp_IO_Console.echo = checked
|
||||
}
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[3]
|
||||
checked: Cpp_IO_Console.lineEnding === 3
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
//
|
||||
// Help menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Help")
|
||||
|
||||
Menu {
|
||||
title: qsTr("Display mode")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Normal (plain text)")
|
||||
checked: Cpp_IO_Console.displayMode === 0
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 0 : 1
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Binary (hexadecimal)")
|
||||
checked: Cpp_IO_Console.displayMode === 1
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Line ending character")
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[0]
|
||||
checked: Cpp_IO_Console.lineEnding === 0
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 0
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[1]
|
||||
checked: Cpp_IO_Console.lineEnding === 1
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 1
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[2]
|
||||
checked: Cpp_IO_Console.lineEnding === 2
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 2
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[3]
|
||||
checked: Cpp_IO_Console.lineEnding === 3
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 3
|
||||
}
|
||||
}
|
||||
DecentMenuItem {
|
||||
onTriggered: app.aboutDialog.show()
|
||||
text: qsTr("About %1").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
//
|
||||
// Help menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Help")
|
||||
|
||||
DecentMenuItem {
|
||||
onTriggered: app.aboutDialog.show()
|
||||
text: qsTr("About %1").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("About %1").arg("Qt")
|
||||
onTriggered: Cpp_Misc_Utilities.aboutQt()
|
||||
}
|
||||
|
||||
MenuSeparator {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
checked: mainWindow.automaticUpdates
|
||||
onTriggered: mainWindow.automaticUpdates = checked
|
||||
text: qsTr("Auto-updater")
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
onTriggered: app.checkForUpdates()
|
||||
text: qsTr("Check for updates") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Project website") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://www.alex-spataru.com/serial-studio")
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "f1"
|
||||
text: qsTr("Documentation/wiki") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Report bug") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
DecentMenuItem {
|
||||
text: qsTr("About %1").arg("Qt")
|
||||
onTriggered: Cpp_Misc_Utilities.aboutQt()
|
||||
}
|
||||
|
||||
MenuSeparator {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
checkable: true
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
checked: mainWindow.automaticUpdates
|
||||
onTriggered: mainWindow.automaticUpdates = checked
|
||||
text: qsTr("Auto-updater")
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
onTriggered: app.checkForUpdates()
|
||||
text: qsTr("Check for updates") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Project website") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://www.alex-spataru.com/serial-studio")
|
||||
}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: "f1"
|
||||
text: qsTr("Documentation/wiki") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
DecentMenuItem {
|
||||
text: qsTr("Report bug") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,307 +24,307 @@ import QtQuick
|
||||
import Qt.labs.platform
|
||||
|
||||
MenuBar {
|
||||
//
|
||||
// File menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
//
|
||||
// File menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("File")
|
||||
|
||||
MenuItem {
|
||||
shortcut: "ctrl+j"
|
||||
text: qsTr("Select JSON file") + "..."
|
||||
onTriggered: Cpp_JSON_Generator.loadJsonMap()
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
Menu {
|
||||
title: qsTr("CSV export")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Enable CSV export")
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
onTriggered: Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: "ctrl+shift+o"
|
||||
enabled: Cpp_CSV_Export.isOpen
|
||||
text: qsTr("Show CSV in explorer")
|
||||
onTriggered: Cpp_CSV_Export.openCurrentCsv()
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: "ctrl+o"
|
||||
text: qsTr("Replay CSV") + "..."
|
||||
onTriggered: Cpp_CSV_Player.openFile()
|
||||
enabled: Cpp_JSON_Generator.operationMode === 0
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Print
|
||||
text: qsTr("Print") + "..."
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Save
|
||||
onTriggered: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
text: qsTr("Export console output") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Quit")
|
||||
onTriggered: Qt.quit()
|
||||
shortcut: StandardKey.Quit
|
||||
}
|
||||
MenuItem {
|
||||
shortcut: "ctrl+j"
|
||||
text: qsTr("Select JSON file") + "..."
|
||||
onTriggered: Cpp_JSON_Generator.loadJsonMap()
|
||||
}
|
||||
|
||||
//
|
||||
// Edit menu
|
||||
//
|
||||
MenuSeparator {}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
title: qsTr("CSV export")
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Copy")
|
||||
shortcut: StandardKey.Copy
|
||||
onTriggered: mainWindow.consoleCopy()
|
||||
}
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Enable CSV export")
|
||||
checked: Cpp_CSV_Export.exportEnabled
|
||||
onTriggered: Cpp_CSV_Export.exportEnabled = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.SelectAll
|
||||
text: qsTr("Select all") + "..."
|
||||
onTriggered: mainWindow.consoleSelectAll()
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Delete
|
||||
onTriggered: mainWindow.consoleClear()
|
||||
text: qsTr("Clear console output")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Communication mode")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Device sends JSON")
|
||||
checked: Cpp_JSON_Generator.operationMode === 1
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Load JSON from computer")
|
||||
checked: Cpp_JSON_Generator.operationMode === 0
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 0 : 1
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
shortcut: "ctrl+shift+o"
|
||||
enabled: Cpp_CSV_Export.isOpen
|
||||
text: qsTr("Show CSV in explorer")
|
||||
onTriggered: Cpp_CSV_Export.openCurrentCsv()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// View menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("View")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+t"
|
||||
text: qsTr("Console")
|
||||
checked: mainWindow.consoleVisible
|
||||
onTriggered: mainWindow.showConsole()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.consoleVisible !== checked)
|
||||
checked = mainWindow.consoleVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+d"
|
||||
text: qsTr("Dashboard")
|
||||
checked: mainWindow.dashboardVisible
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
onTriggered: mainWindow.showDashboard()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.dashboardVisible !== checked)
|
||||
checked = mainWindow.dashboardVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+,"
|
||||
checked: mainWindow.setupVisible
|
||||
text: qsTr("Show setup pane")
|
||||
onTriggered: mainWindow.showSetup()
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: StandardKey.FullScreen
|
||||
onTriggered: mainWindow.toggleFullscreen()
|
||||
text: mainWindow.fullScreen ? qsTr("Exit full screen") : qsTr("Enter full screen")
|
||||
}
|
||||
MenuItem {
|
||||
shortcut: "ctrl+o"
|
||||
text: qsTr("Replay CSV") + "..."
|
||||
onTriggered: Cpp_CSV_Player.openFile()
|
||||
enabled: Cpp_JSON_Generator.operationMode === 0
|
||||
}
|
||||
|
||||
//
|
||||
// Console format
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Console")
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Autoscroll")
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onTriggered: Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Show timestamp")
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onTriggered: Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
checked: mainWindow.vt100emulation
|
||||
text: qsTr("VT-100 emulation")
|
||||
onTriggered: mainWindow.vt100emulation = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Echo user commands")
|
||||
checked: Cpp_IO_Console.echo
|
||||
onTriggered: Cpp_IO_Console.echo = checked
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Display mode")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Normal (plain text)")
|
||||
checked: Cpp_IO_Console.displayMode === 0
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 0 : 1
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Binary (hexadecimal)")
|
||||
checked: Cpp_IO_Console.displayMode === 1
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Line ending character")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[0]
|
||||
checked: Cpp_IO_Console.lineEnding === 0
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 0
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[1]
|
||||
checked: Cpp_IO_Console.lineEnding === 1
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 1
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[2]
|
||||
checked: Cpp_IO_Console.lineEnding === 2
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 2
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[3]
|
||||
checked: Cpp_IO_Console.lineEnding === 3
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 3
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Print
|
||||
text: qsTr("Print") + "..."
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
//
|
||||
// Help menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Help")
|
||||
|
||||
MenuItem {
|
||||
onTriggered: app.aboutDialog.show()
|
||||
text: qsTr("About %1").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("About %1").arg("Qt")
|
||||
onTriggered: Cpp_Misc_Utilities.aboutQt()
|
||||
}
|
||||
|
||||
MenuSeparator {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
checked: mainWindow.automaticUpdates
|
||||
onTriggered: mainWindow.automaticUpdates = checked
|
||||
text: qsTr("Auto-updater")
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
onTriggered: app.checkForUpdates()
|
||||
text: qsTr("Check for updates") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Project website") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://www.alex-spataru.com/serial-studio")
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.HelpContents
|
||||
text: qsTr("Documentation/wiki") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Report bug") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Save
|
||||
onTriggered: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
text: qsTr("Export console output") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Quit")
|
||||
onTriggered: Qt.quit()
|
||||
shortcut: StandardKey.Quit
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Edit menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Edit")
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Copy")
|
||||
shortcut: StandardKey.Copy
|
||||
onTriggered: mainWindow.consoleCopy()
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.SelectAll
|
||||
text: qsTr("Select all") + "..."
|
||||
onTriggered: mainWindow.consoleSelectAll()
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.Delete
|
||||
onTriggered: mainWindow.consoleClear()
|
||||
text: qsTr("Clear console output")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Communication mode")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Device sends JSON")
|
||||
checked: Cpp_JSON_Generator.operationMode === 1
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Load JSON from computer")
|
||||
checked: Cpp_JSON_Generator.operationMode === 0
|
||||
onTriggered: Cpp_JSON_Generator.operationMode = checked ? 0 : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// View menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("View")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+t"
|
||||
text: qsTr("Console")
|
||||
checked: mainWindow.consoleVisible
|
||||
onTriggered: mainWindow.showConsole()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.consoleVisible !== checked)
|
||||
checked = mainWindow.consoleVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+d"
|
||||
text: qsTr("Dashboard")
|
||||
checked: mainWindow.dashboardVisible
|
||||
enabled: Cpp_UI_Dashboard.available
|
||||
onTriggered: mainWindow.showDashboard()
|
||||
onCheckedChanged: {
|
||||
if (mainWindow.dashboardVisible !== checked)
|
||||
checked = mainWindow.dashboardVisible
|
||||
}
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
shortcut: "ctrl+,"
|
||||
checked: mainWindow.setupVisible
|
||||
text: qsTr("Show setup pane")
|
||||
onTriggered: mainWindow.showSetup()
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
DecentMenuItem {
|
||||
sequence: StandardKey.FullScreen
|
||||
onTriggered: mainWindow.toggleFullscreen()
|
||||
text: mainWindow.fullScreen ? qsTr("Exit full screen") : qsTr("Enter full screen")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console format
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Console")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Autoscroll")
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onTriggered: Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Show timestamp")
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onTriggered: Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
checked: mainWindow.vt100emulation
|
||||
text: qsTr("VT-100 emulation")
|
||||
onTriggered: mainWindow.vt100emulation = checked
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Echo user commands")
|
||||
checked: Cpp_IO_Console.echo
|
||||
onTriggered: Cpp_IO_Console.echo = checked
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Display mode")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Normal (plain text)")
|
||||
checked: Cpp_IO_Console.displayMode === 0
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 0 : 1
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: qsTr("Binary (hexadecimal)")
|
||||
checked: Cpp_IO_Console.displayMode === 1
|
||||
onTriggered: Cpp_IO_Console.displayMode = checked ? 1 : 0
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
title: qsTr("Line ending character")
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[0]
|
||||
checked: Cpp_IO_Console.lineEnding === 0
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 0
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[1]
|
||||
checked: Cpp_IO_Console.lineEnding === 1
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 1
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[2]
|
||||
checked: Cpp_IO_Console.lineEnding === 2
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 2
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
text: Cpp_IO_Console.lineEndings()[3]
|
||||
checked: Cpp_IO_Console.lineEnding === 3
|
||||
onTriggered: Cpp_IO_Console.lineEnding = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Help menu
|
||||
//
|
||||
Menu {
|
||||
title: qsTr("Help")
|
||||
|
||||
MenuItem {
|
||||
onTriggered: app.aboutDialog.show()
|
||||
text: qsTr("About %1").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("About %1").arg("Qt")
|
||||
onTriggered: Cpp_Misc_Utilities.aboutQt()
|
||||
}
|
||||
|
||||
MenuSeparator {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
checkable: true
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
checked: mainWindow.automaticUpdates
|
||||
onTriggered: mainWindow.automaticUpdates = checked
|
||||
text: qsTr("Auto-updater")
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
visible: Cpp_UpdaterEnabled
|
||||
enabled: Cpp_UpdaterEnabled
|
||||
onTriggered: app.checkForUpdates()
|
||||
text: qsTr("Check for updates") + "..."
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Project website") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://www.alex-spataru.com/serial-studio")
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
shortcut: StandardKey.HelpContents
|
||||
text: qsTr("Documentation/wiki") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
MenuSeparator{}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Report bug") + "..."
|
||||
onTriggered: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,147 +27,147 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
color: Cpp_ThemeManager.toolbarGradient2
|
||||
height: footer.implicitHeight + 4 * app.spacing
|
||||
id: root
|
||||
color: Cpp_ThemeManager.toolbarGradient2
|
||||
height: footer.implicitHeight + 4 * app.spacing
|
||||
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal closeWindow()
|
||||
signal scrollToBottom()
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal closeWindow()
|
||||
signal scrollToBottom()
|
||||
|
||||
//
|
||||
// Radius compensator
|
||||
//
|
||||
Rectangle {
|
||||
color: root.color
|
||||
height: root.radius
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
//
|
||||
// Radius compensator
|
||||
//
|
||||
Rectangle {
|
||||
color: root.color
|
||||
height: root.radius
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Top border
|
||||
//
|
||||
Rectangle {
|
||||
height: 1
|
||||
color: Cpp_ThemeManager.toolbarGradient1
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dialog buttons
|
||||
//
|
||||
RowLayout {
|
||||
id: footer
|
||||
spacing: app.spacing
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: app.spacing * 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
//
|
||||
// Top border
|
||||
//
|
||||
Rectangle {
|
||||
height: 1
|
||||
color: Cpp_ThemeManager.toolbarGradient1
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
onClicked: root.closeWindow()
|
||||
text: qsTr("Close") + _btSpacer
|
||||
icon.source: "qrc:/icons/close.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
//
|
||||
// Dialog buttons
|
||||
//
|
||||
RowLayout {
|
||||
id: footer
|
||||
spacing: app.spacing
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: app.spacing * 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
onClicked: root.closeWindow()
|
||||
text: qsTr("Close") + _btSpacer
|
||||
icon.source: "qrc:/icons/close.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: addGrp
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
highlighted: true
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Add group")
|
||||
icon.source: "qrc:/icons/add.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
onClicked: {
|
||||
Cpp_Project_Model.addGroup()
|
||||
root.scrollToBottom()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
text: qsTr("Customize frame parser")
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_CodeEditor.displayWindow()
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.source: "qrc:/icons/open.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_Model.openJsonFile()
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
text: qsTr("Open existing project...") + _btSpacer
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.source: "qrc:/icons/new.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_Model.newJsonFile()
|
||||
text: qsTr("Create new project") + _btSpacer
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
opacity: enabled ? 1: 0.5
|
||||
enabled: Cpp_Project_Model.modified
|
||||
icon.source: "qrc:/icons/apply.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
text: (Cpp_Project_Model.jsonFilePath.length > 0 ? qsTr("Apply") : qsTr("Save")) + _btSpacer
|
||||
|
||||
onClicked: {
|
||||
if (Cpp_Project_Model.saveJsonFile())
|
||||
root.closeWindow()
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: addGrp
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
highlighted: true
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Add group")
|
||||
icon.source: "qrc:/icons/add.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
onClicked: {
|
||||
Cpp_Project_Model.addGroup()
|
||||
root.scrollToBottom()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
icon.source: "qrc:/icons/code.svg"
|
||||
text: qsTr("Customize frame parser")
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_CodeEditor.displayWindow()
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.source: "qrc:/icons/open.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_Model.openJsonFile()
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
text: qsTr("Open existing project...") + _btSpacer
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
icon.source: "qrc:/icons/new.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
onClicked: Cpp_Project_Model.newJsonFile()
|
||||
text: qsTr("Create new project") + _btSpacer
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
opacity: enabled ? 1: 0.5
|
||||
enabled: Cpp_Project_Model.modified
|
||||
icon.source: "qrc:/icons/apply.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
text: (Cpp_Project_Model.jsonFilePath.length > 0 ? qsTr("Apply") : qsTr("Save")) + _btSpacer
|
||||
|
||||
onClicked: {
|
||||
if (Cpp_Project_Model.saveJsonFile())
|
||||
root.closeWindow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,90 +27,90 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
spacing: 0
|
||||
id: root
|
||||
spacing: 0
|
||||
|
||||
//
|
||||
// Connections with JSON editor model
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
//
|
||||
// Connections with JSON editor model
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
|
||||
function onGroupCountChanged() {
|
||||
tabRepeater.model = 0
|
||||
stackRepeater.model = 0
|
||||
tabRepeater.model = Cpp_Project_Model.groupCount
|
||||
stackRepeater.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
function onGroupOrderChanged() {
|
||||
tabRepeater.model = 0
|
||||
stackRepeater.model = 0
|
||||
tabRepeater.model = Cpp_Project_Model.groupCount
|
||||
stackRepeater.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
function onGroupCountChanged() {
|
||||
tabRepeater.model = 0
|
||||
stackRepeater.model = 0
|
||||
tabRepeater.model = Cpp_Project_Model.groupCount
|
||||
stackRepeater.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
//
|
||||
// Function to scroll to the last group
|
||||
//
|
||||
function selectLastGroup() {
|
||||
tabBar.currentIndex = tabBar.count - 1
|
||||
function onGroupOrderChanged() {
|
||||
tabRepeater.model = 0
|
||||
stackRepeater.model = 0
|
||||
tabRepeater.model = Cpp_Project_Model.groupCount
|
||||
stackRepeater.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
//
|
||||
// Function to scroll to the last group
|
||||
//
|
||||
function selectLastGroup() {
|
||||
tabBar.currentIndex = tabBar.count - 1
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// Tab widget
|
||||
//
|
||||
TabBar {
|
||||
id: tabBar
|
||||
Layout.fillWidth: true
|
||||
visible: tabRepeater.model > 0
|
||||
|
||||
Repeater {
|
||||
id: tabRepeater
|
||||
delegate: TabButton {
|
||||
height: 24
|
||||
text: qsTr("Group %1").arg(index + 1) + " <i>" + (Cpp_Project_Model.groupTitle(index)) + "</i>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Tab widget
|
||||
//
|
||||
TabBar {
|
||||
id: tabBar
|
||||
Layout.fillWidth: true
|
||||
visible: tabRepeater.model > 0
|
||||
//
|
||||
// StackView
|
||||
//
|
||||
StackLayout {
|
||||
id: swipe
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tabBar.currentIndex
|
||||
Layout.topMargin: -parent.spacing - 1
|
||||
|
||||
Repeater {
|
||||
id: tabRepeater
|
||||
delegate: TabButton {
|
||||
height: 24
|
||||
text: qsTr("Group %1").arg(index + 1) + " <i>" + (Cpp_Project_Model.groupTitle(index)) + "</i>"
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: stackRepeater
|
||||
|
||||
//
|
||||
// StackView
|
||||
//
|
||||
StackLayout {
|
||||
id: swipe
|
||||
delegate: Loader {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tabBar.currentIndex
|
||||
Layout.topMargin: -parent.spacing - 1
|
||||
active: swipe.currentIndex == index
|
||||
|
||||
Repeater {
|
||||
id: stackRepeater
|
||||
|
||||
delegate: Loader {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
active: swipe.currentIndex == index
|
||||
|
||||
sourceComponent: JsonGroupDelegate {
|
||||
group: index
|
||||
}
|
||||
}
|
||||
sourceComponent: JsonGroupDelegate {
|
||||
group: index
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
}
|
||||
|
@ -27,169 +27,169 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
height: header.implicitHeight + 4 * app.spacing
|
||||
id: root
|
||||
height: header.implicitHeight + 4 * app.spacing
|
||||
|
||||
//
|
||||
// Background & border
|
||||
//
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
color: Cpp_ThemeManager.toolbarGradient2
|
||||
border.width: Cpp_ThemeManager.titlebarSeparator ? 1 : 0
|
||||
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
|
||||
//
|
||||
// Background & border
|
||||
//
|
||||
Rectangle {
|
||||
id: bg
|
||||
anchors.fill: parent
|
||||
color: Cpp_ThemeManager.toolbarGradient2
|
||||
border.width: Cpp_ThemeManager.titlebarSeparator ? 1 : 0
|
||||
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
height: 1
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5)
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
visible: Cpp_ThemeManager.titlebarSeparator
|
||||
color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
GridLayout {
|
||||
id: header
|
||||
columns: 2
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing * 2
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: app.spacing * 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
//
|
||||
// Project title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/registration.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 320
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.title
|
||||
onTextChanged: Cpp_Project_Model.setTitle(text)
|
||||
placeholderText: qsTr("Project title (required)")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Separator character
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/separator.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 420
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.separator
|
||||
onTextChanged: Cpp_Project_Model.setSeparator(text)
|
||||
placeholderText: qsTr("Data separator (default is ',')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start sequence
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/start-sequence.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 256
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.frameStartSequence
|
||||
onTextChanged: Cpp_Project_Model.setFrameStartSequence(text)
|
||||
placeholderText: qsTr("Frame start sequence (default is '/*')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End sequence
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/end-sequence.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 256
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.frameEndSequence
|
||||
onTextChanged: Cpp_Project_Model.setFrameEndSequence(text)
|
||||
placeholderText: qsTr("Frame end sequence (default is '*/')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
margins: 0
|
||||
top: parent.top
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
GridLayout {
|
||||
id: header
|
||||
columns: 2
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing * 2
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: app.spacing * 2
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
//
|
||||
// Project title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/registration.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 320
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.title
|
||||
onTextChanged: Cpp_Project_Model.setTitle(text)
|
||||
placeholderText: qsTr("Project title (required)")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Separator character
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/separator.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 420
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.separator
|
||||
onTextChanged: Cpp_Project_Model.setSeparator(text)
|
||||
placeholderText: qsTr("Data separator (default is ',')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Start sequence
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/start-sequence.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 256
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.frameStartSequence
|
||||
onTextChanged: Cpp_Project_Model.setFrameStartSequence(text)
|
||||
placeholderText: qsTr("Frame start sequence (default is '/*')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// End sequence
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Widgets.Icon {
|
||||
color: Cpp_ThemeManager.menubarText
|
||||
source: "qrc:/icons/end-sequence.svg"
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 256
|
||||
Layout.maximumHeight: 24
|
||||
Layout.minimumHeight: 24
|
||||
text: Cpp_Project_Model.frameEndSequence
|
||||
onTextChanged: Cpp_Project_Model.setFrameEndSequence(text)
|
||||
placeholderText: qsTr("Frame end sequence (default is '*/')")
|
||||
|
||||
palette {
|
||||
base: "#fff"
|
||||
text: "#000"
|
||||
//placeholderText: "#444"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
margins: 0
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
@ -27,282 +27,282 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Widgets.Window {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/dataset.svg"
|
||||
borderColor: Cpp_ThemeManager.widgetWindowBorder
|
||||
palette.window: Cpp_ThemeManager.widgetWindowBackground
|
||||
title: qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset))
|
||||
|
||||
//
|
||||
// Delete dataset button
|
||||
//
|
||||
altButtonEnabled: !showGroupWidget
|
||||
altButtonIcon.source: "qrc:/icons/close.svg"
|
||||
onAltButtonClicked: Cpp_Project_Model.deleteDataset(group, dataset)
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int group
|
||||
property int dataset
|
||||
property bool multiplotGroup
|
||||
property bool showGroupWidget
|
||||
|
||||
//
|
||||
// Convenience variables
|
||||
//
|
||||
readonly property bool fftSamplesVisible: fftCheck.checked
|
||||
readonly property bool alarmVisible: widget.currentIndex === 2
|
||||
readonly property bool minMaxVisible: widget.currentIndex === 1 ||
|
||||
widget.currentIndex === 2 ||
|
||||
logPlot.checked ||
|
||||
linearPlot.checked ||
|
||||
root.multiplotGroup
|
||||
|
||||
//
|
||||
// User interface
|
||||
//
|
||||
GridLayout {
|
||||
x: 0
|
||||
columns: 2
|
||||
anchors.fill: parent
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
anchors.margins: app.spacing * 2
|
||||
|
||||
//
|
||||
// Window properties
|
||||
// Dataset title
|
||||
//
|
||||
headerDoubleClickEnabled: false
|
||||
icon.source: "qrc:/icons/dataset.svg"
|
||||
borderColor: Cpp_ThemeManager.widgetWindowBorder
|
||||
palette.window: Cpp_ThemeManager.widgetWindowBackground
|
||||
title: qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset))
|
||||
|
||||
//
|
||||
// Delete dataset button
|
||||
//
|
||||
altButtonEnabled: !showGroupWidget
|
||||
altButtonIcon.source: "qrc:/icons/close.svg"
|
||||
onAltButtonClicked: Cpp_Project_Model.deleteDataset(group, dataset)
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int group
|
||||
property int dataset
|
||||
property bool multiplotGroup
|
||||
property bool showGroupWidget
|
||||
|
||||
//
|
||||
// Convenience variables
|
||||
//
|
||||
readonly property bool fftSamplesVisible: fftCheck.checked
|
||||
readonly property bool alarmVisible: widget.currentIndex === 2
|
||||
readonly property bool minMaxVisible: widget.currentIndex === 1 ||
|
||||
widget.currentIndex === 2 ||
|
||||
logPlot.checked ||
|
||||
linearPlot.checked ||
|
||||
root.multiplotGroup
|
||||
|
||||
//
|
||||
// User interface
|
||||
//
|
||||
GridLayout {
|
||||
x: 0
|
||||
columns: 2
|
||||
anchors.fill: parent
|
||||
rowSpacing: app.spacing
|
||||
columnSpacing: app.spacing
|
||||
anchors.margins: app.spacing * 2
|
||||
|
||||
//
|
||||
// Dataset title
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Title:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetTitle(group, dataset)
|
||||
placeholderText: qsTr("Sensor reading, uptime, etc...")
|
||||
onTextChanged: {
|
||||
Cpp_Project_Model.setDatasetTitle(group, dataset, text)
|
||||
root.title = qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset units
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Units:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetUnits(group, dataset)
|
||||
placeholderText: qsTr("Volts, meters, seconds, etc...")
|
||||
onTextChanged: Cpp_Project_Model.setDatasetUnits(group, dataset, text)
|
||||
}
|
||||
|
||||
//
|
||||
// Frame index
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Frame index:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetIndex(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetIndex(group, dataset, text)
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
top: 100
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset LED
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Display LED:")
|
||||
} Switch {
|
||||
id: led
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetLED(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetLED(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset graph
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Generate plot:")
|
||||
} Switch {
|
||||
id: linearPlot
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetGraph(group, dataset)
|
||||
onCheckedChanged: {
|
||||
if (!checked)
|
||||
logPlot.checked = false
|
||||
|
||||
Cpp_Project_Model.setDatasetGraph(group, dataset, checked)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Log plot
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Logarithmic plot:")
|
||||
visible: linearPlot.checked
|
||||
} CheckBox {
|
||||
id: logPlot
|
||||
visible: linearPlot.checked
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetLogPlot(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetLogPlot(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// FFT plot
|
||||
//
|
||||
Label {
|
||||
text: qsTr("FFT plot:")
|
||||
} Switch {
|
||||
id: fftCheck
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetFftPlot(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetFftPlot(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset widget (user selectable or group-level constant)
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Widget:")
|
||||
} ComboBox {
|
||||
id: widget
|
||||
Layout.fillWidth: true
|
||||
visible: !showGroupWidget
|
||||
enabled: !showGroupWidget
|
||||
model: Cpp_Project_Model.availableDatasetLevelWidgets()
|
||||
currentIndex: Cpp_Project_Model.datasetWidgetIndex(group, dataset)
|
||||
onCurrentIndexChanged: {
|
||||
if (visible && currentIndex !== Cpp_Project_Model.datasetWidgetIndex(group, dataset))
|
||||
Cpp_Project_Model.setDatasetWidget(group, dataset, currentIndex)
|
||||
}
|
||||
} TextField {
|
||||
readOnly: true
|
||||
Layout.fillWidth: true
|
||||
visible: showGroupWidget
|
||||
enabled: showGroupWidget
|
||||
text: Cpp_Project_Model.datasetWidget(group, dataset)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FFT max frequency
|
||||
//
|
||||
Label {
|
||||
text: qsTr("FFT Samples:")
|
||||
visible: root.fftSamplesVisible
|
||||
} TextField {
|
||||
id: fftSamples
|
||||
Layout.fillWidth: true
|
||||
visible: root.fftSamplesVisible
|
||||
text: Cpp_Project_Model.datasetFFTSamples(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetFFTSamples(group, dataset, parseInt(text))
|
||||
validator: IntValidator {
|
||||
bottom: 8
|
||||
top: 40 * 1000
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Widget minimum value
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Min value:")
|
||||
visible: root.minMaxVisible
|
||||
} TextField {
|
||||
id: min
|
||||
Layout.fillWidth: true
|
||||
visible: root.minMaxVisible
|
||||
text: Cpp_Project_Model.datasetWidgetMin(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetMin(group, dataset, text)
|
||||
validator: DoubleValidator {
|
||||
top: parseFloat(max.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Widget maximum value
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Max value:")
|
||||
visible: root.minMaxVisible
|
||||
} TextField {
|
||||
id: max
|
||||
Layout.fillWidth: true
|
||||
visible: root.minMaxVisible
|
||||
text: Cpp_Project_Model.datasetWidgetMax(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetMax(group, dataset, text)
|
||||
|
||||
validator: DoubleValidator {
|
||||
bottom: parseFloat(min.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bar alarm level
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Alarm level:")
|
||||
visible: root.alarmVisible
|
||||
} TextField {
|
||||
id: alarm
|
||||
Layout.fillWidth: true
|
||||
visible: root.alarmVisible
|
||||
text: Cpp_Project_Model.datasetWidgetAlarm(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetAlarm(group, dataset, text)
|
||||
|
||||
validator: DoubleValidator {
|
||||
top: parseFloat(max.text)
|
||||
bottom: parseFloat(min.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
} Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
//
|
||||
// Compass note label
|
||||
//
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
color: palette.text
|
||||
source: "qrc:/icons/compass.svg"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 3
|
||||
} Label {
|
||||
font.pixelSize: 16
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WordWrap
|
||||
visible: widget.currentIndex === 3
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The compass widget expects values from 0° to 360°.")
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
} Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
Label {
|
||||
text: qsTr("Title:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetTitle(group, dataset)
|
||||
placeholderText: qsTr("Sensor reading, uptime, etc...")
|
||||
onTextChanged: {
|
||||
Cpp_Project_Model.setDatasetTitle(group, dataset, text)
|
||||
root.title = qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset units
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Units:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetUnits(group, dataset)
|
||||
placeholderText: qsTr("Volts, meters, seconds, etc...")
|
||||
onTextChanged: Cpp_Project_Model.setDatasetUnits(group, dataset, text)
|
||||
}
|
||||
|
||||
//
|
||||
// Frame index
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Frame index:")
|
||||
} TextField {
|
||||
Layout.fillWidth: true
|
||||
text: Cpp_Project_Model.datasetIndex(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetIndex(group, dataset, text)
|
||||
validator: IntValidator {
|
||||
bottom: 1
|
||||
top: 100
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset LED
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Display LED:")
|
||||
} Switch {
|
||||
id: led
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetLED(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetLED(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset graph
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Generate plot:")
|
||||
} Switch {
|
||||
id: linearPlot
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetGraph(group, dataset)
|
||||
onCheckedChanged: {
|
||||
if (!checked)
|
||||
logPlot.checked = false
|
||||
|
||||
Cpp_Project_Model.setDatasetGraph(group, dataset, checked)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Log plot
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Logarithmic plot:")
|
||||
visible: linearPlot.checked
|
||||
} CheckBox {
|
||||
id: logPlot
|
||||
visible: linearPlot.checked
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetLogPlot(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetLogPlot(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// FFT plot
|
||||
//
|
||||
Label {
|
||||
text: qsTr("FFT plot:")
|
||||
} Switch {
|
||||
id: fftCheck
|
||||
Layout.leftMargin: -app.spacing
|
||||
checked: Cpp_Project_Model.datasetFftPlot(group, dataset)
|
||||
onCheckedChanged: Cpp_Project_Model.setDatasetFftPlot(group, dataset, checked)
|
||||
}
|
||||
|
||||
//
|
||||
// Dataset widget (user selectable or group-level constant)
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Widget:")
|
||||
} ComboBox {
|
||||
id: widget
|
||||
Layout.fillWidth: true
|
||||
visible: !showGroupWidget
|
||||
enabled: !showGroupWidget
|
||||
model: Cpp_Project_Model.availableDatasetLevelWidgets()
|
||||
currentIndex: Cpp_Project_Model.datasetWidgetIndex(group, dataset)
|
||||
onCurrentIndexChanged: {
|
||||
if (visible && currentIndex !== Cpp_Project_Model.datasetWidgetIndex(group, dataset))
|
||||
Cpp_Project_Model.setDatasetWidget(group, dataset, currentIndex)
|
||||
}
|
||||
} TextField {
|
||||
readOnly: true
|
||||
Layout.fillWidth: true
|
||||
visible: showGroupWidget
|
||||
enabled: showGroupWidget
|
||||
text: Cpp_Project_Model.datasetWidget(group, dataset)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FFT max frequency
|
||||
//
|
||||
Label {
|
||||
text: qsTr("FFT Samples:")
|
||||
visible: root.fftSamplesVisible
|
||||
} TextField {
|
||||
id: fftSamples
|
||||
Layout.fillWidth: true
|
||||
visible: root.fftSamplesVisible
|
||||
text: Cpp_Project_Model.datasetFFTSamples(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetFFTSamples(group, dataset, parseInt(text))
|
||||
validator: IntValidator {
|
||||
bottom: 8
|
||||
top: 40 * 1000
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Widget minimum value
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Min value:")
|
||||
visible: root.minMaxVisible
|
||||
} TextField {
|
||||
id: min
|
||||
Layout.fillWidth: true
|
||||
visible: root.minMaxVisible
|
||||
text: Cpp_Project_Model.datasetWidgetMin(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetMin(group, dataset, text)
|
||||
validator: DoubleValidator {
|
||||
top: parseFloat(max.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Widget maximum value
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Max value:")
|
||||
visible: root.minMaxVisible
|
||||
} TextField {
|
||||
id: max
|
||||
Layout.fillWidth: true
|
||||
visible: root.minMaxVisible
|
||||
text: Cpp_Project_Model.datasetWidgetMax(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetMax(group, dataset, text)
|
||||
|
||||
validator: DoubleValidator {
|
||||
bottom: parseFloat(min.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Bar alarm level
|
||||
//
|
||||
Label {
|
||||
text: qsTr("Alarm level:")
|
||||
visible: root.alarmVisible
|
||||
} TextField {
|
||||
id: alarm
|
||||
Layout.fillWidth: true
|
||||
visible: root.alarmVisible
|
||||
text: Cpp_Project_Model.datasetWidgetAlarm(group, dataset)
|
||||
onTextChanged: Cpp_Project_Model.setDatasetWidgetAlarm(group, dataset, text)
|
||||
|
||||
validator: DoubleValidator {
|
||||
top: parseFloat(max.text)
|
||||
bottom: parseFloat(min.text)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
} Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
//
|
||||
// Compass note label
|
||||
//
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
color: palette.text
|
||||
source: "qrc:/icons/compass.svg"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 3
|
||||
} Label {
|
||||
font.pixelSize: 16
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Label.WordWrap
|
||||
visible: widget.currentIndex === 3
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The compass widget expects values from 0° to 360°.")
|
||||
}
|
||||
|
||||
//
|
||||
// Vertical spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
} Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,287 +27,287 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Page {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Page background
|
||||
//
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
//
|
||||
// Page background
|
||||
//
|
||||
background: TextField {
|
||||
enabled: false
|
||||
palette.base: Cpp_ThemeManager.setupPanelBackground
|
||||
}
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int group
|
||||
readonly property int minSize: 320
|
||||
readonly property int maxSize: 380
|
||||
readonly property int cellHeight: 420
|
||||
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth)
|
||||
readonly property int cellWidth: cWidth + ((grid.width - 2 * scroll.width) - (cWidth) * columns) / columns
|
||||
readonly property int cWidth: Math.min(maxSize, Math.max(minSize, (grid.width - 2 * scroll.width) / grid.model))
|
||||
|
||||
//
|
||||
// Connections with JSON editor
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
|
||||
function onGroupChanged(id) {
|
||||
if (id === group) {
|
||||
grid.model = 0
|
||||
grid.model = Cpp_Project_Model.datasetCount(group)
|
||||
grid.positionViewAtIndex(grid.count - 1, GridView.Beginning)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
// Notes rectangle
|
||||
//
|
||||
property int group
|
||||
readonly property int minSize: 320
|
||||
readonly property int maxSize: 380
|
||||
readonly property int cellHeight: 420
|
||||
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth)
|
||||
readonly property int cellWidth: cWidth + ((grid.width - 2 * scroll.width) - (cWidth) * columns) / columns
|
||||
readonly property int cWidth: Math.min(maxSize, Math.max(minSize, (grid.width - 2 * scroll.width) / grid.model))
|
||||
Rectangle {
|
||||
id: notes
|
||||
radius: 16
|
||||
Layout.fillWidth: true
|
||||
color: Cpp_ThemeManager.highlight
|
||||
Layout.minimumHeight: 32 + 2 * app.spacing
|
||||
visible: widget.currentIndex === 1 || widget.currentIndex === 2
|
||||
|
||||
//
|
||||
// Connections with JSON editor
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
|
||||
function onGroupChanged(id) {
|
||||
if (id === group) {
|
||||
grid.model = 0
|
||||
grid.model = Cpp_Project_Model.datasetCount(group)
|
||||
grid.positionViewAtIndex(grid.count - 1, GridView.Beginning)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
anchors.centerIn: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 1
|
||||
|
||||
//
|
||||
// Notes rectangle
|
||||
//
|
||||
Rectangle {
|
||||
id: notes
|
||||
radius: 16
|
||||
Layout.fillWidth: true
|
||||
color: Cpp_ThemeManager.highlight
|
||||
Layout.minimumHeight: 32 + 2 * app.spacing
|
||||
visible: widget.currentIndex === 1 || widget.currentIndex === 2
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 1
|
||||
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
color: palette.highlightedText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
source: "qrc:/icons/accelerometer.svg"
|
||||
} Label {
|
||||
font.pixelSize: 18
|
||||
wrapMode: Label.WordWrap
|
||||
color: palette.highlightedText
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The accelerometer widget expects values in m/s².")
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 2
|
||||
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
source: "qrc:/icons/gyro.svg"
|
||||
color: palette.highlightedText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
} Label {
|
||||
font.pixelSize: 18
|
||||
wrapMode: Label.WordWrap
|
||||
color: palette.highlightedText
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The gyroscope widget expects values in degrees (0° to 360°).")
|
||||
}
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
color: palette.highlightedText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
source: "qrc:/icons/accelerometer.svg"
|
||||
} Label {
|
||||
font.pixelSize: 18
|
||||
wrapMode: Label.WordWrap
|
||||
color: palette.highlightedText
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The accelerometer widget expects values in m/s².")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Group title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: widget.currentIndex === 2
|
||||
|
||||
Label {
|
||||
text: qsTr("Title") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.minimumWidth: 320
|
||||
placeholderText: qsTr("Title")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.groupTitle(group)
|
||||
|
||||
onTextChanged: {
|
||||
Cpp_Project_Model.setGroupTitle(group, text)
|
||||
root.title = qsTr("Group %1 - %2").arg(group + 1).arg(Cpp_Project_Model.groupTitle(group))
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Group widget") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: widget
|
||||
Layout.minimumWidth: 180
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_Project_Model.availableGroupLevelWidgets()
|
||||
currentIndex: Cpp_Project_Model.groupWidgetIndex(group)
|
||||
onCurrentIndexChanged: {
|
||||
var prevIndex = Cpp_Project_Model.groupWidgetIndex(group)
|
||||
if (currentIndex !== prevIndex) {
|
||||
if (!Cpp_Project_Model.setGroupWidget(group, currentIndex))
|
||||
currentIndex = prevIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
enabled: group > 0
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.source: "qrc:/icons/up.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
onClicked: Cpp_Project_Model.moveGroupUp(group)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
icon.source: "qrc:/icons/down.svg"
|
||||
enabled: group < Cpp_Project_Model.groupCount - 1
|
||||
onClicked: Cpp_Project_Model.moveGroupDown(group)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
icon.source: "qrc:/icons/delete-item.svg"
|
||||
onClicked: Cpp_Project_Model.deleteGroup(group)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Datasets
|
||||
//
|
||||
Item {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
//
|
||||
// Background
|
||||
//
|
||||
TextField {
|
||||
enabled: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
//
|
||||
// Empty group text & icon
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
visible: grid.model === 0
|
||||
|
||||
Widgets.Icon {
|
||||
width: 128
|
||||
height: 128
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/group.svg"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
text: qsTr("Empty group")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
Layout.maximumWidth: grid.width - 8 * app.spacing
|
||||
text: qsTr("Set group title and click on the \"Add dataset\" button to begin")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Grid
|
||||
//
|
||||
GridView {
|
||||
id: grid
|
||||
clip: true
|
||||
anchors.margins: 1
|
||||
anchors.fill: parent
|
||||
cellWidth: root.cellWidth
|
||||
cellHeight: root.cellHeight
|
||||
model: Cpp_Project_Model.datasetCount(group)
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scroll
|
||||
policy: ScrollBar.AsNeeded
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
sourceComponent: JsonDatasetDelegate {
|
||||
dataset: index
|
||||
group: root.group
|
||||
multiplotGroup: widget.currentIndex === 4
|
||||
showGroupWidget: widget.currentIndex > 0 && widget.currentIndex !== 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add dataset button
|
||||
//
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Add dataset")
|
||||
icon.source: "qrc:/icons/add.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
visible: widget.currentIndex === 0 || widget.currentIndex === 4
|
||||
onClicked: {
|
||||
Cpp_Project_Model.addDataset(group)
|
||||
grid.positionViewAtIndex(grid.count - 1, GridView.Beginning)
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 32
|
||||
height: 32
|
||||
source: "qrc:/icons/gyro.svg"
|
||||
color: palette.highlightedText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
} Label {
|
||||
font.pixelSize: 18
|
||||
wrapMode: Label.WordWrap
|
||||
color: palette.highlightedText
|
||||
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The gyroscope widget expects values in degrees (0° to 360°).")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Group title
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
text: qsTr("Title") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
TextField {
|
||||
Layout.minimumWidth: 320
|
||||
placeholderText: qsTr("Title")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.groupTitle(group)
|
||||
|
||||
onTextChanged: {
|
||||
Cpp_Project_Model.setGroupTitle(group, text)
|
||||
root.title = qsTr("Group %1 - %2").arg(group + 1).arg(Cpp_Project_Model.groupTitle(group))
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
text: qsTr("Group widget") + ":"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: widget
|
||||
Layout.minimumWidth: 180
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_Project_Model.availableGroupLevelWidgets()
|
||||
currentIndex: Cpp_Project_Model.groupWidgetIndex(group)
|
||||
onCurrentIndexChanged: {
|
||||
var prevIndex = Cpp_Project_Model.groupWidgetIndex(group)
|
||||
if (currentIndex !== prevIndex) {
|
||||
if (!Cpp_Project_Model.setGroupWidget(group, currentIndex))
|
||||
currentIndex = prevIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
enabled: group > 0
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.source: "qrc:/icons/up.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
onClicked: Cpp_Project_Model.moveGroupUp(group)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
opacity: enabled ? 1 : 0.5
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
icon.source: "qrc:/icons/down.svg"
|
||||
enabled: group < Cpp_Project_Model.groupCount - 1
|
||||
onClicked: Cpp_Project_Model.moveGroupDown(group)
|
||||
}
|
||||
|
||||
RoundButton {
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
icon.source: "qrc:/icons/delete-item.svg"
|
||||
onClicked: Cpp_Project_Model.deleteGroup(group)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Datasets
|
||||
//
|
||||
Item {
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
//
|
||||
// Background
|
||||
//
|
||||
TextField {
|
||||
enabled: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
//
|
||||
// Empty group text & icon
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
visible: grid.model === 0
|
||||
|
||||
Widgets.Icon {
|
||||
width: 128
|
||||
height: 128
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/group.svg"
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
text: qsTr("Empty group")
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
Layout.maximumWidth: grid.width - 8 * app.spacing
|
||||
text: qsTr("Set group title and click on the \"Add dataset\" button to begin")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Grid
|
||||
//
|
||||
GridView {
|
||||
id: grid
|
||||
clip: true
|
||||
anchors.margins: 1
|
||||
anchors.fill: parent
|
||||
cellWidth: root.cellWidth
|
||||
cellHeight: root.cellHeight
|
||||
model: Cpp_Project_Model.datasetCount(group)
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scroll
|
||||
policy: ScrollBar.AsNeeded
|
||||
}
|
||||
|
||||
delegate: Item {
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
sourceComponent: JsonDatasetDelegate {
|
||||
dataset: index
|
||||
group: root.group
|
||||
multiplotGroup: widget.currentIndex === 4
|
||||
showGroupWidget: widget.currentIndex > 0 && widget.currentIndex !== 4
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add dataset button
|
||||
//
|
||||
Button {
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Add dataset")
|
||||
icon.source: "qrc:/icons/add.svg"
|
||||
icon.color: Cpp_ThemeManager.menubarText
|
||||
palette.buttonText: Cpp_ThemeManager.menubarText
|
||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||
visible: widget.currentIndex === 0 || widget.currentIndex === 4
|
||||
onClicked: {
|
||||
Cpp_Project_Model.addDataset(group)
|
||||
grid.positionViewAtIndex(grid.count - 1, GridView.Beginning)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,131 +27,131 @@ import QtQuick.Controls
|
||||
import "../Widgets" as Widgets
|
||||
|
||||
Widgets.Window {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
gradient: true
|
||||
headerDoubleClickEnabled: false
|
||||
title: qsTr("JSON Project Tree")
|
||||
icon.source: "qrc:/icons/json.svg"
|
||||
//
|
||||
// Window properties
|
||||
//
|
||||
gradient: true
|
||||
headerDoubleClickEnabled: false
|
||||
title: qsTr("JSON Project Tree")
|
||||
icon.source: "qrc:/icons/json.svg"
|
||||
|
||||
//
|
||||
// Connections with JSON editor model
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
//
|
||||
// Connections with JSON editor model
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_Project_Model
|
||||
|
||||
function onGroupCountChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
function onGroupOrderChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
function onDatasetChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
function onGroupCountChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
//
|
||||
// List view
|
||||
//
|
||||
ListView {
|
||||
id: view
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing * 2
|
||||
anchors.margins: app.spacing
|
||||
model: Cpp_Project_Model.groupCount
|
||||
function onGroupOrderChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
width: view.width - app.spacing * 2
|
||||
height: Cpp_Project_Model.datasetCount(index) * 24 + 24
|
||||
function onDatasetChanged() {
|
||||
view.model = 0
|
||||
view.model = Cpp_Project_Model.groupCount
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: ColumnLayout {
|
||||
id: groupDelegate
|
||||
spacing: app.spacing
|
||||
//
|
||||
// List view
|
||||
//
|
||||
ListView {
|
||||
id: view
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing * 2
|
||||
anchors.margins: app.spacing
|
||||
model: Cpp_Project_Model.groupCount
|
||||
|
||||
readonly property var groupId: index
|
||||
delegate: Loader {
|
||||
width: view.width - app.spacing * 2
|
||||
height: Cpp_Project_Model.datasetCount(index) * 24 + 24
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: ColumnLayout {
|
||||
id: groupDelegate
|
||||
spacing: app.spacing
|
||||
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/group.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
readonly property var groupId: index
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.groupTitle(groupDelegate.groupId)
|
||||
}
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
opacity: 0.5
|
||||
visible: text !== "[]"
|
||||
font.family: app.monoFont
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "[" + Cpp_Project_Model.groupWidget(groupDelegate.groupId) + "]"
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/group.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.groupTitle(groupDelegate.groupId)
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.5
|
||||
visible: text !== "[]"
|
||||
font.family: app.monoFont
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "[" + Cpp_Project_Model.groupWidget(groupDelegate.groupId) + "]"
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Cpp_Project_Model.datasetCount(groupDelegate.groupId)
|
||||
|
||||
delegate: Loader {
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
Item {
|
||||
width: 2 * app.spacing
|
||||
}
|
||||
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/dataset.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.datasetTitle(groupDelegate.groupId, index)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Cpp_Project_Model.datasetCount(groupDelegate.groupId)
|
||||
|
||||
delegate: Loader {
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
Item {
|
||||
width: 2 * app.spacing
|
||||
}
|
||||
|
||||
Widgets.Icon {
|
||||
width: 18
|
||||
height: 18
|
||||
color: Cpp_ThemeManager.text
|
||||
source: "qrc:/icons/dataset.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Label {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Cpp_Project_Model.datasetTitle(groupDelegate.groupId, index)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.5
|
||||
visible: text !== "[]"
|
||||
font.family: app.monoFont
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "[" + Cpp_Project_Model.datasetWidget(groupDelegate.groupId, index) + "]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Label {
|
||||
opacity: 0.5
|
||||
visible: text !== "[]"
|
||||
font.family: app.monoFont
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "[" + Cpp_Project_Model.datasetWidget(groupDelegate.groupId, index) + "]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,222 +28,222 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Custom properties to control the map from other QML files
|
||||
//
|
||||
property real latitude: 0
|
||||
property real longitude: 0
|
||||
property real altitude: 0 // Not used yet :(
|
||||
onLatitudeChanged: {
|
||||
if (autoCenter.checked)
|
||||
centerMap()
|
||||
}
|
||||
//
|
||||
// Custom properties to control the map from other QML files
|
||||
//
|
||||
property real latitude: 0
|
||||
property real longitude: 0
|
||||
property real altitude: 0 // Not used yet :(
|
||||
onLatitudeChanged: {
|
||||
if (autoCenter.checked)
|
||||
centerMap()
|
||||
}
|
||||
|
||||
onLongitudeChanged: {
|
||||
if (autoCenter.checked)
|
||||
centerMap()
|
||||
onLongitudeChanged: {
|
||||
if (autoCenter.checked)
|
||||
centerMap()
|
||||
}
|
||||
|
||||
//
|
||||
// Centers the map to the current coordinates
|
||||
//
|
||||
function centerMap() {
|
||||
map.center = QtPositioning.coordinate(root.latitude, root.longitude)
|
||||
}
|
||||
|
||||
//
|
||||
// Save settings accross runs
|
||||
//
|
||||
Settings {
|
||||
property alias mapTilt: tiltSlider.value
|
||||
property alias mapZoom: zoomSlider.value
|
||||
property alias mapCenter: autoCenter.checked
|
||||
property alias mapVariant: mapType.currentIndex
|
||||
}
|
||||
|
||||
//
|
||||
// UI controls
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
Label {
|
||||
text: qsTr("Map Type:")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: mapType
|
||||
Layout.fillWidth: true
|
||||
textRole: "description"
|
||||
model: map.supportedMapTypes
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onCurrentIndexChanged: map.activeMapType = map.supportedMapTypes[currentIndex]
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Centers the map to the current coordinates
|
||||
// Center map + zoom slider
|
||||
//
|
||||
function centerMap() {
|
||||
map.center = QtPositioning.coordinate(root.latitude, root.longitude)
|
||||
RowLayout {
|
||||
CheckBox {
|
||||
id: autoCenter
|
||||
checked: true
|
||||
checkable: true
|
||||
Layout.leftMargin: -6
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Center on coordinate")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
root.centerMap()
|
||||
}
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: zoomSlider
|
||||
value: map.zoomLevel
|
||||
Layout.fillWidth: true
|
||||
to: map.maximumZoomLevel
|
||||
from: map.minimumZoomLevel
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
onValueChanged: {
|
||||
if (map.zoomLevel !== value)
|
||||
map.zoomLevel = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save settings accross runs
|
||||
// Map
|
||||
//
|
||||
Settings {
|
||||
property alias mapTilt: tiltSlider.value
|
||||
property alias mapZoom: zoomSlider.value
|
||||
property alias mapCenter: autoCenter.checked
|
||||
property alias mapVariant: mapType.currentIndex
|
||||
}
|
||||
RowLayout {
|
||||
//
|
||||
// Tilt slider
|
||||
//
|
||||
Slider {
|
||||
id: tiltSlider
|
||||
orientation: Qt.Vertical
|
||||
Layout.fillHeight: true
|
||||
from: map.minimumTilt
|
||||
to: map.maximumTilt
|
||||
value: map.tilt
|
||||
onValueChanged: {
|
||||
if (map.tilt != value)
|
||||
map.tilt = value
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// UI controls
|
||||
//
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.spacing
|
||||
//
|
||||
// Map
|
||||
//
|
||||
Rectangle {
|
||||
id: mapRect
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
|
||||
Label {
|
||||
text: qsTr("Map Type:")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: mapType
|
||||
Layout.fillWidth: true
|
||||
textRole: "description"
|
||||
model: map.supportedMapTypes
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onCurrentIndexChanged: map.activeMapType = map.supportedMapTypes[currentIndex]
|
||||
}
|
||||
border {
|
||||
width: 2
|
||||
color: Cpp_ThemeManager.border
|
||||
}
|
||||
|
||||
//
|
||||
// Center map + zoom slider
|
||||
//
|
||||
RowLayout {
|
||||
CheckBox {
|
||||
id: autoCenter
|
||||
checked: true
|
||||
checkable: true
|
||||
Layout.leftMargin: -6
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Center on coordinate")
|
||||
onCheckedChanged: {
|
||||
if (checked)
|
||||
root.centerMap()
|
||||
}
|
||||
}
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
color: "#6ba9d1"
|
||||
position: Math.max(0.4,
|
||||
(map.maximumTilt - map.tilt) /
|
||||
map.maximumTilt)
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: zoomSlider
|
||||
value: map.zoomLevel
|
||||
Layout.fillWidth: true
|
||||
to: map.maximumZoomLevel
|
||||
from: map.minimumZoomLevel
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
onValueChanged: {
|
||||
if (map.zoomLevel !== value)
|
||||
map.zoomLevel = value
|
||||
}
|
||||
}
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#283e51"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Map
|
||||
//
|
||||
RowLayout {
|
||||
//
|
||||
// Tilt slider
|
||||
//
|
||||
Slider {
|
||||
id: tiltSlider
|
||||
orientation: Qt.Vertical
|
||||
Layout.fillHeight: true
|
||||
from: map.minimumTilt
|
||||
to: map.maximumTilt
|
||||
value: map.tilt
|
||||
onValueChanged: {
|
||||
if (map.tilt != value)
|
||||
map.tilt = value
|
||||
}
|
||||
Map {
|
||||
id: map
|
||||
smooth: true
|
||||
antialiasing: true
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
copyrightsVisible: false
|
||||
anchors.margins: parent.border.width
|
||||
|
||||
tilt: 27
|
||||
zoomLevel: 16
|
||||
|
||||
MapQuickItem {
|
||||
anchorPoint: Qt.point(sourceItem.width / 2,
|
||||
sourceItem.height/ 2)
|
||||
coordinate: QtPositioning.coordinate(root.latitude,
|
||||
root.longitude)
|
||||
|
||||
sourceItem: Rectangle {
|
||||
id: dot
|
||||
width: 20
|
||||
height: 20
|
||||
opacity: 0.8
|
||||
border.width: 2
|
||||
radius: width / 2
|
||||
color: "#ff0000"
|
||||
border.color: "#ffffff"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Map
|
||||
//
|
||||
Rectangle {
|
||||
id: mapRect
|
||||
clip: true
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
plugin: Plugin {
|
||||
preferred: "osm"
|
||||
|
||||
border {
|
||||
width: 2
|
||||
color: Cpp_ThemeManager.border
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
color: "#6ba9d1"
|
||||
position: Math.max(0.4,
|
||||
(map.maximumTilt - map.tilt) /
|
||||
map.maximumTilt)
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#283e51"
|
||||
}
|
||||
}
|
||||
|
||||
Map {
|
||||
id: map
|
||||
smooth: true
|
||||
antialiasing: true
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
copyrightsVisible: false
|
||||
anchors.margins: parent.border.width
|
||||
|
||||
tilt: 27
|
||||
zoomLevel: 16
|
||||
|
||||
MapQuickItem {
|
||||
anchorPoint: Qt.point(sourceItem.width / 2,
|
||||
sourceItem.height/ 2)
|
||||
coordinate: QtPositioning.coordinate(root.latitude,
|
||||
root.longitude)
|
||||
|
||||
sourceItem: Rectangle {
|
||||
id: dot
|
||||
width: 20
|
||||
height: 20
|
||||
opacity: 0.8
|
||||
border.width: 2
|
||||
radius: width / 2
|
||||
color: "#ff0000"
|
||||
border.color: "#ffffff"
|
||||
}
|
||||
}
|
||||
|
||||
plugin: Plugin {
|
||||
preferred: "osm"
|
||||
|
||||
PluginParameter {
|
||||
name: "osm.mapping.highdpi_tiles"
|
||||
value: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: smog
|
||||
height: 32
|
||||
opacity: 0.5
|
||||
|
||||
Connections {
|
||||
target: map
|
||||
function onTiltChanged() {
|
||||
var x = map.tilt / map.maximumTilt
|
||||
smog.y = (1.666 * x - 1.416) * mapRect.height
|
||||
}
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: "#dedede"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
PluginParameter {
|
||||
name: "osm.mapping.highdpi_tiles"
|
||||
value: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: smog
|
||||
height: 32
|
||||
opacity: 0.5
|
||||
|
||||
Connections {
|
||||
target: map
|
||||
function onTiltChanged() {
|
||||
var x = map.tilt / map.maximumTilt
|
||||
smog.y = (1.666 * x - 1.416) * mapRect.height
|
||||
}
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: "#dedede"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,28 +24,28 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
Item {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property string source: ""
|
||||
property alias icon: button.icon
|
||||
property color color: Cpp_ThemeManager.menubarText
|
||||
property string source: ""
|
||||
property alias icon: button.icon
|
||||
property color color: Cpp_ThemeManager.menubarText
|
||||
|
||||
width: 24
|
||||
height: 24
|
||||
width: 24
|
||||
height: 24
|
||||
|
||||
ToolButton {
|
||||
id: button
|
||||
enabled: false
|
||||
background: Item {}
|
||||
icon.color: root.color
|
||||
icon.width: root.width
|
||||
icon.height: root.width
|
||||
icon.source: root.source
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
ToolButton {
|
||||
id: button
|
||||
enabled: false
|
||||
background: Item {}
|
||||
icon.color: root.color
|
||||
icon.width: root.width
|
||||
icon.height: root.width
|
||||
icon.source: root.source
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: true
|
||||
}
|
||||
}
|
||||
|
@ -25,110 +25,110 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
DropArea {
|
||||
//
|
||||
// Show rectangle and set color based on file extension on drag enter
|
||||
//
|
||||
onEntered: {
|
||||
// Get file name & set color of rectangle accordingly
|
||||
if (drag.urls.length > 0) {
|
||||
var path = drag.urls[0].toString()
|
||||
if (path.endsWith(".json") || path.endsWith(".csv")) {
|
||||
drag.accept(Qt.LinkAction)
|
||||
dropRectangle.color = Qt.darker(palette.highlight, 1.4)
|
||||
}
|
||||
//
|
||||
// Show rectangle and set color based on file extension on drag enter
|
||||
//
|
||||
onEntered: {
|
||||
// Get file name & set color of rectangle accordingly
|
||||
if (drag.urls.length > 0) {
|
||||
var path = drag.urls[0].toString()
|
||||
if (path.endsWith(".json") || path.endsWith(".csv")) {
|
||||
drag.accept(Qt.LinkAction)
|
||||
dropRectangle.color = Qt.darker(palette.highlight, 1.4)
|
||||
}
|
||||
|
||||
// Invalid file name, show red rectangle
|
||||
else
|
||||
dropRectangle.color = Cpp_ThemeManager.alternativeHighlight
|
||||
// Invalid file name, show red rectangle
|
||||
else
|
||||
dropRectangle.color = Cpp_ThemeManager.alternativeHighlight
|
||||
|
||||
// Show drag&drop rectangle
|
||||
dropRectangle.opacity = 0.8
|
||||
}
|
||||
// Show drag&drop rectangle
|
||||
dropRectangle.opacity = 0.8
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Open *.json & *.csv files on drag drop
|
||||
//
|
||||
onDropped: {
|
||||
// Hide rectangle
|
||||
dropRectangle.hide()
|
||||
|
||||
// Get dropped file URL and remove prefixed "file://"
|
||||
var path = drop.urls[0].toString()
|
||||
if (!Cpp_IsWin)
|
||||
path = path.replace(/^(file:\/{2})/,"");
|
||||
else
|
||||
path = path.replace(/^(file:\/{3})/,"");
|
||||
|
||||
// Unescape html codes like '%23' for '#'
|
||||
var cleanPath = decodeURIComponent(path);
|
||||
|
||||
// Process JSON files
|
||||
if (cleanPath.endsWith(".json")) {
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
Cpp_JSON_Generator.loadJsonMap(cleanPath)
|
||||
}
|
||||
|
||||
//
|
||||
// Open *.json & *.csv files on drag drop
|
||||
//
|
||||
onDropped: {
|
||||
// Hide rectangle
|
||||
dropRectangle.hide()
|
||||
// Process CSV files
|
||||
else if (cleanPath.endsWith(".csv"))
|
||||
Cpp_CSV_Player.openFile(cleanPath)
|
||||
}
|
||||
|
||||
// Get dropped file URL and remove prefixed "file://"
|
||||
var path = drop.urls[0].toString()
|
||||
if (!Cpp_IsWin)
|
||||
path = path.replace(/^(file:\/{2})/,"");
|
||||
else
|
||||
path = path.replace(/^(file:\/{3})/,"");
|
||||
//
|
||||
// Hide drag & drop rectangle on drag exit
|
||||
//
|
||||
onExited: {
|
||||
dropRectangle.hide()
|
||||
}
|
||||
|
||||
// Unescape html codes like '%23' for '#'
|
||||
var cleanPath = decodeURIComponent(path);
|
||||
//
|
||||
// Drop rectangle + icon + text
|
||||
//
|
||||
Rectangle {
|
||||
id: dropRectangle
|
||||
|
||||
// Process JSON files
|
||||
if (cleanPath.endsWith(".json")) {
|
||||
Cpp_JSON_Generator.setOperationMode(0)
|
||||
Cpp_JSON_Generator.loadJsonMap(cleanPath)
|
||||
}
|
||||
|
||||
// Process CSV files
|
||||
else if (cleanPath.endsWith(".csv"))
|
||||
Cpp_CSV_Player.openFile(cleanPath)
|
||||
function hide() {
|
||||
rectTimer.start()
|
||||
}
|
||||
|
||||
//
|
||||
// Hide drag & drop rectangle on drag exit
|
||||
//
|
||||
onExited: {
|
||||
dropRectangle.hide()
|
||||
opacity: 0
|
||||
border.width: 1
|
||||
anchors.centerIn: parent
|
||||
color: Cpp_ThemeManager.highlight
|
||||
border.color: Cpp_ThemeManager.text
|
||||
width: dropLayout.implicitWidth + 6 * app.spacing
|
||||
height: dropLayout.implicitHeight + 6 * app.spacing
|
||||
|
||||
ColumnLayout {
|
||||
id: dropLayout
|
||||
spacing: app.spacing * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
ToolButton {
|
||||
flat: true
|
||||
enabled: false
|
||||
icon.width: 128
|
||||
icon.height: 128
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
icon.source: "qrc:/icons/drag-drop.svg"
|
||||
icon.color: Cpp_ThemeManager.highlightedText
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: Cpp_ThemeManager.highlightedText
|
||||
text: qsTr("Drop JSON and CSV files here")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Drop rectangle + icon + text
|
||||
//
|
||||
Rectangle {
|
||||
id: dropRectangle
|
||||
|
||||
function hide() {
|
||||
rectTimer.start()
|
||||
}
|
||||
|
||||
opacity: 0
|
||||
border.width: 1
|
||||
anchors.centerIn: parent
|
||||
color: Cpp_ThemeManager.highlight
|
||||
border.color: Cpp_ThemeManager.text
|
||||
width: dropLayout.implicitWidth + 6 * app.spacing
|
||||
height: dropLayout.implicitHeight + 6 * app.spacing
|
||||
|
||||
ColumnLayout {
|
||||
id: dropLayout
|
||||
spacing: app.spacing * 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
ToolButton {
|
||||
flat: true
|
||||
enabled: false
|
||||
icon.width: 128
|
||||
icon.height: 128
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
icon.source: "qrc:/icons/drag-drop.svg"
|
||||
icon.color: Cpp_ThemeManager.highlightedText
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: Cpp_ThemeManager.highlightedText
|
||||
text: qsTr("Drop JSON and CSV files here")
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: rectTimer
|
||||
interval: 200
|
||||
onTriggered: dropRectangle.opacity = 0
|
||||
}
|
||||
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
Timer {
|
||||
id: rectTimer
|
||||
interval: 200
|
||||
onTriggered: dropRectangle.opacity = 0
|
||||
}
|
||||
|
||||
Behavior on opacity {NumberAnimation{}}
|
||||
}
|
||||
}
|
||||
|
@ -23,37 +23,37 @@
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property real topMargin: -8
|
||||
property real leftMargin: -8
|
||||
property real rightMargin: -10
|
||||
property real bottomMargin: -10
|
||||
property alias border: borderImage.border
|
||||
property alias source: borderImage.source
|
||||
property alias shadowOpacity: borderImage.opacity
|
||||
id: root
|
||||
property real topMargin: -8
|
||||
property real leftMargin: -8
|
||||
property real rightMargin: -10
|
||||
property real bottomMargin: -10
|
||||
property alias border: borderImage.border
|
||||
property alias source: borderImage.source
|
||||
property alias shadowOpacity: borderImage.opacity
|
||||
|
||||
BorderImage {
|
||||
id: borderImage
|
||||
BorderImage {
|
||||
id: borderImage
|
||||
|
||||
opacity: 0.5
|
||||
smooth: true
|
||||
anchors.fill: parent
|
||||
source: "qrc:/images/shadow.png"
|
||||
verticalTileMode: BorderImage.Round
|
||||
horizontalTileMode: BorderImage.Round
|
||||
opacity: 0.5
|
||||
smooth: true
|
||||
anchors.fill: parent
|
||||
source: "qrc:/images/shadow.png"
|
||||
verticalTileMode: BorderImage.Round
|
||||
horizontalTileMode: BorderImage.Round
|
||||
|
||||
anchors {
|
||||
topMargin: root.topMargin
|
||||
leftMargin: root.leftMargin
|
||||
rightMargin: root.rightMargin
|
||||
bottomMargin: root.bottomMargin
|
||||
}
|
||||
|
||||
border {
|
||||
left: 10
|
||||
top: 10
|
||||
right: 10
|
||||
bottom: 10
|
||||
}
|
||||
anchors {
|
||||
topMargin: root.topMargin
|
||||
leftMargin: root.leftMargin
|
||||
rightMargin: root.rightMargin
|
||||
bottomMargin: root.bottomMargin
|
||||
}
|
||||
|
||||
border {
|
||||
left: 10
|
||||
top: 10
|
||||
right: 10
|
||||
bottom: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,297 +27,297 @@ import QtQuick.Controls
|
||||
import SerialStudio as SerialStudio
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool isExternalWindow: false
|
||||
property alias widgetEnabled: textEdit.widgetEnabled
|
||||
property alias vt100emulation: textEdit.vt100emulation
|
||||
id: root
|
||||
property bool isExternalWindow: false
|
||||
property alias widgetEnabled: textEdit.widgetEnabled
|
||||
property alias vt100emulation: textEdit.vt100emulation
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
property alias hex: hexCheckbox.checked
|
||||
property alias echo: echoCheckbox.checked
|
||||
property alias timestamp: timestampCheck.checked
|
||||
property alias autoscroll: autoscrollCheck.checked
|
||||
property alias vt100Enabled: textEdit.vt100emulation
|
||||
property alias lineEnding: lineEndingCombo.currentIndex
|
||||
property alias displayMode: displayModeCombo.currentIndex
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
property alias hex: hexCheckbox.checked
|
||||
property alias echo: echoCheckbox.checked
|
||||
property alias timestamp: timestampCheck.checked
|
||||
property alias autoscroll: autoscrollCheck.checked
|
||||
property alias vt100Enabled: textEdit.vt100emulation
|
||||
property alias lineEnding: lineEndingCombo.currentIndex
|
||||
property alias displayMode: displayModeCombo.currentIndex
|
||||
}
|
||||
|
||||
//
|
||||
// Function to send through serial port data
|
||||
//
|
||||
function sendData() {
|
||||
Cpp_IO_Console.send(send.text)
|
||||
send.clear()
|
||||
}
|
||||
|
||||
//
|
||||
// Clears console output
|
||||
//
|
||||
function clear() {
|
||||
Cpp_IO_Console.clear()
|
||||
textEdit.clear()
|
||||
}
|
||||
|
||||
//
|
||||
// Copy function
|
||||
//
|
||||
function copy() {
|
||||
textEdit.copy()
|
||||
}
|
||||
|
||||
//
|
||||
// Select all text
|
||||
//
|
||||
function selectAll() {
|
||||
textEdit.selectAll()
|
||||
}
|
||||
|
||||
//
|
||||
// Right-click context menu
|
||||
//
|
||||
Menu {
|
||||
id: contextMenu
|
||||
|
||||
MenuItem {
|
||||
id: copyMenu
|
||||
text: qsTr("Copy")
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: textEdit.copy()
|
||||
enabled: textEdit.copyAvailable
|
||||
}
|
||||
|
||||
//
|
||||
// Function to send through serial port data
|
||||
//
|
||||
function sendData() {
|
||||
Cpp_IO_Console.send(send.text)
|
||||
send.clear()
|
||||
MenuItem {
|
||||
text: qsTr("Select all")
|
||||
enabled: !textEdit.empty
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onTriggered: textEdit.selectAll()
|
||||
}
|
||||
|
||||
//
|
||||
// Clears console output
|
||||
//
|
||||
function clear() {
|
||||
Cpp_IO_Console.clear()
|
||||
textEdit.clear()
|
||||
MenuItem {
|
||||
text: qsTr("Clear")
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onTriggered: root.clear()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
|
||||
//
|
||||
// Copy function
|
||||
//
|
||||
function copy() {
|
||||
textEdit.copy()
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Print")
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
//
|
||||
// Select all text
|
||||
//
|
||||
function selectAll() {
|
||||
textEdit.selectAll()
|
||||
MenuItem {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Save as") + "..."
|
||||
onTriggered: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.margins: app.spacing * 1.5
|
||||
|
||||
//
|
||||
// Right-click context menu
|
||||
// Console display
|
||||
//
|
||||
Menu {
|
||||
id: contextMenu
|
||||
SerialStudio.Terminal {
|
||||
id: textEdit
|
||||
focus: true
|
||||
readOnly: true
|
||||
font.pixelSize: 12
|
||||
vt100emulation: true
|
||||
centerOnScroll: false
|
||||
undoRedoEnabled: false
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
maximumBlockCount: 12000
|
||||
font.family: app.monoFont
|
||||
autoscroll: Cpp_IO_Console.autoscroll
|
||||
renderTarget: PaintedItem.FramebufferObject
|
||||
wordWrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
placeholderText: qsTr("No data received so far") + "..."
|
||||
|
||||
MenuItem {
|
||||
id: copyMenu
|
||||
text: qsTr("Copy")
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: textEdit.copy()
|
||||
enabled: textEdit.copyAvailable
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Select all")
|
||||
enabled: !textEdit.empty
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onTriggered: textEdit.selectAll()
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Clear")
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onTriggered: root.clear()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
|
||||
MenuItem {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Print")
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
onTriggered: Cpp_IO_Console.print(app.monoFont)
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
text: qsTr("Save as") + "..."
|
||||
onTriggered: Cpp_IO_Console.save()
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Controls
|
||||
//
|
||||
ColumnLayout {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.margins: app.spacing * 1.5
|
||||
cursorShape: Qt.IBeamCursor
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: Qt.RightButton
|
||||
anchors.rightMargin: textEdit.scrollbarWidth
|
||||
|
||||
//
|
||||
// Console display
|
||||
//
|
||||
SerialStudio.Terminal {
|
||||
id: textEdit
|
||||
focus: true
|
||||
readOnly: true
|
||||
font.pixelSize: 12
|
||||
vt100emulation: true
|
||||
centerOnScroll: false
|
||||
undoRedoEnabled: false
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
maximumBlockCount: 12000
|
||||
font.family: app.monoFont
|
||||
autoscroll: Cpp_IO_Console.autoscroll
|
||||
renderTarget: PaintedItem.FramebufferObject
|
||||
wordWrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
placeholderText: qsTr("No data received so far") + "..."
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.IBeamCursor
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: Qt.RightButton
|
||||
anchors.rightMargin: textEdit.scrollbarWidth
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
contextMenu.popup()
|
||||
mouse.accepted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Data-write controls
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextField {
|
||||
id: send
|
||||
height: 24
|
||||
font: textEdit.font
|
||||
Layout.fillWidth: true
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
palette.text: Cpp_ThemeManager.consoleText
|
||||
palette.base: Cpp_ThemeManager.consoleBase
|
||||
placeholderText: qsTr("Send data to device") + "..."
|
||||
Component.onCompleted: {
|
||||
if (Cpp_Qt6)
|
||||
placeholderTextColor = Cpp_ThemeManager.consolePlaceholderText
|
||||
}
|
||||
|
||||
//
|
||||
// Validate hex strings
|
||||
//
|
||||
//validator: RegExpValidator {
|
||||
// regExp: hexCheckbox.checked ? /^(?:([a-f0-9]{2})\s*)+$/i : /[\s\S]*/
|
||||
//}
|
||||
|
||||
//
|
||||
// Send data on <enter>
|
||||
//
|
||||
Keys.onReturnPressed: root.sendData()
|
||||
|
||||
//
|
||||
// Add space automatically in hex view
|
||||
//
|
||||
onTextChanged: {
|
||||
if (hexCheckbox.checked)
|
||||
send.text = Cpp_IO_Console.formatUserHex(send.text)
|
||||
}
|
||||
|
||||
//
|
||||
// Navigate command history upwards with <up>
|
||||
//
|
||||
Keys.onUpPressed: {
|
||||
Cpp_IO_Console.historyUp()
|
||||
send.text = Cpp_IO_Console.currentHistoryString
|
||||
}
|
||||
|
||||
//
|
||||
// Navigate command history downwards with <down>
|
||||
//
|
||||
Keys.onDownPressed: {
|
||||
Cpp_IO_Console.historyDown()
|
||||
send.text = Cpp_IO_Console.currentHistoryString
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "HEX"
|
||||
id: hexCheckbox
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
checked: Cpp_IO_Console.dataMode === 1
|
||||
onCheckedChanged: Cpp_IO_Console.dataMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
visible: false
|
||||
text: qsTr("Echo")
|
||||
id: echoCheckbox
|
||||
opacity: enabled ? 1 : 0.5
|
||||
checked: Cpp_IO_Console.echo
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.echo !== checked)
|
||||
Cpp_IO_Console.echo = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Terminal output options
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
CheckBox {
|
||||
id: autoscrollCheck
|
||||
text: qsTr("Autoscroll")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.autoscroll !== checked)
|
||||
Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: timestampCheck
|
||||
text: qsTr("Show timestamp")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.showTimestamp !== checked)
|
||||
Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: lineEndingCombo
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Console.lineEndings()
|
||||
currentIndex: Cpp_IO_Console.lineEnding
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Console.lineEnding)
|
||||
Cpp_IO_Console.lineEnding = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: displayModeCombo
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Console.displayModes()
|
||||
currentIndex: Cpp_IO_Console.displayMode
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Console.displayMode)
|
||||
Cpp_IO_Console.displayMode = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
height: 24
|
||||
Layout.maximumWidth: 32
|
||||
icon.color: palette.text
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: Cpp_IO_Console.save()
|
||||
icon.source: "qrc:/icons/save.svg"
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
|
||||
Button {
|
||||
height: 24
|
||||
Layout.maximumWidth: 32
|
||||
icon.color: palette.text
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: root.clear()
|
||||
icon.source: "qrc:/icons/delete.svg"
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
}
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
contextMenu.popup()
|
||||
mouse.accepted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Data-write controls
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextField {
|
||||
id: send
|
||||
height: 24
|
||||
font: textEdit.font
|
||||
Layout.fillWidth: true
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
palette.text: Cpp_ThemeManager.consoleText
|
||||
palette.base: Cpp_ThemeManager.consoleBase
|
||||
placeholderText: qsTr("Send data to device") + "..."
|
||||
Component.onCompleted: {
|
||||
if (Cpp_Qt6)
|
||||
placeholderTextColor = Cpp_ThemeManager.consolePlaceholderText
|
||||
}
|
||||
|
||||
//
|
||||
// Validate hex strings
|
||||
//
|
||||
//validator: RegExpValidator {
|
||||
// regExp: hexCheckbox.checked ? /^(?:([a-f0-9]{2})\s*)+$/i : /[\s\S]*/
|
||||
//}
|
||||
|
||||
//
|
||||
// Send data on <enter>
|
||||
//
|
||||
Keys.onReturnPressed: root.sendData()
|
||||
|
||||
//
|
||||
// Add space automatically in hex view
|
||||
//
|
||||
onTextChanged: {
|
||||
if (hexCheckbox.checked)
|
||||
send.text = Cpp_IO_Console.formatUserHex(send.text)
|
||||
}
|
||||
|
||||
//
|
||||
// Navigate command history upwards with <up>
|
||||
//
|
||||
Keys.onUpPressed: {
|
||||
Cpp_IO_Console.historyUp()
|
||||
send.text = Cpp_IO_Console.currentHistoryString
|
||||
}
|
||||
|
||||
//
|
||||
// Navigate command history downwards with <down>
|
||||
//
|
||||
Keys.onDownPressed: {
|
||||
Cpp_IO_Console.historyDown()
|
||||
send.text = Cpp_IO_Console.currentHistoryString
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "HEX"
|
||||
id: hexCheckbox
|
||||
opacity: enabled ? 1 : 0.5
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
checked: Cpp_IO_Console.dataMode === 1
|
||||
onCheckedChanged: Cpp_IO_Console.dataMode = checked ? 1 : 0
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
visible: false
|
||||
text: qsTr("Echo")
|
||||
id: echoCheckbox
|
||||
opacity: enabled ? 1 : 0.5
|
||||
checked: Cpp_IO_Console.echo
|
||||
enabled: Cpp_IO_Manager.readWrite
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.echo !== checked)
|
||||
Cpp_IO_Console.echo = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Terminal output options
|
||||
//
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
CheckBox {
|
||||
id: autoscrollCheck
|
||||
text: qsTr("Autoscroll")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_IO_Console.autoscroll
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.autoscroll !== checked)
|
||||
Cpp_IO_Console.autoscroll = checked
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: timestampCheck
|
||||
text: qsTr("Show timestamp")
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
checked: Cpp_IO_Console.showTimestamp
|
||||
onCheckedChanged: {
|
||||
if (Cpp_IO_Console.showTimestamp !== checked)
|
||||
Cpp_IO_Console.showTimestamp = checked
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: lineEndingCombo
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Console.lineEndings()
|
||||
currentIndex: Cpp_IO_Console.lineEnding
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Console.lineEnding)
|
||||
Cpp_IO_Console.lineEnding = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: displayModeCombo
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
model: Cpp_IO_Console.displayModes()
|
||||
currentIndex: Cpp_IO_Console.displayMode
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== Cpp_IO_Console.displayMode)
|
||||
Cpp_IO_Console.displayMode = currentIndex
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
height: 24
|
||||
Layout.maximumWidth: 32
|
||||
icon.color: palette.text
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: Cpp_IO_Console.save()
|
||||
icon.source: "qrc:/icons/save.svg"
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
|
||||
Button {
|
||||
height: 24
|
||||
Layout.maximumWidth: 32
|
||||
icon.color: palette.text
|
||||
opacity: enabled ? 1 : 0.5
|
||||
onClicked: root.clear()
|
||||
icon.source: "qrc:/icons/delete.svg"
|
||||
enabled: Cpp_IO_Console.saveAvailable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,165 +25,165 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
Page {
|
||||
id: root
|
||||
clip: true
|
||||
id: root
|
||||
clip: true
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int borderWidth: 3
|
||||
property alias icon: _bt.icon
|
||||
property bool gradient: false
|
||||
property int headerHeight: 32
|
||||
property bool headerVisible: true
|
||||
property alias showIcon: _bt.visible
|
||||
property int radius: root.borderWidth + 2
|
||||
property color titleColor: palette.brightText
|
||||
property color borderColor: palette.highlight
|
||||
property bool altButtonEnabled: false
|
||||
property alias altButtonIcon: altBt.icon
|
||||
property alias headerDoubleClickEnabled: headerMouseArea.enabled
|
||||
property color backgroundColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
property color gradientColor1: root.gradient ? Cpp_ThemeManager.windowGradient1 :
|
||||
root.borderColor
|
||||
property color gradientColor2: root.gradient ? Cpp_ThemeManager.windowGradient2 :
|
||||
root.borderColor
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int borderWidth: 3
|
||||
property alias icon: _bt.icon
|
||||
property bool gradient: false
|
||||
property int headerHeight: 32
|
||||
property bool headerVisible: true
|
||||
property alias showIcon: _bt.visible
|
||||
property int radius: root.borderWidth + 2
|
||||
property color titleColor: palette.brightText
|
||||
property color borderColor: palette.highlight
|
||||
property bool altButtonEnabled: false
|
||||
property alias altButtonIcon: altBt.icon
|
||||
property alias headerDoubleClickEnabled: headerMouseArea.enabled
|
||||
property color backgroundColor: Cpp_ThemeManager.widgetWindowBackground
|
||||
property color gradientColor1: root.gradient ? Cpp_ThemeManager.windowGradient1 :
|
||||
root.borderColor
|
||||
property color gradientColor2: root.gradient ? Cpp_ThemeManager.windowGradient2 :
|
||||
root.borderColor
|
||||
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal altButtonClicked()
|
||||
signal headerDoubleClicked()
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
signal altButtonClicked()
|
||||
signal headerDoubleClicked()
|
||||
|
||||
//
|
||||
// Layout properties
|
||||
//
|
||||
visible: opacity > 0
|
||||
Layout.preferredWidth: enabled ? implicitWidth : 0
|
||||
Layout.preferredHeight: enabled ? implicitHeight : 0
|
||||
//
|
||||
// Layout properties
|
||||
//
|
||||
visible: opacity > 0
|
||||
Layout.preferredWidth: enabled ? implicitWidth : 0
|
||||
Layout.preferredHeight: enabled ? implicitHeight : 0
|
||||
|
||||
//
|
||||
// Background widget
|
||||
//
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
border.width: root.borderWidth
|
||||
border.color: root.gradientColor1
|
||||
//
|
||||
// Background widget
|
||||
//
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
border.width: root.borderWidth
|
||||
border.color: root.gradientColor1
|
||||
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: header.height
|
||||
anchors.margins: root.borderWidth
|
||||
border.color: Cpp_ThemeManager.border
|
||||
}
|
||||
Rectangle {
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: header.height
|
||||
anchors.margins: root.borderWidth
|
||||
border.color: Cpp_ThemeManager.border
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window title & controls
|
||||
//
|
||||
header: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.borderColor
|
||||
height: root.headerHeight
|
||||
visible: root.headerVisible
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: root.gradientColor1
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: root.gradientColor2
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window title & controls
|
||||
//
|
||||
header: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.borderColor
|
||||
height: root.headerHeight
|
||||
visible: root.headerVisible
|
||||
Rectangle {
|
||||
z: 5
|
||||
color: root.gradientColor1
|
||||
height: root.gradient ? 1 : parent.radius
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: root.gradientColor1
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: root.gradientColor2
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
z: 5
|
||||
color: root.gradientColor1
|
||||
height: root.gradient ? 1 : parent.radius
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
z: 2
|
||||
id: headerMouseArea
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: root.headerDoubleClicked()
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.x >= headerBt.x && mouse.x <= headerBt.x + headerBt.width)
|
||||
root.headerDoubleClicked()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Icon {
|
||||
id: _bt
|
||||
color: root.titleColor
|
||||
source: "qrc:/icons/widget.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: root.title
|
||||
Layout.fillWidth: true
|
||||
color: root.titleColor
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.pixelSize: root.headerHeight * 14 / 32
|
||||
horizontalAlignment: root.showIcon ? Label.AlignLeft : Label.AlignHCenter
|
||||
}
|
||||
|
||||
Icon {
|
||||
id: headerBt
|
||||
color: root.titleColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
icon.source: "qrc:/icons/expand.svg"
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
visible: root.headerDoubleClickEnabled
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
}
|
||||
|
||||
Button {
|
||||
id: altBt
|
||||
flat: true
|
||||
enabled: visible
|
||||
icon.color: root.titleColor
|
||||
visible: root.altButtonEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: root.altButtonClicked()
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
background: Item {}
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
z: 2
|
||||
id: headerMouseArea
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: root.headerDoubleClicked()
|
||||
|
||||
onClicked: (mouse) => {
|
||||
if (mouse.x >= headerBt.x && mouse.x <= headerBt.x + headerBt.width)
|
||||
root.headerDoubleClicked()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
Icon {
|
||||
id: _bt
|
||||
color: root.titleColor
|
||||
source: "qrc:/icons/widget.svg"
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: root.title
|
||||
Layout.fillWidth: true
|
||||
color: root.titleColor
|
||||
elide: Label.ElideRight
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
font.pixelSize: root.headerHeight * 14 / 32
|
||||
horizontalAlignment: root.showIcon ? Label.AlignLeft : Label.AlignHCenter
|
||||
}
|
||||
|
||||
Icon {
|
||||
id: headerBt
|
||||
color: root.titleColor
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
icon.source: "qrc:/icons/expand.svg"
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
visible: root.headerDoubleClickEnabled
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
}
|
||||
|
||||
Button {
|
||||
id: altBt
|
||||
flat: true
|
||||
enabled: visible
|
||||
icon.color: root.titleColor
|
||||
visible: root.altButtonEnabled
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: root.altButtonClicked()
|
||||
Layout.maximumHeight: parent.height
|
||||
Layout.minimumHeight: parent.height
|
||||
Layout.minimumWidth: root.headerHeight
|
||||
Layout.maximumWidth: root.headerHeight
|
||||
icon.width: root.headerHeight * 20 / 32
|
||||
icon.height: root.headerHeight * 20 / 32
|
||||
background: Item {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,197 +28,197 @@ import QtQuick.Controls
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
readonly property int year: new Date().getFullYear()
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
readonly property int year: new Date().getFullYear()
|
||||
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
title: qsTr("About")
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
title: qsTr("About")
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
|
||||
//
|
||||
// Titlebar options
|
||||
//
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
//
|
||||
// Titlebar options
|
||||
//
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
root.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Image {
|
||||
width: 128
|
||||
height: 128
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
sourceSize: Qt.size(width, height)
|
||||
source: {
|
||||
if (Screen.pixelDensity >= 2)
|
||||
return "qrc:/images/icon@2x.png"
|
||||
|
||||
return "qrc:/images/icon@1x.png"
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: Cpp_AppName
|
||||
font.pixelSize: 28
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.5
|
||||
font.pixelSize: 16
|
||||
text: qsTr("Version %1").arg(Cpp_AppVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 320
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
text: qsTr("Copyright © 2020-%1 %2, released under the MIT License.").arg(root.year).arg(Cpp_AppOrganization)
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 320
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.")
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Website")
|
||||
onClicked: Qt.openUrlExternally("https://serial-studio.github.io/")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Make a donation")
|
||||
onClicked: app.donateDialog.show()
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Report bug")
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Documentation")
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Acknowledgements")
|
||||
onClicked: acknowledgementsDialog.show()
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
onClicked: root.close()
|
||||
text: qsTr("Close")
|
||||
}
|
||||
}
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
root.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
|
||||
Image {
|
||||
width: 128
|
||||
height: 128
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
sourceSize: Qt.size(width, height)
|
||||
source: {
|
||||
if (Screen.pixelDensity >= 2)
|
||||
return "qrc:/images/icon@2x.png"
|
||||
|
||||
return "qrc:/images/icon@1x.png"
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
text: Cpp_AppName
|
||||
font.pixelSize: 28
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.5
|
||||
font.pixelSize: 16
|
||||
text: qsTr("Version %1").arg(Cpp_AppVersion)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 320
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
text: qsTr("Copyright © 2020-%1 %2, released under the MIT License.").arg(root.year).arg(Cpp_AppOrganization)
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: 320
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.")
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Website")
|
||||
onClicked: Qt.openUrlExternally("https://serial-studio.github.io/")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Make a donation")
|
||||
onClicked: app.donateDialog.show()
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Report bug")
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/issues")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Documentation")
|
||||
onClicked: Qt.openUrlExternally("https://github.com/Serial-Studio/Serial-Studio/wiki")
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Acknowledgements")
|
||||
onClicked: acknowledgementsDialog.show()
|
||||
}
|
||||
|
||||
Item {
|
||||
height: app.spacing
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
onClicked: root.close()
|
||||
text: qsTr("Close")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,101 +28,101 @@ import QtQuick.Controls
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
title: qsTr("Acknowledgements")
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
title: qsTr("Acknowledgements")
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 640
|
||||
Layout.maximumWidth: 640
|
||||
Layout.minimumHeight: 480
|
||||
Layout.maximumHeight: 480
|
||||
|
||||
TextArea {
|
||||
readOnly: true
|
||||
textFormat: TextArea.MarkdownText
|
||||
wrapMode: TextArea.WrapAtWordBoundaryOrAnywhere
|
||||
text: Cpp_Misc_Translator.acknowledgementsText()
|
||||
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Close")
|
||||
onClicked: root.close()
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
}
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 640
|
||||
Layout.maximumWidth: 640
|
||||
Layout.minimumHeight: 480
|
||||
Layout.maximumHeight: 480
|
||||
|
||||
TextArea {
|
||||
readOnly: true
|
||||
textFormat: TextArea.MarkdownText
|
||||
wrapMode: TextArea.WrapAtWordBoundaryOrAnywhere
|
||||
text: Cpp_Misc_Translator.acknowledgementsText()
|
||||
|
||||
background: TextField {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Close")
|
||||
onClicked: root.close()
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,155 +28,155 @@ import QtQuick.Controls
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
title: qsTr("CSV Player")
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
title: qsTr("CSV Player")
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
|
||||
//
|
||||
// Close CSV file when window is closed
|
||||
//
|
||||
onVisibleChanged: {
|
||||
if (!visible && Cpp_CSV_Player.isOpen)
|
||||
Cpp_CSV_Player.closeFile()
|
||||
//
|
||||
// Close CSV file when window is closed
|
||||
//
|
||||
onVisibleChanged: {
|
||||
if (!visible && Cpp_CSV_Player.isOpen)
|
||||
Cpp_CSV_Player.closeFile()
|
||||
}
|
||||
|
||||
//
|
||||
// Automatically display the window when the CSV file is opened
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_CSV_Player
|
||||
function onOpenChanged() {
|
||||
if (Cpp_CSV_Player.isOpen)
|
||||
root.visible = true
|
||||
else
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Automatically display the window when the CSV file is opened
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_CSV_Player
|
||||
function onOpenChanged() {
|
||||
if (Cpp_CSV_Player.isOpen)
|
||||
root.visible = true
|
||||
else
|
||||
root.visible = false
|
||||
}
|
||||
}
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: app.spacing * 2
|
||||
|
||||
//
|
||||
// Timestamp display
|
||||
//
|
||||
Label {
|
||||
font.family: app.monoFont
|
||||
text: Cpp_CSV_Player.timestamp
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
//
|
||||
// Progress display
|
||||
//
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
value: Cpp_CSV_Player.progress
|
||||
onValueChanged: {
|
||||
if (value !== Cpp_CSV_Player.progress)
|
||||
Cpp_CSV_Player.setProgress(value)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Play/pause buttons
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Button {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: Cpp_CSV_Player.previousFrame()
|
||||
icon.source: "qrc:/icons/media-prev.svg"
|
||||
enabled: Cpp_CSV_Player.progress > 0 && !Cpp_CSV_Player.isPlaying
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 32
|
||||
icon.height: 32
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
onClicked: Cpp_CSV_Player.toggle()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: Cpp_CSV_Player.isPlaying ? "qrc:/icons/media-pause.svg" :
|
||||
"qrc:/icons/media-play.svg"
|
||||
}
|
||||
|
||||
Button {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: Cpp_CSV_Player.nextFrame()
|
||||
icon.source: "qrc:/icons/media-next.svg"
|
||||
enabled: Cpp_CSV_Player.progress < 1 && !Cpp_CSV_Player.isPlaying
|
||||
}
|
||||
}
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: app.spacing * 2
|
||||
|
||||
//
|
||||
// Timestamp display
|
||||
//
|
||||
Label {
|
||||
font.family: app.monoFont
|
||||
text: Cpp_CSV_Player.timestamp
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
}
|
||||
|
||||
//
|
||||
// Progress display
|
||||
//
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
value: Cpp_CSV_Player.progress
|
||||
onValueChanged: {
|
||||
if (value !== Cpp_CSV_Player.progress)
|
||||
Cpp_CSV_Player.setProgress(value)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Play/pause buttons
|
||||
//
|
||||
RowLayout {
|
||||
spacing: app.spacing
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
Button {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: Cpp_CSV_Player.previousFrame()
|
||||
icon.source: "qrc:/icons/media-prev.svg"
|
||||
enabled: Cpp_CSV_Player.progress > 0 && !Cpp_CSV_Player.isPlaying
|
||||
}
|
||||
|
||||
Button {
|
||||
icon.width: 32
|
||||
icon.height: 32
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
onClicked: Cpp_CSV_Player.toggle()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
icon.source: Cpp_CSV_Player.isPlaying ? "qrc:/icons/media-pause.svg" :
|
||||
"qrc:/icons/media-play.svg"
|
||||
}
|
||||
|
||||
Button {
|
||||
opacity: enabled ? 1 : 0.5
|
||||
icon.color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: Cpp_CSV_Player.nextFrame()
|
||||
icon.source: "qrc:/icons/media-next.svg"
|
||||
enabled: Cpp_CSV_Player.progress < 1 && !Cpp_CSV_Player.isPlaying
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,222 +29,222 @@ import QtQuick.Controls
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
title: qsTr("Donate")
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
title: qsTr("Donate")
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimizeEnabled: false
|
||||
maximizeEnabled: false
|
||||
titlebarText: Cpp_ThemeManager.text
|
||||
x: (Screen.desktopAvailableWidth - width) / 2
|
||||
y: (Screen.desktopAvailableHeight - height) / 2
|
||||
titlebarColor: Cpp_ThemeManager.dialogBackground
|
||||
backgroundColor: Cpp_ThemeManager.dialogBackground
|
||||
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
|
||||
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
maximumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
|
||||
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property alias doNotShowAgain: doNotShowAgainCheck.checked
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property alias doNotShowAgain: doNotShowAgainCheck.checked
|
||||
|
||||
//
|
||||
// Enables the "do not show again" checkbox and sets
|
||||
// the text of the close button to "later".
|
||||
//
|
||||
// This is used when the window is shown automatically
|
||||
// every now and then to the user.
|
||||
//
|
||||
function showAutomatically() {
|
||||
doNotShowAgainCheck.visible = true
|
||||
closeBt.text = qsTr("Later")
|
||||
showNormal()
|
||||
//
|
||||
// Enables the "do not show again" checkbox and sets
|
||||
// the text of the close button to "later".
|
||||
//
|
||||
// This is used when the window is shown automatically
|
||||
// every now and then to the user.
|
||||
//
|
||||
function showAutomatically() {
|
||||
doNotShowAgainCheck.visible = true
|
||||
closeBt.text = qsTr("Later")
|
||||
showNormal()
|
||||
}
|
||||
|
||||
//
|
||||
// Disables the "do not show again" checkbox and sets
|
||||
// the text of the close button to "close".
|
||||
//
|
||||
// This is used when the user opens this dialog from
|
||||
// the "about" window.
|
||||
//
|
||||
function show() {
|
||||
doNotShowAgainCheck.visible = false
|
||||
closeBt.text = qsTr("Close")
|
||||
showNormal()
|
||||
}
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
property alias disableDonationsWindow: root.doNotShowAgain
|
||||
}
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
//
|
||||
// Disables the "do not show again" checkbox and sets
|
||||
// the text of the close button to "close".
|
||||
//
|
||||
// This is used when the user opens this dialog from
|
||||
// the "about" window.
|
||||
//
|
||||
function show() {
|
||||
doNotShowAgainCheck.visible = false
|
||||
closeBt.text = qsTr("Close")
|
||||
showNormal()
|
||||
}
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
//
|
||||
// Save settings
|
||||
//
|
||||
Settings {
|
||||
property alias disableDonationsWindow: root.doNotShowAgain
|
||||
}
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: root.shadowMargin
|
||||
topMargin: titlebar.height + root.shadowMargin
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
Rectangle {
|
||||
height: root.radius
|
||||
color: root.backgroundColor
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
root.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: app.spacing * 2
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: app.spacing * 2
|
||||
|
||||
Image {
|
||||
sourceSize: Qt.size(120, 120)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/images/donate-qr.svg"
|
||||
|
||||
Rectangle {
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
border.color: "#000"
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: app.spacing * 2
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: title
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize
|
||||
text: qsTr("Support the development of %1!").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize * 3
|
||||
Layout.maximumWidth: title.implicitWidth
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
text: qsTr("Serial Studio is free & open-source software supported by volunteers. " +
|
||||
"Consider donating to support development efforts :)")
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize * 2
|
||||
Layout.maximumWidth: title.implicitWidth
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("You can also support this project by sharing it, reporting bugs and proposing new features!")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: app.spacing
|
||||
|
||||
CheckBox {
|
||||
id: doNotShowAgainCheck
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: qsTr("Don't annoy me again!")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: closeBt
|
||||
onClicked: root.close()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Button {
|
||||
highlighted: true
|
||||
text: qsTr("Donate")
|
||||
Keys.onEnterPressed: clicked()
|
||||
Keys.onReturnPressed: clicked()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
onClicked: Qt.openUrlExternally("https://www.paypal.com/donate?hosted_button_id=XN68J47QJKYDE")
|
||||
}
|
||||
}
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window drag handler
|
||||
//
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onPressedChanged: {
|
||||
if (pressed)
|
||||
root.startSystemMove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: app.spacing * 2
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: app.spacing * 2
|
||||
|
||||
Image {
|
||||
sourceSize: Qt.size(120, 120)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
source: "qrc:/images/donate-qr.svg"
|
||||
|
||||
Rectangle {
|
||||
border.width: 2
|
||||
color: "transparent"
|
||||
anchors.fill: parent
|
||||
border.color: "#000"
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: app.spacing * 2
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Label {
|
||||
id: title
|
||||
font.bold: true
|
||||
font.pixelSize: 16
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize
|
||||
text: qsTr("Support the development of %1!").arg(Cpp_AppName)
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize * 3
|
||||
Layout.maximumWidth: title.implicitWidth
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
text: qsTr("Serial Studio is free & open-source software supported by volunteers. " +
|
||||
"Consider donating to support development efforts :)")
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: font.pixelSize * 2
|
||||
Layout.maximumWidth: title.implicitWidth
|
||||
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
|
||||
color: Cpp_ThemeManager.highlightedTextAlternative
|
||||
text: qsTr("You can also support this project by sharing it, reporting bugs and proposing new features!")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: app.spacing
|
||||
|
||||
CheckBox {
|
||||
id: doNotShowAgainCheck
|
||||
Layout.leftMargin: -app.spacing
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: qsTr("Don't annoy me again!")
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: closeBt
|
||||
onClicked: root.close()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
Button {
|
||||
highlighted: true
|
||||
text: qsTr("Donate")
|
||||
Keys.onEnterPressed: clicked()
|
||||
Keys.onReturnPressed: clicked()
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
onClicked: Qt.openUrlExternally("https://www.paypal.com/donate?hosted_button_id=XN68J47QJKYDE")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,355 +34,355 @@ import "../FramelessWindow" as FramelessWindow
|
||||
import "../PlatformDependent" as PlatformDependent
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Quit application when this window is closed
|
||||
//
|
||||
onClosed: Qt.quit()
|
||||
//
|
||||
// Quit application when this window is closed
|
||||
//
|
||||
onClosed: Qt.quit()
|
||||
|
||||
//
|
||||
// Customize window border
|
||||
//
|
||||
showIcon: true
|
||||
borderWidth: 1
|
||||
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
//
|
||||
// Customize window border
|
||||
//
|
||||
showIcon: true
|
||||
borderWidth: 1
|
||||
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
|
||||
//
|
||||
// Global properties
|
||||
//
|
||||
readonly property bool setupVisible: setup.visible
|
||||
readonly property bool consoleVisible: terminal.visible
|
||||
readonly property bool dashboardVisible: dashboard.visible
|
||||
//
|
||||
// Global properties
|
||||
//
|
||||
readonly property bool setupVisible: setup.visible
|
||||
readonly property bool consoleVisible: terminal.visible
|
||||
readonly property bool dashboardVisible: dashboard.visible
|
||||
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int appLaunchCount: 0
|
||||
property bool firstValidFrame: false
|
||||
property bool automaticUpdates: false
|
||||
property alias vt100emulation: terminal.vt100emulation
|
||||
//
|
||||
// Custom properties
|
||||
//
|
||||
property int appLaunchCount: 0
|
||||
property bool firstValidFrame: false
|
||||
property bool automaticUpdates: false
|
||||
property alias vt100emulation: terminal.vt100emulation
|
||||
|
||||
//
|
||||
// Toolbar functions aliases
|
||||
//
|
||||
function showSetup() { toolbar.setupClicked() }
|
||||
function showConsole() { toolbar.consoleClicked() }
|
||||
function showDashboard() { dbTimer.start() }
|
||||
//
|
||||
// Toolbar functions aliases
|
||||
//
|
||||
function showSetup() { toolbar.setupClicked() }
|
||||
function showConsole() { toolbar.consoleClicked() }
|
||||
function showDashboard() { dbTimer.start() }
|
||||
|
||||
//
|
||||
// Wait a little before showing the dashboard to avoid UI glitches and/or overloading
|
||||
// the rendering engine
|
||||
//
|
||||
Timer {
|
||||
id: dbTimer
|
||||
interval: 500
|
||||
onTriggered: toolbar.dashboardClicked()
|
||||
//
|
||||
// Wait a little before showing the dashboard to avoid UI glitches and/or overloading
|
||||
// the rendering engine
|
||||
//
|
||||
Timer {
|
||||
id: dbTimer
|
||||
interval: 500
|
||||
onTriggered: toolbar.dashboardClicked()
|
||||
}
|
||||
|
||||
//
|
||||
// Console-related functions
|
||||
//
|
||||
function consoleCopy() { terminal.copy() }
|
||||
function consoleClear() { terminal.clear() }
|
||||
function consoleSelectAll() { terminal.selectAll() }
|
||||
|
||||
//
|
||||
// Window geometry
|
||||
//
|
||||
visible: false
|
||||
title: Cpp_AppName
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimumWidth: 1120 + 2 * root.shadowMargin
|
||||
backgroundColor: Cpp_ThemeManager.windowBackground
|
||||
minimumHeight: 650 + 2 * root.shadowMargin + root.titlebar.height
|
||||
|
||||
//
|
||||
// Startup code
|
||||
//
|
||||
Component.onCompleted: {
|
||||
// Load welcome text
|
||||
terminal.showWelcomeGuide()
|
||||
|
||||
// Increment app launch count
|
||||
++appLaunchCount
|
||||
|
||||
// Show app window
|
||||
if (root.isFullscreen)
|
||||
root.showFullScreen()
|
||||
else if (root.isMaximized)
|
||||
root.showMaximized()
|
||||
else {
|
||||
// Fix maximize not working on first try on macOS & Windows
|
||||
root.opacity = 0
|
||||
var x = root.x
|
||||
var y = root.y
|
||||
var w = root.width
|
||||
var h = root.height
|
||||
root.showMaximized()
|
||||
root.showNormal()
|
||||
root.setGeometry(x, y, w,h)
|
||||
root.opacity = 1
|
||||
}
|
||||
|
||||
// Force active focus
|
||||
root.requestActivate()
|
||||
root.requestUpdate()
|
||||
|
||||
// Show donations dialog every 15 launches
|
||||
if (root.appLaunchCount % 15 == 0 && !app.donateDialog.doNotShowAgain)
|
||||
app.donateDialog.showAutomatically()
|
||||
|
||||
// Ask user if he/she wants to enable automatic updates
|
||||
if (root.appLaunchCount == 2 && Cpp_UpdaterEnabled) {
|
||||
if (Cpp_Misc_Utilities.askAutomaticUpdates()) {
|
||||
root.automaticUpdates = true
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
}
|
||||
|
||||
else
|
||||
root.automaticUpdates = false
|
||||
}
|
||||
|
||||
// Check for updates (if we are allowed)
|
||||
if (root.automaticUpdates && Cpp_UpdaterEnabled)
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
}
|
||||
|
||||
//
|
||||
// Hide console & device manager when we receive first valid frame
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onUpdated() {
|
||||
if (root.firstValidFrame)
|
||||
return
|
||||
|
||||
if ((Cpp_IO_Manager.connected || Cpp_CSV_Player.isOpen) && Cpp_UI_Dashboard.frameValid()) {
|
||||
setup.hide()
|
||||
root.showDashboard()
|
||||
root.firstValidFrame = true
|
||||
}
|
||||
|
||||
else {
|
||||
setup.show()
|
||||
root.showConsole()
|
||||
root.firstValidFrame = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Show console tab on serial disconnect
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
function onDataReset() {
|
||||
setup.show()
|
||||
root.showConsole()
|
||||
root.firstValidFrame = false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save window size & position
|
||||
//
|
||||
Settings {
|
||||
property alias wx: root.x
|
||||
property alias wy: root.y
|
||||
property alias ww: root.width
|
||||
property alias wh: root.height
|
||||
property alias wm: root.isMaximized
|
||||
property alias wf: root.isFullscreen
|
||||
property alias appStatus: root.appLaunchCount
|
||||
property alias autoUpdater: root.automaticUpdates
|
||||
}
|
||||
|
||||
//
|
||||
// macOS menubar loader
|
||||
//
|
||||
Loader {
|
||||
active: Cpp_IsMac
|
||||
asynchronous: false
|
||||
sourceComponent: PlatformDependent.MenubarMacOS {}
|
||||
}
|
||||
|
||||
//
|
||||
// Rectangle for the menubar (only used if custom window flags are disabled)
|
||||
//
|
||||
Rectangle {
|
||||
color: root.titlebarColor
|
||||
anchors.fill: menubarLayout
|
||||
visible: !Cpp_ThemeManager.customWindowDecorations
|
||||
}
|
||||
|
||||
//
|
||||
// Menubar, shown by default on Windows & Linux and when the app is fullscreen
|
||||
//
|
||||
RowLayout {
|
||||
id: menubarLayout
|
||||
z: titlebar.z + 1
|
||||
spacing: app.spacing
|
||||
height: !showMenubar ? titlebar.height : 38
|
||||
|
||||
readonly property bool showMenubar: !root.showMacControls || isFullscreen
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: root.leftTitlebarMargin + root.shadowMargin
|
||||
rightMargin: root.rightTitlebarMargin + root.shadowMargin
|
||||
topMargin: root.shadowMargin + (!root.showMacControls ? 1 : 0)
|
||||
}
|
||||
|
||||
//
|
||||
// Console-related functions
|
||||
//
|
||||
function consoleCopy() { terminal.copy() }
|
||||
function consoleClear() { terminal.clear() }
|
||||
function consoleSelectAll() { terminal.selectAll() }
|
||||
|
||||
//
|
||||
// Window geometry
|
||||
//
|
||||
visible: false
|
||||
title: Cpp_AppName
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
minimumWidth: 1120 + 2 * root.shadowMargin
|
||||
backgroundColor: Cpp_ThemeManager.windowBackground
|
||||
minimumHeight: 650 + 2 * root.shadowMargin + root.titlebar.height
|
||||
|
||||
//
|
||||
// Startup code
|
||||
//
|
||||
Component.onCompleted: {
|
||||
// Load welcome text
|
||||
terminal.showWelcomeGuide()
|
||||
|
||||
// Increment app launch count
|
||||
++appLaunchCount
|
||||
|
||||
// Show app window
|
||||
if (root.isFullscreen)
|
||||
root.showFullScreen()
|
||||
else if (root.isMaximized)
|
||||
root.showMaximized()
|
||||
else {
|
||||
// Fix maximize not working on first try on macOS & Windows
|
||||
root.opacity = 0
|
||||
var x = root.x
|
||||
var y = root.y
|
||||
var w = root.width
|
||||
var h = root.height
|
||||
root.showMaximized()
|
||||
root.showNormal()
|
||||
root.setGeometry(x, y, w,h)
|
||||
root.opacity = 1
|
||||
}
|
||||
|
||||
// Force active focus
|
||||
root.requestActivate()
|
||||
root.requestUpdate()
|
||||
|
||||
// Show donations dialog every 15 launches
|
||||
if (root.appLaunchCount % 15 == 0 && !app.donateDialog.doNotShowAgain)
|
||||
app.donateDialog.showAutomatically()
|
||||
|
||||
// Ask user if he/she wants to enable automatic updates
|
||||
if (root.appLaunchCount == 2 && Cpp_UpdaterEnabled) {
|
||||
if (Cpp_Misc_Utilities.askAutomaticUpdates()) {
|
||||
root.automaticUpdates = true
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
}
|
||||
|
||||
else
|
||||
root.automaticUpdates = false
|
||||
}
|
||||
|
||||
// Check for updates (if we are allowed)
|
||||
if (root.automaticUpdates && Cpp_UpdaterEnabled)
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
}
|
||||
|
||||
//
|
||||
// Hide console & device manager when we receive first valid frame
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
|
||||
function onUpdated() {
|
||||
if (root.firstValidFrame)
|
||||
return
|
||||
|
||||
if ((Cpp_IO_Manager.connected || Cpp_CSV_Player.isOpen) && Cpp_UI_Dashboard.frameValid()) {
|
||||
setup.hide()
|
||||
root.showDashboard()
|
||||
root.firstValidFrame = true
|
||||
}
|
||||
|
||||
else {
|
||||
setup.show()
|
||||
root.showConsole()
|
||||
root.firstValidFrame = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Show console tab on serial disconnect
|
||||
//
|
||||
Connections {
|
||||
target: Cpp_UI_Dashboard
|
||||
function onDataReset() {
|
||||
setup.show()
|
||||
root.showConsole()
|
||||
root.firstValidFrame = false
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Save window size & position
|
||||
//
|
||||
Settings {
|
||||
property alias wx: root.x
|
||||
property alias wy: root.y
|
||||
property alias ww: root.width
|
||||
property alias wh: root.height
|
||||
property alias wm: root.isMaximized
|
||||
property alias wf: root.isFullscreen
|
||||
property alias appStatus: root.appLaunchCount
|
||||
property alias autoUpdater: root.automaticUpdates
|
||||
}
|
||||
|
||||
//
|
||||
// macOS menubar loader
|
||||
// Menubar
|
||||
//
|
||||
Loader {
|
||||
active: Cpp_IsMac
|
||||
asynchronous: false
|
||||
sourceComponent: PlatformDependent.MenubarMacOS {}
|
||||
opacity: 0.8
|
||||
asynchronous: false
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
sourceComponent: PlatformDependent.Menubar {
|
||||
enabled: !root.showMacControls || isFullscreen
|
||||
visible: !root.showMacControls || isFullscreen
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Rectangle for the menubar (only used if custom window flags are disabled)
|
||||
// Spacer
|
||||
//
|
||||
Rectangle {
|
||||
color: root.titlebarColor
|
||||
anchors.fill: menubarLayout
|
||||
visible: !Cpp_ThemeManager.customWindowDecorations
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
Page {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
anchors.topMargin: menubarLayout.height + root.shadowMargin
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: Cpp_ThemeManager.windowBackground
|
||||
}
|
||||
|
||||
//
|
||||
// Menubar, shown by default on Windows & Linux and when the app is fullscreen
|
||||
//
|
||||
RowLayout {
|
||||
id: menubarLayout
|
||||
z: titlebar.z + 1
|
||||
spacing: app.spacing
|
||||
height: !showMenubar ? titlebar.height : 38
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
readonly property bool showMenubar: !root.showMacControls || isFullscreen
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: root.leftTitlebarMargin + root.shadowMargin
|
||||
rightMargin: root.rightTitlebarMargin + root.shadowMargin
|
||||
topMargin: root.shadowMargin + (!root.showMacControls ? 1 : 0)
|
||||
}
|
||||
|
||||
//
|
||||
// Menubar
|
||||
//
|
||||
Loader {
|
||||
opacity: 0.8
|
||||
asynchronous: false
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
sourceComponent: PlatformDependent.Menubar {
|
||||
enabled: !root.showMacControls || isFullscreen
|
||||
visible: !root.showMacControls || isFullscreen
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main layout
|
||||
//
|
||||
Page {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
anchors.topMargin: menubarLayout.height + root.shadowMargin
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: Cpp_ThemeManager.windowBackground
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
anchors.fill: parent
|
||||
|
||||
//
|
||||
// Application toolbar
|
||||
//
|
||||
Toolbar {
|
||||
id: toolbar
|
||||
window: root
|
||||
z: titlebar.z
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 48
|
||||
Layout.maximumHeight: 48
|
||||
setupChecked: root.setupVisible
|
||||
consoleChecked: root.consoleVisible
|
||||
dashboardChecked: root.dashboardVisible
|
||||
onProjectEditorClicked: app.projectEditorWindow.show()
|
||||
onSetupClicked: setup.visible ? setup.hide() : setup.show()
|
||||
|
||||
onDashboardClicked: {
|
||||
if (Cpp_UI_Dashboard.available) {
|
||||
consoleChecked = 0
|
||||
dashboardChecked = 1
|
||||
if (stack.currentItem != dashboard)
|
||||
stack.push(dashboard)
|
||||
}
|
||||
|
||||
else
|
||||
root.showConsole()
|
||||
}
|
||||
|
||||
onConsoleClicked: {
|
||||
consoleChecked = 1
|
||||
dashboardChecked = 0
|
||||
stack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console, dashboard & setup panel
|
||||
//
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
StackView {
|
||||
id: stack
|
||||
clip: true
|
||||
initialItem: terminal
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
data: [
|
||||
Console {
|
||||
id: terminal
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
},
|
||||
|
||||
Dashboard {
|
||||
id: dashboard
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Setup {
|
||||
id: setup
|
||||
Layout.fillHeight: true
|
||||
Layout.rightMargin: setupMargin
|
||||
Layout.minimumWidth: displayedWidth
|
||||
Layout.maximumWidth: displayedWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// JSON project drop area
|
||||
//
|
||||
JSONDropArea {
|
||||
anchors.fill: parent
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
}
|
||||
|
||||
//
|
||||
// Resize handler
|
||||
//
|
||||
FramelessWindow.ResizeHandles {
|
||||
//
|
||||
// Application toolbar
|
||||
//
|
||||
Toolbar {
|
||||
id: toolbar
|
||||
window: root
|
||||
anchors.fill: parent
|
||||
handleSize: root.handleSize
|
||||
z: titlebar.z
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 48
|
||||
Layout.maximumHeight: 48
|
||||
setupChecked: root.setupVisible
|
||||
consoleChecked: root.consoleVisible
|
||||
dashboardChecked: root.dashboardVisible
|
||||
onProjectEditorClicked: app.projectEditorWindow.show()
|
||||
onSetupClicked: setup.visible ? setup.hide() : setup.show()
|
||||
|
||||
onDashboardClicked: {
|
||||
if (Cpp_UI_Dashboard.available) {
|
||||
consoleChecked = 0
|
||||
dashboardChecked = 1
|
||||
if (stack.currentItem != dashboard)
|
||||
stack.push(dashboard)
|
||||
}
|
||||
|
||||
else
|
||||
root.showConsole()
|
||||
}
|
||||
|
||||
onConsoleClicked: {
|
||||
consoleChecked = 1
|
||||
dashboardChecked = 0
|
||||
stack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Console, dashboard & setup panel
|
||||
//
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
StackView {
|
||||
id: stack
|
||||
clip: true
|
||||
initialItem: terminal
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
data: [
|
||||
Console {
|
||||
id: terminal
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
},
|
||||
|
||||
Dashboard {
|
||||
id: dashboard
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Setup {
|
||||
id: setup
|
||||
Layout.fillHeight: true
|
||||
Layout.rightMargin: setupMargin
|
||||
Layout.minimumWidth: displayedWidth
|
||||
Layout.maximumWidth: displayedWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// JSON project drop area
|
||||
//
|
||||
JSONDropArea {
|
||||
anchors.fill: parent
|
||||
enabled: !Cpp_IO_Manager.connected
|
||||
}
|
||||
|
||||
//
|
||||
// Resize handler
|
||||
//
|
||||
FramelessWindow.ResizeHandles {
|
||||
window: root
|
||||
anchors.fill: parent
|
||||
handleSize: root.handleSize
|
||||
}
|
||||
}
|
||||
|
@ -31,139 +31,139 @@ import "../Widgets" as Widgets
|
||||
import "../FramelessWindow" as FramelessWindow
|
||||
|
||||
FramelessWindow.CustomWindow {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
minimumWidth: 910
|
||||
minimumHeight: 720
|
||||
title: qsTr("Project Editor - %1").arg(Cpp_Project_Model.jsonFileName)
|
||||
//
|
||||
// Window options
|
||||
//
|
||||
minimumWidth: 910
|
||||
minimumHeight: 720
|
||||
title: qsTr("Project Editor - %1").arg(Cpp_Project_Model.jsonFileName)
|
||||
|
||||
//
|
||||
// Customize window border
|
||||
//
|
||||
borderWidth: 1
|
||||
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
//
|
||||
// Customize window border
|
||||
//
|
||||
borderWidth: 1
|
||||
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
|
||||
|
||||
//
|
||||
// Ensure that current JSON file is shown
|
||||
//
|
||||
Component.onCompleted: Cpp_Project_Model.openJsonFile(Cpp_JSON_Generator.jsonMapFilepath)
|
||||
//
|
||||
// Ensure that current JSON file is shown
|
||||
//
|
||||
Component.onCompleted: Cpp_Project_Model.openJsonFile(Cpp_JSON_Generator.jsonMapFilepath)
|
||||
|
||||
//
|
||||
// Ask user to save changes before closing the window
|
||||
//
|
||||
onClosing: (close) => close.accepted = Cpp_Project_Model.askSave()
|
||||
//
|
||||
// Ask user to save changes before closing the window
|
||||
//
|
||||
onClosing: (close) => close.accepted = Cpp_Project_Model.askSave()
|
||||
|
||||
//
|
||||
// Dummy string to increase width of buttons
|
||||
//
|
||||
readonly property string _btSpacer: " "
|
||||
//
|
||||
// Dummy string to increase width of buttons
|
||||
//
|
||||
readonly property string _btSpacer: " "
|
||||
|
||||
//
|
||||
// Save window size
|
||||
//
|
||||
Settings {
|
||||
category: "ProjectEditor"
|
||||
property alias windowX: root.x
|
||||
property alias windowY: root.y
|
||||
property alias windowWidth: root.width
|
||||
property alias windowHeight: root.height
|
||||
//
|
||||
// Save window size
|
||||
//
|
||||
Settings {
|
||||
category: "ProjectEditor"
|
||||
property alias windowX: root.x
|
||||
property alias windowY: root.y
|
||||
property alias windowWidth: root.width
|
||||
property alias windowHeight: root.height
|
||||
}
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
//
|
||||
Page {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
anchors.topMargin: titlebar.height + root.shadowMargin
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: Cpp_ThemeManager.windowBackground
|
||||
}
|
||||
|
||||
//
|
||||
// Use page item to set application palette
|
||||
// Shadows
|
||||
//
|
||||
Page {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.shadowMargin
|
||||
anchors.topMargin: titlebar.height + root.shadowMargin
|
||||
Widgets.Shadow {
|
||||
anchors.fill: header
|
||||
} Widgets.Shadow {
|
||||
anchors.fill: footer
|
||||
anchors.bottomMargin: footer.height / 2
|
||||
}
|
||||
|
||||
palette.alternateBase: Cpp_ThemeManager.base
|
||||
palette.base: Cpp_ThemeManager.base
|
||||
palette.brightText: Cpp_ThemeManager.brightText
|
||||
palette.button: Cpp_ThemeManager.button
|
||||
palette.buttonText: Cpp_ThemeManager.buttonText
|
||||
palette.highlight: Cpp_ThemeManager.highlight
|
||||
palette.highlightedText: Cpp_ThemeManager.highlightedText
|
||||
palette.link: Cpp_ThemeManager.link
|
||||
palette.placeholderText: Cpp_ThemeManager.placeholderText
|
||||
palette.text: Cpp_ThemeManager.text
|
||||
palette.toolTipBase: Cpp_ThemeManager.tooltipBase
|
||||
palette.toolTipText: Cpp_ThemeManager.tooltipText
|
||||
palette.window: Cpp_ThemeManager.window
|
||||
palette.windowText: Cpp_ThemeManager.windowText
|
||||
//
|
||||
// Header (project properties)
|
||||
//
|
||||
Header {
|
||||
id: header
|
||||
anchors {
|
||||
margins: 0
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
radius: root.radius
|
||||
color: Cpp_ThemeManager.windowBackground
|
||||
}
|
||||
//
|
||||
// Footer background
|
||||
//
|
||||
Footer {
|
||||
id: footer
|
||||
radius: root.radius
|
||||
onCloseWindow: root.close()
|
||||
onScrollToBottom: groupEditor.selectLastGroup()
|
||||
|
||||
//
|
||||
// Shadows
|
||||
//
|
||||
Widgets.Shadow {
|
||||
anchors.fill: header
|
||||
} Widgets.Shadow {
|
||||
anchors.fill: footer
|
||||
anchors.bottomMargin: footer.height / 2
|
||||
}
|
||||
anchors {
|
||||
margins: 0
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Header (project properties)
|
||||
//
|
||||
Header {
|
||||
id: header
|
||||
anchors {
|
||||
margins: 0
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
RowLayout {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.topMargin: header.height
|
||||
anchors.bottomMargin: footer.height
|
||||
|
||||
//
|
||||
// Footer background
|
||||
//
|
||||
Footer {
|
||||
id: footer
|
||||
radius: root.radius
|
||||
onCloseWindow: root.close()
|
||||
onScrollToBottom: groupEditor.selectLastGroup()
|
||||
//
|
||||
// Horizontal spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: app.spacing
|
||||
Layout.maximumWidth: app.spacing
|
||||
}
|
||||
|
||||
anchors {
|
||||
margins: 0
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Window controls
|
||||
//
|
||||
RowLayout {
|
||||
clip: true
|
||||
anchors.fill: parent
|
||||
spacing: app.spacing
|
||||
anchors.topMargin: header.height
|
||||
anchors.bottomMargin: footer.height
|
||||
|
||||
//
|
||||
// Horizontal spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: app.spacing
|
||||
Layout.maximumWidth: app.spacing
|
||||
}
|
||||
|
||||
//
|
||||
// JSON structure tree
|
||||
//
|
||||
/*TreeView {
|
||||
//
|
||||
// JSON structure tree
|
||||
//
|
||||
/*TreeView {
|
||||
id: jsonTree
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: 240
|
||||
@ -173,69 +173,69 @@ FramelessWindow.CustomWindow {
|
||||
visible: Cpp_Project_Model.groupCount !== 0
|
||||
}*/
|
||||
|
||||
//
|
||||
// Group editor
|
||||
//
|
||||
GroupEditor {
|
||||
id: groupEditor
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: Cpp_Project_Model.groupCount !== 0
|
||||
}
|
||||
//
|
||||
// Group editor
|
||||
//
|
||||
GroupEditor {
|
||||
id: groupEditor
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: Cpp_Project_Model.groupCount !== 0
|
||||
}
|
||||
|
||||
//
|
||||
// Empty project text & icon
|
||||
//
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: Cpp_Project_Model.groupCount === 0
|
||||
//
|
||||
// Empty project text & icon
|
||||
//
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: Cpp_Project_Model.groupCount === 0
|
||||
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
ColumnLayout {
|
||||
spacing: app.spacing
|
||||
anchors.centerIn: parent
|
||||
|
||||
Widgets.Icon {
|
||||
width: 128
|
||||
height: 128
|
||||
color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
source: "qrc:/icons/developer-board.svg"
|
||||
}
|
||||
Widgets.Icon {
|
||||
width: 128
|
||||
height: 128
|
||||
color: Cpp_ThemeManager.text
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
source: "qrc:/icons/developer-board.svg"
|
||||
}
|
||||
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Start something awesome")
|
||||
}
|
||||
Label {
|
||||
font.bold: true
|
||||
font.pixelSize: 24
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Start something awesome")
|
||||
}
|
||||
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Click on the \"Add group\" button to begin")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Horizontal spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: app.spacing
|
||||
Layout.maximumWidth: app.spacing
|
||||
}
|
||||
Label {
|
||||
opacity: 0.8
|
||||
font.pixelSize: 18
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Click on the \"Add group\" button to begin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resize handler
|
||||
//
|
||||
FramelessWindow.ResizeHandles {
|
||||
window: root
|
||||
anchors.fill: parent
|
||||
handleSize: root.handleSize
|
||||
//
|
||||
// Horizontal spacer
|
||||
//
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: app.spacing
|
||||
Layout.maximumWidth: app.spacing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resize handler
|
||||
//
|
||||
FramelessWindow.ResizeHandles {
|
||||
window: root
|
||||
anchors.fill: parent
|
||||
handleSize: root.handleSize
|
||||
}
|
||||
}
|
||||
|
@ -27,92 +27,92 @@ import QtQuick.Controls
|
||||
import "Windows" as Windows
|
||||
|
||||
Item {
|
||||
id: app
|
||||
id: app
|
||||
|
||||
//
|
||||
// Global propeties
|
||||
//
|
||||
readonly property int spacing: 8
|
||||
readonly property string monoFont: "Roboto Mono"
|
||||
//
|
||||
// Global propeties
|
||||
//
|
||||
readonly property int spacing: 8
|
||||
readonly property string monoFont: "Roboto Mono"
|
||||
|
||||
//
|
||||
// Access to dialogs & windows
|
||||
//
|
||||
property Windows.About aboutDialog: null
|
||||
property Windows.Donate donateDialog: null
|
||||
property Windows.MainWindow mainWindow: null
|
||||
property Windows.CsvPlayer csvPlayerDialog: null
|
||||
property Windows.ProjectEditor projectEditorWindow: null
|
||||
property Windows.Acknowledgements acknowledgementsDialog: null
|
||||
//
|
||||
// Access to dialogs & windows
|
||||
//
|
||||
property Window aboutDialog: null
|
||||
property Window donateDialog: null
|
||||
property Window mainWindow: null
|
||||
property Window csvPlayerDialog: null
|
||||
property Window projectEditorWindow: null
|
||||
property Window acknowledgementsDialog: null
|
||||
|
||||
//
|
||||
// Check for updates (non-silent mode)
|
||||
//
|
||||
function checkForUpdates() {
|
||||
Cpp_Updater.setNotifyOnFinish(Cpp_AppUpdaterUrl, true)
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
//
|
||||
// Check for updates (non-silent mode)
|
||||
//
|
||||
function checkForUpdates() {
|
||||
Cpp_Updater.setNotifyOnFinish(Cpp_AppUpdaterUrl, true)
|
||||
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
|
||||
}
|
||||
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.MainWindow {
|
||||
Component.onCompleted: {
|
||||
app.forceActiveFocus()
|
||||
app.mainWindow = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MainWindow
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.MainWindow {
|
||||
Component.onCompleted: {
|
||||
app.forceActiveFocus()
|
||||
app.mainWindow = this
|
||||
}
|
||||
}
|
||||
//
|
||||
// About window
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.About {
|
||||
Component.onCompleted: app.aboutDialog = this
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// About window
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.About {
|
||||
Component.onCompleted: app.aboutDialog = this
|
||||
}
|
||||
//
|
||||
// CSV player window
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.CsvPlayer {
|
||||
Component.onCompleted: app.csvPlayerDialog = this
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CSV player window
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.CsvPlayer {
|
||||
Component.onCompleted: app.csvPlayerDialog = this
|
||||
}
|
||||
//
|
||||
// Project editor dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.ProjectEditor {
|
||||
Component.onCompleted: app.projectEditorWindow = this
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Project editor dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.ProjectEditor {
|
||||
Component.onCompleted: app.projectEditorWindow = this
|
||||
}
|
||||
//
|
||||
// Donations dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: false
|
||||
sourceComponent: Windows.Donate {
|
||||
Component.onCompleted: app.donateDialog = this
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Donations dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: false
|
||||
sourceComponent: Windows.Donate {
|
||||
Component.onCompleted: app.donateDialog = this
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Acknowledgements dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.Acknowledgements {
|
||||
Component.onCompleted: app.acknowledgementsDialog = this
|
||||
}
|
||||
//
|
||||
// Acknowledgements dialog
|
||||
//
|
||||
Loader {
|
||||
asynchronous: true
|
||||
sourceComponent: Windows.Acknowledgements {
|
||||
Component.onCompleted: app.acknowledgementsDialog = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6.1 KiB |
@ -8,5 +8,5 @@ StartupNotify=true
|
||||
Categories=Electronics;Engineering;Science;
|
||||
Icon=serial-studio
|
||||
X-AppImage-Name=Serial Studio
|
||||
X-AppImage-Version=2.0.0
|
||||
X-AppImage-Version=2.1.0
|
||||
X-AppImage-Arch=x86_64
|
||||
|
@ -31,7 +31,7 @@ Unicode True
|
||||
!define COMPANYNAME "Alex Spataru"
|
||||
!define DESCRIPTION "Multi-purpose data visualization & processing program"
|
||||
!define VERSIONMAJOR 2
|
||||
!define VERSIONMINOR 0
|
||||
!define VERSIONMINOR 1
|
||||
!define VERSIONBUILD 0
|
||||
!define MUI_ABORTWARNING
|
||||
!define INSTALL_DIR "$PROGRAMFILES64\${APPNAME}"
|
||||
|
7
libs/KDMacTouchBar/.gitignore
vendored
7
libs/KDMacTouchBar/.gitignore
vendored
@ -1,7 +0,0 @@
|
||||
Makefile
|
||||
*.moc
|
||||
*.o
|
||||
lib
|
||||
.qmake.cache
|
||||
.qmake.stash
|
||||
.DS_Store
|
@ -1,16 +0,0 @@
|
||||
CHECKSETS qt5,c++,foss
|
||||
|
||||
#KDAB-specific checks
|
||||
EXTRA kdabcopyright,kdabcontactus
|
||||
|
||||
#additional checks
|
||||
#EXTRA defines,null
|
||||
|
||||
#exclude checks now being done by clazy or clang-tools
|
||||
EXCLUDE strings,explicit,normalize,passbyvalue,operators,nullstrcompare,nullstrassign,doublequote_chars,qobject,sigsandslots,staticobjects
|
||||
#exclude more checks
|
||||
EXCLUDE style
|
||||
|
||||
#skip the borrowed code in the cmake subdir
|
||||
SKIP /cmake/Qt5Portability.cmake
|
||||
|
@ -1,46 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
|
||||
if("${CMAKE_INSTALL_PREFIX}" STREQUAL "")
|
||||
set(USE_DEFAULT_INSTALL_LOCATION True)
|
||||
else()
|
||||
set(USE_DEFAULT_INSTALL_LOCATION False)
|
||||
endif()
|
||||
|
||||
project(KDMacTouchBar CXX)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
set(${PROJECT_NAME}_VERSION_MAJOR 1)
|
||||
set(${PROJECT_NAME}_VERSION_MINOR 0)
|
||||
set(${PROJECT_NAME}_VERSION_PATCH 0)
|
||||
set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH})
|
||||
|
||||
if(CMAKE_VERSION VERSION_LESS "3.1")
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif ()
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
endif()
|
||||
|
||||
if(USE_DEFAULT_INSTALL_LOCATION)
|
||||
set(CMAKE_INSTALL_PREFIX "/usr/local/KDAB/${PROJECT_NAME}-${${PROJECT_NAME}_VERSION}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Building ${PROJECT_NAME} ${${PROJECT_NAME}_VERSION} in ${CMAKE_BUILD_TYPE} mode. Installing to ${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
find_package(Qt5Core REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
set(QT_LIBRARIES Qt5::Widgets)
|
||||
set(QT_USE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Qt5Portability.cmake")
|
||||
|
||||
install(FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/KDMacTouchBarConfig.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake")
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(examples)
|
@ -1,175 +0,0 @@
|
||||
|
||||
KDMacTouchBar is Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB.
|
||||
|
||||
You may use, distribute and copy KDMacTouchBar under the terms of
|
||||
GNU Lesser General Public License version 3, which is displayed below.
|
||||
|
||||
You may even contact us at info@kdab.com for different licensing options.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
@ -1,64 +0,0 @@
|
||||
# KDMacTouchBar
|
||||
KDAB's Qt Widget for the Mac Touch Bar
|
||||
|
||||
## Introduction
|
||||
The KDMacTouchBar class wraps the native NSTouchBar class.
|
||||
|
||||
KDMacTouchBar provides a Qt-based API for NSTouchBar. The touchbar displays
|
||||
a number of QActions. Each QAction can have a text and an icon. Alternatively,
|
||||
the QActions might be separators (with or without text) or QWidgetActions.
|
||||
|
||||
Add actions by calling addAction(). Alternatively, you can use one of the
|
||||
convenience methods like addDialogButtonBox() or addTabBar() which provide
|
||||
common use cases.
|
||||
|
||||
If an action with a associated menu is added, its menu items are added as
|
||||
sub-touchbar. Showing sub-menus of this menu is not supported, due to macOS
|
||||
system restrictions.
|
||||
|
||||
## Usage:
|
||||
```
|
||||
QMainWindow *mw = ...;
|
||||
KDMacTouchBar *touchBar = new KDMacTouchBar(mw);
|
||||
touchBar->addAction(actionNewFile);
|
||||
touchBar->addSeparator();
|
||||
touchBar->addAction(actionSaveFile);
|
||||
```
|
||||
|
||||
## Licensing:
|
||||
KD MacTouchBar is (C) 2019-2021, Klarälvdalens Datakonsult AB,
|
||||
and is available under the terms of:
|
||||
|
||||
* the LGPL (see LICENSE.LGPL.txt for details)
|
||||
* the KDAB commercial license, provided that you buy a license.
|
||||
please contact info@kdab.com if you are interested in buying commercial licenses.
|
||||
|
||||
## Get Involved:
|
||||
KDAB will happily accept external contributions; however, **all**
|
||||
contributions will require a signed Contributor License Agreement
|
||||
(see docs/KDMacTouchBar-CopyrightAssignmentForm.pdf).
|
||||
|
||||
Contact info@kdab.com for more information.
|
||||
|
||||
Please submit your contributions or issue reports from our GitHub space at
|
||||
https://github.com/KDAB/KDMacTouchBar
|
||||
|
||||
## About KDAB
|
||||
KD MacTouchBar is supported and maintained by Klarälvdalens Datakonsult AB (KDAB).
|
||||
|
||||
The KDAB Group is the global No.1 software consultancy for Qt, C++ and
|
||||
OpenGL applications across desktop, embedded and mobile platforms.
|
||||
|
||||
The KDAB Group provides consulting and mentoring for developing Qt applications
|
||||
from scratch and in porting from all popular and legacy frameworks to Qt.
|
||||
We continue to help develop parts of Qt and are one of the major contributors
|
||||
to the Qt Project. We can give advanced or standard trainings anywhere
|
||||
around the globe on Qt as well as C++, OpenGL, 3D and more.
|
||||
|
||||
Please visit https://www.kdab.com to meet the people who write code like this.
|
||||
|
||||
Stay up-to-date with KDAB product announcements:
|
||||
|
||||
* [KDAB Newsletter](https://news.kdab.com)
|
||||
* [KDAB Blogs](https://www.kdab.com/category/blogs)
|
||||
* [KDAB on Twitter](https://twitter.com/KDABQt)
|
@ -1,2 +0,0 @@
|
||||
set(KDMacTouchBar_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../KDMacTouchBar.framework/Headers)
|
||||
set(KDMacTouchBar_LIBRARIES ${CMAKE_CURRENT_LIST_DIR}/../KDMacTouchBar.framework/Versions/Current/KDMacTouchBar)
|
@ -1,32 +0,0 @@
|
||||
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||
|
||||
if(QT_USE_QTNETWORK)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
list(APPEND QT_LIBRARIES Qt5::Network)
|
||||
include_directories(${Qt5Network_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(QT_USE_QTXML)
|
||||
find_package(Qt5Xml REQUIRED)
|
||||
list(APPEND QT_LIBRARIES Qt5::Xml)
|
||||
include_directories(${Qt5Xml_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
if(QT_USE_QTTEST)
|
||||
find_package(Qt5Test REQUIRED)
|
||||
list(APPEND QT_LIBRARIES Qt5::Test)
|
||||
include_directories(${Qt5Test_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
macro(qt4_wrap_ui)
|
||||
qt5_wrap_ui(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt4_wrap_cpp)
|
||||
qt5_wrap_cpp(${ARGN})
|
||||
endmacro()
|
||||
|
||||
macro(qt4_add_resources)
|
||||
qt5_add_resources(${ARGN})
|
||||
endmacro()
|
Binary file not shown.
@ -1 +0,0 @@
|
||||
add_subdirectory(mactouchbar)
|
@ -1,3 +0,0 @@
|
||||
TEMPLATE=subdirs
|
||||
|
||||
SUBDIRS=mactouchbar
|
@ -1,19 +0,0 @@
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
add_executable(mactouchbar MACOSX_BUNDLE
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
mactouchbar.qrc)
|
||||
|
||||
include_directories(../../src)
|
||||
|
||||
install(TARGETS mactouchbar
|
||||
DESTINATION "${CMAKE_INSTALL_PREFIX}/examples/mactouchbar")
|
||||
|
||||
target_link_libraries(mactouchbar KDMacTouchBar)
|
@ -1,12 +0,0 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS += mainwindow.h
|
||||
SOURCES += mainwindow.cpp main.cpp
|
||||
RESOURCES += mactouchbar.qrc
|
||||
|
||||
INCLUDEPATH = ../../src
|
||||
LIBS += -F../../lib -framework KDMacTouchBar
|
||||
QMAKE_LFLAGS = '-Wl,-rpath,\'$$OUT_PWD/../../lib\',-rpath,\'$$INSTALL_PREFIX/lib\''
|
||||
|
||||
target.path = "$${INSTALL_PREFIX}/examples/mactouchbar"
|
||||
INSTALLS += target
|
@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qtlogo.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -1,38 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include "kdmactouchbar.h"
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// enable automatic message box on touchbar
|
||||
KDMacTouchBar::setAutomaticallyCreateMessageBoxTouchBar(true);
|
||||
|
||||
MainWindow mw;
|
||||
mw.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QtGui/QCloseEvent>
|
||||
|
||||
#include <QtWidgets/QAction>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QLabel>
|
||||
|
||||
#include "kdmactouchbar.h"
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
setWindowTitle("KDMacTouchBar Example");
|
||||
resize(400, 200);
|
||||
|
||||
// attach a touchbar to this window
|
||||
KDMacTouchBar *touchBar = new KDMacTouchBar(this);
|
||||
|
||||
QIcon qtIcon(QStringLiteral(":qtlogo.png"));
|
||||
|
||||
// add item
|
||||
QAction *action = new QAction(qtIcon, tr("Qt with touchbar"));
|
||||
touchBar->addAction(action);
|
||||
connect(action, &QAction::triggered, this, &MainWindow::activated);
|
||||
|
||||
// separator
|
||||
touchBar->addSeparator();
|
||||
touchBar->addSeparator()->setText(tr("More items:"));
|
||||
|
||||
// and more items
|
||||
QAction *action1 = new QAction(tr("Item 1"));
|
||||
touchBar->addAction(action1);
|
||||
connect(action1, &QAction::triggered, this, &MainWindow::activated);
|
||||
|
||||
QAction *action2 = new QAction(tr("Item 2"));
|
||||
touchBar->addAction(action2);
|
||||
connect(action2, &QAction::triggered, this, &MainWindow::activated);
|
||||
|
||||
// make special escape button
|
||||
QAction *quit = new QAction(tr("Quit"));
|
||||
touchBar->setEscapeAction(quit);
|
||||
connect(quit, &QAction::triggered, this, &QWidget::close);
|
||||
}
|
||||
|
||||
void MainWindow::activated()
|
||||
{
|
||||
QMessageBox::information(this, tr("Activated"), tr("You activated the touchbar action!"));
|
||||
}
|
||||
|
||||
void MainWindow::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
event->setAccepted(QMessageBox::question(this, tr("Quit"), tr("Do yo really want to quit?")) == QMessageBox::Yes);
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef EX_MAINWINDOW_H
|
||||
#define EX_MAINWINDOW_H
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow();
|
||||
|
||||
public Q_SLOTS:
|
||||
void activated();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
@ -1,8 +0,0 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
features.path = $$INSTALL_PREFIX/share/mkspecs/features
|
||||
features.files = *.prf
|
||||
|
||||
INSTALLS += features
|
||||
|
||||
OTHER_FILES = *.prf
|
@ -1,4 +0,0 @@
|
||||
LIBPATH=$$clean_path($$PWD/../../../lib)
|
||||
LIBS += -F$$LIBPATH -framework KDMacTouchBar
|
||||
QMAKE_LFLAGS += '-Wl,-rpath,\'$$LIBPATH\''
|
||||
INCLUDEPATH += $$LIBPATH/KDMacTouchBar.framework/Headers
|
@ -1 +0,0 @@
|
||||
VERSION = 1.0
|
@ -1,33 +0,0 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
include(kdmactouchbar.pri)
|
||||
|
||||
DEFAULT_INSTALL_PREFIX = /usr/local/KDAB/KDMacTouchBar-$$VERSION
|
||||
|
||||
isEmpty( KDMACTOUCHBAR_INSTALL_PREFIX ): KDMACTOUCHBAR_INSTALL_PREFIX=$$PREFIX
|
||||
|
||||
isEmpty( KDMACTOUCHBAR_INSTALL_PREFIX ): KDMACTOUCHBAR_INSTALL_PREFIX=$$DEFAULT_INSTALL_PREFIX
|
||||
|
||||
# if the default was either set by configure or set by the line above:
|
||||
equals( KDMACTOUCHBAR_INSTALL_PREFIX, $$DEFAULT_INSTALL_PREFIX ){
|
||||
INSTALL_PREFIX=$$DEFAULT_INSTALL_PREFIX
|
||||
message( "No install prefix given, using default of" $$DEFAULT_INSTALL_PREFIX (use configure.sh -prefix DIR to specify))
|
||||
} else {
|
||||
INSTALL_PREFIX=$$KDMACTOUCHBAR_INSTALL_PREFIX
|
||||
}
|
||||
|
||||
# This file is in the build directory (because "somecommand >> somefile" puts it there)
|
||||
QMAKE_CACHE = "$${OUT_PWD}/.qmake.cache"
|
||||
|
||||
MESSAGE = '\\'$$LITERAL_HASH\\' KDAB qmake cache file: following lines autogenerated during qmake run'
|
||||
system('echo $${MESSAGE} > $${QMAKE_CACHE}')
|
||||
|
||||
TMP_SOURCE_DIR = $${PWD}
|
||||
TMP_BUILD_DIR = $${OUT_PWD}
|
||||
system('echo TOP_SOURCE_DIR=$${TMP_SOURCE_DIR} >> $${QMAKE_CACHE}')
|
||||
system('echo TOP_BUILD_DIR=$${TMP_BUILD_DIR} >> $${QMAKE_CACHE}')
|
||||
system('echo INSTALL_PREFIX=$$INSTALL_PREFIX >> $${QMAKE_CACHE}')
|
||||
|
||||
SUBDIRS += src examples features
|
||||
|
||||
examples.depends = src
|
@ -1,24 +0,0 @@
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
set(HEADERS kdmactouchbar.h
|
||||
kdmactouchbar_global.h)
|
||||
|
||||
add_definitions(-DKDMACTOUCHBAR_BUILD_KDMACTOUCHBAR_LIB -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNING)
|
||||
|
||||
add_library(KDMacTouchBar SHARED
|
||||
kdmactouchbar.mm
|
||||
${HEADERS})
|
||||
|
||||
install(TARGETS KDMacTouchBar
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
|
||||
target_link_libraries(KDMacTouchBar ${QT_LIBRARIES} "-framework Cocoa")
|
||||
|
||||
set_target_properties(KDMacTouchBar PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION 1
|
||||
MACOSX_FRAMEWORK_IDENTIFIER com.kdab.KDMacTouchBar
|
||||
PUBLIC_HEADER "${HEADERS}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
|
||||
MACOSX_RPATH TRUE
|
||||
)
|
@ -1,88 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef KDMACTOUCHBAR_H
|
||||
#define KDMACTOUCHBAR_H
|
||||
|
||||
#include "kdmactouchbar_global.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QAction>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QDialogButtonBox;
|
||||
class QMessageBox;
|
||||
class QTabBar;
|
||||
|
||||
|
||||
class KDMACTOUCHBAR_EXPORT KDMacTouchBar : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QAction *principialAction READ principialAction WRITE setPrincipialAction)
|
||||
Q_PROPERTY(QAction *escapeAction READ escapeAction WRITE setEscapeAction)
|
||||
Q_PROPERTY(TouchButtonStyle touchButtonStyle READ touchButtonStyle WRITE setTouchButtonStyle)
|
||||
public:
|
||||
explicit KDMacTouchBar(QWidget *parent = nullptr);
|
||||
explicit KDMacTouchBar(QMessageBox *messageBox);
|
||||
~KDMacTouchBar();
|
||||
|
||||
enum TouchButtonStyle
|
||||
{
|
||||
IconOnly,
|
||||
TextOnly,
|
||||
TextBesideIcon
|
||||
};
|
||||
|
||||
static void setAutomaticallyCreateMessageBoxTouchBar(bool automatic);
|
||||
static bool isAutomacicallyCreatingMessageBoxTouchBar();
|
||||
|
||||
QAction *addSeparator();
|
||||
QAction *addTabBar(QTabBar *tabBar);
|
||||
void removeTabBar(QTabBar *tabBar);
|
||||
|
||||
QAction *addMessageBox(QMessageBox *messageBox);
|
||||
void removeMessageBox(QMessageBox *messageBox);
|
||||
|
||||
QAction *addDialogButtonBox(QDialogButtonBox *buttonBox);
|
||||
void removeDialogButtonBox(QDialogButtonBox *buttonBox);
|
||||
|
||||
void setPrincipialAction(QAction *action);
|
||||
QAction *principialAction() const;
|
||||
|
||||
void setEscapeAction(QAction *action);
|
||||
QAction *escapeAction() const;
|
||||
|
||||
void setTouchButtonStyle(TouchButtonStyle touchButtonStyle);
|
||||
TouchButtonStyle touchButtonStyle() const;
|
||||
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
Private *const d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
@ -1,980 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
#include "kdmactouchbar.h"
|
||||
|
||||
#include <QActionEvent>
|
||||
#include <QApplication>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLayout>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QProxyStyle>
|
||||
#include <QStack>
|
||||
#include <QTabBar>
|
||||
#include <QTimer>
|
||||
#include <QWidgetAction>
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize = 0);
|
||||
#else
|
||||
// defined in gui/painting/qcoregraphics.mm
|
||||
@interface NSImage (QtExtras)
|
||||
+ (instancetype)imageFromQIcon:(const QIcon &)icon;
|
||||
@end
|
||||
static NSImage *qt_mac_create_nsimage(const QIcon &icon)
|
||||
{
|
||||
return [NSImage imageFromQIcon:icon];
|
||||
}
|
||||
#endif
|
||||
|
||||
static QString identifierForAction(QObject *action)
|
||||
{
|
||||
return QStringLiteral("0x%1 %2")
|
||||
.arg((quintptr)action, QT_POINTER_SIZE * 2, 16, QLatin1Char('0'))
|
||||
.arg(action->objectName());
|
||||
}
|
||||
|
||||
|
||||
static QString removeMnemonics(const QString &original)
|
||||
{
|
||||
QString returnText(original.size(), QChar('\0'));
|
||||
int finalDest = 0;
|
||||
int currPos = 0;
|
||||
int l = original.length();
|
||||
while (l) {
|
||||
if (original.at(currPos) == QLatin1Char('&')) {
|
||||
++currPos;
|
||||
--l;
|
||||
if (l == 0)
|
||||
break;
|
||||
} else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
|
||||
original.at(currPos + 1) == QLatin1Char('&') &&
|
||||
original.at(currPos + 2) != QLatin1Char('&') &&
|
||||
original.at(currPos + 3) == QLatin1Char(')')) {
|
||||
/* remove mnemonics its format is "\s*(&X)" */
|
||||
int n = 0;
|
||||
while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
|
||||
++n;
|
||||
finalDest -= n;
|
||||
currPos += 4;
|
||||
l -= 4;
|
||||
continue;
|
||||
}
|
||||
returnText[finalDest] = original.at(currPos);
|
||||
++currPos;
|
||||
++finalDest;
|
||||
--l;
|
||||
}
|
||||
returnText.truncate(finalDest);
|
||||
return returnText;
|
||||
}
|
||||
|
||||
class TabBarAction : public QAction
|
||||
{
|
||||
public:
|
||||
TabBarAction(QTabBar *tabBar, QObject *parent)
|
||||
: QAction(parent)
|
||||
{
|
||||
setData(QVariant::fromValue<QObject *>(tabBar));
|
||||
connect(tabBar, &QTabBar::currentChanged, this, &TabBarAction::sendDataChanged);
|
||||
connect(tabBar, &QObject::destroyed, this, &QObject::deleteLater);
|
||||
}
|
||||
|
||||
void sendDataChanged()
|
||||
{
|
||||
QActionEvent e(QEvent::ActionChanged, this);
|
||||
for (auto w : associatedWidgets())
|
||||
QApplication::sendEvent(w, &e);
|
||||
}
|
||||
};
|
||||
|
||||
class ButtonBoxAction : public QAction
|
||||
{
|
||||
public:
|
||||
ButtonBoxAction(QDialogButtonBox *buttonBox, QObject *parent)
|
||||
: QAction(parent)
|
||||
, mButtonBox(buttonBox)
|
||||
{
|
||||
setData(QVariant::fromValue<QObject *>(buttonBox));
|
||||
|
||||
checkStandardButtonAndTexts();
|
||||
|
||||
auto timer = new QTimer(buttonBox);
|
||||
timer->start(200);
|
||||
connect(timer, &QTimer::timeout, this, &ButtonBoxAction::checkStandardButtonAndTexts);
|
||||
connect(buttonBox, &QObject::destroyed, this, &QObject::deleteLater);
|
||||
}
|
||||
|
||||
void checkStandardButtonAndTexts()
|
||||
{
|
||||
QStringList buttonTexts;
|
||||
QPushButton *defaultButton = nullptr;
|
||||
for (auto b : mButtonBox->buttons()) {
|
||||
buttonTexts.append(b->text());
|
||||
if (auto pb = qobject_cast<QPushButton *>(b))
|
||||
if (pb->isDefault())
|
||||
defaultButton = pb;
|
||||
}
|
||||
|
||||
if (buttonTexts != mButtonTexts || defaultButton != mDefaultButton) {
|
||||
sendDataChanged();
|
||||
mButtonTexts = buttonTexts;
|
||||
mDefaultButton = defaultButton;
|
||||
}
|
||||
}
|
||||
|
||||
void sendDataChanged()
|
||||
{
|
||||
QActionEvent e(QEvent::ActionChanged, this);
|
||||
for (auto w : associatedWidgets())
|
||||
QApplication::sendEvent(w, &e);
|
||||
}
|
||||
|
||||
QDialogButtonBox *mButtonBox;
|
||||
QList<QAbstractButton *> mButtons;
|
||||
QPushButton *mDefaultButton = nullptr;
|
||||
QStringList mButtonTexts;
|
||||
};
|
||||
|
||||
@interface QObjectPointer : NSObject {
|
||||
}
|
||||
@property (readonly) QObject *qobject;
|
||||
@end
|
||||
|
||||
@implementation QObjectPointer
|
||||
QObject *_qobject;
|
||||
@synthesize qobject = _qobject;
|
||||
|
||||
- (id)initWithQObject:(QObject *)aQObject
|
||||
{
|
||||
self = [super init];
|
||||
_qobject = aQObject;
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
class WidgetActionContainerWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
WidgetActionContainerWidget(QWidget *widget, NSView *view)
|
||||
: w(widget)
|
||||
, v(view)
|
||||
{
|
||||
widget->setParent(this);
|
||||
widget->move(0, 0);
|
||||
if (!widget->testAttribute(Qt::WA_Resized))
|
||||
widget->resize(widget->sizeHint()
|
||||
.boundedTo(QSize(widget->maximumWidth(), 30))
|
||||
.expandedTo(widget->minimumSize()));
|
||||
setAttribute(Qt::WA_DontShowOnScreen);
|
||||
setAttribute(Qt::WA_QuitOnClose, false);
|
||||
ensurePolished();
|
||||
setVisible(true);
|
||||
QPixmap pm(1, 1);
|
||||
render(&pm, QPoint(), QRegion(),
|
||||
widget->autoFillBackground()
|
||||
? (QWidget::DrawWindowBackground | QWidget::DrawChildren)
|
||||
: QWidget::DrawChildren);
|
||||
}
|
||||
|
||||
QSize sizeHint() const { return w->size(); }
|
||||
|
||||
void resizeEvent(QResizeEvent *event) { w->resize(event->size()); }
|
||||
|
||||
bool event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::UpdateRequest)
|
||||
[v setNeedsDisplay:YES];
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
QWidget *w;
|
||||
NSView *v;
|
||||
};
|
||||
|
||||
@interface WidgetActionView : NSView
|
||||
@property WidgetActionContainerWidget *widget;
|
||||
@property QWidget *touchTarget;
|
||||
@property QWidgetAction *action;
|
||||
@property (readonly) NSSize intrinsicContentSize;
|
||||
@end
|
||||
|
||||
@implementation WidgetActionView
|
||||
@synthesize action;
|
||||
@synthesize widget;
|
||||
@synthesize touchTarget;
|
||||
|
||||
- (NSSize)intrinsicContentSize
|
||||
{
|
||||
return NSMakeSize(widget->width(), widget->height());
|
||||
}
|
||||
|
||||
- (id)initWithWidgetAction:(QWidgetAction *)wa
|
||||
{
|
||||
self = [super init];
|
||||
action = wa;
|
||||
widget = new WidgetActionContainerWidget(action->requestWidget(nullptr), self);
|
||||
if (!widget->testAttribute(Qt::WA_Resized))
|
||||
widget->resize(widget->sizeHint()
|
||||
.boundedTo(QSize(widget->maximumWidth(), 30))
|
||||
.expandedTo(widget->minimumSize()));
|
||||
[self setNeedsDisplay:YES];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
widget->w->setParent(0);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)frame
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
widget->w->resize(frame.size.width, frame.size.height);
|
||||
QPixmap pm(widget->w->size() * 2);
|
||||
pm.setDevicePixelRatio(2);
|
||||
pm.fill(Qt::transparent);
|
||||
widget->w->render(&pm, QPoint(), QRegion(),
|
||||
widget->w->autoFillBackground()
|
||||
? (QWidget::DrawWindowBackground | QWidget::DrawChildren)
|
||||
: QWidget::DrawChildren);
|
||||
CGImageRef cgImage = pm.toImage().toCGImage();
|
||||
NSImage *image = [[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize];
|
||||
[image drawInRect:frame];
|
||||
[pool release];
|
||||
}
|
||||
|
||||
- (void)touchesBeganWithEvent:(NSEvent *)event
|
||||
{
|
||||
NSTouch *touch = [[event touchesMatchingPhase:NSTouchPhaseBegan inView:self] anyObject];
|
||||
const QPoint point = QPointF::fromCGPoint([touch locationInView:self]).toPoint();
|
||||
touchTarget = widget->childAt(point);
|
||||
if (touchTarget == nullptr)
|
||||
touchTarget = widget;
|
||||
QMouseEvent e(QEvent::MouseButtonPress, touchTarget->mapFrom(widget, point), Qt::LeftButton,
|
||||
Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(touchTarget, &e);
|
||||
}
|
||||
- (void)touchesMovedWithEvent:(NSEvent *)event
|
||||
{
|
||||
NSTouch *touch = [[event touchesMatchingPhase:NSTouchPhaseMoved inView:self] anyObject];
|
||||
const QPoint point = QPointF::fromCGPoint([touch locationInView:self]).toPoint();
|
||||
QMouseEvent e(QEvent::MouseButtonPress, touchTarget->mapFrom(widget, point), Qt::LeftButton,
|
||||
Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(touchTarget, &e);
|
||||
}
|
||||
- (void)touchesEndedWithEvent:(NSEvent *)event
|
||||
{
|
||||
NSTouch *touch = [[event touchesMatchingPhase:NSTouchPhaseEnded inView:self] anyObject];
|
||||
const QPoint point = QPointF::fromCGPoint([touch locationInView:self]).toPoint();
|
||||
QMouseEvent e(QEvent::MouseButtonRelease, touchTarget->mapFrom(widget, point), Qt::LeftButton,
|
||||
Qt::LeftButton, Qt::NoModifier);
|
||||
qApp->sendEvent(touchTarget, &e);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface DynamicTouchBarProviderDelegate : NSResponder <NSTouchBarDelegate>
|
||||
@property (strong) NSMutableDictionary *items;
|
||||
@end
|
||||
|
||||
@implementation DynamicTouchBarProviderDelegate
|
||||
@synthesize items;
|
||||
|
||||
- (id)initWithItems:(NSMutableDictionary *)i
|
||||
{
|
||||
self = [super init];
|
||||
self.items = i;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar
|
||||
makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier
|
||||
{
|
||||
Q_UNUSED(touchBar);
|
||||
|
||||
if ([self.items objectForKey:identifier] != nil)
|
||||
return [self.items objectForKey:identifier];
|
||||
|
||||
return nil;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface DynamicTouchBarProvider
|
||||
: NSResponder <NSTouchBarProvider, NSApplicationDelegate, NSWindowDelegate>
|
||||
@property (strong) NSMutableDictionary *items;
|
||||
@property (strong) NSMutableDictionary *commands;
|
||||
@property (strong) NSObject *qtDelegate;
|
||||
@property (strong, readonly) NSTouchBar *touchBar;
|
||||
@property (strong) DynamicTouchBarProviderDelegate *delegate;
|
||||
@property KDMacTouchBar *qMacTouchBar;
|
||||
@property QStack<NSPopoverTouchBarItem *> openedPopOvers;
|
||||
@end
|
||||
|
||||
@implementation DynamicTouchBarProvider
|
||||
@synthesize items;
|
||||
@synthesize commands;
|
||||
@synthesize touchBar;
|
||||
@synthesize delegate;
|
||||
@synthesize qMacTouchBar;
|
||||
@synthesize openedPopOvers;
|
||||
|
||||
- (id)initWithKDMacTouchBar:(KDMacTouchBar *)bar
|
||||
{
|
||||
self = [super init];
|
||||
items = [[NSMutableDictionary alloc] init];
|
||||
commands = [[NSMutableDictionary alloc] init];
|
||||
qMacTouchBar = bar;
|
||||
delegate = [[DynamicTouchBarProviderDelegate alloc] initWithItems:items];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)addItem:(QAction *)action
|
||||
{
|
||||
// Create custom button item
|
||||
NSString *identifier = identifierForAction(action).toNSString();
|
||||
NSTouchBarItem *item = nil;
|
||||
NSView *view = nil;
|
||||
|
||||
if (auto wa = qobject_cast<QWidgetAction *>(action)) {
|
||||
NSPopoverTouchBarItem *i =
|
||||
[[[NSPopoverTouchBarItem alloc] initWithIdentifier:identifier] autorelease];
|
||||
item = i;
|
||||
view = [[WidgetActionView alloc] initWithWidgetAction:wa];
|
||||
i.collapsedRepresentation = view;
|
||||
} else if (auto tb = qobject_cast<QTabBar *>(action->data().value<QObject *>())) {
|
||||
NSCustomTouchBarItem *i =
|
||||
[[[NSCustomTouchBarItem alloc] initWithIdentifier:identifier] autorelease];
|
||||
item = i;
|
||||
NSMutableArray *labels = [[NSMutableArray alloc] init];
|
||||
view =
|
||||
[[NSSegmentedControl segmentedControlWithLabels:labels
|
||||
trackingMode:NSSegmentSwitchTrackingSelectOne
|
||||
target:self
|
||||
action:@selector(tabBarAction:)] autorelease];
|
||||
i.view = view;
|
||||
} else if (auto bb = qobject_cast<QDialogButtonBox *>(action->data().value<QObject *>())) {
|
||||
NSMutableArray *buttonItems = [[NSMutableArray alloc] init];
|
||||
|
||||
for (int i = 0; i < bb->layout()->count(); ++i) {
|
||||
auto layoutItem = bb->layout()->itemAt(i);
|
||||
if (auto b = qobject_cast<QPushButton *>(layoutItem->widget())) {
|
||||
auto buttonIdentifier = identifierForAction(b).toNSString();
|
||||
NSCustomTouchBarItem *buttonItem = nil;
|
||||
NSButton *button = nil;
|
||||
if ([[items allKeys] containsObject:buttonIdentifier]) {
|
||||
buttonItem = [items objectForKey:buttonIdentifier];
|
||||
button = buttonItem.view;
|
||||
} else {
|
||||
buttonItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:buttonIdentifier];
|
||||
button = [NSButton buttonWithTitle:removeMnemonics(b->text()).toNSString()
|
||||
target:self
|
||||
action:@selector(buttonAction:)];
|
||||
}
|
||||
if (b->isDefault())
|
||||
[button setKeyEquivalent:@"\r"];
|
||||
button.title = removeMnemonics(b->text()).toNSString();
|
||||
buttonItem.view = button;
|
||||
[buttonItems addObject:buttonItem];
|
||||
[commands setObject:[[QObjectPointer alloc] initWithQObject:b]
|
||||
forKey:[NSValue valueWithPointer:button]];
|
||||
[items setObject:buttonItem forKey:buttonIdentifier];
|
||||
}
|
||||
}
|
||||
|
||||
item = [[NSGroupTouchBarItem groupItemWithIdentifier:identifier items:buttonItems]
|
||||
autorelease];
|
||||
} else if (action->isSeparator()) {
|
||||
NSPopoverTouchBarItem *i =
|
||||
[[[NSPopoverTouchBarItem alloc] initWithIdentifier:identifier] autorelease];
|
||||
item = i;
|
||||
view = [NSTextField labelWithString:action->text().toNSString()];
|
||||
i.collapsedRepresentation = view;
|
||||
} else {
|
||||
NSPopoverTouchBarItem *i =
|
||||
[[[NSPopoverTouchBarItem alloc] initWithIdentifier:identifier] autorelease];
|
||||
item = i;
|
||||
view = [[NSButton buttonWithTitle:removeMnemonics(action->text()).toNSString()
|
||||
target:self
|
||||
action:@selector(itemAction:)] autorelease];
|
||||
i.collapsedRepresentation = view;
|
||||
}
|
||||
|
||||
if (view)
|
||||
[view retain];
|
||||
[item retain];
|
||||
|
||||
[items setObject:item forKey:identifier];
|
||||
[commands setObject:[[QObjectPointer alloc] initWithQObject:action]
|
||||
forKey:[NSValue valueWithPointer:view]];
|
||||
|
||||
if (!qobject_cast<QDialogButtonBox *>(action->data().value<QObject *>()))
|
||||
[self changeItem:action];
|
||||
else
|
||||
[self makeTouchBar];
|
||||
}
|
||||
|
||||
- (void)changeItem:(QAction *)action
|
||||
{
|
||||
NSString *identifier = identifierForAction(action).toNSString();
|
||||
|
||||
if (auto wa = qobject_cast<QWidgetAction *>(action)) {
|
||||
|
||||
} else if (auto tb = qobject_cast<QTabBar *>(action->data().value<QObject *>())) {
|
||||
NSCustomTouchBarItem *item = [items objectForKey:identifier];
|
||||
NSSegmentedControl *control = item.view;
|
||||
control.segmentCount = tb->count();
|
||||
for (int i = 0; i < tb->count(); ++i) {
|
||||
[control setLabel:tb->tabText(i).toNSString() forSegment:i];
|
||||
}
|
||||
control.selectedSegment = tb->currentIndex();
|
||||
} else if (auto bb = qobject_cast<QDialogButtonBox *>(action->data().value<QObject *>())) {
|
||||
// unfortunately we cannot modify a NSGroupTouchBarItem, so we
|
||||
// have to recreate it from scratch :-(
|
||||
int index = qMacTouchBar->actions().indexOf(action);
|
||||
if (index == qMacTouchBar->actions().count() - 1) {
|
||||
qMacTouchBar->removeAction(action);
|
||||
qMacTouchBar->addAction(action);
|
||||
} else {
|
||||
QAction *before = qMacTouchBar->actions().at(index + 1);
|
||||
qMacTouchBar->removeAction(action);
|
||||
qMacTouchBar->insertAction(before, action);
|
||||
}
|
||||
} else if (action->isSeparator()) {
|
||||
NSPopoverTouchBarItem *item = [items objectForKey:identifier];
|
||||
NSTextField *field = item.collapsedRepresentation;
|
||||
field.stringValue = action->text().toNSString();
|
||||
} else {
|
||||
NSPopoverTouchBarItem *item = [items objectForKey:identifier];
|
||||
NSButton *button = item.collapsedRepresentation;
|
||||
button.imagePosition = NSImageLeft;
|
||||
button.enabled = action->isEnabled();
|
||||
button.buttonType =
|
||||
action->isCheckable() ? NSButtonTypePushOnPushOff : NSButtonTypeAccelerator;
|
||||
button.bordered = action->isSeparator() && !action->text().isEmpty() ? NO : YES;
|
||||
button.highlighted = !button.bordered;
|
||||
button.state = action->isChecked();
|
||||
button.hidden = !action->isVisible();
|
||||
button.image = qt_mac_create_nsimage(action->icon());
|
||||
button.title = removeMnemonics(action->text()).toNSString();
|
||||
switch (qMacTouchBar->touchButtonStyle())
|
||||
{
|
||||
case KDMacTouchBar::IconOnly:
|
||||
button.imagePosition = NSImageOnly;
|
||||
break;
|
||||
case KDMacTouchBar::TextOnly:
|
||||
button.imagePosition = NSNoImage;
|
||||
break;
|
||||
case KDMacTouchBar::TextBesideIcon:
|
||||
button.imagePosition = NSImageLeft;
|
||||
break;
|
||||
}
|
||||
item.showsCloseButton = action->menu() != nullptr;
|
||||
if (action->menu()) {
|
||||
item.popoverTouchBar = [[NSTouchBar alloc] init];
|
||||
item.popoverTouchBar.delegate = delegate;
|
||||
// Add ordered items array
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (auto action : action->menu()->actions()) {
|
||||
if (action->isVisible()) {
|
||||
[self addItem:action];
|
||||
if (action->isSeparator() && action->text().isEmpty())
|
||||
[array addObject:NSTouchBarItemIdentifierFixedSpaceLarge];
|
||||
else
|
||||
[array addObject:identifierForAction(action).toNSString()];
|
||||
}
|
||||
}
|
||||
item.popoverTouchBar.defaultItemIdentifiers = array;
|
||||
}
|
||||
}
|
||||
|
||||
[self makeTouchBar];
|
||||
}
|
||||
|
||||
- (void)removeItem:(QAction *)action
|
||||
{
|
||||
NSString *identifier = identifierForAction(action).toNSString();
|
||||
NSPopoverTouchBarItem *item = [items objectForKey:identifier];
|
||||
if (item == nil)
|
||||
return;
|
||||
QObjectPointer *command = [commands objectForKey:[NSValue valueWithPointer:item.view]];
|
||||
[commands removeObjectForKey:[NSValue valueWithPointer:item.view]];
|
||||
[items removeObjectForKey:identifier];
|
||||
[command release];
|
||||
|
||||
[self makeTouchBar];
|
||||
}
|
||||
|
||||
- (void)buttonAction:(id)sender
|
||||
{
|
||||
QObjectPointer *qobjectPointer =
|
||||
(QObjectPointer *)[commands objectForKey:[NSValue valueWithPointer:sender]];
|
||||
// Missing entry in commands dict. Should not really happen, but does
|
||||
if (!qobjectPointer)
|
||||
return;
|
||||
|
||||
QPushButton *button = qobject_cast<QPushButton *>(qobjectPointer.qobject);
|
||||
if (!button)
|
||||
return;
|
||||
|
||||
button->click();
|
||||
}
|
||||
|
||||
- (void)tabBarAction:(id)sender
|
||||
{
|
||||
QObjectPointer *qobjectPointer =
|
||||
(QObjectPointer *)[commands objectForKey:[NSValue valueWithPointer:sender]];
|
||||
// Missing entry in commands dict. Should not really happen, but does
|
||||
if (!qobjectPointer)
|
||||
return;
|
||||
|
||||
// Check for deleted QObject
|
||||
if (!qobjectPointer.qobject)
|
||||
return;
|
||||
|
||||
QAction *action = static_cast<QAction *>(qobjectPointer.qobject);
|
||||
if (!action)
|
||||
return;
|
||||
QTabBar *tabBar = qobject_cast<QTabBar *>(action->data().value<QObject *>());
|
||||
if (!tabBar)
|
||||
return;
|
||||
|
||||
NSString *identifier = identifierForAction(action).toNSString();
|
||||
NSCustomTouchBarItem *item = [items objectForKey:identifier];
|
||||
NSSegmentedControl *control = item.view;
|
||||
|
||||
tabBar->setCurrentIndex(control.selectedSegment);
|
||||
}
|
||||
|
||||
- (void)itemAction:(id)sender
|
||||
{
|
||||
QObjectPointer *qobjectPointer =
|
||||
(QObjectPointer *)[commands objectForKey:[NSValue valueWithPointer:sender]];
|
||||
// Missing entry in commands dict. Should not really happen, but does
|
||||
if (!qobjectPointer)
|
||||
return;
|
||||
|
||||
// Check for deleted QObject
|
||||
if (!qobjectPointer.qobject)
|
||||
return;
|
||||
|
||||
QAction *action = static_cast<QAction *>(qobjectPointer.qobject);
|
||||
if (!action || action->isSeparator())
|
||||
return;
|
||||
if (!action->isEnabled())
|
||||
return;
|
||||
action->activate(QAction::Trigger);
|
||||
|
||||
if (action->menu()) {
|
||||
NSString *identifier = identifierForAction(action).toNSString();
|
||||
NSPopoverTouchBarItem *item = [items objectForKey:identifier];
|
||||
[item showPopover:item];
|
||||
openedPopOvers.push(item);
|
||||
} else {
|
||||
while (!openedPopOvers.isEmpty()) {
|
||||
auto poppedItem = openedPopOvers.pop();
|
||||
[poppedItem dismissPopover:poppedItem];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearItems
|
||||
{
|
||||
[items removeAllObjects];
|
||||
[commands removeAllObjects];
|
||||
}
|
||||
|
||||
- (NSTouchBar *)makeTouchBar
|
||||
{
|
||||
// Create the touch bar with this instance as its delegate
|
||||
if (touchBar == nil) {
|
||||
touchBar = [[NSTouchBar alloc] init];
|
||||
touchBar.delegate = delegate;
|
||||
}
|
||||
|
||||
// Add ordered items array
|
||||
NSMutableArray *array = [[NSMutableArray alloc] init];
|
||||
for (auto action : qMacTouchBar->actions()) {
|
||||
if (action->isVisible()) {
|
||||
if (action->isSeparator() && action->text().isEmpty())
|
||||
[array addObject:NSTouchBarItemIdentifierFixedSpaceLarge];
|
||||
else
|
||||
[array addObject:identifierForAction(action).toNSString()];
|
||||
}
|
||||
}
|
||||
touchBar.defaultItemIdentifiers = array;
|
||||
|
||||
return touchBar;
|
||||
}
|
||||
|
||||
- (void)installAsDelegateForWindow:(NSWindow *)window
|
||||
{
|
||||
_qtDelegate = window.delegate; // Save current delegate for forwarding
|
||||
window.delegate = self;
|
||||
}
|
||||
|
||||
- (void)installAsDelegateForApplication:(NSApplication *)application
|
||||
{
|
||||
_qtDelegate = application.delegate; // Save current delegate for forwarding
|
||||
application.delegate = self;
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||
{
|
||||
// We want to forward to the qt delegate. Respond to selectors it
|
||||
// responds to in addition to selectors this instance resonds to.
|
||||
return [_qtDelegate respondsToSelector:aSelector] || [super respondsToSelector:aSelector];
|
||||
}
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)anInvocation
|
||||
{
|
||||
// Forward to the existing delegate. This function is only called for selectors
|
||||
// this instance does not responds to, which means that the qt delegate
|
||||
// must respond to it (due to the respondsToSelector implementation above).
|
||||
[anInvocation invokeWithTarget:_qtDelegate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
class KDMacTouchBar::Private
|
||||
{
|
||||
public:
|
||||
DynamicTouchBarProvider *touchBarProvider = nil;
|
||||
QAction *principialAction = nullptr;
|
||||
QAction *escapeAction = nullptr;
|
||||
KDMacTouchBar::TouchButtonStyle touchButtonStyle = TextBesideIcon;
|
||||
|
||||
static bool automaticallyCreateMessageBoxTouchBar;
|
||||
};
|
||||
|
||||
bool KDMacTouchBar::Private::automaticallyCreateMessageBoxTouchBar = false;
|
||||
|
||||
class AutomaticMessageBoxTouchBarStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
using QProxyStyle::QProxyStyle;
|
||||
|
||||
void polish(QWidget *w) override
|
||||
{
|
||||
if (auto mb = qobject_cast<QMessageBox *>(w)) {
|
||||
if (KDMacTouchBar::isAutomacicallyCreatingMessageBoxTouchBar())
|
||||
new KDMacTouchBar(mb);
|
||||
}
|
||||
QProxyStyle::polish(w);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\class KDMacTouchBar
|
||||
\brief The KDMacTouchBar class wraps the native NSTouchBar class.
|
||||
|
||||
KDMacTouchBar provides a Qt-based API for NSTouchBar. The touchbar displays
|
||||
a number of QActions. Each QAction can have a text and an icon. Alternatively,
|
||||
the QActions might be separators (with or without text) or QWidgetActions.
|
||||
|
||||
Add actions by calling addAction(). Alternatively, you can use one of the
|
||||
convenience methods like addDialogButtonBox() or addTabBar() which provide
|
||||
common use cases.
|
||||
|
||||
If an action with a associated menu is added, its menu items are added as
|
||||
sub-touchbar. Showing sub-menus of this menu is not supported, due to macOS
|
||||
system restrictions.
|
||||
|
||||
Usage: (QtWidgets)
|
||||
\code
|
||||
QMainWindow *mw = ...;
|
||||
KDMacTouchBar *touchBar = new KDMacTouchBar(mw);
|
||||
touchBar->addAction(actionNewFile);
|
||||
touchBar->addSeparator();
|
||||
touchBar->addAction(actionSaveFile);
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum KDMacTouchBar::TouchButtonStyle
|
||||
\value IconOnly Only display the icon.
|
||||
\value TextOnly Only display the text.
|
||||
\value TextBesideIcon The text appears beside the icon.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a KDMacTouchBar for the window of \a parent. If \a parent is
|
||||
nullptr, the KDMacTouchBar is shown as soon as this QApplication has focus,
|
||||
if no other window with an own KDMacTouchBar has focus.
|
||||
*/
|
||||
KDMacTouchBar::KDMacTouchBar(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, d(new Private)
|
||||
{
|
||||
d->touchBarProvider = [[DynamicTouchBarProvider alloc] initWithKDMacTouchBar:this];
|
||||
if (parent) {
|
||||
NSView *view = reinterpret_cast<NSView *>(parent->window()->winId());
|
||||
[d->touchBarProvider installAsDelegateForWindow:[view window]];
|
||||
} else {
|
||||
[d->touchBarProvider installAsDelegateForApplication:[NSApplication sharedApplication]];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a KDMacTouchBar containing the QDialogButtonBox from inside of
|
||||
\a messageBox.
|
||||
*/
|
||||
KDMacTouchBar::KDMacTouchBar(QMessageBox *messageBox)
|
||||
: QWidget( messageBox)
|
||||
, d(new Private)
|
||||
{
|
||||
d->touchBarProvider = [[DynamicTouchBarProvider alloc] initWithKDMacTouchBar:this];
|
||||
NSView *view = reinterpret_cast<NSView *>(messageBox->window()->winId());
|
||||
[d->touchBarProvider installAsDelegateForWindow:[view window]];
|
||||
setPrincipialAction(addMessageBox(messageBox));
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the touch bar.
|
||||
*/
|
||||
KDMacTouchBar::~KDMacTouchBar()
|
||||
{
|
||||
[d->touchBarProvider release];
|
||||
delete d;
|
||||
}
|
||||
|
||||
/*!
|
||||
This static convenience method controls, whether KDMacTouchBar will
|
||||
automatically create a touchbar for QMessageBox instances. The
|
||||
created touchbar contains the buttons of the message box.
|
||||
This enables to use the static QMessageBox method and still having
|
||||
a touchbar for them.
|
||||
|
||||
\note When you enable this setting for the first time, KDMacTouchBar will
|
||||
install a QProxyStyle into the QApplication object to be able to create
|
||||
the KDMacTouchBar in its polish method. The installed QProxyStyle will
|
||||
use the existing application style as base style.
|
||||
*/
|
||||
void KDMacTouchBar::setAutomaticallyCreateMessageBoxTouchBar(bool automatic)
|
||||
{
|
||||
static AutomaticMessageBoxTouchBarStyle *touchStyle = nullptr;
|
||||
if (automatic && !touchStyle) {
|
||||
qApp->setStyle(touchStyle = new AutomaticMessageBoxTouchBarStyle(qApp->style()));
|
||||
}
|
||||
Private::automaticallyCreateMessageBoxTouchBar = automatic;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether KDMacTouchBar automatically creates a touchbar for
|
||||
QMessageBox instances.
|
||||
*/
|
||||
bool KDMacTouchBar::isAutomacicallyCreatingMessageBoxTouchBar()
|
||||
{
|
||||
return Private::automaticallyCreateMessageBoxTouchBar;
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a separator item to the end of the touch bar.
|
||||
*/
|
||||
QAction *KDMacTouchBar::addSeparator()
|
||||
{
|
||||
auto action = new QAction(this);
|
||||
action->setSeparator(true);
|
||||
addAction(action);
|
||||
return action;
|
||||
}
|
||||
|
||||
/*! \reimp */
|
||||
bool KDMacTouchBar::event(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::ActionAdded:
|
||||
[d->touchBarProvider addItem:static_cast<QActionEvent *>(event)->action()];
|
||||
break;
|
||||
case QEvent::ActionChanged:
|
||||
[d->touchBarProvider changeItem:static_cast<QActionEvent *>(event)->action()];
|
||||
break;
|
||||
case QEvent::ActionRemoved:
|
||||
[d->touchBarProvider removeItem:static_cast<QActionEvent *>(event)->action()];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a button group controlling a \a tabBar item to the end of the touch bar.
|
||||
*/
|
||||
QAction *KDMacTouchBar::addTabBar(QTabBar *tabBar)
|
||||
{
|
||||
auto a = new TabBarAction(tabBar, this);
|
||||
addAction(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes \a tabBar from the touch bar.
|
||||
*/
|
||||
void KDMacTouchBar::removeTabBar(QTabBar *tabBar)
|
||||
{
|
||||
for (auto a : actions()) {
|
||||
if (a->data().value<QObject *>() == tabBar) {
|
||||
removeAction(a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds the QDialogButtonBox of \a messageBox to the end of the touch bar.
|
||||
*/
|
||||
QAction *KDMacTouchBar::addMessageBox(QMessageBox *messageBox)
|
||||
{
|
||||
return addDialogButtonBox(messageBox->findChild<QDialogButtonBox *>(QStringLiteral("qt_msgbox_buttonbox")));
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the QDialogButtonBox of \a messageBox from the touch bar.
|
||||
*/
|
||||
void KDMacTouchBar::removeMessageBox(QMessageBox *messageBox)
|
||||
{
|
||||
return removeDialogButtonBox(messageBox->findChild<QDialogButtonBox *>(QStringLiteral("qt_msgbox_buttonbox")));
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds a button group controlling \a buttonBox to the end of the touch bar.
|
||||
*/
|
||||
QAction *KDMacTouchBar::addDialogButtonBox(QDialogButtonBox *buttonBox)
|
||||
{
|
||||
auto a = new ButtonBoxAction(buttonBox, this);
|
||||
addAction(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the \a buttonBox from the touch bar.
|
||||
*/
|
||||
void KDMacTouchBar::removeDialogButtonBox(QDialogButtonBox *buttonBox)
|
||||
{
|
||||
for (auto a : actions()) {
|
||||
if (a->data().value<QObject *>() == buttonBox) {
|
||||
removeAction(a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\property KDMacTouchBar::principialAction
|
||||
\brief the principial action of the touch bar
|
||||
|
||||
The principial action of the touch bar is the QAction you want the system
|
||||
to center in the touch bar.
|
||||
|
||||
You need to add the action to the touch bar before you can set it as principial
|
||||
action.
|
||||
*/
|
||||
void KDMacTouchBar::setPrincipialAction(QAction *action)
|
||||
{
|
||||
d->principialAction = action;
|
||||
d->touchBarProvider.touchBar.principalItemIdentifier = action ? identifierForAction(action).toNSString() : nil;
|
||||
}
|
||||
|
||||
QAction *KDMacTouchBar::principialAction() const
|
||||
{
|
||||
return d->principialAction;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property KDMacTouchBar::escapeAction
|
||||
\brief the action used as system escape key action
|
||||
|
||||
By setting a QAction as escapeAction, it is possible to replace the system
|
||||
escape key with a random action.
|
||||
|
||||
You don't need to add the action to the touch bar before you can set it as
|
||||
escape action.
|
||||
*/
|
||||
void KDMacTouchBar::setEscapeAction(QAction *action)
|
||||
{
|
||||
if (d->escapeAction == action)
|
||||
return;
|
||||
if (d->escapeAction)
|
||||
[d->touchBarProvider removeItem:d->escapeAction];
|
||||
d->escapeAction = action;
|
||||
if (d->escapeAction) {
|
||||
[d->touchBarProvider addItem:d->escapeAction];
|
||||
d->touchBarProvider.touchBar.escapeKeyReplacementItemIdentifier =
|
||||
identifierForAction(action).toNSString();
|
||||
} else
|
||||
d->touchBarProvider.touchBar.escapeKeyReplacementItemIdentifier = nil;
|
||||
}
|
||||
|
||||
QAction *KDMacTouchBar::escapeAction() const
|
||||
{
|
||||
return d->escapeAction;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property KDMacTouchBar::touchButtonStyle
|
||||
This property holds the style of touch bar buttons.
|
||||
|
||||
This property defines the style of all touch buttons that are added as QActions.
|
||||
Added tab widgets, dialog button boxes, message boxes or QWidgetActions won't
|
||||
follow this style.
|
||||
|
||||
The default is KDMacTouchBar::TextBesideIcon
|
||||
*/
|
||||
void KDMacTouchBar::setTouchButtonStyle(TouchButtonStyle touchButtonStyle)
|
||||
{
|
||||
if (d->touchButtonStyle == touchButtonStyle)
|
||||
return;
|
||||
|
||||
d->touchButtonStyle = touchButtonStyle;
|
||||
|
||||
for (auto* action : actions())
|
||||
[d->touchBarProvider changeItem:action];
|
||||
if (d->escapeAction)
|
||||
[d->touchBarProvider changeItem:d->escapeAction];
|
||||
}
|
||||
|
||||
KDMacTouchBar::TouchButtonStyle KDMacTouchBar::touchButtonStyle() const
|
||||
{
|
||||
return d->touchButtonStyle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes all actions from the touch bar. Removes even the escapeAction.
|
||||
The principialAction is cleared.
|
||||
*/
|
||||
void KDMacTouchBar::clear()
|
||||
{
|
||||
setEscapeAction(nullptr);
|
||||
setPrincipialAction(nullptr);
|
||||
for (auto* action : actions())
|
||||
removeAction(action);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,33 +0,0 @@
|
||||
/****************************************************************************
|
||||
** Copyright (C) 2019-2021 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This file is part of the KD MacTouchBar library.
|
||||
**
|
||||
** This file may be distributed and/or modified under the terms of the
|
||||
** GNU Lesser General Public License version 3 as published by the
|
||||
** Free Software Foundation and appearing in the file LICENSE.LGPL.txt included.
|
||||
**
|
||||
** You may even contact us at info@kdab.com for different licensing options.
|
||||
**
|
||||
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
**
|
||||
** Contact info@kdab.com if any conditions of this licensing are not
|
||||
** clear to you.
|
||||
**
|
||||
**********************************************************************/
|
||||
#ifndef KDMACTOUCHBAR_GLOBAL_H
|
||||
#define KDMACTOUCHBAR_GLOBAL_H
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
#ifdef KDMACTOUCHBAR_BUILD_KDMACTOUCHBAR_LIB
|
||||
# define KDMACTOUCHBAR_EXPORT Q_DECL_EXPORT
|
||||
#elif defined(KDMACTOUCHBAR_BUILD_KDMACTOUCHBAR_SRC)
|
||||
# define KDMACTOUCHBAR_EXPORT
|
||||
#else
|
||||
# define KDMACTOUCHBAR_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#endif /* KDMACTOUCHBAR_GLOBAL_H */
|
@ -1,28 +0,0 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = KDMacTouchBar
|
||||
QT += widgets
|
||||
|
||||
include($${TOP_SOURCE_DIR}/kdmactouchbar.pri)
|
||||
|
||||
CONFIG += lib_bundle
|
||||
|
||||
DESTDIR = ../lib
|
||||
|
||||
SOURCES = kdmactouchbar.mm
|
||||
|
||||
HEADERS = kdmactouchbar.h kdmactouchbar_global.h
|
||||
|
||||
LIBS += -framework Cocoa
|
||||
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@rpath/
|
||||
|
||||
DEFINES += KDMACTOUCHBAR_BUILD_KDMACTOUCHBAR_LIB QT_NO_CAST_TO_ASCII QT_ASCII_CAST_WARNING
|
||||
|
||||
target.path = "$${INSTALL_PREFIX}/lib"
|
||||
|
||||
INSTALLS += target
|
||||
|
||||
FRAMEWORK_HEADERS.version = Versions
|
||||
FRAMEWORK_HEADERS.files = $$HEADERS
|
||||
FRAMEWORK_HEADERS.path = Headers
|
||||
QMAKE_BUNDLE_DATA += FRAMEWORK_HEADERS
|
||||
QMAKE_TARGET_BUNDLE_PREFIX = "com.kdab"
|
11
libs/Libraries.pri
vendored
11
libs/Libraries.pri
vendored
@ -49,14 +49,3 @@ include($$PWD/OpenSSL/OpenSSL.pri)
|
||||
include($$PWD/QRealFourier/QRealFourier.pri)
|
||||
include($$PWD/QSimpleUpdater/QSimpleUpdater.pri)
|
||||
include($$PWD/QSourceHighlite/QSourceHighlite.pri)
|
||||
|
||||
macx* {
|
||||
DEFINES += KDMACTOUCHBAR_BUILD_KDMACTOUCHBAR_SRC
|
||||
LIBS += -framework Cocoa
|
||||
INCLUDEPATH += $$PWD/KDMacTouchBar/src
|
||||
SOURCES += \
|
||||
$$PWD/KDMacTouchBar/src/kdmactouchbar.mm
|
||||
HEADERS += \
|
||||
$$PWD/KDMacTouchBar/src/kdmactouchbar.h \
|
||||
$$PWD/KDMacTouchBar/src/kdmactouchbar_global.h
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -16,239 +16,291 @@
|
||||
#ifdef VPAES_ASM
|
||||
int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
||||
int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
||||
void vpaes_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void vpaes_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void vpaes_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int enc);
|
||||
void vpaes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void vpaes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void vpaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, unsigned char *ivec,
|
||||
int enc);
|
||||
#endif /* VPAES_ASM */
|
||||
|
||||
#ifdef BSAES_ASM
|
||||
void ossl_bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char ivec[16], int enc);
|
||||
void ossl_bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, const unsigned char ivec[16]);
|
||||
void ossl_bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void ossl_bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void ossl_bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char ivec[16], int enc);
|
||||
void ossl_bsaes_ctr32_encrypt_blocks(const unsigned char *in,
|
||||
unsigned char *out, size_t len,
|
||||
const AES_KEY *key,
|
||||
const unsigned char ivec[16]);
|
||||
void ossl_bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void ossl_bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
|
||||
size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
#endif /* BSAES_ASM */
|
||||
|
||||
#ifdef AES_CTR_ASM
|
||||
void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]);
|
||||
void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
const unsigned char ivec[AES_BLOCK_SIZE]);
|
||||
#endif /* AES_CTR_ASM */
|
||||
|
||||
#ifdef AES_XTS_ASM
|
||||
void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
#endif /* AES_XTS_ASM */
|
||||
|
||||
#if defined(OPENSSL_CPUID_OBJ)
|
||||
# if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
|
||||
# include "crypto/ppc_arch.h"
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
|
||||
# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_p8_encrypt
|
||||
# define HWAES_decrypt aes_p8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
|
||||
# define HWAES_xts_encrypt aes_p8_xts_encrypt
|
||||
# define HWAES_xts_decrypt aes_p8_xts_decrypt
|
||||
# ifndef OPENSSL_SYS_AIX
|
||||
# define PPC_AES_GCM_CAPABLE (OPENSSL_ppccap_P & PPC_MADD300)
|
||||
# define AES_GCM_ENC_BYTES 128
|
||||
# define AES_GCM_DEC_BYTES 128
|
||||
size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
# define AES_GCM_ASM_PPC(gctx) \
|
||||
((gctx)->ctr == aes_p8_ctr32_encrypt_blocks \
|
||||
&& (gctx)->gcm.funcs.ghash == gcm_ghash_p8)
|
||||
void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len);
|
||||
# endif /* OPENSSL_SYS_AIX */
|
||||
# endif /* PPC */
|
||||
|
||||
# if (defined(__arm__) || defined(__arm) || defined(__aarch64__))
|
||||
# include "arm_arch.h"
|
||||
# if __ARM_MAX_ARCH__ >= 7
|
||||
# if defined(BSAES_ASM)
|
||||
# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# if defined(VPAES_ASM)
|
||||
# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
|
||||
# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_v8_encrypt
|
||||
# define HWAES_decrypt aes_v8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
|
||||
# define HWAES_ecb_encrypt aes_v8_ecb_encrypt
|
||||
# if __ARM_MAX_ARCH__ >= 8 && defined(__aarch64__)
|
||||
# define HWAES_xts_encrypt aes_v8_xts_encrypt
|
||||
# define HWAES_xts_decrypt aes_v8_xts_decrypt
|
||||
# endif
|
||||
# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
|
||||
# define AES_PMULL_CAPABLE \
|
||||
((OPENSSL_armcap_P & ARMV8_PMULL) && (OPENSSL_armcap_P & ARMV8_AES))
|
||||
# define AES_GCM_ENC_BYTES 512
|
||||
# define AES_GCM_DEC_BYTES 512
|
||||
# if __ARM_MAX_ARCH__ >= 8 && defined(__aarch64__)
|
||||
# define AES_gcm_encrypt armv8_aes_gcm_encrypt
|
||||
# define AES_gcm_decrypt armv8_aes_gcm_decrypt
|
||||
# define AES_GCM_ASM(gctx) \
|
||||
((gctx)->ctr == aes_v8_ctr32_encrypt_blocks \
|
||||
&& (gctx)->gcm.funcs.ghash == gcm_ghash_v8)
|
||||
size_t aes_gcm_enc_128_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_enc_192_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_enc_256_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_128_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_192_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_256_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_128_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16], const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_192_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16], const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_256_kernel(const uint8_t *plaintext, uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16], const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_128_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_192_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_256_kernel(const uint8_t *ciphertext, uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const void *key, unsigned char ivec[16], u64 *Xi);
|
||||
size_t armv8_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const void *key, unsigned char ivec[16], u64 *Xi);
|
||||
void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len);
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
|
||||
# include "crypto/ppc_arch.h"
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207)
|
||||
# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_p8_encrypt
|
||||
# define HWAES_decrypt aes_p8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
|
||||
# define HWAES_xts_encrypt aes_p8_xts_encrypt
|
||||
# define HWAES_xts_decrypt aes_p8_xts_decrypt
|
||||
# ifndef OPENSSL_SYS_AIX
|
||||
# define PPC_AES_GCM_CAPABLE (OPENSSL_ppccap_P & PPC_MADD300)
|
||||
# define AES_GCM_ENC_BYTES 128
|
||||
# define AES_GCM_DEC_BYTES 128
|
||||
size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key, unsigned char ivec[16],
|
||||
u64 *Xi);
|
||||
size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key, unsigned char ivec[16],
|
||||
u64 *Xi);
|
||||
# define AES_GCM_ASM_PPC(gctx) \
|
||||
((gctx)->ctr == aes_p8_ctr32_encrypt_blocks \
|
||||
&& (gctx)->gcm.funcs.ghash == gcm_ghash_p8)
|
||||
void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len);
|
||||
# endif /* OPENSSL_SYS_AIX */
|
||||
# endif /* PPC */
|
||||
|
||||
# if (defined(__arm__) || defined(__arm) || defined(__aarch64__))
|
||||
# include "arm_arch.h"
|
||||
# if __ARM_MAX_ARCH__ >= 7
|
||||
# if defined(BSAES_ASM)
|
||||
# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# if defined(VPAES_ASM)
|
||||
# define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
|
||||
# endif
|
||||
# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
|
||||
# define HWAES_set_encrypt_key aes_v8_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_v8_set_decrypt_key
|
||||
# define HWAES_encrypt aes_v8_encrypt
|
||||
# define HWAES_decrypt aes_v8_decrypt
|
||||
# define HWAES_cbc_encrypt aes_v8_cbc_encrypt
|
||||
# define HWAES_ecb_encrypt aes_v8_ecb_encrypt
|
||||
# if __ARM_MAX_ARCH__ >= 8 && defined(__aarch64__)
|
||||
# define HWAES_xts_encrypt aes_v8_xts_encrypt
|
||||
# define HWAES_xts_decrypt aes_v8_xts_decrypt
|
||||
# endif
|
||||
# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
|
||||
# define AES_PMULL_CAPABLE \
|
||||
((OPENSSL_armcap_P & ARMV8_PMULL) && (OPENSSL_armcap_P & ARMV8_AES))
|
||||
# define AES_GCM_ENC_BYTES 512
|
||||
# define AES_GCM_DEC_BYTES 512
|
||||
# if __ARM_MAX_ARCH__ >= 8 && defined(__aarch64__)
|
||||
# define AES_gcm_encrypt armv8_aes_gcm_encrypt
|
||||
# define AES_gcm_decrypt armv8_aes_gcm_decrypt
|
||||
# define AES_GCM_ASM(gctx) \
|
||||
((gctx)->ctr == aes_v8_ctr32_encrypt_blocks \
|
||||
&& (gctx)->gcm.funcs.ghash == gcm_ghash_v8)
|
||||
size_t aes_gcm_enc_128_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length, uint8_t *ciphertext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_enc_192_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length, uint8_t *ciphertext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_enc_256_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length, uint8_t *ciphertext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_128_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length, uint8_t *plaintext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_192_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length, uint8_t *plaintext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t aes_gcm_dec_256_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length, uint8_t *plaintext,
|
||||
uint64_t *Xi, unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_128_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_192_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_enc_256_kernel(const uint8_t *plaintext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *ciphertext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_128_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_192_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t unroll8_eor3_aes_gcm_dec_256_kernel(const uint8_t *ciphertext,
|
||||
uint64_t plaintext_length,
|
||||
uint8_t *plaintext, uint64_t *Xi,
|
||||
unsigned char ivec[16],
|
||||
const void *key);
|
||||
size_t armv8_aes_gcm_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
size_t armv8_aes_gcm_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp, size_t len);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif /* OPENSSL_CPUID_OBJ */
|
||||
|
||||
#if defined(AES_ASM) \
|
||||
&& (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64))
|
||||
# define AES_CBC_HMAC_SHA_CAPABLE 1
|
||||
# define AESNI_CBC_HMAC_SHA_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
|
||||
#if defined(AES_ASM) \
|
||||
&& (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
|
||||
|| defined(_M_X64))
|
||||
# define AES_CBC_HMAC_SHA_CAPABLE 1
|
||||
# define AESNI_CBC_HMAC_SHA_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
|
||||
#endif
|
||||
|
||||
#if defined(__loongarch__) || defined(__loongarch64)
|
||||
# include "loongarch_arch.h"
|
||||
# if defined(VPAES_ASM)
|
||||
# define VPAES_CAPABLE (OPENSSL_loongarchcap_P & LOONGARCH_CFG2_LSX)
|
||||
# endif
|
||||
# include "loongarch_arch.h"
|
||||
# if defined(VPAES_ASM)
|
||||
# define VPAES_CAPABLE (OPENSSL_loongarchcap_P & LOONGARCH_CFG2_LSX)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(AES_ASM) && !defined(I386_ONLY) \
|
||||
&& (((defined(__i386) || defined(__i386__) || defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2)) \
|
||||
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64))
|
||||
#if defined(AES_ASM) && !defined(I386_ONLY) \
|
||||
&& (((defined(__i386) || defined(__i386__) || defined(_M_IX86)) \
|
||||
&& defined(OPENSSL_IA32_SSE2)) \
|
||||
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
|
||||
|| defined(_M_X64))
|
||||
|
||||
/* AES-NI section */
|
||||
|
||||
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
|
||||
# endif
|
||||
# ifdef BSAES_ASM
|
||||
# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
|
||||
# endif
|
||||
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
|
||||
# ifdef VPAES_ASM
|
||||
# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
|
||||
# endif
|
||||
# ifdef BSAES_ASM
|
||||
# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
|
||||
# endif
|
||||
|
||||
# define AES_GCM_ENC_BYTES 32
|
||||
# define AES_GCM_DEC_BYTES 16
|
||||
# define AES_GCM_ENC_BYTES 32
|
||||
# define AES_GCM_DEC_BYTES 16
|
||||
|
||||
int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
||||
int aesni_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key);
|
||||
|
||||
void aesni_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void aesni_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void aesni_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void aesni_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
|
||||
void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, int enc);
|
||||
void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int enc);
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key,
|
||||
size_t start_block_num, unsigned char offset_i[16],
|
||||
const unsigned char L_[][16], unsigned char checksum[16]);
|
||||
void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key,
|
||||
size_t start_block_num, unsigned char offset_i[16],
|
||||
const unsigned char L_[][16], unsigned char checksum[16]);
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, int enc);
|
||||
void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, unsigned char *ivec,
|
||||
int enc);
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key, size_t start_block_num,
|
||||
unsigned char offset_i[16], const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key, size_t start_block_num,
|
||||
unsigned char offset_i[16], const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
|
||||
void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const void *key, const unsigned char *ivec);
|
||||
void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
const unsigned char *ivec);
|
||||
|
||||
void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void aesni_xts_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
|
||||
void aesni_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
void aesni_xts_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
|
||||
void aesni_ccm64_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const void *key, const unsigned char ivec[16],
|
||||
void aesni_ccm64_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
const unsigned char ivec[16],
|
||||
unsigned char cmac[16]);
|
||||
|
||||
void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const void *key, const unsigned char ivec[16],
|
||||
void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key,
|
||||
const unsigned char ivec[16],
|
||||
unsigned char cmac[16]);
|
||||
|
||||
# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
|
||||
size_t aesni_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
size_t aesni_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key,
|
||||
unsigned char ivec[16], u64 *Xi);
|
||||
# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
|
||||
|| defined(_M_X64)
|
||||
size_t aesni_gcm_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key, unsigned char ivec[16],
|
||||
u64 *Xi);
|
||||
size_t aesni_gcm_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key, unsigned char ivec[16],
|
||||
u64 *Xi);
|
||||
void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, size_t len);
|
||||
|
||||
# define AES_gcm_encrypt aesni_gcm_encrypt
|
||||
# define AES_gcm_decrypt aesni_gcm_decrypt
|
||||
# define AES_GCM_ASM(ctx) \
|
||||
(ctx->ctr == aesni_ctr32_encrypt_blocks && ctx->gcm.funcs.ghash == gcm_ghash_avx)
|
||||
# endif
|
||||
# define AES_gcm_encrypt aesni_gcm_encrypt
|
||||
# define AES_gcm_decrypt aesni_gcm_decrypt
|
||||
# define AES_GCM_ASM(ctx) \
|
||||
(ctx->ctr == aesni_ctr32_encrypt_blocks \
|
||||
&& ctx->gcm.funcs.ghash == gcm_ghash_avx)
|
||||
# endif
|
||||
|
||||
#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
|
||||
|
||||
/* Fujitsu SPARC64 X support */
|
||||
# include "crypto/sparc_arch.h"
|
||||
# include "crypto/sparc_arch.h"
|
||||
|
||||
# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
|
||||
# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
|
||||
# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
|
||||
# define HWAES_encrypt aes_fx_encrypt
|
||||
# define HWAES_decrypt aes_fx_decrypt
|
||||
# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
|
||||
# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
|
||||
# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
|
||||
# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
|
||||
# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
|
||||
# define HWAES_encrypt aes_fx_encrypt
|
||||
# define HWAES_decrypt aes_fx_decrypt
|
||||
# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
|
||||
# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
|
||||
|
||||
void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
|
||||
void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
|
||||
void aes_t4_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void aes_t4_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
/*
|
||||
* Key-length specific subroutines were chosen for following reason.
|
||||
* Each SPARC T4 core can execute up to 8 threads which share core's
|
||||
@ -260,165 +312,216 @@ void aes_t4_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *
|
||||
* acceptable, while latter means code size increase to size occupied
|
||||
* by multiple key-length specific subroutines, so why fight?
|
||||
*/
|
||||
void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const AES_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key, unsigned char *ivec);
|
||||
void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key, unsigned char *ivec);
|
||||
void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key, unsigned char *ivec);
|
||||
void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec,
|
||||
int /*unused*/);
|
||||
void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const AES_KEY *key1,
|
||||
const AES_KEY *key2, const unsigned char *ivec);
|
||||
|
||||
#elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
|
||||
/* IBM S390X support */
|
||||
# include "s390x_arch.h"
|
||||
# include "s390x_arch.h"
|
||||
|
||||
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */
|
||||
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
|
||||
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
|
||||
|
||||
/* Most modes of operation need km for partial block processing. */
|
||||
# define S390X_aes_128_CAPABLE (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_256))
|
||||
# define S390X_aes_128_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_256))
|
||||
|
||||
# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_cbc_CAPABLE 1
|
||||
# define S390X_aes_256_cbc_CAPABLE 1
|
||||
# define S390X_aes_128_cbc_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_cbc_CAPABLE 1
|
||||
# define S390X_aes_256_cbc_CAPABLE 1
|
||||
|
||||
# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE
|
||||
# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE
|
||||
# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE
|
||||
# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE
|
||||
# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE
|
||||
# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE
|
||||
|
||||
# define S390X_aes_128_ofb_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ofb_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ofb_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_aes_128_ofb_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ofb_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ofb_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
# define S390X_aes_128_cfb_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_cfb_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_cfb_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256))
|
||||
# define S390X_aes_128_cfb1_CAPABLE 0
|
||||
# define S390X_aes_192_cfb1_CAPABLE 0
|
||||
# define S390X_aes_256_cfb1_CAPABLE 0
|
||||
# define S390X_aes_128_cfb_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_cfb_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_cfb_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_aes_128_cfb8_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128))
|
||||
# define S390X_aes_192_cfb8_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192))
|
||||
# define S390X_aes_256_cfb8_CAPABLE \
|
||||
(OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256))
|
||||
# define S390X_aes_128_cfb1_CAPABLE 0
|
||||
# define S390X_aes_192_cfb1_CAPABLE 0
|
||||
# define S390X_aes_256_cfb1_CAPABLE 0
|
||||
|
||||
# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_ctr_CAPABLE 1
|
||||
# define S390X_aes_256_ctr_CAPABLE 1
|
||||
# define S390X_aes_128_ctr_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_192_ctr_CAPABLE 1
|
||||
# define S390X_aes_256_ctr_CAPABLE 1
|
||||
|
||||
# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_256_xts_CAPABLE 1
|
||||
# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */
|
||||
# define S390X_aes_256_xts_CAPABLE 1
|
||||
|
||||
# define S390X_aes_128_gcm_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_gcm_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_gcm_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_aes_128_gcm_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_gcm_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_gcm_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
|
||||
# define S390X_aes_128_ccm_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ccm_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ccm_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_CCM_AAD_FLAG 0x40
|
||||
# define S390X_aes_128_ccm_CAPABLE \
|
||||
(S390X_aes_128_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_128)))
|
||||
# define S390X_aes_192_ccm_CAPABLE \
|
||||
(S390X_aes_192_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_192)))
|
||||
# define S390X_aes_256_ccm_CAPABLE \
|
||||
(S390X_aes_256_CAPABLE \
|
||||
&& (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_256)))
|
||||
# define S390X_CCM_AAD_FLAG 0x40
|
||||
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
# define S390X_aes_128_ocb_CAPABLE 0
|
||||
# define S390X_aes_192_ocb_CAPABLE 0
|
||||
# define S390X_aes_256_ocb_CAPABLE 0
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
# define S390X_aes_128_ocb_CAPABLE 0
|
||||
# define S390X_aes_192_ocb_CAPABLE 0
|
||||
# define S390X_aes_256_ocb_CAPABLE 0
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
|
||||
# ifndef OPENSSL_NO_SIV
|
||||
# define S390X_aes_128_siv_CAPABLE 0
|
||||
# define S390X_aes_192_siv_CAPABLE 0
|
||||
# define S390X_aes_256_siv_CAPABLE 0
|
||||
# endif /* OPENSSL_NO_SIV */
|
||||
# ifndef OPENSSL_NO_SIV
|
||||
# define S390X_aes_128_siv_CAPABLE 0
|
||||
# define S390X_aes_192_siv_CAPABLE 0
|
||||
# define S390X_aes_256_siv_CAPABLE 0
|
||||
# endif /* OPENSSL_NO_SIV */
|
||||
|
||||
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */
|
||||
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
|
||||
# define S390X_AES_FC(keylen) (S390X_AES_128 + ((((keylen) << 3) - 128) >> 6))
|
||||
#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64
|
||||
/* RISC-V 64 support */
|
||||
# include "riscv_arch.h"
|
||||
# define RV64I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
|
||||
# include "riscv_arch.h"
|
||||
# define RV64I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
|
||||
|
||||
int rv64i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
int rv64i_zknd_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
void rv64i_zkne_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void rv64i_zknd_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
int rv64i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
int rv64i_zknd_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
void rv64i_zkne_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void rv64i_zknd_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
#elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32
|
||||
/* RISC-V 32 support */
|
||||
# include "riscv_arch.h"
|
||||
# define RV32I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
|
||||
# define RV32I_ZBKB_ZKND_ZKNE_CAPABLE (RV32I_ZKND_ZKNE_CAPABLE && RISCV_HAS_ZBKB())
|
||||
# include "riscv_arch.h"
|
||||
# define RV32I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
|
||||
# define RV32I_ZBKB_ZKND_ZKNE_CAPABLE \
|
||||
(RV32I_ZKND_ZKNE_CAPABLE && RISCV_HAS_ZBKB())
|
||||
|
||||
int rv32i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
int rv32i_zkne_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
/* set_decrypt_key needs both zknd and zkne */
|
||||
int rv32i_zknd_zkne_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
int rv32i_zbkb_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
int rv32i_zbkb_zknd_zkne_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
void rv32i_zkne_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void rv32i_zknd_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
int rv32i_zknd_zkne_set_decrypt_key(const unsigned char *userKey,
|
||||
const int bits, AES_KEY *key);
|
||||
int rv32i_zbkb_zkne_set_encrypt_key(const unsigned char *userKey,
|
||||
const int bits, AES_KEY *key);
|
||||
int rv32i_zbkb_zknd_zkne_set_decrypt_key(const unsigned char *userKey,
|
||||
const int bits, AES_KEY *key);
|
||||
void rv32i_zkne_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void rv32i_zknd_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
#endif
|
||||
|
||||
#if defined(HWAES_CAPABLE)
|
||||
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);
|
||||
void HWAES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void HWAES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
|
||||
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, const int enc);
|
||||
void HWAES_ecb_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, const int enc);
|
||||
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const void *key, const unsigned char ivec[16]);
|
||||
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key);
|
||||
void HWAES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void HWAES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key);
|
||||
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, unsigned char *ivec,
|
||||
const int enc);
|
||||
void HWAES_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, const int enc);
|
||||
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const void *key,
|
||||
const unsigned char ivec[16]);
|
||||
void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
|
||||
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]);
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
# ifdef HWAES_ocb_encrypt
|
||||
void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key,
|
||||
size_t start_block_num, unsigned char offset_i[16],
|
||||
const unsigned char L_[][16], unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_encrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# ifdef HWAES_ocb_decrypt
|
||||
void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key,
|
||||
size_t start_block_num, unsigned char offset_i[16],
|
||||
const unsigned char L_[][16], unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_decrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
const AES_KEY *key1, const AES_KEY *key2,
|
||||
const unsigned char iv[16]);
|
||||
# ifndef OPENSSL_NO_OCB
|
||||
# ifdef HWAES_ocb_encrypt
|
||||
void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key, size_t start_block_num,
|
||||
unsigned char offset_i[16], const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_encrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# ifdef HWAES_ocb_decrypt
|
||||
void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const void *key, size_t start_block_num,
|
||||
unsigned char offset_i[16], const unsigned char L_[][16],
|
||||
unsigned char checksum[16]);
|
||||
# else
|
||||
# define HWAES_ocb_decrypt ((ocb128_f)NULL)
|
||||
# endif
|
||||
# endif /* OPENSSL_NO_OCB */
|
||||
|
||||
#endif /* HWAES_CAPABLE */
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2017 National Security Research Institute. All rights reserved. */
|
||||
/* Copyright (c) 2017 National Security Research Institute. All rights
|
||||
* reserved. */
|
||||
|
||||
#ifndef OSSL_CRYPTO_ARIA_H
|
||||
#define OSSL_CRYPTO_ARIA_H
|
||||
@ -17,33 +18,36 @@
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_NO_ARIA
|
||||
# error ARIA is disabled.
|
||||
# error ARIA is disabled.
|
||||
#endif
|
||||
|
||||
#define ARIA_ENCRYPT 1
|
||||
#define ARIA_DECRYPT 0
|
||||
|
||||
#define ARIA_BLOCK_SIZE 16 /* Size of each encryption/decryption block */
|
||||
#define ARIA_MAX_KEYS 17 /* Number of keys needed in the worst case */
|
||||
#define ARIA_MAX_KEYS 17 /* Number of keys needed in the worst case */
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned char c[ARIA_BLOCK_SIZE];
|
||||
unsigned int u[ARIA_BLOCK_SIZE / sizeof(unsigned int)];
|
||||
unsigned char c[ARIA_BLOCK_SIZE];
|
||||
unsigned int u[ARIA_BLOCK_SIZE / sizeof(unsigned int)];
|
||||
} ARIA_u128;
|
||||
|
||||
typedef unsigned char ARIA_c128[ARIA_BLOCK_SIZE];
|
||||
|
||||
struct aria_key_st
|
||||
{
|
||||
ARIA_u128 rd_key[ARIA_MAX_KEYS];
|
||||
unsigned int rounds;
|
||||
ARIA_u128 rd_key[ARIA_MAX_KEYS];
|
||||
unsigned int rounds;
|
||||
};
|
||||
typedef struct aria_key_st ARIA_KEY;
|
||||
|
||||
int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits, ARIA_KEY *key);
|
||||
int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits, ARIA_KEY *key);
|
||||
int ossl_aria_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
ARIA_KEY *key);
|
||||
int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
ARIA_KEY *key);
|
||||
|
||||
void ossl_aria_encrypt(const unsigned char *in, unsigned char *out, const ARIA_KEY *key);
|
||||
void ossl_aria_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const ARIA_KEY *key);
|
||||
|
||||
#endif
|
||||
|
@ -22,59 +22,65 @@
|
||||
|
||||
struct evp_pkey_asn1_method_st
|
||||
{
|
||||
int pkey_id;
|
||||
int pkey_base_id;
|
||||
unsigned long pkey_flags;
|
||||
char *pem_str;
|
||||
char *info;
|
||||
int (*pub_decode)(EVP_PKEY *pk, const X509_PUBKEY *pub);
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
|
||||
int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf);
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
|
||||
int (*pkey_size)(const EVP_PKEY *pk);
|
||||
int (*pkey_bits)(const EVP_PKEY *pk);
|
||||
int (*pkey_security_bits)(const EVP_PKEY *pk);
|
||||
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_missing)(const EVP_PKEY *pk);
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
|
||||
int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent,
|
||||
int pkey_id;
|
||||
int pkey_base_id;
|
||||
unsigned long pkey_flags;
|
||||
char *pem_str;
|
||||
char *info;
|
||||
int (*pub_decode)(EVP_PKEY *pk, const X509_PUBKEY *pub);
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
|
||||
int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf);
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
int (*pkey_size)(const EVP_PKEY *pk);
|
||||
int (*pkey_bits)(const EVP_PKEY *pk);
|
||||
int (*pkey_security_bits)(const EVP_PKEY *pk);
|
||||
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_missing)(const EVP_PKEY *pk);
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
/* Legacy functions for old PEM */
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
/* Custom ASN1 signature verification */
|
||||
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, const X509_ALGOR *a,
|
||||
const ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
|
||||
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, X509_ALGOR *alg1,
|
||||
X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
|
||||
int (*siginf_set)(X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig);
|
||||
/* Check */
|
||||
int (*pkey_check)(const EVP_PKEY *pk);
|
||||
int (*pkey_public_check)(const EVP_PKEY *pk);
|
||||
int (*pkey_param_check)(const EVP_PKEY *pk);
|
||||
/* Get/set raw private/public key data */
|
||||
int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *priv, size_t len);
|
||||
int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *pub, size_t len);
|
||||
int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *priv, size_t *len);
|
||||
int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *pub, size_t *len);
|
||||
int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
|
||||
int indent, ASN1_PCTX *pctx);
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
/* Legacy functions for old PEM */
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
|
||||
int derlen);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
/* Custom ASN1 signature verification */
|
||||
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
|
||||
const X509_ALGOR *a, const ASN1_BIT_STRING *sig,
|
||||
EVP_PKEY *pkey);
|
||||
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
|
||||
int (*siginf_set)(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig);
|
||||
/* Check */
|
||||
int (*pkey_check)(const EVP_PKEY *pk);
|
||||
int (*pkey_public_check)(const EVP_PKEY *pk);
|
||||
int (*pkey_param_check)(const EVP_PKEY *pk);
|
||||
/* Get/set raw private/public key data */
|
||||
int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *priv, size_t len);
|
||||
int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *pub, size_t len);
|
||||
int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *priv, size_t *len);
|
||||
int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *pub, size_t *len);
|
||||
|
||||
/* Exports and imports to / from providers */
|
||||
size_t (*dirty_cnt)(const EVP_PKEY *pk);
|
||||
int (*export_to)(const EVP_PKEY *pk, void *to_keydata, OSSL_FUNC_keymgmt_import_fn *importer,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
OSSL_CALLBACK *import_from;
|
||||
int (*copy)(EVP_PKEY *to, EVP_PKEY *from);
|
||||
/* Exports and imports to / from providers */
|
||||
size_t (*dirty_cnt)(const EVP_PKEY *pk);
|
||||
int (*export_to)(const EVP_PKEY *pk, void *to_keydata,
|
||||
OSSL_FUNC_keymgmt_import_fn *importer, OSSL_LIB_CTX *libctx,
|
||||
const char *propq);
|
||||
OSSL_CALLBACK *import_from;
|
||||
int (*copy)(EVP_PKEY *to, EVP_PKEY *from);
|
||||
|
||||
int (*priv_decode_ex)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf, OSSL_LIB_CTX *libctx,
|
||||
const char *propq);
|
||||
int (*priv_decode_ex)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
} /* EVP_PKEY_ASN1_METHOD */;
|
||||
|
||||
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
|
||||
@ -96,35 +102,36 @@ extern const EVP_PKEY_ASN1_METHOD ossl_rsa_pss_asn1_meth;
|
||||
* These are used internally in the ASN1_OBJECT to keep track of whether the
|
||||
* names and data need to be free()ed
|
||||
*/
|
||||
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
|
||||
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
|
||||
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
|
||||
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
|
||||
#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
|
||||
#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
|
||||
#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
|
||||
struct asn1_object_st
|
||||
{
|
||||
const char *sn, *ln;
|
||||
int nid;
|
||||
int length;
|
||||
const unsigned char *data; /* data remains const after init */
|
||||
int flags; /* Should we free this one */
|
||||
const char *sn, *ln;
|
||||
int nid;
|
||||
int length;
|
||||
const unsigned char *data; /* data remains const after init */
|
||||
int flags; /* Should we free this one */
|
||||
};
|
||||
|
||||
/* ASN1 print context structure */
|
||||
|
||||
struct asn1_pctx_st
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long nm_flags;
|
||||
unsigned long cert_flags;
|
||||
unsigned long oid_flags;
|
||||
unsigned long str_flags;
|
||||
unsigned long flags;
|
||||
unsigned long nm_flags;
|
||||
unsigned long cert_flags;
|
||||
unsigned long oid_flags;
|
||||
unsigned long str_flags;
|
||||
} /* ASN1_PCTX */;
|
||||
|
||||
/* ASN1 type functions */
|
||||
|
||||
int ossl_asn1_type_set_octetstring_int(ASN1_TYPE *a, long num, unsigned char *data, int len);
|
||||
int ossl_asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, unsigned char *data,
|
||||
int max_len);
|
||||
int ossl_asn1_type_set_octetstring_int(ASN1_TYPE *a, long num,
|
||||
unsigned char *data, int len);
|
||||
int ossl_asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num,
|
||||
unsigned char *data, int max_len);
|
||||
|
||||
int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md);
|
||||
const EVP_MD *ossl_x509_algor_get_md(X509_ALGOR *alg);
|
||||
@ -132,8 +139,9 @@ X509_ALGOR *ossl_x509_algor_mgf1_decode(X509_ALGOR *alg);
|
||||
int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md);
|
||||
int ossl_asn1_time_print_ex(BIO *bp, const ASN1_TIME *tm, unsigned long flags);
|
||||
|
||||
EVP_PKEY *ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a, const unsigned char **pp,
|
||||
long length, OSSL_LIB_CTX *libctx, const char *propq);
|
||||
EVP_PKEY *ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a,
|
||||
const unsigned char **pp, long length,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval);
|
||||
|
||||
time_t ossl_asn1_string_to_time_t(const char *asn1_string);
|
||||
|
@ -18,6 +18,7 @@ int ossl_encode_der_integer(WPACKET *pkt, const BIGNUM *n);
|
||||
int ossl_encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s);
|
||||
int ossl_decode_der_length(PACKET *pkt, PACKET *subpkt);
|
||||
int ossl_decode_der_integer(PACKET *pkt, BIGNUM *n);
|
||||
size_t ossl_decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, size_t len);
|
||||
size_t ossl_decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin,
|
||||
size_t len);
|
||||
|
||||
#endif
|
||||
|
@ -71,35 +71,44 @@ int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words);
|
||||
* is constant-time by itself. They all have pre-conditions, consult source
|
||||
* code...
|
||||
*/
|
||||
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx);
|
||||
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx);
|
||||
int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx);
|
||||
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
|
||||
int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
|
||||
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mont, BN_CTX *ctx);
|
||||
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx);
|
||||
int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx);
|
||||
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m);
|
||||
int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m);
|
||||
int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
|
||||
int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
|
||||
int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
|
||||
int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
|
||||
int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
|
||||
int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
|
||||
BN_CTX *ctx);
|
||||
|
||||
#define BN_PRIMETEST_COMPOSITE 0
|
||||
#define BN_PRIMETEST_COMPOSITE_WITH_FACTOR 1
|
||||
#define BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME 2
|
||||
#define BN_PRIMETEST_PROBABLY_PRIME 3
|
||||
|
||||
int ossl_bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx, BN_GENCB *cb,
|
||||
int enhanced, int *status);
|
||||
int ossl_bn_check_generated_prime(const BIGNUM *w, int checks, BN_CTX *ctx, BN_GENCB *cb);
|
||||
int ossl_bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx,
|
||||
BN_GENCB *cb, int enhanced, int *status);
|
||||
int ossl_bn_check_generated_prime(const BIGNUM *w, int checks, BN_CTX *ctx,
|
||||
BN_GENCB *cb);
|
||||
|
||||
const BIGNUM *ossl_bn_get0_small_factors(void);
|
||||
|
||||
int ossl_bn_rsa_fips186_4_gen_prob_primes(BIGNUM *p, BIGNUM *Xpout, BIGNUM *p1, BIGNUM *p2,
|
||||
const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
|
||||
int nlen, const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
|
||||
int ossl_bn_rsa_fips186_4_gen_prob_primes(BIGNUM *p, BIGNUM *Xpout, BIGNUM *p1,
|
||||
BIGNUM *p2, const BIGNUM *Xp,
|
||||
const BIGNUM *Xp1, const BIGNUM *Xp2,
|
||||
int nlen, const BIGNUM *e,
|
||||
BN_CTX *ctx, BN_GENCB *cb);
|
||||
|
||||
int ossl_bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, const BIGNUM *r1,
|
||||
const BIGNUM *r2, int nlen, const BIGNUM *e, BN_CTX *ctx,
|
||||
int ossl_bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin,
|
||||
const BIGNUM *r1, const BIGNUM *r2,
|
||||
int nlen, const BIGNUM *e, BN_CTX *ctx,
|
||||
BN_GENCB *cb);
|
||||
|
||||
OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx);
|
||||
|
@ -7,10 +7,10 @@
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#define declare_dh_bn(x) \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_p; \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_q; \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_g;
|
||||
#define declare_dh_bn(x) \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_p; \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_q; \
|
||||
extern const BIGNUM ossl_bignum_dh##x##_g;
|
||||
|
||||
declare_dh_bn(1024_160) declare_dh_bn(2048_224) declare_dh_bn(2048_256)
|
||||
|
||||
|
@ -31,9 +31,9 @@ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len,
|
||||
* as trivial as collecting bytes into 32-bit elements, it's reckoned
|
||||
* that below macro is sufficient.
|
||||
*/
|
||||
#define CHACHA_U8TOU32(p) \
|
||||
(((unsigned int)(p)[0]) | ((unsigned int)(p)[1] << 8) | ((unsigned int)(p)[2] << 16) \
|
||||
| ((unsigned int)(p)[3] << 24))
|
||||
#define CHACHA_U8TOU32(p) \
|
||||
(((unsigned int)(p)[0]) | ((unsigned int)(p)[1] << 8) \
|
||||
| ((unsigned int)(p)[2] << 16) | ((unsigned int)(p)[3] << 24))
|
||||
|
||||
#define CHACHA_KEY_SIZE 32
|
||||
#define CHACHA_CTR_SIZE 16
|
||||
|
@ -14,29 +14,37 @@
|
||||
#if defined(CMLL_ASM) && (defined(__sparc) || defined(__sparc__))
|
||||
|
||||
/* Fujitsu SPARC64 X support */
|
||||
# include "crypto/sparc_arch.h"
|
||||
# include "crypto/sparc_arch.h"
|
||||
|
||||
# ifndef OPENSSL_NO_CAMELLIA
|
||||
# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
|
||||
# include <openssl/camellia.h>
|
||||
# ifndef OPENSSL_NO_CAMELLIA
|
||||
# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
|
||||
# include <openssl/camellia.h>
|
||||
|
||||
void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
|
||||
void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key);
|
||||
void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key);
|
||||
void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const CAMELLIA_KEY *key);
|
||||
void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const CAMELLIA_KEY *key);
|
||||
|
||||
void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/);
|
||||
void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec);
|
||||
void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks,
|
||||
const CAMELLIA_KEY *key, unsigned char *ivec);
|
||||
# endif /* OPENSSL_NO_CAMELLIA */
|
||||
void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec, int /*unused*/);
|
||||
void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec, int /*unused*/);
|
||||
void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec, int /*unused*/);
|
||||
void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec, int /*unused*/);
|
||||
void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t blocks, const CAMELLIA_KEY *key,
|
||||
unsigned char *ivec);
|
||||
# endif /* OPENSSL_NO_CAMELLIA */
|
||||
|
||||
#endif /* CMLL_ASM && sparc */
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
/* This file is not scanned by mkdef.pl, whereas cryptlib.h is */
|
||||
|
||||
int ossl_init_thread_start(const void *index, void *arg, OSSL_thread_stop_handler_fn handfn);
|
||||
int ossl_init_thread_start(const void *index, void *arg,
|
||||
OSSL_thread_stop_handler_fn handfn);
|
||||
int ossl_init_thread_deregister(void *index);
|
||||
int ossl_init_thread(void);
|
||||
void ossl_cleanup_thread(void);
|
||||
@ -32,6 +33,7 @@ void ossl_ctx_thread_stop(OSSL_LIB_CTX *ctx);
|
||||
void ossl_trace_cleanup(void);
|
||||
void ossl_malloc_setup_failures(void);
|
||||
|
||||
int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj, CRYPTO_EX_DATA *ad, int idx);
|
||||
int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj,
|
||||
CRYPTO_EX_DATA *ad, int idx);
|
||||
|
||||
#endif /* OSSL_CRYPTO_CRYPTLIB_H */
|
||||
|
@ -53,8 +53,8 @@
|
||||
int ossl_toascii(int c);
|
||||
int ossl_fromascii(int c);
|
||||
#else
|
||||
# define ossl_toascii(c) (c)
|
||||
# define ossl_fromascii(c) (c)
|
||||
# define ossl_toascii(c) (c)
|
||||
# define ossl_fromascii(c) (c)
|
||||
#endif
|
||||
int ossl_ctype_check(int c, unsigned int mask);
|
||||
|
||||
@ -70,9 +70,9 @@ int ossl_ascii_isdigit(int c);
|
||||
#define ossl_isalnum(c) (ossl_ctype_check((c), CTYPE_MASK_alnum))
|
||||
#define ossl_isalpha(c) (ossl_ctype_check((c), CTYPE_MASK_alpha))
|
||||
#ifdef CHARSET_EBCDIC
|
||||
# define ossl_isascii(c) (ossl_ctype_check((c), CTYPE_MASK_ascii))
|
||||
# define ossl_isascii(c) (ossl_ctype_check((c), CTYPE_MASK_ascii))
|
||||
#else
|
||||
# define ossl_isascii(c) (((c) & ~127) == 0)
|
||||
# define ossl_isascii(c) (((c) & ~127) == 0)
|
||||
#endif
|
||||
#define ossl_isblank(c) (ossl_ctype_check((c), CTYPE_MASK_blank))
|
||||
#define ossl_iscntrl(c) (ossl_ctype_check((c), CTYPE_MASK_cntrl))
|
||||
|
@ -19,14 +19,18 @@
|
||||
* except read a DER blob and pass it on as a provider object abstraction
|
||||
* (provider-object(7)).
|
||||
*/
|
||||
void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef, OSSL_PROVIDER *prov);
|
||||
void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
|
||||
OSSL_PROVIDER *prov);
|
||||
|
||||
OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx);
|
||||
OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder,
|
||||
void *decoderctx);
|
||||
void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst);
|
||||
int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, OSSL_DECODER_INSTANCE *di);
|
||||
int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx,
|
||||
OSSL_DECODER_INSTANCE *di);
|
||||
|
||||
int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, EVP_PKEY **pkey, const char *keytype,
|
||||
OSSL_LIB_CTX *libctx, const char *propquery);
|
||||
int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, EVP_PKEY **pkey,
|
||||
const char *keytype, OSSL_LIB_CTX *libctx,
|
||||
const char *propquery);
|
||||
|
||||
int ossl_decoder_get_number(const OSSL_DECODER *encoder);
|
||||
int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx);
|
||||
|
@ -14,21 +14,21 @@
|
||||
#if defined(DES_ASM) && (defined(__sparc) || defined(__sparc__))
|
||||
|
||||
/* Fujitsu SPARC64 X support */
|
||||
# include "crypto/sparc_arch.h"
|
||||
# include "crypto/sparc_arch.h"
|
||||
|
||||
# ifndef OPENSSL_NO_DES
|
||||
# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
|
||||
# include <openssl/des.h>
|
||||
# ifndef OPENSSL_NO_DES
|
||||
# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
|
||||
# include <openssl/des.h>
|
||||
void des_t4_key_expand(const void *key, DES_key_schedule *ks);
|
||||
void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, const DES_key_schedule ks[3],
|
||||
unsigned char iv[8]);
|
||||
void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, const DES_key_schedule ks[3],
|
||||
unsigned char iv[8]);
|
||||
void des_t4_cbc_encrypt(const void *inp, void *out, size_t len, const DES_key_schedule *ks,
|
||||
unsigned char iv[8]);
|
||||
void des_t4_cbc_decrypt(const void *inp, void *out, size_t len, const DES_key_schedule *ks,
|
||||
unsigned char iv[8]);
|
||||
# endif /* OPENSSL_NO_DES */
|
||||
void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
|
||||
const DES_key_schedule ks[3], unsigned char iv[8]);
|
||||
void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
|
||||
const DES_key_schedule ks[3], unsigned char iv[8]);
|
||||
void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
|
||||
const DES_key_schedule *ks, unsigned char iv[8]);
|
||||
void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
|
||||
const DES_key_schedule *ks, unsigned char iv[8]);
|
||||
# endif /* OPENSSL_NO_DES */
|
||||
|
||||
#endif /* DES_ASM && sparc */
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user