Format code, update to Qt 6.7.0 & attend issue #189

This commit is contained in:
Alex Spataru 2024-05-05 00:20:10 -05:00
parent d4f7fbc0e3
commit 2684acaec5
669 changed files with 88632 additions and 88731 deletions

View File

@ -1,39 +1,24 @@
# Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> BasedOnStyle: LLVM
# Standard: Cpp11
# You may use this file under the terms of the 3-clause BSD license. CommentPragmas: "^!|^:"
# See the file LICENSE from this package for details. 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: BraceWrapping:
AfterClass: true AfterClass: true
AfterControlStatement: true AfterControlStatement: true
@ -47,48 +32,7 @@ BraceWrapping:
BeforeElse: true BeforeElse: true
IndentBraces: false 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 ] 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'] #StatementMacros ['Q_OBJECT', 'Q_UNUSED']
ColumnLimit: 90

56
.clang-tidy Normal file
View 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

View File

@ -1,6 +1,6 @@
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Workflow configuration # Workflow configuration
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
name: Deploy name: Deploy
on: on:
@ -12,9 +12,9 @@ on:
paths-ignore: # File-patterns to ignore paths-ignore: # File-patterns to ignore
- '**.md' # Ignore changes to *.md files - '**.md' # Ignore changes to *.md files
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Define application name & version # Define application name & version
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
env: env:
VERSION: "2.0.0" VERSION: "2.0.0"
@ -26,14 +26,14 @@ env:
QML_DIR_WIN: "assets\\qml" QML_DIR_WIN: "assets\\qml"
PUBLISHER: "Alex Spataru" PUBLISHER: "Alex Spataru"
REPO_DIR: "/home/runner/work/Serial-Studio" REPO_DIR: "/home/runner/work/Serial-Studio"
QT_VERSION: 6.6.2 QT_VERSION: 6.7.0
QT_MODULES: qtserialport qtconnectivity qt5compat qtpositioning qtlocation QT_MODULES: qtserialport qtconnectivity qtpositioning qtlocation
QMAKE: qmake6 QMAKE: qmake6
CORES: 16 CORES: 16
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Workflow jobs (GNU/Linux, macOS & Windows) # Workflow jobs (GNU/Linux, macOS & Windows)
#-------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
jobs: jobs:
# #
@ -60,12 +60,15 @@ jobs:
- name: '⚙️ Install dependencies' - name: '⚙️ Install dependencies'
run: | run: |
sudo apt-get update 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' - name: '🚧 Compile application'
run: | run: |
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr ${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr
make -j${{env.CORES}} make -j${{env.CORES}}
- name: '⚙️ Install linuxdeploy' - name: '⚙️ Install linuxdeploy'
run: | run: |
@ -109,24 +112,58 @@ jobs:
version: ${{env.QT_VERSION}} version: ${{env.QT_VERSION}}
modules: ${{env.QT_MODULES}} modules: ${{env.QT_MODULES}}
cache: true cache: true
arch: clang_64
install-deps: 'true' install-deps: 'true'
- name: '⚙️ Install Node'
uses: actions/setup-node@v4
with:
node-version: 20
- name: '🚧 Compile application' - name: '🚧 Compile application'
run: | run: |
${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release PREFIX=/usr ${{env.QMAKE}} ${{env.QMAKE_PROJECT}} CONFIG+=release
make -j${{env.CORES}} make -j${{env.CORES}}
- name: '📦 Package application (macdeployqt and zipfile)' - name: '📦 Package application'
run: | run: |
macdeployqt ${{env.EXECUTABLE}}.app -qmldir="${{env.QML_DIR_NIX}}" macdeployqt ${{env.EXECUTABLE}}.app -qmldir="${{env.QML_DIR_NIX}}"
mv "${{env.EXECUTABLE}}.app" "${{env.APPLICATION}}.app" 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' - name: '🪪 Import Code Signing Certificate'
uses: actions/upload-artifact@v2 uses: apple-actions/import-codesign-certs@v2
with: with:
name: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip p12-file-base64: ${{secrets.CERTIFICATES_P12}}
path: ${{env.EXECUTABLE}}-${{env.VERSION}}-macOS.zip 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 # Windows build
@ -259,7 +296,9 @@ jobs:
name: msys2-pkgs name: msys2-pkgs
path: msys2/*.zst path: msys2/*.zst
#
# Test Windows MSYS2 packages # Test Windows MSYS2 packages
#
msys2-test: msys2-test:
if: ${{false}} if: ${{false}}
needs: msys2-makepkg needs: msys2-makepkg
@ -324,6 +363,6 @@ jobs:
wget -q https://github.com/TheAssassin/pyuploadtool/releases/download/continuous/pyuploadtool-x86_64.AppImage wget -q https://github.com/TheAssassin/pyuploadtool/releases/download/continuous/pyuploadtool-x86_64.AppImage
chmod +x 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}}-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.exe
./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-Windows.zip ./pyuploadtool-x86_64.AppImage **/${{env.EXECUTABLE}}-${{env.VERSION}}-Windows.zip

12
.gitignore vendored
View File

@ -4,8 +4,11 @@
.AppleDouble .AppleDouble
.LSOverride .LSOverride
# SciTools understand # Build & IDEs
Serial-Studio.und *.kdev*
build/*
*.vscode
*.layout
# Icon must end with two \r # Icon must end with two \r
Icon Icon
@ -31,3 +34,8 @@ Temporary Items
# Qt project file # Qt project file
*.pro.user *.pro.user
*.user
# Clion
.idea/*
cmake-build-*

View File

@ -20,9 +20,9 @@
# THE SOFTWARE. # THE SOFTWARE.
# #
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Make options # Make options
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
UI_DIR = uic UI_DIR = uic
MOC_DIR = moc MOC_DIR = moc
@ -33,15 +33,15 @@ isEmpty(PREFIX) {
PREFIX = /usr PREFIX = /usr
} }
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Qt configuration # Qt configuration
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
TEMPLATE = app # Project template TEMPLATE = app
TARGET = serial-studio # Set default target name TARGET = serial-studio
CONFIG += qtquickcompiler # Pre-compile QML interface CONFIG += qtquickcompiler
CONFIG += utf8_source # Source code encoding CONFIG += utf8_source
QTPLUGIN += qsvg # Fixes issues with windeployqt QTPLUGIN += qsvg
QT += xml QT += xml
QT += svg QT += svg
@ -56,15 +56,9 @@ QT += printsupport
QT += quickcontrols2 QT += quickcontrols2
equals(QT_MAJOR_VERSION, 6) { #-------------------------------------------------------------------------------
QT += core5compat
}
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x050F00
#-----------------------------------------------------------------------------------------
# Compiler options # Compiler options
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
CONFIG += c++11 CONFIG += c++11
CONFIG += silent CONFIG += silent
@ -79,68 +73,64 @@ CONFIG(release, debug|release) {
} }
} }
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Serial Studio compile-time settings # 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 # Libraries
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
include(libs/Libraries.pri) include(libs/Libraries.pri)
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Assets # Assets
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
include(assets/Assets.pri) include(assets/Assets.pri)
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Deploy options # Deploy options
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
win32* { win32* {
TARGET = SerialStudio # Change target name TARGET = SerialStudio
RC_FILE = deploy/windows/resources/info.rc # Set applicaiton icon RC_FILE = deploy/windows/resources/info.rc
OTHER_FILES += deploy/windows/nsis/setup.nsi # Setup script OTHER_FILES += deploy/windows/nsis/setup.nsi
} }
macx* { macx* {
TARGET = SerialStudio # Change target name TARGET = SerialStudio
ICON = deploy/macOS/icon.icns # icon file ICON = deploy/macOS/icon.icns
RC_FILE = deploy/macOS/icon.icns # icon file RC_FILE = deploy/macOS/icon.icns
QMAKE_INFO_PLIST = deploy/macOS/info.plist # Add info.plist file QMAKE_INFO_PLIST = deploy/macOS/info.plist
CONFIG += sdk_no_version_check # Avoid warnings with Big Sur CONFIG += sdk_no_version_check
} }
linux:!android { linux:!android {
PKGCONFIG += libssl # Add OpenSSL library PKGCONFIG += libssl
target.path = $$PREFIX/bin # Set binary installation path target.path = $$PREFIX/bin
icon.path = $$PREFIX/share/pixmaps # icon instalation path icon.path = $$PREFIX/share/pixmaps
desktop.path = $$PREFIX/share/applications # *.desktop instalation path desktop.path = $$PREFIX/share/applications
icon.files += deploy/linux/serial-studio.png # Add application icon icon.files += deploy/linux/serial-studio.png
desktop.files += deploy/linux/serial-studio.desktop # Add *.desktop file desktop.files += deploy/linux/serial-studio.desktop
copyright.files += deploy/linux/copyright # Libc6 file for linuxdeployqt INSTALLS += target copyright desktop icon
copyright.path = $$PREFIX/share/doc/libc6 # libc6 copyright path
INSTALLS += target copyright desktop icon # make install targets
} }
mingw { mingw {
target.path = $$PREFIX/bin target.path = $$PREFIX/bin
license.path = $$PREFIX/share/licenses/$$TARGET # Set license install path license.path = $$PREFIX/share/licenses/$$TARGET
license.files += LICENSE.md # Add LICENSE.md file license.files += LICENSE.md
INSTALLS += target license # Install target+licence (MSYS2) INSTALLS += target license
DEFINES += DISABLE_QSU # Disable QSimpleUpdater (MSYS2) DEFINES += DISABLE_QSU
} }
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Import source code # Import source code
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
INCLUDEPATH += src INCLUDEPATH += src
@ -161,7 +151,6 @@ HEADERS += \
src/JSON/Generator.h \ src/JSON/Generator.h \
src/JSON/Group.h \ src/JSON/Group.h \
src/MQTT/Client.h \ src/MQTT/Client.h \
src/Misc/MacExtras.h \
src/Misc/ModuleManager.h \ src/Misc/ModuleManager.h \
src/Misc/ThemeManager.h \ src/Misc/ThemeManager.h \
src/Misc/TimerEvents.h \ src/Misc/TimerEvents.h \
@ -205,7 +194,6 @@ SOURCES += \
src/JSON/Generator.cpp \ src/JSON/Generator.cpp \
src/JSON/Group.cpp \ src/JSON/Group.cpp \
src/MQTT/Client.cpp \ src/MQTT/Client.cpp \
src/Misc/MacExtras.cpp \
src/Misc/ModuleManager.cpp \ src/Misc/ModuleManager.cpp \
src/Misc/ThemeManager.cpp \ src/Misc/ThemeManager.cpp \
src/Misc/TimerEvents.cpp \ src/Misc/TimerEvents.cpp \
@ -236,9 +224,9 @@ SOURCES += \
src/UI/Widgets/Terminal.cpp \ src/UI/Widgets/Terminal.cpp \
src/main.cpp src/main.cpp
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Import QML source code # Import QML source code
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
DISTFILES += \ DISTFILES += \
assets/qml/*.qml \ assets/qml/*.qml \
@ -252,9 +240,9 @@ DISTFILES += \
assets/qml/PlatformDependent/*.qml \ assets/qml/PlatformDependent/*.qml \
assets/qml/Panes/SetupPanes/Devices/*.qml \ assets/qml/Panes/SetupPanes/Devices/*.qml \
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Deploy files # Deploy files
#----------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
OTHER_FILES += \ OTHER_FILES += \
deploy/linux/* \ deploy/linux/* \

View File

@ -57,6 +57,7 @@
<file>icons/multiplot.svg</file> <file>icons/multiplot.svg</file>
<file>icons/new.svg</file> <file>icons/new.svg</file>
<file>icons/open.svg</file> <file>icons/open.svg</file>
<file>icons/paste.svg</file>
<file>icons/plot.svg</file> <file>icons/plot.svg</file>
<file>icons/points.svg</file> <file>icons/points.svg</file>
<file>icons/power.svg</file> <file>icons/power.svg</file>
@ -131,6 +132,7 @@
<file>qml/ProjectEditor/JsonDatasetDelegate.qml</file> <file>qml/ProjectEditor/JsonDatasetDelegate.qml</file>
<file>qml/ProjectEditor/JsonGroupDelegate.qml</file> <file>qml/ProjectEditor/JsonGroupDelegate.qml</file>
<file>qml/ProjectEditor/TreeView.qml</file> <file>qml/ProjectEditor/TreeView.qml</file>
<file>qml/Widgets/GpsMap.qml</file>
<file>qml/Widgets/Icon.qml</file> <file>qml/Widgets/Icon.qml</file>
<file>qml/Widgets/JSONDropArea.qml</file> <file>qml/Widgets/JSONDropArea.qml</file>
<file>qml/Widgets/Shadow.qml</file> <file>qml/Widgets/Shadow.qml</file>
@ -144,15 +146,13 @@
<file>qml/Windows/MQTTConfiguration.qml</file> <file>qml/Windows/MQTTConfiguration.qml</file>
<file>qml/Windows/ProjectEditor.qml</file> <file>qml/Windows/ProjectEditor.qml</file>
<file>qml/main.qml</file> <file>qml/main.qml</file>
<file>scripts/frame-parser.js</file>
<file>themes/1_Flat.json</file> <file>themes/1_Flat.json</file>
<file>themes/2_Dark.json</file> <file>themes/2_Dark.json</file>
<file>themes/3_Classic.json</file> <file>themes/3_Classic.json</file>
<file>themes/4_Midnight.json</file> <file>themes/4_Midnight.json</file>
<file>themes/5_Noir.json</file> <file>themes/5_Noir.json</file>
<file>themes/6_Mathworks.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.qm</file>
<file>translations/de.ts</file> <file>translations/de.ts</file>
<file>translations/en.qm</file> <file>translations/en.qm</file>
@ -178,8 +178,5 @@
<file>window-border/minimize.svg</file> <file>window-border/minimize.svg</file>
<file>window-border/restore.svg</file> <file>window-border/restore.svg</file>
<file>window-border/unmaximize.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> </qresource>
</RCC> </RCC>

View File

@ -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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. 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 ## qtcsv
Copyright © 2015 Antony Cherepanov (antony.cherepanov@gmail.com) 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. 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 ### GNU Lesser General Public License

View File

@ -24,5 +24,5 @@ MCU-Projekten, lesen Sie bitte das Wiki:
→ https://github.com/Serial-Studio/Serial-Studio/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. Serial Studio-Projektdateien.

View File

@ -22,4 +22,4 @@ the wiki:
→ https://github.com/Serial-Studio/Serial-Studio/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.

View File

@ -22,4 +22,4 @@ actuales, por favor lea la wiki:
→ https://github.com/Serial-Studio/Serial-Studio/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.

View File

@ -28,69 +28,69 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Rectangle { Rectangle {
id: root id: root
radius: 5 radius: 5
property alias consoleChecked: consoleBt.checked property alias consoleChecked: consoleBt.checked
Settings { Settings {
property alias consoleVisible: root.consoleChecked property alias consoleVisible: root.consoleChecked
}
gradient: Gradient {
GradientStop {
position: 0
color: Cpp_ThemeManager.windowGradient1
} }
gradient: Gradient { GradientStop {
GradientStop { position: 1
position: 0 color: Cpp_ThemeManager.windowGradient2
color: Cpp_ThemeManager.windowGradient1 }
} }
GradientStop { RowLayout {
position: 1 spacing: app.spacing
color: Cpp_ThemeManager.windowGradient2
} anchors {
margins: 0
left: parent.left
right: parent.right
leftMargin: app.spacing
rightMargin: app.spacing
verticalCenter: parent.verticalCenter
} }
RowLayout { Widgets.Icon {
spacing: app.spacing Layout.alignment: Qt.AlignVCenter
source: "qrc:/icons/arrow-right.svg"
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
}
} }
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
}
}
} }

View File

@ -28,307 +28,307 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Widgets.Window { 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 ColumnLayout {
title: qsTr("View") id: layout
headerDoubleClickEnabled: false x: app.spacing
icon.source: "qrc:/icons/visibility.svg" spacing: app.spacing / 2
backgroundColor: Cpp_ThemeManager.paneWindowBackground width: parent.width - 10 - 2 * app.spacing
// //
// Signals // Spacer
// //
signal widgetSizeChanged(var maxSize) Item {
height: app.spacing
}
// //
// Maps the slider position to points // View options title
// https://stackoverflow.com/a/846249 //
// RowLayout {
function logslider(position) { spacing: app.spacing
var minp = 0 Layout.fillWidth: true
var maxp = 100 visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
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);
}
// Widgets.Icon {
// Maps the points value to the slider position width: 18
// https://stackoverflow.com/a/846249 height: 18
// color: palette.text
function logposition(value) { source: "qrc:/icons/visibility.svg"
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)
}
} }
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)
}
} }
}
} }

View File

@ -5,76 +5,76 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
ColumnLayout { ColumnLayout {
id: root id: root
visible: count > 0 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 spacing: app.spacing
visible: root.count > 0
property int count: 0 Widgets.Icon {
property var titles:[""] width: 18
property string icon: "" height: 18
property string title: "" source: root.icon
color: palette.text
signal checkedChanged(var index, var checked) opacity: hideAll.checked ? 0.5 : 1
Connections {
target: Cpp_UI_Dashboard
function onDataReset() {
hideAll.checked = false
}
} }
RowLayout { Label {
spacing: app.spacing font.bold: true
visible: root.count > 0 text: root.title
opacity: hideAll.checked ? 0.5 : 1
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
}
} }
Item { Item {
height: app.spacing Layout.fillWidth: true
visible: !hideAll.checked && count > 0
} }
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
}
} }

View File

@ -30,125 +30,125 @@ import "../Widgets" as Widgets
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
Item { Item {
id: root id: root
property int widgetIndex: -1 property int widgetIndex: -1
property FramelessWindow.CustomWindow externalWindow: null property FramelessWindow.CustomWindow externalWindow: null
Widgets.Window { Widgets.Window {
id: 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 anchors.fill: parent
title: widget.widgetTitle asynchronous: true
icon.source: widget.widgetIcon active: widget.isGpsMap
headerDoubleClickEnabled: true visible: widget.isGpsMap && status == Loader.Ready
borderColor: Cpp_ThemeManager.widgetWindowBorder sourceComponent: Widgets.GpsMap {
onHeaderDoubleClicked: { altitude: widget.gpsAltitude
if (root.externalWindow !== null) latitude: widget.gpsLatitude
root.externalWindow.showNormal() longitude: widget.gpsLongitude
else }
externalWindowLoader.active = true }
}
}
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 { DashboardWidget {
id: widget id: externalWidget
widgetIndex: root.widgetIndex anchors.fill: parent
anchors { isExternalWindow: true
fill: parent widgetIndex: root.widgetIndex
leftMargin: window.borderWidth widgetVisible: _window.visible
rightMargin: window.borderWidth anchors.margins: _window.radius
bottomMargin: window.borderWidth
}
// Loader {
// Hack: render a GPS map using QML code instead of QtWidgets anchors.fill: parent
// asynchronous: true
Loader { active: externalWidget.isGpsMap
anchors.fill: parent visible: externalWidget.isGpsMap && status == Loader.Ready
asynchronous: true sourceComponent: Widgets.GpsMap {
active: widget.isGpsMap altitude: externalWidget.gpsAltitude
visible: widget.isGpsMap && status == Loader.Ready latitude: externalWidget.gpsLatitude
sourceComponent: Widgets.GpsMap { longitude: externalWidget.gpsLongitude
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
} }
}
} }
}
FramelessWindow.ResizeHandles {
window: _window
anchors.fill: parent
handleSize: _window.handleSize
}
} }
}
} }

View File

@ -27,101 +27,101 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Widgets.Window { Widgets.Window {
id: root id: root
// //
// Window properties // Window properties
// //
gradient: true gradient: true
title: qsTr("Data") title: qsTr("Data")
headerDoubleClickEnabled: false headerDoubleClickEnabled: false
icon.source: "qrc:/icons/dataset.svg" icon.source: "qrc:/icons/dataset.svg"
backgroundColor: Cpp_ThemeManager.paneWindowBackground backgroundColor: Cpp_ThemeManager.paneWindowBackground
// Hacks for calculating cell width // Hacks for calculating cell width
property int maxSize: 480 property int maxSize: 480
readonly property int minSize: maxSize * 356/480 readonly property int minSize: maxSize * 356/480
readonly property int cellHeight: cellWidth * (2/3) readonly property int cellHeight: cellWidth * (2/3)
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth) 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 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) 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 // Put everything into a flickable to enable scrolling
// //
Item { Item {
clip: true clip: true
anchors.fill: parent anchors.fill: parent
Flickable { Flickable {
contentWidth: width contentWidth: width
contentHeight: grid.height contentHeight: grid.height
anchors { anchors {
fill: parent fill: parent
margins: app.spacing * 2 margins: app.spacing * 2
rightMargin: app.spacing rightMargin: app.spacing
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
id: scroll id: scroll
} }
Grid { Grid {
id: grid id: grid
width: parent.width width: parent.width
columns: root.columns columns: root.columns
rowSpacing: app.spacing rowSpacing: app.spacing
columnSpacing: app.spacing columnSpacing: app.spacing
height: childrenRect.height height: childrenRect.height
Timer { Timer {
id: timer id: timer
interval: 200 interval: 200
onTriggered: transition.enabled = false 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
}
}
} }
}
// Connections {
// Redraw bottom window border over flickable items target: Cpp_UI_Dashboard
// function onWidgetVisibilityChanged() {
Rectangle { transition.enabled = true
height: root.borderWidth timer.start()
color: root.gradientColor1 }
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
leftMargin: root.radius
rightMargin: root.radius
} }
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
}
}
} }

View File

@ -23,27 +23,27 @@
import QtQuick import QtQuick
Repeater { Repeater {
id: root id: root
property real cellWidth: 0 property real cellWidth: 0
property real cellHeight: 0 property real cellHeight: 0
delegate: Loader { delegate: Loader {
id: loader id: loader
asynchronous: true asynchronous: true
width: root.cellWidth width: root.cellWidth
height: root.cellHeight height: root.cellHeight
sourceComponent: WidgetDelegate { sourceComponent: WidgetDelegate {
widgetIndex: index widgetIndex: index
}
Connections {
target: Cpp_UI_Dashboard
function onWidgetVisibilityChanged() {
loader.visible = Cpp_UI_Dashboard.widgetVisible(index)
}
}
} }
Connections {
target: Cpp_UI_Dashboard
function onWidgetVisibilityChanged() {
loader.visible = Cpp_UI_Dashboard.widgetVisible(index)
}
}
}
} }

View File

@ -26,304 +26,304 @@ import QtQuick.Window as QtWindow
import "../Widgets" as Widgets import "../Widgets" as Widgets
QtWindow.Window { 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" color: "transparent"
flags: (Cpp_ThemeManager.customWindowDecorations ? root.customFlags : Qt.Window) | root.extraFlags radius: root.radius
anchors.fill: parent
anchors.margins: root.shadowMargin
}
// //
// Custom signals // Window border
// //
signal closed() Rectangle {
signal minimized() opacity: 0.8
signal maximized() z: titlebar.z + 1
signal unmaximized() 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 // Global mouse area to set cursor shape while resizing
// //
Connections { MouseArea {
target: Cpp_ThemeManager 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 (p.x < b && p.y < b)
if (Cpp_ThemeManager.customWindowDecorations) return Qt.SizeFDiagCursor
root.flags = root.customFlags | root.extraFlags
else
root.flags = Qt.Window | root.extraFlags
var prevVisible = root.visible if (p.x >= width - b && p.y >= height - b)
root.visible = false return Qt.SizeFDiagCursor
root.visible = prevVisible
} 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 // Titlebar control
// //
property int borderWidth: Cpp_ThemeManager.customWindowDecorations ? 2 : 0 Titlebar {
readonly property int handleSize: radius > 0 ? radius + shadowMargin + 10 : 0 z: 2000
readonly property int radius: Cpp_ThemeManager.customWindowDecorations ? id: _title
(((root.visibility === QtWindow.Window.Maximized && window: root
maximizeEnabled) || isFullscreen) ? 0 : 10) : 0 radius: root.radius
color: root.titlebarColor
textColor: root.titlebarText
// onClosed: root.closed()
// Visibility properties onMinimized: root.minimized()
// onMaximized: root.maximized()
property int extraFlags: 0 onUnmaximized: root.unmaximized()
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
// anchors {
// The macOS window manager is able to generate shadows for Qt frameless top: parent.top
// windows. Other operating systems have varied mileage, so we draw the left: parent.left
// shadow ourselves to avoid ugly surprises. right: parent.right
// margins: root.shadowMargin
// 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 // Maximize window fixes
// //
function toggleFullscreen() { onVisibilityChanged: (visibility) => {
root.isFullscreen = !root.isFullscreen // Ensure that correct window flags are still used
if (root.isFullscreen) if (Cpp_ThemeManager.customWindowDecorations) {
root.showFullScreen() // Hard-reset window flags on macOS to fix most glitches
else if (Cpp_IsMac)
root.showNormal() root.flags = Qt.Window
}
// // Apply custom flags
// Alias to the titlebar root.flags = root.customFlags | root.extraFlags
// }
property alias titlebar: _title
// // Apply basic flags
// Size of the shadow object else
// root.flags = Qt.Window | root.extraFlags
property int shadowMargin: (Cpp_IsMac | !Cpp_ThemeManager.customWindowDecorations) ?
0 : (root.radius > 0 ? 20 : 0)
// // Window has been just maximized, update internal variables
// Titlebar left/right margins for custom controls if (visibility === QtWindow.Window.Maximized) {
// if (!root.isMaximized)
property alias showMacControls: _title.showMacControls root.firstChange = false
readonly property real leftTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.leftMargin : 0
readonly property real rightTitlebarMargin: Cpp_ThemeManager.customWindowDecorations ? _title.rightMargin : 0
// root.isMaximized = true
// Background color of the window & the titlebar root.isFullscreen = false
// }
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 has been just minimized, update internal variables
// Window controls else if (visibility === QtWindow.Window.Minimized) {
// root.isFullscreen = false
property alias closeEnabled: _title.closeEnabled root.isMaximized = false
property alias minimizeEnabled: _title.minimizeEnabled }
property alias maximizeEnabled: _title.maximizeEnabled
// // Window has been just switched to full-screen, update internal variables
// Ensure that window size & position is valid upon showing else if (visibility === QtWindow.Window.FullScreen) {
// if (!root.isFullscreen)
Component.onCompleted: { root.firstChange = false
// 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 root.isFullscreen = true
if (root.x < 0 || root.x >= QtWindow.Screen.desktopAvailableWidth) root.isMaximized = false
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 // Window was just restored to "normal" mode, recover previous geometry
if (root.width > QtWindow.Screen.desktopAvailableWidth) { else if (visibility !== QtWindow.Window.Hidden) {
root.x = 100 if (isMaximized || isFullscreen && firstChange) {
root.width = QtWindow.Screen.desktopAvailableWidth - root.x 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 root.isMaximized = false
if (root.height > QtWindow.Screen.desktopAvailableHeight) { root.isFullscreen = false
root.y = 100
root.height = QtWindow.Screen.desktopAvailableHeight - root.y
}
}
// // Force active focus
// Custom shadow implementation for non-macOS systems. The shadow shall be disabled root.requestActivate()
// when the window is maximized. root.requestUpdate()
// }
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()
}
}
} }

View File

@ -24,216 +24,216 @@ import QtQuick
import QtQuick.Window import QtQuick.Window
Item { Item {
id: root id: root
// //
// Pointer to window to control // Pointer to window to control
// //
property Window window property Window window
property int handleSize property int handleSize
// //
// Disable handles if window size is fixed or window is maximized // Disable handles if window size is fixed or window is maximized
// //
enabled: ((window.minimumWidth !== window.maximumWidth) || enabled: ((window.minimumWidth !== window.maximumWidth) ||
(window.minimumHeight !== window.maximumHeight)) && (window.minimumHeight !== window.maximumHeight)) &&
(window.visibility !== Window.Maximized) (window.visibility !== Window.Maximized)
// //
// Right resize handle // Right resize handle
// //
MouseArea { MouseArea {
property bool dragging: false property bool dragging: false
property point lastMousePos: Qt.point(0, 0) property point lastMousePos: Qt.point(0, 0)
anchors { anchors {
top: parent.top top: parent.top
bottom: parent.bottom bottom: parent.bottom
right: parent.right right: parent.right
topMargin: titlebar.height 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)
}
}
} }
// width: handleSize
// Left resize handle onPressedChanged: dragging = pressed
// onPressed: lastMousePos = Qt.point(mouseX, mouseY)
MouseArea {
property bool dragging: false
property point lastMousePos: Qt.point(0, 0)
anchors { onMouseXChanged: {
top: parent.top if (dragging) {
left: parent.left var dx = mouseX + lastMousePos.x
bottom: parent.bottom var width = window.width + dx
topMargin: titlebar.height if (width < window.minimumWidth)
} width = window.minimumWidth
else if (width > window.maximumWidth)
width = window.maximumWidth
width: handleSize window.setGeometry(window.x, window.y, width, window.height)
onPressedChanged: dragging = pressed }
onPressed: lastMousePos = Qt.point(mouseX, mouseY) }
}
onMouseXChanged: { //
if (dragging) { // Left resize handle
var dx = mouseX - lastMousePos.x //
var y = window.y MouseArea {
var x = window.x + dx property bool dragging: false
var height = window.height property point lastMousePos: Qt.point(0, 0)
var width = window.width - dx
if (x > window.x) { anchors {
width = window.width - dx / 2 top: parent.top
if (width < window.minimumWidth) { left: parent.left
width = window.minimumWidth bottom: parent.bottom
x = window.x topMargin: titlebar.height
}
else if (width > window.maximumWidth) {
width = window.maximumWidth
x = window.x
}
}
window.setGeometry(x, y, width, height)
}
}
} }
// width: handleSize
// Bottom resize handle onPressedChanged: dragging = pressed
// onPressed: lastMousePos = Qt.point(mouseX, mouseY)
MouseArea {
property bool dragging: false
property point lastMousePos: Qt.point(0, 0)
anchors { onMouseXChanged: {
left: parent.left if (dragging) {
right: parent.right var dx = mouseX - lastMousePos.x
bottom: parent.bottom 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 window.setGeometry(x, y, width, height)
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(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
} }
// height: handleSize
// Bottom right corner onPressedChanged: dragging = pressed
// onPressed: lastMousePos = Qt.point(mouseX, mouseY)
MouseArea { onMouseYChanged: {
property bool dragging: false if (dragging) {
property point lastMousePos: Qt.point(0, 0) 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() { window.setGeometry(window.x, window.y, window.width, height)
if (dragging) { }
var dy = mouseY - lastMousePos.y }
var dx = mouseX + lastMousePos.x }
var width = window.width + dx
var height = window.height + dy
if (width < window.minimumWidth) //
width = window.minimumWidth // Bottom right corner
else if (width > window.maximumWidth) //
width = window.maximumWidth MouseArea {
property bool dragging: false
property point lastMousePos: Qt.point(0, 0)
if (height < window.minimumHeight) function updateWindowPosition() {
height = window.minimumHeight if (dragging) {
else if (height > window.maximumHeight) var dy = mouseY - lastMousePos.y
height = window.maximumHeight 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 { if (height < window.minimumHeight)
right: parent.right height = window.minimumHeight
bottom: parent.bottom else if (height > window.maximumHeight)
} height = window.maximumHeight
width: handleSize window.setGeometry(window.x, window.y, width, height)
height: handleSize }
enabled: Cpp_IsMac
onPressedChanged: dragging = pressed
onMouseXChanged: updateWindowPosition()
onPressed: lastMousePos = Qt.point(mouseX, mouseY)
} }
// anchors {
// Bottom left corner right: parent.right
// bottom: parent.bottom
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)
} }
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)
}
} }

View File

@ -28,312 +28,312 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Rectangle { Rectangle {
id: root id: root
// //
// Custom signals // Custom signals
// //
signal closed() signal closed()
signal minimized() signal minimized()
signal maximized() signal maximized()
signal unmaximized() signal unmaximized()
// //
// Window controls // Window controls
// //
property Window window property Window window
property bool showIcon: false property bool showIcon: false
property bool closeEnabled: true property bool closeEnabled: true
property bool isFullscreen: false property bool isFullscreen: false
property bool minimizeEnabled: true property bool minimizeEnabled: true
property bool maximizeEnabled: true property bool maximizeEnabled: true
property color textColor: palette.text property color textColor: palette.text
property bool showMacControls: Cpp_IsMac property bool showMacControls: Cpp_IsMac
// //
// Access to left titlebar button widths (e.g. for implementing custom controls over // Access to left titlebar button widths (e.g. for implementing custom controls over
// the window titlebar, such as the main window menubar) // the window titlebar, such as the main window menubar)
// //
readonly property real leftMargin: { readonly property real leftMargin: {
var margin = 0 var margin = 0
// Calculations for macOS layout // Calculations for macOS layout
if (showMacControls) { if (showMacControls) {
// Default spacer // Default spacer
margin = 4 margin = 4
// Add space for close button // Add space for close button
if (closeEnabled) if (closeEnabled)
margin += 20 margin += 20
// Add space for minimize button // Add space for minimize button
if (minimizeEnabled && !root.isFullscreen) if (minimizeEnabled && !root.isFullscreen)
margin += 20 margin += 20
// Add space for maximize button // Add space for maximize button
if (maximizeEnabled && !root.isFullscreen) if (maximizeEnabled && !root.isFullscreen)
margin += 20 margin += 20
// Add extra spacer if at least one button is visible // Add extra spacer if at least one button is visible
if (margin > 4) if (margin > 4)
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
} }
// // Calculations for Windows/Linux layout
// Access to right titlebar button widths (e.g. for implementing custom controls over else {
// the window titlebar, such as the main window menubar) margin = 8
//
readonly property real rightMargin: {
var margin
// Calculations for macOS layout if (root.showIcon)
if (showMacControls) margin += 24
margin = 8
// Calculations for Windows/Linux layout if (margin > 8)
else { margin += 6
// Default spacer }
margin = 8
// Add space for close button // Return result
if (closeEnabled) return margin
margin += 24 }
// Add space for minimize button //
if (minimizeEnabled && !root.isFullscreen) // Access to right titlebar button widths (e.g. for implementing custom controls over
margin += 24 // the window titlebar, such as the main window menubar)
//
readonly property real rightMargin: {
var margin
// Add space for maximize button // Calculations for macOS layout
if (maximizeEnabled && !root.isFullscreen) if (showMacControls)
margin += 24 margin = 8
// Add extra spacer if at least one button is visible // Calculations for Windows/Linux layout
if (margin > 8) else {
margin += 8 // 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
}
// WindowButtonMacOS {
// Toggle maximized name: "minimize"
// Layout.alignment: Qt.AlignVCenter
function toggleMaximized() { enabled: root.minimizeEnabled && !root.isFullscreen
if (window.visibility === Window.Maximized) { visible: root.minimizeEnabled && !root.isFullscreen
window.showNormal() onClicked: {
root.unmaximized() // Workaround for QTBUG-64994
if (Cpp_IsMac)
window.flags = Qt.Window | Qt.CustomizeWindowHint | Qt.WindowMinMaxButtonsHint
window.showMinimized()
root.minimized()
} }
}
else { WindowButtonMacOS {
window.showMaximized() name: "maximize"
root.maximized() 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 {
// Toggle fullscreen state textColor: root.textColor
// onClicked: root.toggleMaximized()
function toggleFullscreen() { Layout.alignment: Qt.AlignVCenter
root.isFullscreen = !root.isFullscreen enabled: root.maximizeEnabled && !root.isFullscreen
if (root.isFullscreen) visible: root.maximizeEnabled && !root.isFullscreen
window.showFullScreen() name: window.visibility === Window.Maximized ? "unmaximize" : "maximize"
else }
window.showNormal()
}
// WindowButton {
// Height calculation name: "close"
// pressedColor: "#f00"
height: Cpp_ThemeManager.customWindowDecorations ? (!showMacControls ? 38 : 32) : 0 textColor: root.textColor
enabled: root.closeEnabled
// visible: root.closeEnabled
// Radius compensator rectangle Layout.alignment: Qt.AlignVCenter
// onClicked: {
Rectangle { window.close()
color: parent.color root.closed()
height: parent.radius
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
} }
}
Item {
width: 8
}
} }
}
// Label {
// Window drag handler & maximize by double click font.bold: true
// font.pixelSize: 14
Item { text: window.title
anchors.fill: parent color: root.textColor
enabled: Cpp_ThemeManager.customWindowDecorations anchors.centerIn: parent
visible: 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
}
} }

View File

@ -24,26 +24,26 @@ import QtQuick
import "../Widgets" as Widgets import "../Widgets" as Widgets
Widgets.Icon { Widgets.Icon {
id: root id: root
signal clicked() signal clicked()
property string name property string name
property color textColor property color textColor
property color pressedColor: Cpp_ThemeManager.highlight property color pressedColor: Cpp_ThemeManager.highlight
width: 24 width: 24
height: 24 height: 24
color: root.textColor color: root.textColor
source: "qrc:/window-border/" + name + ".svg" source: "qrc:/window-border/" + name + ".svg"
Behavior on color { ColorAnimation{} } Behavior on color { ColorAnimation{} }
MouseArea { MouseArea {
hoverEnabled: true hoverEnabled: true
anchors.fill: parent anchors.fill: parent
preventStealing: true preventStealing: true
onClicked: root.clicked() onClicked: root.clicked()
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onContainsMouseChanged: root.color = containsMouse ? root.pressedColor : root.textColor onContainsMouseChanged: root.color = containsMouse ? root.pressedColor : root.textColor
} }
} }

View File

@ -23,23 +23,23 @@
import QtQuick import QtQuick
Image { Image {
id: root id: root
signal clicked() signal clicked()
property string name property string name
property string variant: "normal" property string variant: "normal"
width: sourceSize.width width: sourceSize.width
height: sourceSize.height height: sourceSize.height
sourceSize: Qt.size(20, 20) sourceSize: Qt.size(20, 20)
source: ("qrc:/window-border/macOS/" + name + "-" + variant + ".svg") source: ("qrc:/window-border/macOS/" + name + "-" + variant + ".svg")
MouseArea { MouseArea {
hoverEnabled: true hoverEnabled: true
anchors.fill: parent anchors.fill: parent
onReleased: root.clicked() onReleased: root.clicked()
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
onPressedChanged: root.variant = (pressed ? "active" : "normal") onPressedChanged: root.variant = (pressed ? "active" : "normal")
onContainsMouseChanged: root.variant = (containsMouse ? "hover" : "normal") onContainsMouseChanged: root.variant = (containsMouse ? "hover" : "normal")
} }
} }

View File

@ -27,61 +27,61 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Item { Item {
id: root id: root
// //
// Custom properties // Custom properties
// //
property alias vt100emulation: terminal.vt100emulation property alias vt100emulation: terminal.vt100emulation
// //
// Utility functions between terminal widget & main window // Utility functions between terminal widget & main window
// //
function sendData() { function sendData() {
terminal.sendData() terminal.sendData()
} function clear() { } function clear() {
terminal.clear() terminal.clear()
} function copy() { } function copy() {
terminal.copy() terminal.copy()
} function selectAll() { } function selectAll() {
terminal.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 // Console window
// //
function showWelcomeGuide() { Widgets.Window {
clear() id: window
Cpp_IO_Console.append(Cpp_Misc_Translator.welcomeConsoleText() + "\n") gradient: true
} anchors.fill: parent
title: qsTr("Console")
// headerDoubleClickEnabled: false
// Re-load welcome text when the language is changed icon.source: "qrc:/icons/code.svg"
// anchors.margins: (app.spacing * 1.5) - 5
Connections { backgroundColor: Cpp_ThemeManager.paneWindowBackground
target: Cpp_Misc_Translator
function onLanguageChanged() { Widgets.Terminal {
root.showWelcomeGuide() 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
}
} }
}
} }

View File

@ -28,94 +28,94 @@ import "../Widgets" as Widgets
import "../Dashboard" as DashboardItems import "../Dashboard" as DashboardItems
Item { 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 { RowLayout {
anchors.fill: parent spacing: app.spacing
spacing: app.spacing Layout.fillWidth: true
anchors.margins: (app.spacing * 1.5) - 5 Layout.fillHeight: true
// //
// Widget selector + widgets // View options window
// //
RowLayout { DashboardItems.ViewOptions {
spacing: app.spacing Layout.fillHeight: true
Layout.fillWidth: true Layout.minimumWidth: 280
Layout.fillHeight: true onWidgetSizeChanged:(maxSize) => widgetGrid.maxSize = maxSize
}
// //
// View options window // Widget grid + console
// //
DashboardItems.ViewOptions { ColumnLayout {
Layout.fillHeight: true spacing: terminalView.enabled ? app.spacing : 0
Layout.minimumWidth: 280
onWidgetSizeChanged:(maxSize) => widgetGrid.maxSize = maxSize
}
// DashboardItems.WidgetGrid {
// Widget grid + console id: widgetGrid
// Layout.fillWidth: true
ColumnLayout { Layout.fillHeight: true
spacing: terminalView.enabled ? app.spacing : 0 Layout.minimumWidth: 240
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
}
}
}
}
} }
//
// Dashboard title window Item {
// enabled: false
DashboardItems.DashboardTitle { id: terminalView
id: dbTitle Layout.fillWidth: true
height: 32 Layout.fillHeight: false
Layout.fillWidth: true Layout.maximumHeight: 280
onConsoleCheckedChanged: { Layout.minimumHeight: 280
if (terminalView.enabled != consoleChecked) visible: Layout.bottomMargin > -Layout.minimumHeight
terminalView.enabled = consoleChecked 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
}
}
}
} }

View File

@ -29,259 +29,259 @@ import "../Widgets" as Widgets
import "SetupPanes" as SetupPanes import "SetupPanes" as SetupPanes
Item { 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 alias mqttHost: mqtt.host
property int displayedWidth: 380 + app.spacing * 1.5 property alias mqttPort: mqtt.port
readonly property int maxItemWidth: column.width - 2 * spacing 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() { property alias language: settings.language
setupMargin = 0 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() { ColumnLayout {
setupMargin = -1 * displayedWidth id: column
} anchors.fill: parent
spacing: app.spacing / 2
anchors.margins: app.spacing * 1.5
// //
// Animations // Comm mode selector
// //
visible: setupMargin > -1 * displayedWidth Label {
Behavior on setupMargin {NumberAnimation{}} font.bold: true
text: qsTr("Communication Mode") + ":"
// } RadioButton {
// Save settings id: commAuto
// checked: true
Settings { Layout.maximumWidth: root.maxItemWidth
// text: qsTr("No parsing (device sends JSON data)")
// Misc settings onCheckedChanged: {
// if (checked)
property alias auto: commAuto.checked Cpp_JSON_Generator.setOperationMode(1)
property alias manual: commManual.checked else
property alias tabIndex: tab.currentIndex Cpp_JSON_Generator.setOperationMode(0)
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)
} }
} } RadioButton {
id: commManual
// checked: false
// Window Layout.maximumWidth: root.maxItemWidth
// text: qsTr("Parse via JSON project file")
Widgets.Window { onCheckedChanged: {
gradient: true if (checked)
title: qsTr("Setup") Cpp_JSON_Generator.setOperationMode(0)
anchors.fill: parent else
anchors.leftMargin: 0 Cpp_JSON_Generator.setOperationMode(1)
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
}
}
}
} }
}
//
// 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
}
}
}
} }
}
} }

View File

@ -25,150 +25,150 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Control { 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() RowLayout {
Timer { spacing: app.spacing
id: timer visible: opacity > 0
interval: 2000 opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount > 0 ? 1 : 0
onTriggered: Cpp_IO_Bluetooth_LE.startDiscovery()
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 { RowLayout {
id: layout spacing: app.spacing
spacing: app.spacing visible: opacity > 0
anchors.fill: parent opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && serviceNames.count > 1 ? 1 : 0
anchors.margins: app.spacing
// Label {
// Device selector + refresh button id: servLabel
// text: qsTr("Service") + ":"
RowLayout { Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth)
spacing: app.spacing }
visible: opacity > 0
opacity: Cpp_IO_Bluetooth_LE.operatingSystemSupported && Cpp_IO_Bluetooth_LE.deviceCount > 0 ? 1 : 0
Label { ComboBox {
id: devLabel id: serviceNames
opacity: enabled ? 1 : 0.5 Layout.fillWidth: true
text: qsTr("Device") + ":" model: Cpp_IO_Bluetooth_LE.serviceNames
enabled: !Cpp_IO_Manager.connected palette.base: Cpp_ThemeManager.setupPanelBackground
Layout.minimumWidth: Math.max(devLabel.implicitWidth, servLabel.implicitWidth) onCurrentIndexChanged: Cpp_IO_Bluetooth_LE.selectService(currentIndex)
} }
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
}
} }
//
// 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
}
}
} }

View File

@ -25,259 +25,259 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Control { Control {
id: root id: root
// //
// Access to properties // Access to properties
// //
property alias address: _address.text property alias address: _address.text
property alias tcpPort: _tcpPort.text property alias tcpPort: _tcpPort.text
property alias udpLocalPort: _udpLocalPort.text property alias udpLocalPort: _udpLocalPort.text
property alias udpRemotePort: _udpRemotePort.text property alias udpRemotePort: _udpRemotePort.text
property alias socketType: _typeCombo.currentIndex property alias socketType: _typeCombo.currentIndex
property alias udpMulticastEnabled: _udpMulticast.checked property alias udpMulticastEnabled: _udpMulticast.checked
property alias udpProcessDatagramsDirectly: _udpProcessDatagrams.checked property alias udpProcessDatagramsDirectly: _udpProcessDatagrams.checked
//
// React to network manager events
//
Connections {
target: Cpp_IO_Network
function onAddressChanged() { //
if (_address.text.length > 0) // React to network manager events
_address.text = Cpp_IO_Network.remoteAddress //
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() { validator: IntValidator {
if (_tcpPort.text.length > 0) bottom: 0
_tcpPort.text = Cpp_IO_Network.tcpPort top: 65535
if (_udpLocalPort.text.length > 0)
_udpLocalPort.text = Cpp_IO_Network.udpLocalPort
if (_udpRemotePort.text.length > 0)
_udpRemotePort.text = Cpp_IO_Network.udpRemotePort
} }
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 { Item {
id: layout Layout.fillHeight: true
anchors.fill: parent Layout.minimumHeight: app.spacing
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
}
} }
//
// Spacer
//
Item {
Layout.fillHeight: true
}
}
} }

View File

@ -25,207 +25,207 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Control { 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 GridLayout {
property alias baudRate: _baudCombo.currentIndex id: layout
property alias dataBits: _dataCombo.currentIndex columns: 2
property alias parity: _parityCombo.currentIndex Layout.fillWidth: true
property alias flowControl: _flowCombo.currentIndex rowSpacing: app.spacing
property alias stopBits: _stopBitsCombo.currentIndex columnSpacing: app.spacing
property alias autoReconnect: _autoreconnect.checked
// //
// Update listbox models when translation is changed // COM port selector
// //
Connections { Label {
target: Cpp_Misc_Translator opacity: enabled ? 1 : 0.5
function onLanguageChanged() { text: qsTr("COM Port") + ":"
var oldParityIndex = _parityCombo.currentIndex enabled: !Cpp_IO_Manager.connected
var oldFlowControlIndex = _flowCombo.currentIndex } ComboBox {
id: _portCombo
_parityCombo.model = Cpp_IO_Serial.parityList Layout.fillWidth: true
_flowCombo.model = Cpp_IO_Serial.flowControlList opacity: enabled ? 1 : 0.5
model: Cpp_IO_Serial.portList
_parityCombo.currentIndex = oldParityIndex enabled: !Cpp_IO_Manager.connected
_flowCombo.currentIndex = oldFlowControlIndex 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 { Item {
anchors.fill: parent Layout.fillHeight: true
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
}
} }
}
} }

View File

@ -29,90 +29,90 @@ import "Devices" as Devices
import "../../Windows" as Windows import "../../Windows" as Windows
Control { 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 { RowLayout {
property alias driver: _driverCombo.currentIndex spacing: app.spacing
property alias parity: serial.parity Layout.fillWidth: true
property alias baudRate: serial.baudRate
property alias dataBits: serial.dataBits Label {
property alias stopBits: serial.stopBits text: qsTr("Data source") + ":"
property alias flowControl: serial.flowControl Layout.alignment: Qt.AlignVCenter
property alias autoReconnect: serial.autoReconnect }
property alias address: network.address
property alias tcpPort: network.tcpPort ComboBox {
property alias socketType: network.socketType id: _driverCombo
property alias udpLocalPort: network.udpLocalPort Layout.fillWidth: true
property alias udpRemotePort: network.udpRemotePort Layout.alignment: Qt.AlignVCenter
property alias udpMulticastEnabled: network.udpMulticastEnabled model: Cpp_IO_Manager.availableDrivers()
property alias udpProcessDatagramsDirectly: network.udpProcessDatagramsDirectly onCurrentIndexChanged: Cpp_IO_Manager.selectedDriver = currentIndex
}
} }
ColumnLayout { //
id: layout // Device configuration
anchors.fill: parent //
anchors.margins: app.spacing StackLayout {
id: stack
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: Cpp_IO_Manager.selectedDriver
// Devices.Serial {
// Device type selector id: serial
// Layout.fillWidth: true
RowLayout { Layout.fillHeight: true
spacing: app.spacing background: TextField {
Layout.fillWidth: true enabled: false
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.Network {
// Device configuration id: network
// Layout.fillWidth: true
StackLayout { Layout.fillHeight: true
id: stack background: TextField {
clip: true enabled: false
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.BluetoothLE {
id: bluetoothLE
Layout.fillWidth: true
Layout.fillHeight: true
background: TextField {
enabled: false
}
}
} }
}
} }

View File

@ -27,274 +27,274 @@ import QtQuick.Controls
import "../../Windows" as Windows import "../../Windows" as Windows
Control { Control {
id: root id: root
// //
// Aliases // Aliases
// //
property alias host: _host.text property alias host: _host.text
property alias port: _port.text property alias port: _port.text
property alias topic: _topic.text property alias topic: _topic.text
property alias user: _user.text property alias user: _user.text
property alias password: _password.text property alias password: _password.text
property alias version: _version.currentIndex property alias version: _version.currentIndex
property alias mode: _mode.currentIndex property alias mode: _mode.currentIndex
// //
// React to events from MQTT module // React to events from MQTT module
// //
Connections { Connections {
target: Cpp_MQTT_Client target: Cpp_MQTT_Client
function onHostChanged() { function onHostChanged() {
if (_host.text.length > 0) if (_host.text.length > 0)
_host.text = Cpp_MQTT_Client.host _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 { Item {
id: layout Layout.fillHeight: true
anchors.fill: parent Layout.minimumHeight: app.spacing
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
}
} }
// //
// MQTT setup dialog // Spacer
// //
Windows.MQTTConfiguration { Item {
id: mqttSetup 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
}
} }

View File

@ -25,131 +25,115 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Control { 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 GridLayout {
property alias language: _langCombo.currentIndex columns: 2
property alias windowShadows: _windowShadows.checked Layout.fillWidth: true
rowSpacing: app.spacing
columnSpacing: app.spacing
// //
// Layout // Language selector
// //
ColumnLayout { Label {
id: layout text: qsTr("Language") + ":"
anchors.fill: parent } ComboBox {
anchors.margins: app.spacing id: _langCombo
Layout.fillWidth: true
// currentIndex: Cpp_Misc_Translator.language
// Controls model: Cpp_Misc_Translator.availableLanguages
// onCurrentIndexChanged: {
GridLayout { if (currentIndex !== Cpp_Misc_Translator.language)
columns: 2 Cpp_Misc_Translator.setLanguage(currentIndex)
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)
}
}
} }
}
// //
// Plugins label // Theme selector
// //
Label { Label {
opacity: 0.8 text: qsTr("Theme") + ":"
font.pixelSize: 12 } ComboBox {
Layout.fillWidth: true id: _themeCombo
wrapMode: Label.WrapAtWordBoundaryOrAnywhere Layout.fillWidth: true
color: Cpp_ThemeManager.highlightedTextAlternative model: Cpp_ThemeManager.availableThemes
text: qsTr("Applications/plugins can interact with %1 by " + currentIndex: Cpp_ThemeManager.themeId
"establishing a TCP connection on port 7777.").arg(Cpp_AppName) onCurrentIndexChanged: {
if (currentIndex !== Cpp_ThemeManager.themeId)
Cpp_ThemeManager.setTheme(currentIndex)
} }
}
// //
// Vertical spacer // Plugins enabled
// //
Item { Label {
Layout.fillHeight: true 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
}
}
} }

View File

@ -28,322 +28,296 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Control { Control {
id: root id: root
// //
// Reference to parent window to be able to drag it with the toolbar // Reference to parent window to be able to drag it with the toolbar
// //
property Window window property Window window
// //
// Dummy string to increase width of buttons // Dummy string to increase width of buttons
// //
readonly property string _btSpacer: " " readonly property string _btSpacer: " "
// //
// Custom signals // Custom signals
// //
signal setupClicked() signal setupClicked()
signal consoleClicked() signal consoleClicked()
signal dashboardClicked() signal dashboardClicked()
signal projectEditorClicked() signal projectEditorClicked()
// //
// Aliases to button check status // Aliases to button check status
// //
property alias setupChecked: setupBt.checked property alias setupChecked: setupBt.checked
property alias consoleChecked: consoleBt.checked property alias consoleChecked: consoleBt.checked
property alias dashboardChecked: dashboardBt.checked property alias dashboardChecked: dashboardBt.checked
// //
// Connections with mac touchbar // Toolbar shadow
// //
Connections { Widgets.Shadow {
target: Cpp_Misc_MacExtras anchors.fill: bg
}
function onSetupClicked() { //
setupBt.clicked() // Background gradient + border
Cpp_Misc_MacExtras.setSetupChecked(setupBt.checked) //
} Rectangle {
id: bg
anchors.fill: parent
function onConsoleClicked() { gradient: Gradient {
consoleBt.clicked() GradientStop { position: 0; color: Cpp_ThemeManager.toolbarGradient1 }
Cpp_Misc_MacExtras.setConsoleChecked(consoleBt.checked) GradientStop { position: 1; color: Cpp_ThemeManager.toolbarGradient2 }
}
function onDashboardClicked() {
dashboardBt.clicked()
Cpp_Misc_MacExtras.setDashboardChecked(dashboardBt.checked)
}
} }
//
// Toolbar shadow
//
Widgets.Shadow {
anchors.fill: bg
}
//
// Background gradient + border
//
Rectangle { Rectangle {
id: bg border.width: 1
anchors.fill: parent anchors.fill: parent
color: "transparent"
visible: Cpp_ThemeManager.titlebarSeparator
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
}
gradient: Gradient { Rectangle {
GradientStop { position: 0; color: Cpp_ThemeManager.toolbarGradient1 } height: 1
GradientStop { position: 1; color: Cpp_ThemeManager.toolbarGradient2 } 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 { Rectangle {
border.width: 1 border.width: 1
anchors.fill: parent color: "#626262"
color: "transparent" anchors.fill: parent
visible: Cpp_ThemeManager.titlebarSeparator border.color: "#c2c2c2"
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5) 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 { Rectangle {
height: 1 border.width: 1
visible: Cpp_ThemeManager.titlebarSeparator color: "#626262"
color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5) anchors.fill: parent
border.color: "#c2c2c2"
anchors { radius: parent.radius - 1
left: parent.left anchors.margins: parent.border.width
right: parent.right
bottom: parent.bottom
}
} }
}
}
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 { Item {
spacing: app.spacing height: parent.height
Layout.fillWidth: true
MouseArea {
anchors.fill: parent anchors.fill: parent
anchors.margins: app.spacing onPressedChanged: {
if (pressed)
Button { window.startSystemMove()
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
}
}
} }
}
} }
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
}
}
}
}
} }

View File

@ -25,45 +25,45 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
MenuItem { MenuItem {
id: root id: root
property alias sequence: _shortcut.sequence property alias sequence: _shortcut.sequence
property bool indicatorVisible: root.icon.source.length > 0 || root.checkable property bool indicatorVisible: root.icon.source.length > 0 || root.checkable
Shortcut { Shortcut {
id: _shortcut id: _shortcut
enabled: root.enabled enabled: root.enabled
onActivated: root.triggered() onActivated: root.triggered()
}
contentItem: RowLayout {
spacing: 0
width: root.width
opacity: root.enabled ? 1 : 0.5
Item {
width: root.indicatorVisible ? 18 : 0
} }
contentItem: RowLayout { Label {
spacing: 0 id: _titleLabel
width: root.width text: root.text
opacity: root.enabled ? 1 : 0.5 Layout.fillWidth: true
elide: Label.ElideRight
Item { verticalAlignment: Qt.AlignVCenter
width: root.indicatorVisible ? 18 : 0 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
}
} }
Item {
Layout.fillWidth: true
}
Label {
id: _shortcutLabel
opacity: 0.8
text: _shortcut.nativeText
verticalAlignment: Qt.AlignVCenter
color: root.highlighted ? Cpp_ThemeManager.highlightedText : palette.text
}
}
} }

View File

@ -24,325 +24,325 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
MenuBar { MenuBar {
id: root id: root
// //
// Set background color // Set background color
// //
background: Rectangle { background: Rectangle {
color: "transparent" 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()
} }
// MenuSeparator {}
// Palette
//
palette.text: Cpp_ThemeManager.menubarText
palette.base: Cpp_ThemeManager.toolbarGradient1
palette.window: Cpp_ThemeManager.toolbarGradient2
palette.highlightedText: Cpp_ThemeManager.highlightedText
//
// File menu
//
Menu { Menu {
title: qsTr("File") title: qsTr("CSV export")
DecentMenuItem { DecentMenuItem {
sequence: "ctrl+j" checkable: true
text: qsTr("Select JSON file") + "..." text: qsTr("Enable CSV export")
onTriggered: Cpp_JSON_Generator.loadJsonMap() checked: Cpp_CSV_Export.exportEnabled
} onTriggered: Cpp_CSV_Export.exportEnabled = checked
}
MenuSeparator {} DecentMenuItem {
sequence: "ctrl+shift+o"
Menu { enabled: Cpp_CSV_Export.isOpen
title: qsTr("CSV export") text: qsTr("Show CSV in explorer")
onTriggered: Cpp_CSV_Export.openCurrentCsv()
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 {
// Edit menu 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 { Menu {
title: qsTr("Edit") title: qsTr("Communication mode")
DecentMenuItem { DecentMenuItem {
text: qsTr("Copy") checkable: true
sequence: "ctrl+c" text: qsTr("Device sends JSON")
onTriggered: mainWindow.consoleCopy() checked: Cpp_JSON_Generator.operationMode === 1
} onTriggered: Cpp_JSON_Generator.operationMode = checked ? 1 : 0
}
DecentMenuItem { DecentMenuItem {
sequence: "ctrl+a" checkable: true
text: qsTr("Select all") + "..." text: qsTr("Load JSON from computer")
onTriggered: mainWindow.consoleSelectAll() checked: Cpp_JSON_Generator.operationMode === 0
} onTriggered: Cpp_JSON_Generator.operationMode = checked ? 0 : 1
}
}
}
DecentMenuItem { //
sequence: "ctrl+d" // View menu
onTriggered: mainWindow.consoleClear() //
text: qsTr("Clear console output") Menu {
} title: qsTr("View")
MenuSeparator{} DecentMenuItem {
checkable: true
Menu { sequence: "ctrl+t"
title: qsTr("Communication mode") text: qsTr("Console")
checked: mainWindow.consoleVisible
DecentMenuItem { onTriggered: mainWindow.showConsole()
checkable: true onCheckedChanged: {
text: qsTr("Device sends JSON") if (mainWindow.consoleVisible !== checked)
checked: Cpp_JSON_Generator.operationMode === 1 checked = mainWindow.consoleVisible
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 {
// View menu 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 { Menu {
title: qsTr("View") title: qsTr("Display mode")
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
sequence: "ctrl+t" text: qsTr("Normal (plain text)")
text: qsTr("Console") checked: Cpp_IO_Console.displayMode === 0
checked: mainWindow.consoleVisible onTriggered: Cpp_IO_Console.displayMode = checked ? 0 : 1
onTriggered: mainWindow.showConsole() }
onCheckedChanged: {
if (mainWindow.consoleVisible !== checked)
checked = mainWindow.consoleVisible
}
}
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
sequence: "ctrl+d" text: qsTr("Binary (hexadecimal)")
text: qsTr("Dashboard") checked: Cpp_IO_Console.displayMode === 1
checked: mainWindow.dashboardVisible onTriggered: Cpp_IO_Console.displayMode = checked ? 1 : 0
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 { Menu {
title: qsTr("Console") title: qsTr("Line ending character")
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
text: qsTr("Autoscroll") text: Cpp_IO_Console.lineEndings()[0]
checked: Cpp_IO_Console.autoscroll checked: Cpp_IO_Console.lineEnding === 0
onTriggered: Cpp_IO_Console.autoscroll = checked onTriggered: Cpp_IO_Console.lineEnding = 0
} }
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
text: qsTr("Show timestamp") text: Cpp_IO_Console.lineEndings()[1]
checked: Cpp_IO_Console.showTimestamp checked: Cpp_IO_Console.lineEnding === 1
onTriggered: Cpp_IO_Console.showTimestamp = checked onTriggered: Cpp_IO_Console.lineEnding = 1
} }
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
checked: mainWindow.vt100emulation text: Cpp_IO_Console.lineEndings()[2]
text: qsTr("VT-100 emulation") checked: Cpp_IO_Console.lineEnding === 2
onTriggered: mainWindow.vt100emulation = checked onTriggered: Cpp_IO_Console.lineEnding = 2
} }
DecentMenuItem { DecentMenuItem {
checkable: true checkable: true
text: qsTr("Echo user commands") text: Cpp_IO_Console.lineEndings()[3]
checked: Cpp_IO_Console.echo checked: Cpp_IO_Console.lineEnding === 3
onTriggered: Cpp_IO_Console.echo = checked onTriggered: Cpp_IO_Console.lineEnding = 3
} }
}
}
MenuSeparator{} //
// Help menu
//
Menu {
title: qsTr("Help")
Menu { DecentMenuItem {
title: qsTr("Display mode") onTriggered: app.aboutDialog.show()
text: qsTr("About %1").arg(Cpp_AppName)
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 {
// Help menu text: qsTr("About %1").arg("Qt")
// onTriggered: Cpp_Misc_Utilities.aboutQt()
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")
}
} }
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")
}
}
} }

View File

@ -24,307 +24,307 @@ import QtQuick
import Qt.labs.platform import Qt.labs.platform
MenuBar { MenuBar {
// //
// File menu // File menu
// //
Menu { Menu {
title: qsTr("File") title: qsTr("File")
MenuItem { MenuItem {
shortcut: "ctrl+j" shortcut: "ctrl+j"
text: qsTr("Select JSON file") + "..." text: qsTr("Select JSON file") + "..."
onTriggered: Cpp_JSON_Generator.loadJsonMap() 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
}
} }
// MenuSeparator {}
// Edit menu
//
Menu { Menu {
title: qsTr("Edit") title: qsTr("CSV export")
MenuItem { MenuItem {
text: qsTr("Copy") checkable: true
shortcut: StandardKey.Copy text: qsTr("Enable CSV export")
onTriggered: mainWindow.consoleCopy() checked: Cpp_CSV_Export.exportEnabled
} onTriggered: Cpp_CSV_Export.exportEnabled = checked
}
MenuItem { MenuItem {
shortcut: StandardKey.SelectAll shortcut: "ctrl+shift+o"
text: qsTr("Select all") + "..." enabled: Cpp_CSV_Export.isOpen
onTriggered: mainWindow.consoleSelectAll() text: qsTr("Show CSV in explorer")
} onTriggered: Cpp_CSV_Export.openCurrentCsv()
}
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 {
// View menu shortcut: "ctrl+o"
// text: qsTr("Replay CSV") + "..."
Menu { onTriggered: Cpp_CSV_Player.openFile()
title: qsTr("View") enabled: Cpp_JSON_Generator.operationMode === 0
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")
}
} }
// MenuSeparator {}
// Console format
//
Menu {
title: qsTr("Console")
MenuItem { MenuItem {
checkable: true shortcut: StandardKey.Print
text: qsTr("Autoscroll") text: qsTr("Print") + "..."
checked: Cpp_IO_Console.autoscroll enabled: Cpp_IO_Console.saveAvailable
onTriggered: Cpp_IO_Console.autoscroll = checked onTriggered: Cpp_IO_Console.print(app.monoFont)
}
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 {
// Help menu shortcut: StandardKey.Save
// onTriggered: Cpp_IO_Console.save()
Menu { enabled: Cpp_IO_Console.saveAvailable
title: qsTr("Help") text: qsTr("Export console output") + "..."
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")
}
} }
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")
}
}
} }

View File

@ -27,147 +27,147 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Rectangle { Rectangle {
id: root id: root
color: Cpp_ThemeManager.toolbarGradient2 color: Cpp_ThemeManager.toolbarGradient2
height: footer.implicitHeight + 4 * app.spacing height: footer.implicitHeight + 4 * app.spacing
// //
// Signals // Signals
// //
signal closeWindow() signal closeWindow()
signal scrollToBottom() signal scrollToBottom()
// //
// Radius compensator // Radius compensator
// //
Rectangle { Rectangle {
color: root.color color: root.color
height: root.radius height: root.radius
anchors { anchors {
top: parent.top top: parent.top
left: parent.left left: parent.left
right: parent.right 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
} }
// Button {
// Top border icon.width: 24
// icon.height: 24
Rectangle { onClicked: root.closeWindow()
height: 1 text: qsTr("Close") + _btSpacer
color: Cpp_ThemeManager.toolbarGradient1 icon.source: "qrc:/icons/close.svg"
anchors { icon.color: Cpp_ThemeManager.menubarText
top: parent.top palette.buttonText: Cpp_ThemeManager.menubarText
left: parent.left palette.button: Cpp_ThemeManager.toolbarGradient1
right: parent.right palette.window: Cpp_ThemeManager.toolbarGradient1
}
} }
// Item {
// Dialog buttons Layout.fillWidth: true
//
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()
}
}
} }
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()
}
}
}
} }

View File

@ -27,90 +27,90 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
ColumnLayout { ColumnLayout {
id: root id: root
spacing: 0 spacing: 0
// //
// Connections with JSON editor model // Connections with JSON editor model
// //
Connections { Connections {
target: Cpp_Project_Model target: Cpp_Project_Model
function onGroupCountChanged() { function onGroupCountChanged() {
tabRepeater.model = 0 tabRepeater.model = 0
stackRepeater.model = 0 stackRepeater.model = 0
tabRepeater.model = Cpp_Project_Model.groupCount tabRepeater.model = Cpp_Project_Model.groupCount
stackRepeater.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 onGroupOrderChanged() {
// Function to scroll to the last group tabRepeater.model = 0
// stackRepeater.model = 0
function selectLastGroup() { tabRepeater.model = Cpp_Project_Model.groupCount
tabBar.currentIndex = tabBar.count - 1 stackRepeater.model = Cpp_Project_Model.groupCount
} }
}
// //
// Spacer // Function to scroll to the last group
// //
Item { function selectLastGroup() {
height: app.spacing 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 // StackView
// //
TabBar { StackLayout {
id: tabBar id: swipe
Layout.fillWidth: true Layout.fillWidth: true
visible: tabRepeater.model > 0 Layout.fillHeight: true
currentIndex: tabBar.currentIndex
Layout.topMargin: -parent.spacing - 1
Repeater { Repeater {
id: tabRepeater id: stackRepeater
delegate: TabButton {
height: 24
text: qsTr("Group %1").arg(index + 1) + " <i>" + (Cpp_Project_Model.groupTitle(index)) + "</i>"
}
}
}
// delegate: Loader {
// StackView
//
StackLayout {
id: swipe
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
currentIndex: tabBar.currentIndex active: swipe.currentIndex == index
Layout.topMargin: -parent.spacing - 1
Repeater { sourceComponent: JsonGroupDelegate {
id: stackRepeater group: index
delegate: Loader {
Layout.fillWidth: true
Layout.fillHeight: true
active: swipe.currentIndex == index
sourceComponent: JsonGroupDelegate {
group: index
}
}
} }
}
} }
}
// //
// Spacer // Spacer
// //
Item { Item {
height: app.spacing height: app.spacing
} }
} }

View File

@ -27,169 +27,169 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Rectangle { Rectangle {
id: root id: root
height: header.implicitHeight + 4 * app.spacing 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 { Rectangle {
id: bg height: 1
anchors.fill: parent visible: Cpp_ThemeManager.titlebarSeparator
color: Cpp_ThemeManager.toolbarGradient2 color: Qt.darker(Cpp_ThemeManager.toolbarGradient1, 1.5)
border.width: Cpp_ThemeManager.titlebarSeparator ? 1 : 0
border.color: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
Rectangle { anchors {
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
left: parent.left left: parent.left
right: parent.right 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
}
} }

View File

@ -27,282 +27,282 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Widgets.Window { 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 Label {
icon.source: "qrc:/icons/dataset.svg" text: qsTr("Title:")
borderColor: Cpp_ThemeManager.widgetWindowBorder } TextField {
palette.window: Cpp_ThemeManager.widgetWindowBackground Layout.fillWidth: true
title: qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset)) text: Cpp_Project_Model.datasetTitle(group, dataset)
placeholderText: qsTr("Sensor reading, uptime, etc...")
// onTextChanged: {
// Delete dataset button Cpp_Project_Model.setDatasetTitle(group, dataset, text)
// root.title = qsTr("Dataset %1 - %2").arg(dataset + 1).arg(Cpp_Project_Model.datasetTitle(group, dataset))
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
}
} }
//
// 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
}
}
} }

View File

@ -27,287 +27,287 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Page { Page {
id: root id: root
// //
// Page background // Page background
// //
background: TextField { background: TextField {
enabled: false enabled: false
palette.base: Cpp_ThemeManager.setupPanelBackground 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 Rectangle {
readonly property int minSize: 320 id: notes
readonly property int maxSize: 380 radius: 16
readonly property int cellHeight: 420 Layout.fillWidth: true
readonly property int columns: Math.floor((grid.width - 2 * scroll.width) / cWidth) color: Cpp_ThemeManager.highlight
readonly property int cellWidth: cWidth + ((grid.width - 2 * scroll.width) - (cWidth) * columns) / columns Layout.minimumHeight: 32 + 2 * app.spacing
readonly property int cWidth: Math.min(maxSize, Math.max(minSize, (grid.width - 2 * scroll.width) / grid.model)) visible: widget.currentIndex === 1 || widget.currentIndex === 2
// RowLayout {
// 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 spacing: app.spacing
anchors.fill: parent anchors.centerIn: parent
anchors.margins: app.spacing Layout.alignment: Qt.AlignHCenter
visible: widget.currentIndex === 1
// Widgets.Icon {
// Notes rectangle width: 32
// height: 32
Rectangle { color: palette.highlightedText
id: notes Layout.alignment: Qt.AlignHCenter
radius: 16 source: "qrc:/icons/accelerometer.svg"
Layout.fillWidth: true } Label {
color: Cpp_ThemeManager.highlight font.pixelSize: 18
Layout.minimumHeight: 32 + 2 * app.spacing wrapMode: Label.WordWrap
visible: widget.currentIndex === 1 || widget.currentIndex === 2 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 === 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°).")
}
}
} }
}
// RowLayout {
// Group title spacing: app.spacing
// anchors.centerIn: parent
RowLayout { Layout.alignment: Qt.AlignHCenter
spacing: app.spacing visible: widget.currentIndex === 2
Layout.fillWidth: true
Label { Widgets.Icon {
text: qsTr("Title") + ":" width: 32
Layout.alignment: Qt.AlignVCenter height: 32
} source: "qrc:/icons/gyro.svg"
color: palette.highlightedText
TextField { Layout.alignment: Qt.AlignHCenter
Layout.minimumWidth: 320 } Label {
placeholderText: qsTr("Title") font.pixelSize: 18
Layout.alignment: Qt.AlignVCenter wrapMode: Label.WordWrap
text: Cpp_Project_Model.groupTitle(group) color: palette.highlightedText
text: "<b>" + qsTr("Note:") + "</b> " + qsTr("The gyroscope widget expects values in degrees (0° to 360°).")
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)
}
} }
}
} }
//
// 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)
}
}
}
} }

View File

@ -27,131 +27,131 @@ import QtQuick.Controls
import "../Widgets" as Widgets import "../Widgets" as Widgets
Widgets.Window { Widgets.Window {
id: root id: root
// //
// Window properties // Window properties
// //
gradient: true gradient: true
headerDoubleClickEnabled: false headerDoubleClickEnabled: false
title: qsTr("JSON Project Tree") title: qsTr("JSON Project Tree")
icon.source: "qrc:/icons/json.svg" icon.source: "qrc:/icons/json.svg"
// //
// Connections with JSON editor model // Connections with JSON editor model
// //
Connections { Connections {
target: Cpp_Project_Model target: Cpp_Project_Model
function onGroupCountChanged() { function onGroupCountChanged() {
view.model = 0 view.model = 0
view.model = Cpp_Project_Model.groupCount 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 onGroupOrderChanged() {
// List view view.model = 0
// view.model = Cpp_Project_Model.groupCount
ListView { }
id: view
anchors.fill: parent
spacing: app.spacing * 2
anchors.margins: app.spacing
model: Cpp_Project_Model.groupCount
delegate: Loader { function onDatasetChanged() {
width: view.width - app.spacing * 2 view.model = 0
height: Cpp_Project_Model.datasetCount(index) * 24 + 24 view.model = Cpp_Project_Model.groupCount
}
}
sourceComponent: ColumnLayout { //
id: groupDelegate // List view
spacing: app.spacing //
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 { sourceComponent: ColumnLayout {
spacing: app.spacing id: groupDelegate
Layout.fillWidth: true spacing: app.spacing
Widgets.Icon { readonly property var groupId: index
width: 18
height: 18
color: Cpp_ThemeManager.text
source: "qrc:/icons/group.svg"
Layout.alignment: Qt.AlignVCenter
}
Label { RowLayout {
font.bold: true spacing: app.spacing
Layout.fillWidth: true Layout.fillWidth: true
elide: Label.ElideRight
Layout.alignment: Qt.AlignVCenter
text: Cpp_Project_Model.groupTitle(groupDelegate.groupId)
}
Label { Widgets.Icon {
opacity: 0.5 width: 18
visible: text !== "[]" height: 18
font.family: app.monoFont color: Cpp_ThemeManager.text
Layout.alignment: Qt.AlignVCenter source: "qrc:/icons/group.svg"
text: "[" + Cpp_Project_Model.groupWidget(groupDelegate.groupId) + "]" 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 { Label {
model: Cpp_Project_Model.datasetCount(groupDelegate.groupId) opacity: 0.5
visible: text !== "[]"
delegate: Loader { font.family: app.monoFont
Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter
sourceComponent: RowLayout { text: "[" + Cpp_Project_Model.datasetWidget(groupDelegate.groupId, index) + "]"
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) + "]"
}
}
}
}
} }
}
} }
}
} }
}
} }

View File

@ -28,222 +28,222 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Item { Item {
id: root id: root
// //
// Custom properties to control the map from other QML files // Custom properties to control the map from other QML files
// //
property real latitude: 0 property real latitude: 0
property real longitude: 0 property real longitude: 0
property real altitude: 0 // Not used yet :( property real altitude: 0 // Not used yet :(
onLatitudeChanged: { onLatitudeChanged: {
if (autoCenter.checked) if (autoCenter.checked)
centerMap() centerMap()
} }
onLongitudeChanged: { onLongitudeChanged: {
if (autoCenter.checked) if (autoCenter.checked)
centerMap() 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() { RowLayout {
map.center = QtPositioning.coordinate(root.latitude, root.longitude) 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 { RowLayout {
property alias mapTilt: tiltSlider.value //
property alias mapZoom: zoomSlider.value // Tilt slider
property alias mapCenter: autoCenter.checked //
property alias mapVariant: mapType.currentIndex 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 // Map
// //
ColumnLayout { Rectangle {
spacing: app.spacing id: mapRect
anchors.fill: parent clip: true
anchors.margins: app.spacing Layout.fillWidth: true
Layout.fillHeight: true
RowLayout { border {
spacing: app.spacing width: 2
color: Cpp_ThemeManager.border
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]
}
} }
// gradient: Gradient {
// Center map + zoom slider GradientStop {
// color: "#6ba9d1"
RowLayout { position: Math.max(0.4,
CheckBox { (map.maximumTilt - map.tilt) /
id: autoCenter map.maximumTilt)
checked: true }
checkable: true
Layout.leftMargin: -6
Layout.alignment: Qt.AlignHCenter
text: qsTr("Center on coordinate")
onCheckedChanged: {
if (checked)
root.centerMap()
}
}
Slider { GradientStop {
id: zoomSlider position: 0
value: map.zoomLevel color: "#283e51"
Layout.fillWidth: true }
to: map.maximumZoomLevel
from: map.minimumZoomLevel
Layout.alignment: Qt.AlignHCenter
onValueChanged: {
if (map.zoomLevel !== value)
map.zoomLevel = value
}
}
} }
// Map {
// Map id: map
// smooth: true
RowLayout { antialiasing: true
// color: "transparent"
// Tilt slider anchors.fill: parent
// copyrightsVisible: false
Slider { anchors.margins: parent.border.width
id: tiltSlider
orientation: Qt.Vertical tilt: 27
Layout.fillHeight: true zoomLevel: 16
from: map.minimumTilt
to: map.maximumTilt MapQuickItem {
value: map.tilt anchorPoint: Qt.point(sourceItem.width / 2,
onValueChanged: { sourceItem.height/ 2)
if (map.tilt != value) coordinate: QtPositioning.coordinate(root.latitude,
map.tilt = value 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 {
// Map preferred: "osm"
//
Rectangle {
id: mapRect
clip: true
Layout.fillWidth: true
Layout.fillHeight: true
border { PluginParameter {
width: 2 name: "osm.mapping.highdpi_tiles"
color: Cpp_ThemeManager.border value: true
}
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
}
}
} }
}
} }
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
}
}
}
} }
}
} }

View File

@ -24,28 +24,28 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
Item { Item {
id: root id: root
property string source: "" property string source: ""
property alias icon: button.icon property alias icon: button.icon
property color color: Cpp_ThemeManager.menubarText property color color: Cpp_ThemeManager.menubarText
width: 24 width: 24
height: 24 height: 24
ToolButton { ToolButton {
id: button id: button
enabled: false enabled: false
background: Item {} background: Item {}
icon.color: root.color icon.color: root.color
icon.width: root.width icon.width: root.width
icon.height: root.width icon.height: root.width
icon.source: root.source icon.source: root.source
anchors.centerIn: parent anchors.centerIn: parent
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
propagateComposedEvents: true propagateComposedEvents: true
} }
} }

View File

@ -25,110 +25,110 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
DropArea { DropArea {
// //
// Show rectangle and set color based on file extension on drag enter // Show rectangle and set color based on file extension on drag enter
// //
onEntered: { onEntered: {
// Get file name & set color of rectangle accordingly // Get file name & set color of rectangle accordingly
if (drag.urls.length > 0) { if (drag.urls.length > 0) {
var path = drag.urls[0].toString() var path = drag.urls[0].toString()
if (path.endsWith(".json") || path.endsWith(".csv")) { if (path.endsWith(".json") || path.endsWith(".csv")) {
drag.accept(Qt.LinkAction) drag.accept(Qt.LinkAction)
dropRectangle.color = Qt.darker(palette.highlight, 1.4) dropRectangle.color = Qt.darker(palette.highlight, 1.4)
} }
// Invalid file name, show red rectangle // Invalid file name, show red rectangle
else else
dropRectangle.color = Cpp_ThemeManager.alternativeHighlight dropRectangle.color = Cpp_ThemeManager.alternativeHighlight
// Show drag&drop rectangle // Show drag&drop rectangle
dropRectangle.opacity = 0.8 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)
} }
// // Process CSV files
// Open *.json & *.csv files on drag drop else if (cleanPath.endsWith(".csv"))
// Cpp_CSV_Player.openFile(cleanPath)
onDropped: { }
// Hide rectangle
dropRectangle.hide()
// Get dropped file URL and remove prefixed "file://" //
var path = drop.urls[0].toString() // Hide drag & drop rectangle on drag exit
if (!Cpp_IsWin) //
path = path.replace(/^(file:\/{2})/,""); onExited: {
else dropRectangle.hide()
path = path.replace(/^(file:\/{3})/,""); }
// Unescape html codes like '%23' for '#' //
var cleanPath = decodeURIComponent(path); // Drop rectangle + icon + text
//
Rectangle {
id: dropRectangle
// Process JSON files function hide() {
if (cleanPath.endsWith(".json")) { rectTimer.start()
Cpp_JSON_Generator.setOperationMode(0)
Cpp_JSON_Generator.loadJsonMap(cleanPath)
}
// Process CSV files
else if (cleanPath.endsWith(".csv"))
Cpp_CSV_Player.openFile(cleanPath)
} }
// opacity: 0
// Hide drag & drop rectangle on drag exit border.width: 1
// anchors.centerIn: parent
onExited: { color: Cpp_ThemeManager.highlight
dropRectangle.hide() 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 {
// Drop rectangle + icon + text id: rectTimer
// interval: 200
Rectangle { onTriggered: dropRectangle.opacity = 0
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{}}
} }
Behavior on opacity {NumberAnimation{}}
}
} }

View File

@ -23,37 +23,37 @@
import QtQuick import QtQuick
Item { Item {
id: root id: root
property real topMargin: -8 property real topMargin: -8
property real leftMargin: -8 property real leftMargin: -8
property real rightMargin: -10 property real rightMargin: -10
property real bottomMargin: -10 property real bottomMargin: -10
property alias border: borderImage.border property alias border: borderImage.border
property alias source: borderImage.source property alias source: borderImage.source
property alias shadowOpacity: borderImage.opacity property alias shadowOpacity: borderImage.opacity
BorderImage { BorderImage {
id: borderImage id: borderImage
opacity: 0.5 opacity: 0.5
smooth: true smooth: true
anchors.fill: parent anchors.fill: parent
source: "qrc:/images/shadow.png" source: "qrc:/images/shadow.png"
verticalTileMode: BorderImage.Round verticalTileMode: BorderImage.Round
horizontalTileMode: BorderImage.Round horizontalTileMode: BorderImage.Round
anchors { anchors {
topMargin: root.topMargin topMargin: root.topMargin
leftMargin: root.leftMargin leftMargin: root.leftMargin
rightMargin: root.rightMargin rightMargin: root.rightMargin
bottomMargin: root.bottomMargin bottomMargin: root.bottomMargin
}
border {
left: 10
top: 10
right: 10
bottom: 10
}
} }
border {
left: 10
top: 10
right: 10
bottom: 10
}
}
} }

View File

@ -27,297 +27,297 @@ import QtQuick.Controls
import SerialStudio as SerialStudio import SerialStudio as SerialStudio
Item { Item {
id: root id: root
property bool isExternalWindow: false property bool isExternalWindow: false
property alias widgetEnabled: textEdit.widgetEnabled property alias widgetEnabled: textEdit.widgetEnabled
property alias vt100emulation: textEdit.vt100emulation property alias vt100emulation: textEdit.vt100emulation
// //
// Save settings // Save settings
// //
Settings { Settings {
property alias hex: hexCheckbox.checked property alias hex: hexCheckbox.checked
property alias echo: echoCheckbox.checked property alias echo: echoCheckbox.checked
property alias timestamp: timestampCheck.checked property alias timestamp: timestampCheck.checked
property alias autoscroll: autoscrollCheck.checked property alias autoscroll: autoscrollCheck.checked
property alias vt100Enabled: textEdit.vt100emulation property alias vt100Enabled: textEdit.vt100emulation
property alias lineEnding: lineEndingCombo.currentIndex property alias lineEnding: lineEndingCombo.currentIndex
property alias displayMode: displayModeCombo.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
} }
// MenuItem {
// Function to send through serial port data text: qsTr("Select all")
// enabled: !textEdit.empty
function sendData() { opacity: enabled ? 1 : 0.5
Cpp_IO_Console.send(send.text) onTriggered: textEdit.selectAll()
send.clear()
} }
// MenuItem {
// Clears console output text: qsTr("Clear")
// opacity: enabled ? 1 : 0.5
function clear() { onTriggered: root.clear()
Cpp_IO_Console.clear() enabled: Cpp_IO_Console.saveAvailable
textEdit.clear()
} }
// MenuSeparator {}
// Copy function
// MenuItem {
function copy() { opacity: enabled ? 1 : 0.5
textEdit.copy() text: qsTr("Print")
enabled: Cpp_IO_Console.saveAvailable
onTriggered: Cpp_IO_Console.print(app.monoFont)
} }
// MenuItem {
// Select all text opacity: enabled ? 1 : 0.5
// text: qsTr("Save as") + "..."
function selectAll() { onTriggered: Cpp_IO_Console.save()
textEdit.selectAll() 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 { SerialStudio.Terminal {
id: contextMenu 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 { MouseArea {
id: copyMenu id: mouseArea
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 {
anchors.fill: parent anchors.fill: parent
spacing: app.spacing cursorShape: Qt.IBeamCursor
anchors.margins: app.spacing * 1.5 propagateComposedEvents: true
acceptedButtons: Qt.RightButton
anchors.rightMargin: textEdit.scrollbarWidth
// onClicked: (mouse) => {
// Console display if (mouse.button === Qt.RightButton) {
// contextMenu.popup()
SerialStudio.Terminal { mouse.accepted = true
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
}
}
} }
//
// 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
}
}
}
} }

View File

@ -25,165 +25,165 @@ import QtQuick.Layouts
import QtQuick.Controls import QtQuick.Controls
Page { Page {
id: root id: root
clip: true clip: true
// //
// Custom properties // Custom properties
// //
property int borderWidth: 3 property int borderWidth: 3
property alias icon: _bt.icon property alias icon: _bt.icon
property bool gradient: false property bool gradient: false
property int headerHeight: 32 property int headerHeight: 32
property bool headerVisible: true property bool headerVisible: true
property alias showIcon: _bt.visible property alias showIcon: _bt.visible
property int radius: root.borderWidth + 2 property int radius: root.borderWidth + 2
property color titleColor: palette.brightText property color titleColor: palette.brightText
property color borderColor: palette.highlight property color borderColor: palette.highlight
property bool altButtonEnabled: false property bool altButtonEnabled: false
property alias altButtonIcon: altBt.icon property alias altButtonIcon: altBt.icon
property alias headerDoubleClickEnabled: headerMouseArea.enabled property alias headerDoubleClickEnabled: headerMouseArea.enabled
property color backgroundColor: Cpp_ThemeManager.widgetWindowBackground property color backgroundColor: Cpp_ThemeManager.widgetWindowBackground
property color gradientColor1: root.gradient ? Cpp_ThemeManager.windowGradient1 : property color gradientColor1: root.gradient ? Cpp_ThemeManager.windowGradient1 :
root.borderColor root.borderColor
property color gradientColor2: root.gradient ? Cpp_ThemeManager.windowGradient2 : property color gradientColor2: root.gradient ? Cpp_ThemeManager.windowGradient2 :
root.borderColor root.borderColor
// //
// Signals // Signals
// //
signal altButtonClicked() signal altButtonClicked()
signal headerDoubleClicked() signal headerDoubleClicked()
// //
// Layout properties // Layout properties
// //
visible: opacity > 0 visible: opacity > 0
Layout.preferredWidth: enabled ? implicitWidth : 0 Layout.preferredWidth: enabled ? implicitWidth : 0
Layout.preferredHeight: enabled ? implicitHeight : 0 Layout.preferredHeight: enabled ? implicitHeight : 0
// //
// Background widget // Background widget
// //
background: Rectangle { background: Rectangle {
radius: root.radius radius: root.radius
color: root.backgroundColor color: root.backgroundColor
border.width: root.borderWidth border.width: root.borderWidth
border.color: root.gradientColor1 border.color: root.gradientColor1
Rectangle { Rectangle {
border.width: 1 border.width: 1
color: "transparent" color: "transparent"
anchors.fill: parent anchors.fill: parent
anchors.topMargin: header.height anchors.topMargin: header.height
anchors.margins: root.borderWidth anchors.margins: root.borderWidth
border.color: Cpp_ThemeManager.border 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
}
} }
// Rectangle {
// Window title & controls z: 5
// color: root.gradientColor1
header: Rectangle { height: root.gradient ? 1 : parent.radius
radius: root.radius
color: root.borderColor
height: root.headerHeight
visible: root.headerVisible
gradient: Gradient { anchors {
GradientStop { left: parent.left
position: 0 right: parent.right
color: root.gradientColor1 bottom: parent.bottom
} }
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 {}
}
}
} }
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 {}
}
}
}
} }

View File

@ -28,197 +28,197 @@ import QtQuick.Controls
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Custom properties // Custom properties
// //
readonly property int year: new Date().getFullYear() readonly property int year: new Date().getFullYear()
// //
// Window options // Window options
// //
title: qsTr("About") title: qsTr("About")
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight
x: (Screen.desktopAvailableWidth - width) / 2 x: (Screen.desktopAvailableWidth - width) / 2
y: (Screen.desktopAvailableHeight - height) / 2 y: (Screen.desktopAvailableHeight - height) / 2
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
maximumWidth: 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 minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
// //
// Titlebar options // Titlebar options
// //
minimizeEnabled: false minimizeEnabled: false
maximizeEnabled: false maximizeEnabled: false
titlebarText: Cpp_ThemeManager.text titlebarText: Cpp_ThemeManager.text
titlebarColor: Cpp_ThemeManager.dialogBackground titlebarColor: Cpp_ThemeManager.dialogBackground
backgroundColor: Cpp_ThemeManager.dialogBackground backgroundColor: Cpp_ThemeManager.dialogBackground
// //
// Use page item to set application palette // Use page item to set application palette
// //
Page { Page {
anchors { anchors {
fill: parent fill: parent
margins: root.shadowMargin margins: root.shadowMargin
topMargin: titlebar.height + 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")
}
}
} }
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")
}
}
}
} }

View File

@ -28,101 +28,101 @@ import QtQuick.Controls
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Window options // Window options
// //
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight
minimizeEnabled: false minimizeEnabled: false
maximizeEnabled: false maximizeEnabled: false
title: qsTr("Acknowledgements") title: qsTr("Acknowledgements")
titlebarText: Cpp_ThemeManager.text titlebarText: Cpp_ThemeManager.text
x: (Screen.desktopAvailableWidth - width) / 2 x: (Screen.desktopAvailableWidth - width) / 2
y: (Screen.desktopAvailableHeight - height) / 2 y: (Screen.desktopAvailableHeight - height) / 2
titlebarColor: Cpp_ThemeManager.dialogBackground titlebarColor: Cpp_ThemeManager.dialogBackground
backgroundColor: Cpp_ThemeManager.dialogBackground backgroundColor: Cpp_ThemeManager.dialogBackground
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
maximumWidth: 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 minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
maximumHeight: 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 // Use page item to set application palette
// //
Page { Page {
anchors { anchors {
fill: parent fill: parent
margins: root.shadowMargin margins: root.shadowMargin
topMargin: titlebar.height + 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
}
}
} }
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
}
}
}
} }

View File

@ -28,155 +28,155 @@ import QtQuick.Controls
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Window options // Window options
// //
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight
minimizeEnabled: false minimizeEnabled: false
maximizeEnabled: false maximizeEnabled: false
title: qsTr("CSV Player") title: qsTr("CSV Player")
titlebarText: Cpp_ThemeManager.text titlebarText: Cpp_ThemeManager.text
x: (Screen.desktopAvailableWidth - width) / 2 x: (Screen.desktopAvailableWidth - width) / 2
y: (Screen.desktopAvailableHeight - height) / 2 y: (Screen.desktopAvailableHeight - height) / 2
titlebarColor: Cpp_ThemeManager.dialogBackground titlebarColor: Cpp_ThemeManager.dialogBackground
backgroundColor: Cpp_ThemeManager.dialogBackground backgroundColor: Cpp_ThemeManager.dialogBackground
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
maximumWidth: 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 extraFlags: Qt.WindowStaysOnTopHint | Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 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 maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
// //
// Close CSV file when window is closed // Close CSV file when window is closed
// //
onVisibleChanged: { onVisibleChanged: {
if (!visible && Cpp_CSV_Player.isOpen) if (!visible && Cpp_CSV_Player.isOpen)
Cpp_CSV_Player.closeFile() 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
} }
// palette.alternateBase: Cpp_ThemeManager.base
// Automatically display the window when the CSV file is opened palette.base: Cpp_ThemeManager.base
// palette.brightText: Cpp_ThemeManager.brightText
Connections { palette.button: Cpp_ThemeManager.button
target: Cpp_CSV_Player palette.buttonText: Cpp_ThemeManager.buttonText
function onOpenChanged() { palette.highlight: Cpp_ThemeManager.highlight
if (Cpp_CSV_Player.isOpen) palette.highlightedText: Cpp_ThemeManager.highlightedText
root.visible = true palette.link: Cpp_ThemeManager.link
else palette.placeholderText: Cpp_ThemeManager.placeholderText
root.visible = false 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 { anchors {
fill: parent top: parent.top
margins: root.shadowMargin left: parent.left
topMargin: titlebar.height + root.shadowMargin right: parent.right
}
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
}
}
} }
}
} }
//
// 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
}
}
}
}
} }

View File

@ -29,222 +29,222 @@ import QtQuick.Controls
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Window options // Window options
// //
title: qsTr("Donate") title: qsTr("Donate")
width: minimumWidth width: minimumWidth
height: minimumHeight height: minimumHeight
minimizeEnabled: false minimizeEnabled: false
maximizeEnabled: false maximizeEnabled: false
titlebarText: Cpp_ThemeManager.text titlebarText: Cpp_ThemeManager.text
x: (Screen.desktopAvailableWidth - width) / 2 x: (Screen.desktopAvailableWidth - width) / 2
y: (Screen.desktopAvailableHeight - height) / 2 y: (Screen.desktopAvailableHeight - height) / 2
titlebarColor: Cpp_ThemeManager.dialogBackground titlebarColor: Cpp_ThemeManager.dialogBackground
backgroundColor: Cpp_ThemeManager.dialogBackground backgroundColor: Cpp_ThemeManager.dialogBackground
extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint extraFlags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin minimumWidth: column.implicitWidth + 4 * app.spacing + 2 * root.shadowMargin
maximumWidth: 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 minimumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin maximumHeight: column.implicitHeight + 4 * app.spacing + titlebar.height + 2 * root.shadowMargin
// //
// Custom properties // Custom properties
// //
property alias doNotShowAgain: doNotShowAgainCheck.checked property alias doNotShowAgain: doNotShowAgainCheck.checked
// //
// Enables the "do not show again" checkbox and sets // Enables the "do not show again" checkbox and sets
// the text of the close button to "later". // the text of the close button to "later".
// //
// This is used when the window is shown automatically // This is used when the window is shown automatically
// every now and then to the user. // every now and then to the user.
// //
function showAutomatically() { function showAutomatically() {
doNotShowAgainCheck.visible = true doNotShowAgainCheck.visible = true
closeBt.text = qsTr("Later") closeBt.text = qsTr("Later")
showNormal() 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
} }
// palette.alternateBase: Cpp_ThemeManager.base
// Disables the "do not show again" checkbox and sets palette.base: Cpp_ThemeManager.base
// the text of the close button to "close". palette.brightText: Cpp_ThemeManager.brightText
// palette.button: Cpp_ThemeManager.button
// This is used when the user opens this dialog from palette.buttonText: Cpp_ThemeManager.buttonText
// the "about" window. palette.highlight: Cpp_ThemeManager.highlight
// palette.highlightedText: Cpp_ThemeManager.highlightedText
function show() { palette.link: Cpp_ThemeManager.link
doNotShowAgainCheck.visible = false palette.placeholderText: Cpp_ThemeManager.placeholderText
closeBt.text = qsTr("Close") palette.text: Cpp_ThemeManager.text
showNormal() palette.toolTipBase: Cpp_ThemeManager.tooltipBase
} palette.toolTipText: Cpp_ThemeManager.tooltipText
palette.window: Cpp_ThemeManager.window
palette.windowText: Cpp_ThemeManager.windowText
// background: Rectangle {
// Save settings radius: root.radius
// color: root.backgroundColor
Settings {
property alias disableDonationsWindow: root.doNotShowAgain Rectangle {
} height: root.radius
color: root.backgroundColor
//
// Use page item to set application palette
//
Page {
anchors { anchors {
fill: parent top: parent.top
margins: root.shadowMargin left: parent.left
topMargin: titlebar.height + root.shadowMargin right: parent.right
}
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")
}
}
} }
}
} }
//
// 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

View File

@ -34,355 +34,355 @@ import "../FramelessWindow" as FramelessWindow
import "../PlatformDependent" as PlatformDependent import "../PlatformDependent" as PlatformDependent
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Quit application when this window is closed // Quit application when this window is closed
// //
onClosed: Qt.quit() onClosed: Qt.quit()
// //
// Customize window border // Customize window border
// //
showIcon: true showIcon: true
borderWidth: 1 borderWidth: 1
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5) borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
// //
// Global properties // Global properties
// //
readonly property bool setupVisible: setup.visible readonly property bool setupVisible: setup.visible
readonly property bool consoleVisible: terminal.visible readonly property bool consoleVisible: terminal.visible
readonly property bool dashboardVisible: dashboard.visible readonly property bool dashboardVisible: dashboard.visible
// //
// Custom properties // Custom properties
// //
property int appLaunchCount: 0 property int appLaunchCount: 0
property bool firstValidFrame: false property bool firstValidFrame: false
property bool automaticUpdates: false property bool automaticUpdates: false
property alias vt100emulation: terminal.vt100emulation property alias vt100emulation: terminal.vt100emulation
// //
// Toolbar functions aliases // Toolbar functions aliases
// //
function showSetup() { toolbar.setupClicked() } function showSetup() { toolbar.setupClicked() }
function showConsole() { toolbar.consoleClicked() } function showConsole() { toolbar.consoleClicked() }
function showDashboard() { dbTimer.start() } function showDashboard() { dbTimer.start() }
// //
// Wait a little before showing the dashboard to avoid UI glitches and/or overloading // Wait a little before showing the dashboard to avoid UI glitches and/or overloading
// the rendering engine // the rendering engine
// //
Timer { Timer {
id: dbTimer id: dbTimer
interval: 500 interval: 500
onTriggered: toolbar.dashboardClicked() 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 // Menubar
//
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 { Loader {
active: Cpp_IsMac opacity: 0.8
asynchronous: false asynchronous: false
sourceComponent: PlatformDependent.MenubarMacOS {} 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 { Item {
color: root.titlebarColor Layout.fillWidth: true
anchors.fill: menubarLayout }
visible: !Cpp_ThemeManager.customWindowDecorations }
//
// 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 {
// Menubar, shown by default on Windows & Linux and when the app is fullscreen spacing: 0
// anchors.fill: parent
RowLayout {
id: menubarLayout
z: titlebar.z + 1
spacing: app.spacing
height: !showMenubar ? titlebar.height : 38
readonly property bool showMenubar: !root.showMacControls || isFullscreen //
// Application toolbar
anchors { //
top: parent.top Toolbar {
left: parent.left id: toolbar
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 {
window: root window: root
anchors.fill: parent z: titlebar.z
handleSize: root.handleSize 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
}
} }

View File

@ -31,139 +31,139 @@ import "../Widgets" as Widgets
import "../FramelessWindow" as FramelessWindow import "../FramelessWindow" as FramelessWindow
FramelessWindow.CustomWindow { FramelessWindow.CustomWindow {
id: root id: root
// //
// Window options // Window options
// //
minimumWidth: 910 minimumWidth: 910
minimumHeight: 720 minimumHeight: 720
title: qsTr("Project Editor - %1").arg(Cpp_Project_Model.jsonFileName) title: qsTr("Project Editor - %1").arg(Cpp_Project_Model.jsonFileName)
// //
// Customize window border // Customize window border
// //
borderWidth: 1 borderWidth: 1
borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5) borderColor: Qt.darker(Cpp_ThemeManager.toolbarGradient2, 1.5)
// //
// Ensure that current JSON file is shown // Ensure that current JSON file is shown
// //
Component.onCompleted: Cpp_Project_Model.openJsonFile(Cpp_JSON_Generator.jsonMapFilepath) Component.onCompleted: Cpp_Project_Model.openJsonFile(Cpp_JSON_Generator.jsonMapFilepath)
// //
// Ask user to save changes before closing the window // Ask user to save changes before closing the window
// //
onClosing: (close) => close.accepted = Cpp_Project_Model.askSave() onClosing: (close) => close.accepted = Cpp_Project_Model.askSave()
// //
// Dummy string to increase width of buttons // Dummy string to increase width of buttons
// //
readonly property string _btSpacer: " " readonly property string _btSpacer: " "
// //
// Save window size // Save window size
// //
Settings { Settings {
category: "ProjectEditor" category: "ProjectEditor"
property alias windowX: root.x property alias windowX: root.x
property alias windowY: root.y property alias windowY: root.y
property alias windowWidth: root.width property alias windowWidth: root.width
property alias windowHeight: root.height 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 { Widgets.Shadow {
clip: true anchors.fill: header
anchors.fill: parent } Widgets.Shadow {
anchors.margins: root.shadowMargin anchors.fill: footer
anchors.topMargin: titlebar.height + root.shadowMargin anchors.bottomMargin: footer.height / 2
}
palette.alternateBase: Cpp_ThemeManager.base //
palette.base: Cpp_ThemeManager.base // Header (project properties)
palette.brightText: Cpp_ThemeManager.brightText //
palette.button: Cpp_ThemeManager.button Header {
palette.buttonText: Cpp_ThemeManager.buttonText id: header
palette.highlight: Cpp_ThemeManager.highlight anchors {
palette.highlightedText: Cpp_ThemeManager.highlightedText margins: 0
palette.link: Cpp_ThemeManager.link top: parent.top
palette.placeholderText: Cpp_ThemeManager.placeholderText left: parent.left
palette.text: Cpp_ThemeManager.text right: parent.right
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 // Footer background
color: Cpp_ThemeManager.windowBackground //
} Footer {
id: footer
radius: root.radius
onCloseWindow: root.close()
onScrollToBottom: groupEditor.selectLastGroup()
// anchors {
// Shadows margins: 0
// left: parent.left
Widgets.Shadow { right: parent.right
anchors.fill: header bottom: parent.bottom
} Widgets.Shadow { }
anchors.fill: footer }
anchors.bottomMargin: footer.height / 2
}
// //
// Header (project properties) // Window controls
// //
Header { RowLayout {
id: header clip: true
anchors { anchors.fill: parent
margins: 0 spacing: app.spacing
top: parent.top anchors.topMargin: header.height
left: parent.left anchors.bottomMargin: footer.height
right: parent.right
}
}
// //
// Footer background // Horizontal spacer
// //
Footer { Item {
id: footer Layout.fillHeight: true
radius: root.radius Layout.minimumWidth: app.spacing
onCloseWindow: root.close() Layout.maximumWidth: app.spacing
onScrollToBottom: groupEditor.selectLastGroup() }
anchors { //
margins: 0 // JSON structure tree
left: parent.left //
right: parent.right /*TreeView {
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 {
id: jsonTree id: jsonTree
Layout.fillHeight: true Layout.fillHeight: true
Layout.minimumWidth: 240 Layout.minimumWidth: 240
@ -173,69 +173,69 @@ FramelessWindow.CustomWindow {
visible: Cpp_Project_Model.groupCount !== 0 visible: Cpp_Project_Model.groupCount !== 0
}*/ }*/
// //
// Group editor // Group editor
// //
GroupEditor { GroupEditor {
id: groupEditor id: groupEditor
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: Cpp_Project_Model.groupCount !== 0 visible: Cpp_Project_Model.groupCount !== 0
} }
// //
// Empty project text & icon // Empty project text & icon
// //
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
visible: Cpp_Project_Model.groupCount === 0 visible: Cpp_Project_Model.groupCount === 0
ColumnLayout { ColumnLayout {
spacing: app.spacing spacing: app.spacing
anchors.centerIn: parent anchors.centerIn: parent
Widgets.Icon { Widgets.Icon {
width: 128 width: 128
height: 128 height: 128
color: Cpp_ThemeManager.text color: Cpp_ThemeManager.text
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
source: "qrc:/icons/developer-board.svg" source: "qrc:/icons/developer-board.svg"
} }
Label { Label {
font.bold: true font.bold: true
font.pixelSize: 24 font.pixelSize: 24
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr("Start something awesome") text: qsTr("Start something awesome")
} }
Label { Label {
opacity: 0.8 opacity: 0.8
font.pixelSize: 18 font.pixelSize: 18
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
text: qsTr("Click on the \"Add group\" button to begin") text: qsTr("Click on the \"Add group\" button to begin")
} }
}
}
//
// Horizontal spacer
//
Item {
Layout.fillHeight: true
Layout.minimumWidth: app.spacing
Layout.maximumWidth: app.spacing
}
} }
} }
// //
// Resize handler // Horizontal spacer
// //
FramelessWindow.ResizeHandles { Item {
window: root Layout.fillHeight: true
anchors.fill: parent Layout.minimumWidth: app.spacing
handleSize: root.handleSize Layout.maximumWidth: app.spacing
}
} }
}
//
// Resize handler
//
FramelessWindow.ResizeHandles {
window: root
anchors.fill: parent
handleSize: root.handleSize
}
} }

