diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1099c48..372189c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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
)
diff --git a/resources.ui.qrc b/resources.ui.qrc
new file mode 100644
index 0000000..618fc86
--- /dev/null
+++ b/resources.ui.qrc
@@ -0,0 +1,11 @@
+
+
+ src/qml/Main.qml
+ src/qml/Index.qml
+ src/qml/Tabs.qml
+ src/qml/HowToConnect.qml
+ src/qml/Welcome.qml
+ src/qml/TabButton.qml
+ src/qml/Device.qml
+
+
\ No newline at end of file
diff --git a/src/constants.h b/src/constants.h
new file mode 100644
index 0000000..f25ea37
--- /dev/null
+++ b/src/constants.h
@@ -0,0 +1,18 @@
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#include "iDescriptor.h"
+#include
+
+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
diff --git a/src/iDescriptor.h b/src/iDescriptor.h
index f7b331e..391f323 100644
--- a/src/iDescriptor.h
+++ b/src/iDescriptor.h
@@ -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);
diff --git a/src/main.cpp b/src/main.cpp
index 5298655..feeeb2e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,8 +17,8 @@
* along with this program. If not, see .
*/
+#include "constants.h"
#include "iDescriptor.h"
-#include "mainwindow.h"
#include "settingsmanager.h"
#include
#include
@@ -32,43 +32,55 @@
#include "platform/windows/win_common.h"
#endif
+#include
+#include
+#include
+#include
+#include
+#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();
}
diff --git a/src/platform/windows/blur_imp.cpp b/src/platform/windows/blur_imp.cpp
index 32d7b7b..78f84b2 100644
--- a/src/platform/windows/blur_imp.cpp
+++ b/src/platform/windows/blur_imp.cpp
@@ -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(
- 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(
+ // 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(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(window->winId());
+ // enableMica(hwnd);
/*
normally we had plans to enable acrylic on win 10 but since it's
diff --git a/src/qml/Device.qml b/src/qml/Device.qml
new file mode 100644
index 0000000..bffb5d2
--- /dev/null
+++ b/src/qml/Device.qml
@@ -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
+ }
+
+}
diff --git a/src/qml/HowToConnect.qml b/src/qml/HowToConnect.qml
new file mode 100644
index 0000000..5667b78
--- /dev/null
+++ b/src/qml/HowToConnect.qml
@@ -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 }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/qml/Index.qml b/src/qml/Index.qml
new file mode 100644
index 0000000..d5b5fac
--- /dev/null
+++ b/src/qml/Index.qml
@@ -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
+ }
+}
diff --git a/src/qml/Main.qml b/src/qml/Main.qml
new file mode 100644
index 0000000..183a69a
--- /dev/null
+++ b/src/qml/Main.qml
@@ -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("/")
+ }
+ }
+
+}
diff --git a/src/qml/TabButton.qml b/src/qml/TabButton.qml
new file mode 100644
index 0000000..aa11211
--- /dev/null
+++ b/src/qml/TabButton.qml
@@ -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"
+ }
+}
diff --git a/src/qml/Tabs.qml b/src/qml/Tabs.qml
new file mode 100644
index 0000000..61d4360
--- /dev/null
+++ b/src/qml/Tabs.qml
@@ -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 }
+ }
+ }
+
+}
diff --git a/src/qml/Welcome.qml b/src/qml/Welcome.qml
new file mode 100644
index 0000000..e73df3b
--- /dev/null
+++ b/src/qml/Welcome.qml
@@ -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 }
+ }
+}
diff --git a/src/rust/build.rs b/src/rust/build.rs
index 3e73a93..7b9ba57 100644
--- a/src/rust/build.rs
+++ b/src/rust/build.rs
@@ -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();
+}
\ No newline at end of file
diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs
index 449252d..c9d8839 100644
--- a/src/rust/src/lib.rs
+++ b/src/rust/src/lib.rs
@@ -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]