mirror of
https://github.com/Serial-Studio/Serial-Studio.git
synced 2025-01-31 17:42:55 +08:00
Add macOS touchbar support
This commit is contained in:
parent
5f40442812
commit
198157eb96
@ -138,6 +138,7 @@ 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/TimerEvents.h \
|
src/Misc/TimerEvents.h \
|
||||||
src/Misc/ThemeManager.h \
|
src/Misc/ThemeManager.h \
|
||||||
@ -162,6 +163,7 @@ 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/TimerEvents.cpp \
|
src/Misc/TimerEvents.cpp \
|
||||||
src/Misc/ThemeManager.cpp \
|
src/Misc/ThemeManager.cpp \
|
||||||
|
@ -34,4 +34,5 @@ RESOURCES += \
|
|||||||
$$PWD/messages/rcc_messages.qrc \
|
$$PWD/messages/rcc_messages.qrc \
|
||||||
$$PWD/qml/rcc_qml.qrc \
|
$$PWD/qml/rcc_qml.qrc \
|
||||||
$$PWD/themes/rcc_themes.qrc \
|
$$PWD/themes/rcc_themes.qrc \
|
||||||
|
$$PWD/mac-icons/rcc_mac-icons.qrc \
|
||||||
$$PWD/translations/rcc_translations.qrc
|
$$PWD/translations/rcc_translations.qrc
|
||||||
|
BIN
assets/mac-icons/console.png
Normal file
BIN
assets/mac-icons/console.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
BIN
assets/mac-icons/dashboard.png
Normal file
BIN
assets/mac-icons/dashboard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
8
assets/mac-icons/rcc_mac-icons.qrc
Normal file
8
assets/mac-icons/rcc_mac-icons.qrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/mac-icons">
|
||||||
|
<file>console.png</file>
|
||||||
|
<file>dashboard.png</file>
|
||||||
|
<file>setup.png</file>
|
||||||
|
<file>widgets.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
BIN
assets/mac-icons/setup.png
Normal file
BIN
assets/mac-icons/setup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
BIN
assets/mac-icons/widgets.png
Normal file
BIN
assets/mac-icons/widgets.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
@ -44,11 +44,38 @@ Control {
|
|||||||
//
|
//
|
||||||
// Aliases to button check status
|
// Aliases to button check status
|
||||||
//
|
//
|
||||||
property alias dataChecked: dataBt.checked
|
property alias dataChecked: dashboardBt.checked
|
||||||
property alias setupChecked: setupBt.checked
|
property alias setupChecked: setupBt.checked
|
||||||
property alias consoleChecked: consoleBt.checked
|
property alias consoleChecked: consoleBt.checked
|
||||||
property alias widgetsChecked: widgetsBt.checked
|
property alias widgetsChecked: widgetsBt.checked
|
||||||
|
|
||||||
|
//
|
||||||
|
// Connections with mac touchbar
|
||||||
|
//
|
||||||
|
Connections {
|
||||||
|
target: Cpp_Misc_MacExtras
|
||||||
|
|
||||||
|
function onSetupClicked() {
|
||||||
|
setupBt.clicked()
|
||||||
|
Cpp_Misc_MacExtras.setSetupChecked(setupBt.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onConsoleClicked() {
|
||||||
|
consoleBt.clicked()
|
||||||
|
Cpp_Misc_MacExtras.setConsoleChecked(consoleBt.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWidgetsClicked() {
|
||||||
|
widgetsBt.clicked()
|
||||||
|
Cpp_Misc_MacExtras.setWidgetsChecked(widgetsBt.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDashboardClicked() {
|
||||||
|
dashboardBt.clicked()
|
||||||
|
Cpp_Misc_MacExtras.setDashboardChecked(dashboardBt.checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Background gradient
|
// Background gradient
|
||||||
//
|
//
|
||||||
@ -116,6 +143,7 @@ Control {
|
|||||||
palette.buttonText: Cpp_ThemeManager.brightText
|
palette.buttonText: Cpp_ThemeManager.brightText
|
||||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||||
|
onCheckedChanged: Cpp_Misc_MacExtras.setSetupChecked(checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
@ -128,15 +156,16 @@ Control {
|
|||||||
onClicked: root.consoleClicked()
|
onClicked: root.consoleClicked()
|
||||||
icon.source: "qrc:/icons/code.svg"
|
icon.source: "qrc:/icons/code.svg"
|
||||||
text: qsTr("Console") + _btSpacer
|
text: qsTr("Console") + _btSpacer
|
||||||
enabled: dataBt.enabled || widgetsBt.enabled
|
enabled: dashboardBt.enabled || widgetsBt.enabled
|
||||||
icon.color: Cpp_ThemeManager.brightText
|
icon.color: Cpp_ThemeManager.brightText
|
||||||
palette.buttonText: Cpp_ThemeManager.brightText
|
palette.buttonText: Cpp_ThemeManager.brightText
|
||||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||||
|
onCheckedChanged: Cpp_Misc_MacExtras.setConsoleChecked(checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
id: dataBt
|
id: dashboardBt
|
||||||
|
|
||||||
flat: true
|
flat: true
|
||||||
icon.width: 24
|
icon.width: 24
|
||||||
@ -150,6 +179,8 @@ Control {
|
|||||||
palette.buttonText: Cpp_ThemeManager.brightText
|
palette.buttonText: Cpp_ThemeManager.brightText
|
||||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||||
|
onCheckedChanged: Cpp_Misc_MacExtras.setDashboardChecked(checked)
|
||||||
|
onEnabledChanged: Cpp_Misc_MacExtras.setDashboardEnabled(enabled)
|
||||||
|
|
||||||
opacity: enabled ? 1 : 0.5
|
opacity: enabled ? 1 : 0.5
|
||||||
Behavior on opacity {NumberAnimation{}}
|
Behavior on opacity {NumberAnimation{}}
|
||||||
@ -170,6 +201,8 @@ Control {
|
|||||||
palette.buttonText: Cpp_ThemeManager.brightText
|
palette.buttonText: Cpp_ThemeManager.brightText
|
||||||
palette.button: Cpp_ThemeManager.toolbarGradient1
|
palette.button: Cpp_ThemeManager.toolbarGradient1
|
||||||
palette.window: Cpp_ThemeManager.toolbarGradient1
|
palette.window: Cpp_ThemeManager.toolbarGradient1
|
||||||
|
onCheckedChanged: Cpp_Misc_MacExtras.setWidgetsChecked(checked)
|
||||||
|
onEnabledChanged: Cpp_Misc_MacExtras.setWidgetsEnabled(enabled)
|
||||||
|
|
||||||
opacity: enabled ? 1 : 0.5
|
opacity: enabled ? 1 : 0.5
|
||||||
Behavior on opacity {NumberAnimation{}}
|
Behavior on opacity {NumberAnimation{}}
|
||||||
|
Binary file not shown.
@ -1267,6 +1267,25 @@
|
|||||||
<translation>Drucken</translation>
|
<translation>Drucken</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Misc::MacExtras</name>
|
||||||
|
<message>
|
||||||
|
<source>Setup</source>
|
||||||
|
<translation>Einstellungen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Console</source>
|
||||||
|
<translation>Konsole</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Widgets</source>
|
||||||
|
<translation>Widgets</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dashboard</source>
|
||||||
|
<translation>Dashboard</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Misc::ThemeManager</name>
|
<name>Misc::ThemeManager</name>
|
||||||
<message>
|
<message>
|
||||||
|
Binary file not shown.
@ -1125,6 +1125,25 @@
|
|||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Misc::MacExtras</name>
|
||||||
|
<message>
|
||||||
|
<source>Setup</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Console</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Widgets</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dashboard</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Misc::ThemeManager</name>
|
<name>Misc::ThemeManager</name>
|
||||||
<message>
|
<message>
|
||||||
|
Binary file not shown.
@ -1334,6 +1334,25 @@
|
|||||||
<translation>Imprimir</translation>
|
<translation>Imprimir</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Misc::MacExtras</name>
|
||||||
|
<message>
|
||||||
|
<source>Setup</source>
|
||||||
|
<translation>Configuración</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Console</source>
|
||||||
|
<translation>Consola</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Widgets</source>
|
||||||
|
<translation>Widgets</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dashboard</source>
|
||||||
|
<translation>Tablero</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Misc::ThemeManager</name>
|
<name>Misc::ThemeManager</name>
|
||||||
<message>
|
<message>
|
||||||
|
Binary file not shown.
@ -1299,6 +1299,25 @@
|
|||||||
<translation>打印</translation>
|
<translation>打印</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Misc::MacExtras</name>
|
||||||
|
<message>
|
||||||
|
<source>Setup</source>
|
||||||
|
<translation>体系</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Console</source>
|
||||||
|
<translation>控制台</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Widgets</source>
|
||||||
|
<translation>小部件</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Dashboard</source>
|
||||||
|
<translation>仪表盘</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>Misc::ThemeManager</name>
|
<name>Misc::ThemeManager</name>
|
||||||
<message>
|
<message>
|
||||||
|
7
libs/KDMacTouchBar/.gitignore
vendored
Normal file
7
libs/KDMacTouchBar/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Makefile
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
lib
|
||||||
|
.qmake.cache
|
||||||
|
.qmake.stash
|
||||||
|
.DS_Store
|
16
libs/KDMacTouchBar/.krazy
Normal file
16
libs/KDMacTouchBar/.krazy
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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
|
||||||
|
|
46
libs/KDMacTouchBar/CMakeLists.txt
Normal file
46
libs/KDMacTouchBar/CMakeLists.txt
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
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)
|
175
libs/KDMacTouchBar/LICENSE.LGPL.txt
Normal file
175
libs/KDMacTouchBar/LICENSE.LGPL.txt
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
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.
|
64
libs/KDMacTouchBar/README.md
Normal file
64
libs/KDMacTouchBar/README.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# 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)
|
2
libs/KDMacTouchBar/cmake/KDMacTouchBarConfig.cmake
Normal file
2
libs/KDMacTouchBar/cmake/KDMacTouchBarConfig.cmake
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
set(KDMacTouchBar_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../KDMacTouchBar.framework/Headers)
|
||||||
|
set(KDMacTouchBar_LIBRARIES ${CMAKE_CURRENT_LIST_DIR}/../KDMacTouchBar.framework/Versions/Current/KDMacTouchBar)
|
32
libs/KDMacTouchBar/cmake/Qt5Portability.cmake
Normal file
32
libs/KDMacTouchBar/cmake/Qt5Portability.cmake
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
if(QT_USE_QTNETWORK)
|
||||||
|
find_package(Qt5Network REQUIRED)
|
||||||
|
list(APPEND QT_LIBRARIES Qt5::Network)
|
||||||
|
include_directories(${Qt5Network_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QT_USE_QTXML)
|
||||||
|
find_package(Qt5Xml REQUIRED)
|
||||||
|
list(APPEND QT_LIBRARIES Qt5::Xml)
|
||||||
|
include_directories(${Qt5Xml_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(QT_USE_QTTEST)
|
||||||
|
find_package(Qt5Test REQUIRED)
|
||||||
|
list(APPEND QT_LIBRARIES Qt5::Test)
|
||||||
|
include_directories(${Qt5Test_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
macro(qt4_wrap_ui)
|
||||||
|
qt5_wrap_ui(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_wrap_cpp)
|
||||||
|
qt5_wrap_cpp(${ARGN})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(qt4_add_resources)
|
||||||
|
qt5_add_resources(${ARGN})
|
||||||
|
endmacro()
|
Binary file not shown.
1
libs/KDMacTouchBar/examples/CMakeLists.txt
Normal file
1
libs/KDMacTouchBar/examples/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory(mactouchbar)
|
3
libs/KDMacTouchBar/examples/examples.pro
Normal file
3
libs/KDMacTouchBar/examples/examples.pro
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TEMPLATE=subdirs
|
||||||
|
|
||||||
|
SUBDIRS=mactouchbar
|
19
libs/KDMacTouchBar/examples/mactouchbar/CMakeLists.txt
Normal file
19
libs/KDMacTouchBar/examples/mactouchbar/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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)
|
12
libs/KDMacTouchBar/examples/mactouchbar/mactouchbar.pro
Normal file
12
libs/KDMacTouchBar/examples/mactouchbar/mactouchbar.pro
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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
|
5
libs/KDMacTouchBar/examples/mactouchbar/mactouchbar.qrc
Normal file
5
libs/KDMacTouchBar/examples/mactouchbar/mactouchbar.qrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>qtlogo.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
38
libs/KDMacTouchBar/examples/mactouchbar/main.cpp
Normal file
38
libs/KDMacTouchBar/examples/mactouchbar/main.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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();
|
||||||
|
}
|
73
libs/KDMacTouchBar/examples/mactouchbar/mainwindow.cpp
Normal file
73
libs/KDMacTouchBar/examples/mactouchbar/mainwindow.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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);
|
||||||
|
}
|
39
libs/KDMacTouchBar/examples/mactouchbar/mainwindow.h
Normal file
39
libs/KDMacTouchBar/examples/mactouchbar/mainwindow.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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
|
BIN
libs/KDMacTouchBar/examples/mactouchbar/qtlogo.png
Normal file
BIN
libs/KDMacTouchBar/examples/mactouchbar/qtlogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
8
libs/KDMacTouchBar/features/features.pro
Normal file
8
libs/KDMacTouchBar/features/features.pro
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
features.path = $$INSTALL_PREFIX/share/mkspecs/features
|
||||||
|
features.files = *.prf
|
||||||
|
|
||||||
|
INSTALLS += features
|
||||||
|
|
||||||
|
OTHER_FILES = *.prf
|
4
libs/KDMacTouchBar/features/kdmactouchbar.prf
Normal file
4
libs/KDMacTouchBar/features/kdmactouchbar.prf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LIBPATH=$$clean_path($$PWD/../../../lib)
|
||||||
|
LIBS += -F$$LIBPATH -framework KDMacTouchBar
|
||||||
|
QMAKE_LFLAGS += '-Wl,-rpath,\'$$LIBPATH\''
|
||||||
|
INCLUDEPATH += $$LIBPATH/KDMacTouchBar.framework/Headers
|
1
libs/KDMacTouchBar/kdmactouchbar.pri
Normal file
1
libs/KDMacTouchBar/kdmactouchbar.pri
Normal file
@ -0,0 +1 @@
|
|||||||
|
VERSION = 1.0
|
33
libs/KDMacTouchBar/kdmactouchbar.pro
Normal file
33
libs/KDMacTouchBar/kdmactouchbar.pro
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
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
|
24
libs/KDMacTouchBar/src/CMakeLists.txt
Normal file
24
libs/KDMacTouchBar/src/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
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
|
||||||
|
)
|
87
libs/KDMacTouchBar/src/kdmactouchbar.h
Normal file
87
libs/KDMacTouchBar/src/kdmactouchbar.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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 <QtWidgets/QWidget>
|
||||||
|
|
||||||
|
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
|
980
libs/KDMacTouchBar/src/kdmactouchbar.mm
Normal file
980
libs/KDMacTouchBar/src/kdmactouchbar.mm
Normal file
@ -0,0 +1,980 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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(), 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
|
33
libs/KDMacTouchBar/src/kdmactouchbar_global.h
Normal file
33
libs/KDMacTouchBar/src/kdmactouchbar_global.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
** 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 */
|
28
libs/KDMacTouchBar/src/src.pro
Normal file
28
libs/KDMacTouchBar/src/src.pro
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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"
|
121
src/Misc/MacExtras.cpp
Normal file
121
src/Misc/MacExtras.cpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "MacExtras.h"
|
||||||
|
#include "Translator.h"
|
||||||
|
|
||||||
|
#include <Logger.h>
|
||||||
|
#include <ConsoleAppender.h>
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
# include <kdmactouchbar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace Misc;
|
||||||
|
|
||||||
|
MacExtras *INSTANCE = nullptr;
|
||||||
|
|
||||||
|
MacExtras::MacExtras()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
// Configure action strings
|
||||||
|
updateButtonText();
|
||||||
|
|
||||||
|
// Configure action icons
|
||||||
|
m_setupAction.setIcon(QIcon("://mac-icons/setup.png"));
|
||||||
|
m_consoleAction.setIcon(QIcon("://mac-icons/console.png"));
|
||||||
|
m_widgetsAction.setIcon(QIcon("://mac-icons/widgets.png"));
|
||||||
|
m_dashboardAction.setIcon(QIcon("://mac-icons/dashboard.png"));
|
||||||
|
|
||||||
|
// Setup checkable items
|
||||||
|
m_setupAction.setCheckable(true);
|
||||||
|
m_consoleAction.setCheckable(true);
|
||||||
|
m_widgetsAction.setCheckable(true);
|
||||||
|
m_dashboardAction.setCheckable(true);
|
||||||
|
|
||||||
|
// Configure signals
|
||||||
|
connect(&m_setupAction, SIGNAL(triggered()), this, SIGNAL(setupClicked()));
|
||||||
|
connect(&m_consoleAction, SIGNAL(triggered()), this, SIGNAL(consoleClicked()));
|
||||||
|
connect(&m_widgetsAction, SIGNAL(triggered()), this, SIGNAL(widgetsClicked()));
|
||||||
|
connect(&m_dashboardAction, SIGNAL(triggered()), this, SIGNAL(dashboardClicked()));
|
||||||
|
|
||||||
|
// Create touchbar
|
||||||
|
KDMacTouchBar *bar = new KDMacTouchBar((QWidget *)nullptr);
|
||||||
|
bar->addAction(&m_setupAction);
|
||||||
|
bar->addAction(&m_consoleAction);
|
||||||
|
bar->addAction(&m_dashboardAction);
|
||||||
|
bar->addAction(&m_widgetsAction);
|
||||||
|
|
||||||
|
// Re-translate buttons when language is changed
|
||||||
|
connect(Translator::getInstance(), SIGNAL(languageChanged()), this,
|
||||||
|
SLOT(updateButtonText()));
|
||||||
|
|
||||||
|
// Logger
|
||||||
|
LOG_TRACE() << "Class initialized";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MacExtras *MacExtras::getInstance()
|
||||||
|
{
|
||||||
|
if (!INSTANCE)
|
||||||
|
INSTANCE = new MacExtras;
|
||||||
|
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setSetupChecked(const bool checked)
|
||||||
|
{
|
||||||
|
m_setupAction.setChecked(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setConsoleChecked(const bool checked)
|
||||||
|
{
|
||||||
|
m_consoleAction.setChecked(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setWidgetsChecked(const bool checked)
|
||||||
|
{
|
||||||
|
m_widgetsAction.setChecked(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setWidgetsEnabled(const bool enabled)
|
||||||
|
{
|
||||||
|
m_widgetsAction.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setDashboardChecked(const bool checked)
|
||||||
|
{
|
||||||
|
m_dashboardAction.setChecked(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::setDashboardEnabled(const bool enabled)
|
||||||
|
{
|
||||||
|
m_dashboardAction.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MacExtras::updateButtonText()
|
||||||
|
{
|
||||||
|
m_setupAction.setText(tr("Setup"));
|
||||||
|
m_consoleAction.setText(tr("Console"));
|
||||||
|
m_widgetsAction.setText(tr("Widgets"));
|
||||||
|
m_dashboardAction.setText(tr("Dashboard"));
|
||||||
|
}
|
67
src/Misc/MacExtras.h
Normal file
67
src/Misc/MacExtras.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Alex Spataru <https://github.com/alex-spataru>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MISC_MAC_EXTRAS_H
|
||||||
|
#define MISC_MAC_EXTRAS_H
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace Misc
|
||||||
|
{
|
||||||
|
class MacExtras : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void setupClicked();
|
||||||
|
void widgetsClicked();
|
||||||
|
void connectClicked();
|
||||||
|
void consoleClicked();
|
||||||
|
void dashboardClicked();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MacExtras *getInstance();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setSetupChecked(const bool checked);
|
||||||
|
void setConsoleChecked(const bool checked);
|
||||||
|
void setWidgetsChecked(const bool checked);
|
||||||
|
void setWidgetsEnabled(const bool enabled);
|
||||||
|
void setDashboardChecked(const bool checked);
|
||||||
|
void setDashboardEnabled(const bool enabled);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateButtonText();
|
||||||
|
|
||||||
|
private:
|
||||||
|
MacExtras();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QAction m_setupAction;
|
||||||
|
QAction m_consoleAction;
|
||||||
|
QAction m_widgetsAction;
|
||||||
|
QAction m_dashboardAction;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -43,6 +43,7 @@
|
|||||||
#include <IO/DataSources/Serial.h>
|
#include <IO/DataSources/Serial.h>
|
||||||
#include <IO/DataSources/Network.h>
|
#include <IO/DataSources/Network.h>
|
||||||
|
|
||||||
|
#include <Misc/MacExtras.h>
|
||||||
#include <Misc/Utilities.h>
|
#include <Misc/Utilities.h>
|
||||||
#include <Misc/Translator.h>
|
#include <Misc/Translator.h>
|
||||||
#include <Misc/TimerEvents.h>
|
#include <Misc/TimerEvents.h>
|
||||||
@ -155,6 +156,7 @@ void ModuleManager::initializeQmlInterface()
|
|||||||
auto themeManager = Misc::ThemeManager::getInstance();
|
auto themeManager = Misc::ThemeManager::getInstance();
|
||||||
auto mqttPublisher = MQTT::Client::getInstance();
|
auto mqttPublisher = MQTT::Client::getInstance();
|
||||||
auto pluginsBridge = Plugins::Bridge::getInstance();
|
auto pluginsBridge = Plugins::Bridge::getInstance();
|
||||||
|
auto macExtras = Misc::MacExtras::getInstance();
|
||||||
LOG_INFO() << "Finished initializing C++ modules";
|
LOG_INFO() << "Finished initializing C++ modules";
|
||||||
|
|
||||||
// Retranslate the QML interface automagically
|
// Retranslate the QML interface automagically
|
||||||
@ -180,6 +182,7 @@ void ModuleManager::initializeQmlInterface()
|
|||||||
c->setContextProperty("Cpp_JSON_Generator", jsonGenerator);
|
c->setContextProperty("Cpp_JSON_Generator", jsonGenerator);
|
||||||
c->setContextProperty("Cpp_MQTT_Client", mqttPublisher);
|
c->setContextProperty("Cpp_MQTT_Client", mqttPublisher);
|
||||||
c->setContextProperty("Cpp_Plugins_Bridge", pluginsBridge);
|
c->setContextProperty("Cpp_Plugins_Bridge", pluginsBridge);
|
||||||
|
c->setContextProperty("Cpp_Misc_MacExtras", macExtras);
|
||||||
|
|
||||||
// Register app info with QML
|
// Register app info with QML
|
||||||
c->setContextProperty("Cpp_AppName", qApp->applicationName());
|
c->setContextProperty("Cpp_AppName", qApp->applicationName());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user