View File

@ -27,92 +27,92 @@ import QtQuick.Controls
import "Windows" as Windows import "Windows" as Windows
Item { Item {
id: app id: app
// //
// Global propeties // Global propeties
// //
readonly property int spacing: 8 readonly property int spacing: 8
readonly property string monoFont: "Roboto Mono" readonly property string monoFont: "Roboto Mono"
// //
// Access to dialogs & windows // Access to dialogs & windows
// //
property Windows.About aboutDialog: null property Window aboutDialog: null
property Windows.Donate donateDialog: null property Window donateDialog: null
property Windows.MainWindow mainWindow: null property Window mainWindow: null
property Windows.CsvPlayer csvPlayerDialog: null property Window csvPlayerDialog: null
property Windows.ProjectEditor projectEditorWindow: null property Window projectEditorWindow: null
property Windows.Acknowledgements acknowledgementsDialog: null property Window acknowledgementsDialog: null
// //
// Check for updates (non-silent mode) // Check for updates (non-silent mode)
// //
function checkForUpdates() { function checkForUpdates() {
Cpp_Updater.setNotifyOnFinish(Cpp_AppUpdaterUrl, true) Cpp_Updater.setNotifyOnFinish(Cpp_AppUpdaterUrl, true)
Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl) Cpp_Updater.checkForUpdates(Cpp_AppUpdaterUrl)
}
//
// MainWindow
//
Loader {
asynchronous: true
sourceComponent: Windows.MainWindow {
Component.onCompleted: {
app.forceActiveFocus()
app.mainWindow = this
}
} }
}
// //
// MainWindow // About window
// //
Loader { Loader {
asynchronous: true asynchronous: true
sourceComponent: Windows.MainWindow { sourceComponent: Windows.About {
Component.onCompleted: { Component.onCompleted: app.aboutDialog = this
app.forceActiveFocus()
app.mainWindow = this
}
}
} }
}
// //
// About window // CSV player window
// //
Loader { Loader {
asynchronous: true asynchronous: true
sourceComponent: Windows.About { sourceComponent: Windows.CsvPlayer {
Component.onCompleted: app.aboutDialog = this Component.onCompleted: app.csvPlayerDialog = this
}
} }
}
// //
// CSV player window // Project editor dialog
// //
Loader { Loader {
asynchronous: true asynchronous: true
sourceComponent: Windows.CsvPlayer { sourceComponent: Windows.ProjectEditor {
Component.onCompleted: app.csvPlayerDialog = this Component.onCompleted: app.projectEditorWindow = this
}
} }
}
// //
// Project editor dialog // Donations dialog
// //
Loader { Loader {
asynchronous: true asynchronous: false
sourceComponent: Windows.ProjectEditor { sourceComponent: Windows.Donate {
Component.onCompleted: app.projectEditorWindow = this Component.onCompleted: app.donateDialog = this
}
} }
}
// //
// Donations dialog // Acknowledgements dialog
// //
Loader { Loader {
asynchronous: false asynchronous: true
sourceComponent: Windows.Donate { sourceComponent: Windows.Acknowledgements {
Component.onCompleted: app.donateDialog = this 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

View File

@ -8,5 +8,5 @@ StartupNotify=true
Categories=Electronics;Engineering;Science; Categories=Electronics;Engineering;Science;
Icon=serial-studio Icon=serial-studio
X-AppImage-Name=Serial Studio X-AppImage-Name=Serial Studio
X-AppImage-Version=2.0.0 X-AppImage-Version=2.1.0
X-AppImage-Arch=x86_64 X-AppImage-Arch=x86_64

View File

@ -31,7 +31,7 @@ Unicode True
!define COMPANYNAME "Alex Spataru" !define COMPANYNAME "Alex Spataru"
!define DESCRIPTION "Multi-purpose data visualization & processing program" !define DESCRIPTION "Multi-purpose data visualization & processing program"
!define VERSIONMAJOR 2 !define VERSIONMAJOR 2
!define VERSIONMINOR 0 !define VERSIONMINOR 1
!define VERSIONBUILD 0 !define VERSIONBUILD 0
!define MUI_ABORTWARNING !define MUI_ABORTWARNING
!define INSTALL_DIR "$PROGRAMFILES64\${APPNAME}" !define INSTALL_DIR "$PROGRAMFILES64\${APPNAME}"

View File

@ -1,7 +0,0 @@
Makefile
*.moc
*.o
lib
.qmake.cache
.qmake.stash
.DS_Store

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -1 +0,0 @@
add_subdirectory(mactouchbar)

View File

@ -1,3 +0,0 @@
TEMPLATE=subdirs
SUBDIRS=mactouchbar

View File

@ -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)

View File

@ -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

View File

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file>qtlogo.png</file>
</qresource>
</RCC>

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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

View File

@ -1,8 +0,0 @@
TEMPLATE = subdirs
features.path = $$INSTALL_PREFIX/share/mkspecs/features
features.files = *.prf
INSTALLS += features
OTHER_FILES = *.prf

View File

@ -1,4 +0,0 @@
LIBPATH=$$clean_path($$PWD/../../../lib)
LIBS += -F$$LIBPATH -framework KDMacTouchBar
QMAKE_LFLAGS += '-Wl,-rpath,\'$$LIBPATH\''
INCLUDEPATH += $$LIBPATH/KDMacTouchBar.framework/Headers

View File

@ -1 +0,0 @@
VERSION = 1.0

View File

@ -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

View File

@ -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
)

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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
View File

@ -49,14 +49,3 @@ include($$PWD/OpenSSL/OpenSSL.pri)
include($$PWD/QRealFourier/QRealFourier.pri) include($$PWD/QRealFourier/QRealFourier.pri)
include($$PWD/QSimpleUpdater/QSimpleUpdater.pri) include($$PWD/QSimpleUpdater/QSimpleUpdater.pri)
include($$PWD/QSourceHighlite/QSourceHighlite.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.

View File

@ -16,239 +16,291 @@
#ifdef VPAES_ASM #ifdef VPAES_ASM
int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); 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); 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_encrypt(const unsigned char *in, unsigned char *out,
void vpaes_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); const AES_KEY *key);
void vpaes_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, void vpaes_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec, int enc); 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 */ #endif /* VPAES_ASM */
#ifdef BSAES_ASM #ifdef BSAES_ASM
void ossl_bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, void ossl_bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char ivec[16], int enc); size_t length, const AES_KEY *key,
void ossl_bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len, unsigned char ivec[16], int enc);
const AES_KEY *key, const unsigned char ivec[16]); void ossl_bsaes_ctr32_encrypt_blocks(const unsigned char *in,
void ossl_bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, unsigned char *out, size_t len,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); const AES_KEY *key,
void ossl_bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, const unsigned char ivec[16]);
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[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 */ #endif /* BSAES_ASM */
#ifdef AES_CTR_ASM #ifdef AES_CTR_ASM
void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); size_t blocks, const AES_KEY *key,
const unsigned char ivec[AES_BLOCK_SIZE]);
#endif /* AES_CTR_ASM */ #endif /* AES_CTR_ASM */
#ifdef AES_XTS_ASM #ifdef AES_XTS_ASM
void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1, void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
const AES_KEY *key2, const unsigned char iv[16]); const AES_KEY *key1, const AES_KEY *key2,
void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1, const unsigned char iv[16]);
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 */ #endif /* AES_XTS_ASM */
#if defined(OPENSSL_CPUID_OBJ) #if defined(OPENSSL_CPUID_OBJ)
# if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) # if (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
# include "crypto/ppc_arch.h" # include "crypto/ppc_arch.h"
# ifdef VPAES_ASM # ifdef VPAES_ASM
# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) # 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
# 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 */ #endif /* OPENSSL_CPUID_OBJ */
#if defined(AES_ASM) \ #if defined(AES_ASM) \
&& (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
# define AES_CBC_HMAC_SHA_CAPABLE 1 || defined(_M_X64))
# define AESNI_CBC_HMAC_SHA_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) # define AES_CBC_HMAC_SHA_CAPABLE 1
# define AESNI_CBC_HMAC_SHA_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
#endif #endif
#if defined(__loongarch__) || defined(__loongarch64) #if defined(__loongarch__) || defined(__loongarch64)
# include "loongarch_arch.h" # include "loongarch_arch.h"
# if defined(VPAES_ASM) # if defined(VPAES_ASM)
# define VPAES_CAPABLE (OPENSSL_loongarchcap_P & LOONGARCH_CFG2_LSX) # define VPAES_CAPABLE (OPENSSL_loongarchcap_P & LOONGARCH_CFG2_LSX)
# endif # endif
#endif #endif
#if defined(AES_ASM) && !defined(I386_ONLY) \ #if defined(AES_ASM) && !defined(I386_ONLY) \
&& (((defined(__i386) || defined(__i386__) || defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2)) \ && (((defined(__i386) || defined(__i386__) || defined(_M_IX86)) \
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) && defined(OPENSSL_IA32_SSE2)) \
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
|| defined(_M_X64))
/* AES-NI section */ /* AES-NI section */
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) # define AESNI_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (57 - 32)))
# ifdef VPAES_ASM # ifdef VPAES_ASM
# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) # define VPAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
# endif # endif
# ifdef BSAES_ASM # ifdef BSAES_ASM
# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) # define BSAES_CAPABLE (OPENSSL_ia32cap_P[1] & (1 << (41 - 32)))
# endif # endif
# define AES_GCM_ENC_BYTES 32 # define AES_GCM_ENC_BYTES 32
# define AES_GCM_DEC_BYTES 16 # define AES_GCM_DEC_BYTES 16
int aesni_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); 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); 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_encrypt(const unsigned char *in, unsigned char *out,
void aesni_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 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, void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, int enc); size_t length, const AES_KEY *key, int enc);
void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec, int enc); size_t length, const AES_KEY *key, unsigned char *ivec,
# ifndef OPENSSL_NO_OCB int enc);
void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, # ifndef OPENSSL_NO_OCB
size_t start_block_num, unsigned char offset_i[16], void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out,
const unsigned char L_[][16], unsigned char checksum[16]); size_t blocks, const void *key, size_t start_block_num,
void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, unsigned char offset_i[16], const unsigned char L_[][16],
size_t start_block_num, unsigned char offset_i[16], unsigned char checksum[16]);
const unsigned char L_[][16], unsigned char checksum[16]); void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out,
# endif /* OPENSSL_NO_OCB */ 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, void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
const void *key, const unsigned char *ivec); size_t blocks, const void *key,
const unsigned char *ivec);
void aesni_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, void aesni_xts_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); 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, void aesni_xts_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); 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, void aesni_ccm64_encrypt_blocks(const unsigned char *in, unsigned char *out,
const void *key, const unsigned char ivec[16], size_t blocks, const void *key,
const unsigned char ivec[16],
unsigned char cmac[16]); unsigned char cmac[16]);
void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out, size_t blocks, void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out,
const void *key, const unsigned char ivec[16], size_t blocks, const void *key,
const unsigned char ivec[16],
unsigned char cmac[16]); unsigned char cmac[16]);
# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) # if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) \
size_t aesni_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key, || defined(_M_X64)
unsigned char ivec[16], u64 *Xi); size_t aesni_gcm_encrypt(const unsigned char *in, unsigned char *out,
size_t aesni_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key, size_t len, const void *key, unsigned char ivec[16],
unsigned char ivec[16], u64 *Xi); 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); 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_encrypt aesni_gcm_encrypt
# define AES_gcm_decrypt aesni_gcm_decrypt # define AES_gcm_decrypt aesni_gcm_decrypt
# define AES_GCM_ASM(ctx) \ # define AES_GCM_ASM(ctx) \
(ctx->ctr == aesni_ctr32_encrypt_blocks && ctx->gcm.funcs.ghash == gcm_ghash_avx) (ctx->ctr == aesni_ctr32_encrypt_blocks \
# endif && ctx->gcm.funcs.ghash == gcm_ghash_avx)
# endif
#elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) #elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
/* Fujitsu SPARC64 X support */ /* 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 SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES)
# define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX) # define HWAES_CAPABLE (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
# define HWAES_set_encrypt_key aes_fx_set_encrypt_key # define HWAES_set_encrypt_key aes_fx_set_encrypt_key
# define HWAES_set_decrypt_key aes_fx_set_decrypt_key # define HWAES_set_decrypt_key aes_fx_set_decrypt_key
# define HWAES_encrypt aes_fx_encrypt # define HWAES_encrypt aes_fx_encrypt
# define HWAES_decrypt aes_fx_decrypt # define HWAES_decrypt aes_fx_decrypt
# define HWAES_cbc_encrypt aes_fx_cbc_encrypt # define HWAES_cbc_encrypt aes_fx_cbc_encrypt
# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks # 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_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_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_encrypt(const unsigned char *in, unsigned char *out,
void aes_t4_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 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. * Key-length specific subroutines were chosen for following reason.
* Each SPARC T4 core can execute up to 8 threads which share core's * 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 * acceptable, while latter means code size increase to size occupied
* by multiple key-length specific subroutines, so why fight? * by multiple key-length specific subroutines, so why fight?
*/ */
void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec, int /*unused*/); size_t len, const AES_KEY *key, unsigned char *ivec,
void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len, int /*unused*/);
const AES_KEY *key, unsigned char *ivec, int /*unused*/); void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, size_t len, const AES_KEY *key, unsigned char *ivec,
const AES_KEY *key, unsigned char *ivec, int /*unused*/); int /*unused*/);
void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len, void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec, int /*unused*/); size_t len, const AES_KEY *key, unsigned char *ivec,
void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, int /*unused*/);
const AES_KEY *key, unsigned char *ivec, int /*unused*/); void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len, size_t len, const AES_KEY *key, unsigned char *ivec,
const AES_KEY *key, unsigned char *ivec, int /*unused*/); int /*unused*/);
void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec); size_t len, const AES_KEY *key, unsigned char *ivec,
void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, int /*unused*/);
const AES_KEY *key, unsigned char *ivec); void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, size_t len, const AES_KEY *key, unsigned char *ivec,
const AES_KEY *key, unsigned char *ivec); int /*unused*/);
void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec); size_t blocks, const AES_KEY *key,
void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, unsigned char *ivec);
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec); void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, size_t blocks, const AES_KEY *key,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec); unsigned char *ivec);
void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key1, const AES_KEY *key2, const unsigned char *ivec); 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__) #elif defined(OPENSSL_CPUID_OBJ) && defined(__s390__)
/* IBM S390X support */ /* IBM S390X support */
# include "s390x_arch.h" # include "s390x_arch.h"
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ /* 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. */ /* 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_128_CAPABLE \
# define S390X_aes_192_CAPABLE (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_192)) (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_128))
# define S390X_aes_256_CAPABLE (OPENSSL_s390xcap_P.km[0] & S390X_CAPBIT(S390X_AES_256)) # 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_128_cbc_CAPABLE 1 /* checked by callee */
# define S390X_aes_192_cbc_CAPABLE 1 # define S390X_aes_192_cbc_CAPABLE 1
# define S390X_aes_256_cbc_CAPABLE 1 # define S390X_aes_256_cbc_CAPABLE 1
# define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE # define S390X_aes_128_ecb_CAPABLE S390X_aes_128_CAPABLE
# define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE # define S390X_aes_192_ecb_CAPABLE S390X_aes_192_CAPABLE
# define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE # define S390X_aes_256_ecb_CAPABLE S390X_aes_256_CAPABLE
# define S390X_aes_128_ofb_CAPABLE \ # define S390X_aes_128_ofb_CAPABLE \
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_128))) (S390X_aes_128_CAPABLE \
# define S390X_aes_192_ofb_CAPABLE \ && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_128)))
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_192))) # define S390X_aes_192_ofb_CAPABLE \
# define S390X_aes_256_ofb_CAPABLE \ (S390X_aes_192_CAPABLE \
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmo[0] & S390X_CAPBIT(S390X_AES_256))) && (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 \ # define S390X_aes_128_cfb_CAPABLE \
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128))) (S390X_aes_128_CAPABLE \
# define S390X_aes_192_cfb_CAPABLE \ && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128)))
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192))) # define S390X_aes_192_cfb_CAPABLE \
# define S390X_aes_256_cfb_CAPABLE \ (S390X_aes_192_CAPABLE \
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256))) && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192)))
# define S390X_aes_128_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128)) # define S390X_aes_256_cfb_CAPABLE \
# define S390X_aes_192_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_192)) (S390X_aes_256_CAPABLE \
# define S390X_aes_256_cfb8_CAPABLE (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256)) && (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_256)))
# define S390X_aes_128_cfb1_CAPABLE 0 # define S390X_aes_128_cfb8_CAPABLE \
# define S390X_aes_192_cfb1_CAPABLE 0 (OPENSSL_s390xcap_P.kmf[0] & S390X_CAPBIT(S390X_AES_128))
# define S390X_aes_256_cfb1_CAPABLE 0 # 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_128_ctr_CAPABLE 1 /* checked by callee */
# define S390X_aes_192_ctr_CAPABLE 1 # define S390X_aes_192_ctr_CAPABLE 1
# define S390X_aes_256_ctr_CAPABLE 1 # define S390X_aes_256_ctr_CAPABLE 1
# define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */ # define S390X_aes_128_xts_CAPABLE 1 /* checked by callee */
# define S390X_aes_256_xts_CAPABLE 1 # define S390X_aes_256_xts_CAPABLE 1
# define S390X_aes_128_gcm_CAPABLE \ # define S390X_aes_128_gcm_CAPABLE \
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_128))) (S390X_aes_128_CAPABLE \
# define S390X_aes_192_gcm_CAPABLE \ && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_128)))
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_192))) # define S390X_aes_192_gcm_CAPABLE \
# define S390X_aes_256_gcm_CAPABLE \ (S390X_aes_192_CAPABLE \
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kma[0] & S390X_CAPBIT(S390X_AES_256))) && (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 \ # define S390X_aes_128_ccm_CAPABLE \
(S390X_aes_128_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_128))) (S390X_aes_128_CAPABLE \
# define S390X_aes_192_ccm_CAPABLE \ && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_128)))
(S390X_aes_192_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_192))) # define S390X_aes_192_ccm_CAPABLE \
# define S390X_aes_256_ccm_CAPABLE \ (S390X_aes_192_CAPABLE \
(S390X_aes_256_CAPABLE && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_256))) && (OPENSSL_s390xcap_P.kmac[0] & S390X_CAPBIT(S390X_AES_192)))
# define S390X_CCM_AAD_FLAG 0x40 # 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 # ifndef OPENSSL_NO_OCB
# define S390X_aes_128_ocb_CAPABLE 0 # define S390X_aes_128_ocb_CAPABLE 0
# define S390X_aes_192_ocb_CAPABLE 0 # define S390X_aes_192_ocb_CAPABLE 0
# define S390X_aes_256_ocb_CAPABLE 0 # define S390X_aes_256_ocb_CAPABLE 0
# endif /* OPENSSL_NO_OCB */ # endif /* OPENSSL_NO_OCB */
# ifndef OPENSSL_NO_SIV # ifndef OPENSSL_NO_SIV
# define S390X_aes_128_siv_CAPABLE 0 # define S390X_aes_128_siv_CAPABLE 0
# define S390X_aes_192_siv_CAPABLE 0 # define S390X_aes_192_siv_CAPABLE 0
# define S390X_aes_256_siv_CAPABLE 0 # define S390X_aes_256_siv_CAPABLE 0
# endif /* OPENSSL_NO_SIV */ # endif /* OPENSSL_NO_SIV */
/* Convert key size to function code: [16,24,32] -> [18,19,20]. */ /* 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 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 64
/* RISC-V 64 support */ /* RISC-V 64 support */
# include "riscv_arch.h" # include "riscv_arch.h"
# define RV64I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) # 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_zkne_set_encrypt_key(const unsigned char *userKey, const int bits,
int rv64i_zknd_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); AES_KEY *key);
void rv64i_zkne_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); int rv64i_zknd_set_decrypt_key(const unsigned char *userKey, const int bits,
void rv64i_zknd_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 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 #elif defined(OPENSSL_CPUID_OBJ) && defined(__riscv) && __riscv_xlen == 32
/* RISC-V 32 support */ /* RISC-V 32 support */
# include "riscv_arch.h" # include "riscv_arch.h"
# define RV32I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) # define RV32I_ZKND_ZKNE_CAPABLE (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE())
# define RV32I_ZBKB_ZKND_ZKNE_CAPABLE (RV32I_ZKND_ZKNE_CAPABLE && RISCV_HAS_ZBKB()) # 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 */ /* 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_zknd_zkne_set_decrypt_key(const unsigned char *userKey,
int rv32i_zbkb_zkne_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); const int bits, AES_KEY *key);
int rv32i_zbkb_zknd_zkne_set_decrypt_key(const unsigned char *userKey, const int bits, int rv32i_zbkb_zkne_set_encrypt_key(const unsigned char *userKey,
AES_KEY *key); const int bits, AES_KEY *key);
void rv32i_zkne_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); int rv32i_zbkb_zknd_zkne_set_decrypt_key(const unsigned char *userKey,
void rv32i_zknd_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); 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 #endif
#if defined(HWAES_CAPABLE) #if defined(HWAES_CAPABLE)
int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key); AES_KEY *key);
void HWAES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
void HWAES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); AES_KEY *key);
void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, void HWAES_encrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, unsigned char *ivec, const int enc); const AES_KEY *key);
void HWAES_ecb_encrypt(const unsigned char *in, unsigned char *out, size_t length, void HWAES_decrypt(const unsigned char *in, unsigned char *out,
const AES_KEY *key, const int enc); const AES_KEY *key);
void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len, void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
const void *key, const unsigned char ivec[16]); 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, 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, 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]); const AES_KEY *key1, const AES_KEY *key2,
# ifndef OPENSSL_NO_OCB const unsigned char iv[16]);
# ifdef HWAES_ocb_encrypt # ifndef OPENSSL_NO_OCB
void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, # ifdef HWAES_ocb_encrypt
size_t start_block_num, unsigned char offset_i[16], void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out,
const unsigned char L_[][16], unsigned char checksum[16]); size_t blocks, const void *key, size_t start_block_num,
# else unsigned char offset_i[16], const unsigned char L_[][16],
# define HWAES_ocb_encrypt ((ocb128_f)NULL) unsigned char checksum[16]);
# endif # else
# ifdef HWAES_ocb_decrypt # define HWAES_ocb_encrypt ((ocb128_f)NULL)
void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out, size_t blocks, const void *key, # endif
size_t start_block_num, unsigned char offset_i[16], # ifdef HWAES_ocb_decrypt
const unsigned char L_[][16], unsigned char checksum[16]); void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out,
# else size_t blocks, const void *key, size_t start_block_num,
# define HWAES_ocb_decrypt ((ocb128_f)NULL) unsigned char offset_i[16], const unsigned char L_[][16],
# endif unsigned char checksum[16]);
# endif /* OPENSSL_NO_OCB */ # else
# define HWAES_ocb_decrypt ((ocb128_f)NULL)
# endif
# endif /* OPENSSL_NO_OCB */
#endif /* HWAES_CAPABLE */ #endif /* HWAES_CAPABLE */

