refactor(ui): add initial QML setup

This commit is contained in:
uncor3
2026-04-25 06:18:25 +03:00
parent 5f1158565c
commit e989212264
15 changed files with 736 additions and 94 deletions
+11 -12
View File
@@ -95,10 +95,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
endif()
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CXXQT_QTCOMPONENTS Core Gui Qml QuickControls2 QuickTest Widgets Test)
if(NOT BUILD_WASM)
set(CXXQT_QTCOMPONENTS ${CXXQT_QTCOMPONENTS})
@@ -138,7 +134,7 @@ endif()
cxx_qt_import_crate(
MANIFEST_PATH src/rust/Cargo.toml
CRATES idescriptor_rust_codebase
LOCKED
# LOCKED
QT_MODULES Qt::Core Qt::Gui Qt::Qml Qt::QuickControls2
)
@@ -188,13 +184,16 @@ else()
endif()
file(GLOB PROJECT_SOURCES
src/*.h
src/*.cpp
src/core/helpers/*.cpp
src/core/services/*.cpp
src/base/*.cpp
src/base/*.h
# src/*.h
# src/*.cpp
# src/core/helpers/*.cpp
# src/core/services/*.cpp
# src/base/*.cpp
# src/base/*.h
src/main.cpp
src/constants.h
resources.qrc
resources.ui.qrc
)
@@ -283,6 +282,7 @@ target_link_libraries(iDescriptor PRIVATE
Qt6::Location
Qt6::Positioning
Qt6::QuickWidgets
Qt6::Qml
Qt6::QuickControls2
PkgConfig::SSH
${SSH_LIBRARY}
@@ -312,7 +312,6 @@ if(ENABLE_RECOVERY_DEVICE_SUPPORT)
endif()
target_include_directories(iDescriptor PRIVATE
# Put idevice-rs includes FIRST
${CMAKE_CURRENT_SOURCE_DIR}/lib
${CMAKE_CURRENT_SOURCE_DIR}/lib/zupdater/src
)
+11
View File
@@ -0,0 +1,11 @@
<RCC>
<qresource prefix="/">
<file>src/qml/Main.qml</file>
<file>src/qml/Index.qml</file>
<file>src/qml/Tabs.qml</file>
<file>src/qml/HowToConnect.qml</file>
<file>src/qml/Welcome.qml</file>
<file>src/qml/TabButton.qml</file>
<file>src/qml/Device.qml</file>
</qresource>
</RCC>
+18
View File
@@ -0,0 +1,18 @@
#ifndef CONSTANTS_H
#define CONSTANTS_H
#include "iDescriptor.h"
#include <QObject>
class Constants : public QObject
{
Q_OBJECT
Q_PROPERTY(QString REPO_URL READ REPO_URL CONSTANT)
public:
explicit Constants(QObject *parent = nullptr) : QObject(parent) {}
QString REPO_URL() const { return QStringLiteral(IDESCRIPTOR_REPO_URL); }
};
#endif // CONSTANTS_H
+11 -11
View File
@@ -47,7 +47,7 @@ using u_int64_t = uint64_t;
"© 2026 The iDescriptor Project contributors. See AUTHORS for details."
#define RECOVERY_CLIENT_CONNECTION_TRIES 3
#define APPLE_VENDOR_ID 0x05ac
#define REPO_URL "https://github.com/iDescriptor/iDescriptor"
#define IDESCRIPTOR_REPO_URL "https://github.com/iDescriptor/iDescriptor"
#define SPONSORS_JSON_URL \
"https://raw.githubusercontent.com/iDescriptor/iDescriptor/refs/heads/" \
"main/sponsors.json"
@@ -86,13 +86,13 @@ using u_int64_t = uint64_t;
#endif
// rust codebase
#include "idescriptor_rust_codebase/src/afc2_services.cxxqt.h"
#include "idescriptor_rust_codebase/src/afc_services.cxxqt.h"
#include "idescriptor_rust_codebase/src/hause_arrest.cxxqt.h"
#include "idescriptor_rust_codebase/src/io_manager.cxxqt.h"
#include "idescriptor_rust_codebase/src/lib.cxxqt.h"
#include "idescriptor_rust_codebase/src/screenshot.cxxqt.h"
#include "idescriptor_rust_codebase/src/service_manager.cxxqt.h"
// #include "idescriptor_rust_codebase/src/afc2_services.cxxqt.h"
// #include "idescriptor_rust_codebase/src/afc_services.cxxqt.h"
// #include "idescriptor_rust_codebase/src/hause_arrest.cxxqt.h"
// #include "idescriptor_rust_codebase/src/io_manager.cxxqt.h"
// #include "idescriptor_rust_codebase/src/lib.cxxqt.h"
// #include "idescriptor_rust_codebase/src/screenshot.cxxqt.h"
// #include "idescriptor_rust_codebase/src/service_manager.cxxqt.h"
namespace iDescriptor
{
@@ -233,9 +233,9 @@ struct iDescriptorDevice {
iDescriptor::IdeviceConnectionType conn_type;
DeviceInfo deviceInfo;
unsigned int ios_version;
CXX::ServiceManager *service_manager;
CXX::AfcBackend *afc_backend;
CXX::Afc2Backend *afc2_backend;
QObject *service_manager;
QObject *afc_backend;
QObject *afc2_backend;
};
void fullDeviceInfo(const pugi::xml_document &doc, DeviceInfo &d);
+58 -27
View File
@@ -17,8 +17,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "constants.h"
#include "iDescriptor.h"
#include "mainwindow.h"
#include "settingsmanager.h"
#include <QApplication>
#include <QDebug>
@@ -32,43 +32,55 @@
#include "platform/windows/win_common.h"
#endif
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickWindow>
#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>
#define FLUENTUI_BUILD_STATIC_LIB 1
int main(int argc, char *argv[])
{
#ifdef WIN32
// ::SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
qputenv("QT_QPA_PLATFORM", "windows:darkmode=2");
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
qputenv("QT_QUICK_CONTROLS_STYLE", "Basic");
#else
qputenv("QT_QUICK_CONTROLS_STYLE", "Default");
#endif
#ifdef Q_OS_LINUX
// fix bug UOSv20 v-sync does not work
qputenv("QSG_RENDER_LOOP", "basic");
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
#endif
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QApplication::setHighDpiScaleFactorRoundingPolicy(
Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
#endif
QApplication a(argc, argv);
QCoreApplication::setOrganizationName("iDescriptor");
QCoreApplication::setApplicationName("iDescriptor");
QCoreApplication::setApplicationVersion(APP_VERSION);
if (a.arguments().contains("--reset-settings")) {
SettingsManager::sharedInstance()->clear();
// SettingsManager::sharedInstance()->clear();
QMessageBox::information(nullptr, "Settings Reset",
"All application settings have been reset to "
"their default values.");
}
QQmlApplicationEngine engine;
#ifdef WIN32
bool enableMica = !a.arguments().contains("--disable-mica") &&
!SettingsManager::sharedInstance()->disableMica();
if (!enableMica) {
SettingsManager::sharedInstance()->setDisableMica(true);
qDebug() << "Mica effect disabled";
}
QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
QOperatingSystemVersion osVersion = QOperatingSystemVersion::current();
if (enableMica && osVersion >= QOperatingSystemVersion::Windows11) {
QFile styleFile(detectDarkModeWindows() ? ":/resources/win.dark.qcss"
: ":/resources/win.light.qcss");
if (styleFile.open(QFile::ReadOnly | QFile::Text)) {
const QString style = QString::fromUtf8(styleFile.readAll())
.arg(COLOR_ACCENT_BLUE.name());
qDebug() << "Loaded Windows style sheet successfully.";
a.setStyleSheet(style);
}
} else {
qDebug() << "Not applying WinUI stylesheet.";
}
QString appPath = QCoreApplication::applicationDirPath();
QString gstPluginPath =
QDir::toNativeSeparators(appPath + "/gstreamer-1.0");
@@ -103,7 +115,26 @@ int main(int argc, char *argv[])
setenv("GST_PLUGIN_SYSTEM_PATH", gstPluginPath.toUtf8().constData(), 1);
setenv("GST_PLUGIN_SCANNER", gstPluginScannerPath.toUtf8().constData(), 1);
#endif
MainWindow *w = MainWindow::sharedInstance();
w->show();
const QUrl url(QStringLiteral("qrc:/src/qml/Main.qml"));
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &a,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl) {
QCoreApplication::exit(-1);
}
},
Qt::QueuedConnection);
// FIXME: for some reason we have to set this
// dont let this end up in final build
#ifdef WIN32
engine.addImportPath("C:/Qt/6.8.3/mingw_64/qml");
#endif
Constants constants;
engine.rootContext()->setContextProperty("CONSTANTS", &constants);
engine.load(url);
return a.exec();
}
+31 -31
View File
@@ -71,44 +71,44 @@ void enableMica(HWND hwnd)
{
if (!hwnd)
return;
SettingsManager *sm = SettingsManager::sharedInstance();
WIN_BACKDROP type = sm->winBackdropType();
MARGINS margins = {-1};
DwmExtendFrameIntoClientArea(hwnd, &margins);
// SettingsManager *sm = SettingsManager::sharedInstance();
// WIN_BACKDROP type = sm->winBackdropType();
// MARGINS margins = {-1};
// DwmExtendFrameIntoClientArea(hwnd, &margins);
DWORD build = 0;
RTL_OSVERSIONINFOW rovi = {0};
rovi.dwOSVersionInfoSize = sizeof(rovi);
// DWORD build = 0;
// RTL_OSVERSIONINFOW rovi = {0};
// rovi.dwOSVersionInfoSize = sizeof(rovi);
using RtlGetVersionPtr = LONG(WINAPI *)(PRTL_OSVERSIONINFOW);
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
if (ntdll) {
auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(
GetProcAddress(ntdll, "RtlGetVersion"));
if (pRtlGetVersion && pRtlGetVersion(&rovi) == 0) {
build = rovi.dwBuildNumber;
}
}
// using RtlGetVersionPtr = LONG(WINAPI *)(PRTL_OSVERSIONINFOW);
// HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
// if (ntdll) {
// auto pRtlGetVersion = reinterpret_cast<RtlGetVersionPtr>(
// GetProcAddress(ntdll, "RtlGetVersion"));
// if (pRtlGetVersion && pRtlGetVersion(&rovi) == 0) {
// build = rovi.dwBuildNumber;
// }
// }
if (build >= 22523) {
DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, &type,
sizeof(type));
} else if (build >= 22000) {
// Undocumented old method
BOOL mica = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &mica, sizeof(mica));
}
// if (build >= 22523) {
// DwmSetWindowAttribute(hwnd, DWMWA_SYSTEMBACKDROP_TYPE, &type,
// sizeof(type));
// } else if (build >= 22000) {
// // Undocumented old method
// BOOL mica = TRUE;
// DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &mica, sizeof(mica));
// }
}
void setupWinWindow(QWidget *window)
{
QOperatingSystemVersion osVersion = QOperatingSystemVersion::current();
if (osVersion < QOperatingSystemVersion::Windows11 ||
SettingsManager::sharedInstance()->disableMica())
return;
window->setAttribute(Qt::WA_TranslucentBackground);
HWND hwnd = reinterpret_cast<HWND>(window->winId());
enableMica(hwnd);
// QOperatingSystemVersion osVersion = QOperatingSystemVersion::current();
// if (osVersion < QOperatingSystemVersion::Windows11 ||
// SettingsManager::sharedInstance()->disableMica())
// return;
// window->setAttribute(Qt::WA_TranslucentBackground);
// HWND hwnd = reinterpret_cast<HWND>(window->winId());
// enableMica(hwnd);
/*
normally we had plans to enable acrylic on win 10 but since it's
+56
View File
@@ -0,0 +1,56 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import "."
import com.kdab.cxx_qt.demo 1.0
Item {
id: root
property ListModel devices: ListModel {}
property bool showWelcomePage : true
readonly property Core core: Core {}
Component.onCompleted: {
root.core.init()
}
Connections {
target: root.core
function onDevice_event(eventType, udid, info) {
console.log("Device event:", eventType, udid, info)
root.showWelcomePage = false;
if (eventType === 1) {
// Use append to add items to the ListModel
devices.append({ udid: udid, info: info })
}
}
}
Repeater {
model: devices
delegate: Label {
text: model.info
font.pixelSize: 16
padding: 10
Layout.fillWidth: true
//MouseArea {
// anchors.fill: parent
// onClicked: {
// root.currentIndex = index + 1
// root.showWelcomePage = false
// }
//}
}
}
Welcome {
id: welcomePage
visible : showWelcomePage
Layout.fillWidth: true
Layout.fillHeight: true
}
}
+207
View File
@@ -0,0 +1,207 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Dialog {
id: dlg
modal: true
focus: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
width: 560
height: 560
property int currentIndex: 0
property bool loading: true
onOpened: {
loading = true
currentIndex = 0
loadTimer.restart()
}
Timer {
id: loadTimer
interval: 500
repeat: false
onTriggered: dlg.loading = false
}
function updateNav() {
prevBtn.enabled = dlg.currentIndex > 0
nextBtn.enabled = dlg.currentIndex < (stack.count - 1)
}
onCurrentIndexChanged: updateNav()
Component.onCompleted: updateNav()
background: Rectangle {
radius: 10
color: palette.window
border.color: Qt.rgba(0, 0, 0, 0.12)
border.width: 1
}
contentItem: Item {
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
anchors.margins: 16
spacing: 12
Item {
Layout.fillWidth: true
Layout.fillHeight: true
StackLayout {
id: stack
anchors.fill: parent
currentIndex: dlg.currentIndex
// Page 1
Item {
ColumnLayout {
anchors.fill: parent
spacing: 10
Item { Layout.fillHeight: true }
Text {
Layout.fillWidth: true
text: "Connect your device"
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.pixelSize: 16
font.bold: true
color: palette.text
}
Image {
Layout.alignment: Qt.AlignHCenter
source: "qrc:/resources/connect.png"
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
Layout.preferredWidth: 200
Layout.preferredHeight: 200
}
Item { Layout.fillHeight: true }
}
}
// Page 2
Item {
ColumnLayout {
anchors.fill: parent
spacing: 10
Item { Layout.fillHeight: true }
Text {
Layout.fillWidth: true
text: "Accept the pairing dialog"
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.pixelSize: 16
font.bold: true
color: palette.text
}
Image {
Layout.alignment: Qt.AlignHCenter
source: "qrc:/resources/trust.png"
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
Layout.preferredWidth: 200
Layout.preferredHeight: 200
}
Item { Layout.fillHeight: true }
}
}
// Page 3
Item {
ColumnLayout {
anchors.fill: parent
spacing: 10
Item { Layout.fillHeight: true }
Text {
Layout.fillWidth: true
text: {
if (Qt.platform.os === "windows")
return "You can now unplug the device. iDescriptor will connect to it automatically (requires iOS 15 or later and the Bonjour service)."
if (Qt.platform.os === "linux")
return "You can now unplug the device. iDescriptor will connect to it automatically (requires iOS 15 or later and the Avahi daemon)."
return "You can now unplug the device. iDescriptor will connect to it automatically (requires iOS 15 or later)."
}
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.pixelSize: 16
font.bold: true
color: palette.text
}
Image {
Layout.alignment: Qt.AlignHCenter
source: "qrc:/resources/ios-version.png"
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
Layout.preferredWidth: 200
Layout.preferredHeight: 200
}
Item { Layout.fillHeight: true }
}
}
}
Rectangle {
anchors.fill: parent
visible: dlg.loading
color: Qt.rgba(0, 0, 0, 0.06)
BusyIndicator {
anchors.centerIn: parent
running: dlg.loading
}
}
}
RowLayout {
Layout.fillWidth: true
spacing: 10
Item { Layout.fillWidth: true }
Button {
id: prevBtn
text: "Previous"
icon.source: "qrc:/resources/icons/MaterialSymbolsArrowLeftAlt.png"
Layout.preferredWidth: 48
onClicked: {
if (dlg.currentIndex > 0) dlg.currentIndex -= 1
}
}
Button {
id: nextBtn
text: "Next"
icon.source: "qrc:/resources/icons/MaterialSymbolsArrowRightAlt.png"
Layout.preferredWidth: 48
onClicked: {
if (dlg.currentIndex < stack.count - 1) dlg.currentIndex += 1
}
}
Item { Layout.fillWidth: true }
}
}
}
}
+60
View File
@@ -0,0 +1,60 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
import QtQuick.Layouts 1.15
import "."
FluWindow {
id:window
title: "iDescriptor"
width: 1000
height: 668
minimumWidth: 668
minimumHeight: 320
launchMode: FluWindowType.SingleTask
fitsAppBarWindows: true
property int currentIndex: 0
appBar: FluAppBar {
height: 28
showDark: true
z: 7
RowLayout{
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 10
spacing: 0
TabButton {
text: qsTr("iDevice")
onClicked: currentIndex = 0
active: currentIndex == 0
}
TabButton {
text: qsTr("Apps")
onClicked: currentIndex = 1
active: currentIndex == 1
}
TabButton {
text: qsTr("Toolbox")
onClicked: currentIndex = 2
active: currentIndex == 2
}
TabButton {
text: qsTr("Jailbroken")
onClicked: currentIndex = 3
active: currentIndex == 3
}
}
}
Tabs {
currentIndex: window.currentIndex
anchors.fill: parent
anchors.topMargin: appBar.height
}
}
+50
View File
@@ -0,0 +1,50 @@
import QtQuick 2.15
import QtQuick.Window 2.15
// import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import FluentUI 1.0
FluLauncher {
id: app
// Connections{
// target: FluTheme
// function onDarkModeChanged(){
// SettingsHelper.saveDarkMode(FluTheme.darkMode)
// }
// }
// Connections{
// target: FluApp
// function onUseSystemAppBarChanged(){
// SettingsHelper.saveUseSystemAppBar(FluApp.useSystemAppBar)
// }
// }
// Connections{
// target: TranslateHelper
// function onCurrentChanged(){
// SettingsHelper.saveLanguage(TranslateHelper.current)
// }
// }
Component.onCompleted: {
// Network.openLog = false
// Network.setInterceptor(function(param){
// param.addHeader("Token","000000000000000000000")
// })
FluApp.init(app,Qt.locale())
// FluApp.windowIcon = "qrc:/example/res/image/favicon.ico"
// FluApp.useSystemAppBar = SettingsHelper.getUseSystemAppBar()
FluApp.useSystemAppBar = false
// FluTheme.darkMode = SettingsHelper.getDarkMode()
FluTheme.darkMode = false
FluTheme.animationEnabled = true
FluRouter.routes = {
"/":"qrc:/src/qml/Index.qml",
}
var args = Qt.application.arguments
if(args.length>=2 && args[1].startsWith("-crashed=")){
FluRouter.navigate("/crash",{crashFilePath:args[1].replace("-crashed=","")})
}else{
FluRouter.navigate("/")
}
}
}
+22
View File
@@ -0,0 +1,22 @@
import QtQuick 2.15
import QtQuick.Controls
import QtQuick.Layouts
Button {
id: btn
property bool active: false
contentItem : Text {
text : btn.text
color : btn.active ? "#888888" : "red"
font.pixelSize: 22
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
Layout.fillWidth: true
Layout.fillHeight: true
background: Rectangle {
color : "transparent"
}
}
+28
View File
@@ -0,0 +1,28 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import "."
import com.kdab.cxx_qt.demo 1.0
Item {
id: root
anchors.fill: parent
property int currentIndex : 0
Device {
id : device
visible : currentIndex == 0
opacity: root.currentIndex === 0 ? 1 : 0
property real slideY: root.currentIndex === 0 ? 0 : 20
transform: Translate { y: device.slideY }
Behavior on opacity {
NumberAnimation { duration: 167; easing.type: Easing.OutCubic }
}
Behavior on slideY {
NumberAnimation { duration: 167; easing.type: Easing.OutCubic }
}
}
}
+163
View File
@@ -0,0 +1,163 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Item {
id: root
anchors.fill: parent
// FIXME: theming
property color linkColor: "#3b82f6"
ColumnLayout {
id: mainLayout
anchors.fill: parent
spacing: 0
Item { Layout.preferredHeight: 10 }
Item { Layout.fillHeight: true }
Text {
id: title
Layout.fillWidth: true
text: "Welcome to iDescriptor"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 28
font.weight: Font.DemiBold
wrapMode: Text.WordWrap
color: palette.text
}
Item { Layout.preferredHeight: 6 }
Text {
id: subtitle
Layout.fillWidth: true
text: "Open-Source & Free"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 10
font.weight: Font.Normal
wrapMode: Text.WordWrap
color: palette.text
}
Item { Layout.preferredHeight: 12 }
RowLayout {
id: imageAndWirelessDevicesLayout
Layout.alignment: Qt.AlignHCenter
spacing: 75
Image {
id: connectImage
source: "qrc:/resources/connect.png"
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
sourceSize.width: 0
sourceSize.height: 0
Layout.preferredWidth: implicitWidth
Layout.preferredHeight: implicitHeight
}
ColumnLayout {
id: explorerWithInstructionLayout
spacing: 12
// FIXME: implement
Rectangle {
Layout.preferredWidth: 360
Layout.preferredHeight: 180
radius: 8
color: "#1e40af" // blue
border.color: "#0b2a7a"
border.width: 1
Text {
anchors.centerIn: parent
text: "NetworkDevicesToConnectWidget"
color: "white"
font.pixelSize: 14
font.weight: Font.DemiBold
}
}
Text {
id: howToConnectLink
Layout.alignment: Qt.AlignHCenter
text: "How to connect a wireless device?"
color: root.linkColor
font.pixelSize: 12
font.weight: Font.DemiBold
wrapMode: Text.NoWrap
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: root.howToConnectRequested()
}
}
Item { Layout.preferredHeight: 20 }
}
}
Item { Layout.preferredHeight: 10 }
Text {
id: instruction
Layout.fillWidth: true
text: "Connect an iDevice to get started"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 14
wrapMode: Text.WordWrap
color: palette.text
}
Item { Layout.preferredHeight: 10 }
Text {
id: githubLink
Layout.alignment: Qt.AlignHCenter
text: "Found an issue? Report it on GitHub"
color: root.linkColor
font.pixelSize: 12
font.weight: Font.DemiBold
wrapMode: Text.NoWrap
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Qt.openUrlExternally(CONSTANTS.REPO_URL)
}
}
Item { Layout.preferredHeight: 10 }
// FIXME: implement
Rectangle {
Layout.alignment: Qt.AlignHCenter
visible: Qt.platform.os !== "osx"
Layout.preferredWidth: 520
Layout.preferredHeight: 90
radius: 8
color: "#b91c1c" // red
border.color: "#7f1d1d"
border.width: 1
Text {
anchors.centerIn: parent
text: "DiagnoseWidget"
color: "white"
font.pixelSize: 14
font.weight: Font.DemiBold
}
}
// bottom stretch
Item { Layout.fillHeight: true }
}
}
+8 -11
View File
@@ -1,13 +1,10 @@
use cxx_qt_build::CxxQtBuilder;
use cxx_qt_build::{CxxQtBuilder, QmlModule};
fn main() {
CxxQtBuilder::new()
.file("src/lib.rs")
.file("src/afc_services.rs")
.file("src/afc2_services.rs")
.file("src/service_manager.rs")
.file("src/screenshot.rs")
.file("src/hause_arrest.rs")
.file("src/io_manager.rs")
.build();
}
CxxQtBuilder::new_qml_module(
QmlModule::new("com.kdab.cxx_qt.demo").qml_file("../qml/Tabs.qml"),
)
.qt_module("Qml")
.files(["src/lib.rs","src/afc_services.rs","src/afc2_services.rs","src/service_manager.rs","src/screenshot.rs","src/hause_arrest.rs","src/io_manager.rs"])
.build();
}
+2 -2
View File
@@ -79,9 +79,8 @@ where
rx.recv().expect("Tokio runtime worker panicked")
}
#[cxx_qt::bridge(namespace = "CXX")]
#[cxx_qt::bridge]
mod qobject {
#[namespace = ""]
unsafe extern "C++" {
include!("cxx-qt-lib/qstring.h");
include!("cxx-qt-lib/qlist.h");
@@ -93,6 +92,7 @@ mod qobject {
extern "RustQt" {
#[qobject]
#[qml_element]
type Core = super::RCore;
#[qinvokable]