View File

@ -8,7 +8,8 @@
* https://www.openssl.org/source/license.html * 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 #ifndef OSSL_CRYPTO_ARIA_H
#define OSSL_CRYPTO_ARIA_H #define OSSL_CRYPTO_ARIA_H
@ -17,33 +18,36 @@
#include <openssl/opensslconf.h> #include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_ARIA #ifdef OPENSSL_NO_ARIA
# error ARIA is disabled. # error ARIA is disabled.
#endif #endif
#define ARIA_ENCRYPT 1 #define ARIA_ENCRYPT 1
#define ARIA_DECRYPT 0 #define ARIA_DECRYPT 0
#define ARIA_BLOCK_SIZE 16 /* Size of each encryption/decryption block */ #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 typedef union
{ {
unsigned char c[ARIA_BLOCK_SIZE]; unsigned char c[ARIA_BLOCK_SIZE];
unsigned int u[ARIA_BLOCK_SIZE / sizeof(unsigned int)]; unsigned int u[ARIA_BLOCK_SIZE / sizeof(unsigned int)];
} ARIA_u128; } ARIA_u128;
typedef unsigned char ARIA_c128[ARIA_BLOCK_SIZE]; typedef unsigned char ARIA_c128[ARIA_BLOCK_SIZE];
struct aria_key_st struct aria_key_st
{ {
ARIA_u128 rd_key[ARIA_MAX_KEYS]; ARIA_u128 rd_key[ARIA_MAX_KEYS];
unsigned int rounds; unsigned int rounds;
}; };
typedef struct aria_key_st ARIA_KEY; 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_encrypt_key(const unsigned char *userKey, const int bits,
int ossl_aria_set_decrypt_key(const unsigned char *userKey, const int bits, ARIA_KEY *key); 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 #endif

View File

@ -22,59 +22,65 @@
struct evp_pkey_asn1_method_st struct evp_pkey_asn1_method_st
{ {
int pkey_id; int pkey_id;
int pkey_base_id; int pkey_base_id;
unsigned long pkey_flags; unsigned long pkey_flags;
char *pem_str; char *pem_str;
char *info; char *info;
int (*pub_decode)(EVP_PKEY *pk, const X509_PUBKEY *pub); int (*pub_decode)(EVP_PKEY *pk, const X509_PUBKEY *pub);
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); 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 (*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_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf);
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); 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 (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
int (*pkey_size)(const EVP_PKEY *pk); ASN1_PCTX *pctx);
int (*pkey_bits)(const EVP_PKEY *pk); int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_security_bits)(const EVP_PKEY *pk); int (*pkey_bits)(const EVP_PKEY *pk);
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen); int (*pkey_security_bits)(const EVP_PKEY *pk);
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
int (*param_missing)(const EVP_PKEY *pk); int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); int (*param_missing)(const EVP_PKEY *pk);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx); ASN1_PCTX *pctx);
void (*pkey_free)(EVP_PKEY *pkey); int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, const ASN1_STRING *sig,
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); int indent, ASN1_PCTX *pctx);
/* Legacy functions for old PEM */ void (*pkey_free)(EVP_PKEY *pkey);
int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen); int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); /* Legacy functions for old PEM */
/* Custom ASN1 signature verification */ int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, const X509_ALGOR *a, int derlen);
const ASN1_BIT_STRING *sig, EVP_PKEY *pkey); int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, X509_ALGOR *alg1, /* Custom ASN1 signature verification */
X509_ALGOR *alg2, ASN1_BIT_STRING *sig); int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
int (*siginf_set)(X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig); const X509_ALGOR *a, const ASN1_BIT_STRING *sig,
/* Check */ EVP_PKEY *pkey);
int (*pkey_check)(const EVP_PKEY *pk); int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data,
int (*pkey_public_check)(const EVP_PKEY *pk); X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
int (*pkey_param_check)(const EVP_PKEY *pk); int (*siginf_set)(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
/* Get/set raw private/public key data */ const ASN1_STRING *sig);
int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *priv, size_t len); /* Check */
int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *pub, size_t len); int (*pkey_check)(const EVP_PKEY *pk);
int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *priv, size_t *len); int (*pkey_public_check)(const EVP_PKEY *pk);
int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *pub, size_t *len); 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 */ /* Exports and imports to / from providers */
size_t (*dirty_cnt)(const EVP_PKEY *pk); size_t (*dirty_cnt)(const EVP_PKEY *pk);
int (*export_to)(const EVP_PKEY *pk, void *to_keydata, OSSL_FUNC_keymgmt_import_fn *importer, int (*export_to)(const EVP_PKEY *pk, void *to_keydata,
OSSL_LIB_CTX *libctx, const char *propq); OSSL_FUNC_keymgmt_import_fn *importer, OSSL_LIB_CTX *libctx,
OSSL_CALLBACK *import_from; const char *propq);
int (*copy)(EVP_PKEY *to, EVP_PKEY *from); 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, int (*priv_decode_ex)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf,
const char *propq); OSSL_LIB_CTX *libctx, const char *propq);
} /* EVP_PKEY_ASN1_METHOD */; } /* EVP_PKEY_ASN1_METHOD */;
DEFINE_STACK_OF_CONST(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 * These are used internally in the ASN1_OBJECT to keep track of whether the
* names and data need to be free()ed * names and data need to be free()ed
*/ */
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ #define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */ #define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */ #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 struct asn1_object_st
{ {
const char *sn, *ln; const char *sn, *ln;
int nid; int nid;
int length; int length;
const unsigned char *data; /* data remains const after init */ const unsigned char *data; /* data remains const after init */
int flags; /* Should we free this one */ int flags; /* Should we free this one */
}; };
/* ASN1 print context structure */ /* ASN1 print context structure */
struct asn1_pctx_st struct asn1_pctx_st
{ {
unsigned long flags; unsigned long flags;
unsigned long nm_flags; unsigned long nm_flags;
unsigned long cert_flags; unsigned long cert_flags;
unsigned long oid_flags; unsigned long oid_flags;
unsigned long str_flags; unsigned long str_flags;
} /* ASN1_PCTX */; } /* ASN1_PCTX */;
/* ASN1 type functions */ /* ASN1 type functions */
int ossl_asn1_type_set_octetstring_int(ASN1_TYPE *a, long num, unsigned char *data, int len); int ossl_asn1_type_set_octetstring_int(ASN1_TYPE *a, long num,
int ossl_asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, unsigned char *data, unsigned char *data, int len);
int max_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); 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); 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_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); 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, EVP_PKEY *ossl_d2i_PrivateKey_legacy(int keytype, EVP_PKEY **a,
long length, OSSL_LIB_CTX *libctx, const char *propq); 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); 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); time_t ossl_asn1_string_to_time_t(const char *asn1_string);

View File

@ -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_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_length(PACKET *pkt, PACKET *subpkt);
int ossl_decode_der_integer(PACKET *pkt, BIGNUM *n); 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 #endif

View File

@ -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 * is constant-time by itself. They all have pre-conditions, consult source
* code... * code...
*/ */
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont, int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_CTX *ctx); 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_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx); BN_CTX *ctx);
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); 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_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_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_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
int bn_rshift_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 0
#define BN_PRIMETEST_COMPOSITE_WITH_FACTOR 1 #define BN_PRIMETEST_COMPOSITE_WITH_FACTOR 1
#define BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME 2 #define BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME 2
#define BN_PRIMETEST_PROBABLY_PRIME 3 #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 ossl_bn_miller_rabin_is_prime(const BIGNUM *w, int iterations, BN_CTX *ctx,
int enhanced, int *status); 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_check_generated_prime(const BIGNUM *w, int checks, BN_CTX *ctx,
BN_GENCB *cb);
const BIGNUM *ossl_bn_get0_small_factors(void); 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, int ossl_bn_rsa_fips186_4_gen_prob_primes(BIGNUM *p, BIGNUM *Xpout, BIGNUM *p1,
const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2, BIGNUM *p2, const BIGNUM *Xp,
int nlen, const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); 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, int ossl_bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin,
const BIGNUM *r2, int nlen, const BIGNUM *e, BN_CTX *ctx, const BIGNUM *r1, const BIGNUM *r2,
int nlen, const BIGNUM *e, BN_CTX *ctx,
BN_GENCB *cb); BN_GENCB *cb);
OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx); OSSL_LIB_CTX *ossl_bn_get_libctx(BN_CTX *ctx);

View File

@ -7,10 +7,10 @@
* https://www.openssl.org/source/license.html * https://www.openssl.org/source/license.html
*/ */
#define declare_dh_bn(x) \ #define declare_dh_bn(x) \
extern const BIGNUM ossl_bignum_dh##x##_p; \ extern const BIGNUM ossl_bignum_dh##x##_p; \
extern const BIGNUM ossl_bignum_dh##x##_q; \ extern const BIGNUM ossl_bignum_dh##x##_q; \
extern const BIGNUM ossl_bignum_dh##x##_g; extern const BIGNUM ossl_bignum_dh##x##_g;
declare_dh_bn(1024_160) declare_dh_bn(2048_224) declare_dh_bn(2048_256) declare_dh_bn(1024_160) declare_dh_bn(2048_224) declare_dh_bn(2048_256)

View File

@ -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 * as trivial as collecting bytes into 32-bit elements, it's reckoned
* that below macro is sufficient. * that below macro is sufficient.
*/ */
#define CHACHA_U8TOU32(p) \ #define CHACHA_U8TOU32(p) \
(((unsigned int)(p)[0]) | ((unsigned int)(p)[1] << 8) | ((unsigned int)(p)[2] << 16) \ (((unsigned int)(p)[0]) | ((unsigned int)(p)[1] << 8) \
| ((unsigned int)(p)[3] << 24)) | ((unsigned int)(p)[2] << 16) | ((unsigned int)(p)[3] << 24))
#define CHACHA_KEY_SIZE 32 #define CHACHA_KEY_SIZE 32
#define CHACHA_CTR_SIZE 16 #define CHACHA_CTR_SIZE 16

View File

@ -14,29 +14,37 @@
#if defined(CMLL_ASM) && (defined(__sparc) || defined(__sparc__)) #if defined(CMLL_ASM) && (defined(__sparc) || defined(__sparc__))
/* Fujitsu SPARC64 X support */ /* Fujitsu SPARC64 X support */
# include "crypto/sparc_arch.h" # include "crypto/sparc_arch.h"
# ifndef OPENSSL_NO_CAMELLIA # ifndef OPENSSL_NO_CAMELLIA
# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) # define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
# include <openssl/camellia.h> # include <openssl/camellia.h>
void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); 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_encrypt(const unsigned char *in, unsigned char *out,
void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, const CAMELLIA_KEY *key); 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, void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/); size_t len, const CAMELLIA_KEY *key,
void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len, unsigned char *ivec, int /*unused*/);
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/); void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, size_t len, const CAMELLIA_KEY *key,
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/); unsigned char *ivec, int /*unused*/);
void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, size_t len, void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
const CAMELLIA_KEY *key, unsigned char *ivec, int /*unused*/); size_t len, const CAMELLIA_KEY *key,
void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, unsigned char *ivec, int /*unused*/);
const CAMELLIA_KEY *key, unsigned char *ivec); void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, size_t blocks, size_t len, const CAMELLIA_KEY *key,
const CAMELLIA_KEY *key, unsigned char *ivec); unsigned char *ivec, int /*unused*/);
# endif /* OPENSSL_NO_CAMELLIA */ 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 */ #endif /* CMLL_ASM && sparc */

View File

@ -16,7 +16,8 @@
/* This file is not scanned by mkdef.pl, whereas cryptlib.h is */ /* 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_deregister(void *index);
int ossl_init_thread(void); int ossl_init_thread(void);
void ossl_cleanup_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_trace_cleanup(void);
void ossl_malloc_setup_failures(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 */ #endif /* OSSL_CRYPTO_CRYPTLIB_H */

View File

@ -53,8 +53,8 @@
int ossl_toascii(int c); int ossl_toascii(int c);
int ossl_fromascii(int c); int ossl_fromascii(int c);
#else #else
# define ossl_toascii(c) (c) # define ossl_toascii(c) (c)
# define ossl_fromascii(c) (c) # define ossl_fromascii(c) (c)
#endif #endif
int ossl_ctype_check(int c, unsigned int mask); 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_isalnum(c) (ossl_ctype_check((c), CTYPE_MASK_alnum))
#define ossl_isalpha(c) (ossl_ctype_check((c), CTYPE_MASK_alpha)) #define ossl_isalpha(c) (ossl_ctype_check((c), CTYPE_MASK_alpha))
#ifdef CHARSET_EBCDIC #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 #else
# define ossl_isascii(c) (((c) & ~127) == 0) # define ossl_isascii(c) (((c) & ~127) == 0)
#endif #endif
#define ossl_isblank(c) (ossl_ctype_check((c), CTYPE_MASK_blank)) #define ossl_isblank(c) (ossl_ctype_check((c), CTYPE_MASK_blank))
#define ossl_iscntrl(c) (ossl_ctype_check((c), CTYPE_MASK_cntrl)) #define ossl_iscntrl(c) (ossl_ctype_check((c), CTYPE_MASK_cntrl))

View File

@ -19,14 +19,18 @@
* except read a DER blob and pass it on as a provider object abstraction * except read a DER blob and pass it on as a provider object abstraction
* (provider-object(7)). * (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); 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, int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, EVP_PKEY **pkey,
OSSL_LIB_CTX *libctx, const char *propquery); const char *keytype, OSSL_LIB_CTX *libctx,
const char *propquery);
int ossl_decoder_get_number(const OSSL_DECODER *encoder); int ossl_decoder_get_number(const OSSL_DECODER *encoder);
int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx); int ossl_decoder_store_cache_flush(OSSL_LIB_CTX *libctx);

View File

@ -14,21 +14,21 @@
#if defined(DES_ASM) && (defined(__sparc) || defined(__sparc__)) #if defined(DES_ASM) && (defined(__sparc) || defined(__sparc__))
/* Fujitsu SPARC64 X support */ /* Fujitsu SPARC64 X support */
# include "crypto/sparc_arch.h" # include "crypto/sparc_arch.h"
# ifndef OPENSSL_NO_DES # ifndef OPENSSL_NO_DES
# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) # define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES)
# include <openssl/des.h> # include <openssl/des.h>
void des_t4_key_expand(const void *key, DES_key_schedule *ks); 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], void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
unsigned char iv[8]); 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], void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
unsigned char iv[8]); 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, void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
unsigned char iv[8]); 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, void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
unsigned char iv[8]); const DES_key_schedule *ks, unsigned char iv[8]);
# endif /* OPENSSL_NO_DES */ # endif /* OPENSSL_NO_DES */
#endif /* DES_ASM && sparc */ #endif /* DES_ASM && sparc */

Some files were not shown because too many files have changed in this diff Show More