diff --git a/Cargo.lock b/Cargo.lock index 78a636d..5bf5771 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1441,7 +1441,9 @@ dependencies = [ [[package]] name = "ipatool" -version = "0.1.0" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a31e8e647891da3394cfe231ffdfc37b1d95b7aa056f99cc2d375434c9d5199" dependencies = [ "bytes", "cookie_store", diff --git a/Cargo.toml b/Cargo.toml index fd1b6cc..3e48e97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ rusqlite = { version = "0.39.0", features = ["bundled"] } filetime = "0.2.27" priority-queue = "2.7.0" anyhow = "1.0.102" -ipatool = { path = "/home/uncore/Desktop/proj/ipatool-rs", default-features = false } +ipatool = { version = "0.1.1", default-features = false } cpp = "0.5.11" cstr = "0.2.12" qmetaobject = "0.2.10" diff --git a/build.rs b/build.rs index 0ee830e..12cf04f 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,3 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// Copyright © 2021-2022 Adrian - use cmake::build; use std::env; use std::fmt::Write; @@ -208,14 +205,22 @@ fn compile_bridge(qt_include_path: &str) { let _ = pkg_config::Config::new().probe("libavcodec"); let _ = pkg_config::Config::new().probe("libavutil"); let _ = pkg_config::Config::new().probe("libswscale"); - let _ = pkg_config::Config::new().probe("avahi-client"); + + #[cfg(target_os = "linux")] { + let _ = pkg_config::Config::new().probe("avahi-client"); + } + } cc_build.compile("bridge"); - for lib in ["avformat", "avcodec", "avutil", "swscale", "avahi-client"] { + for lib in ["avformat", "avcodec", "avutil", "swscale"] { println!("cargo:rustc-link-lib={}", lib); } + + #[cfg(target_os = "linux")] { + println!("cargo:rustc-link-lib=avahi-client"); + } } fn compile_uxplay() { @@ -255,7 +260,9 @@ fn compile_uxplay() { pkg_config::Config::new().probe("openssl").unwrap(); // Linux uses avahi - pkg_config::Config::new().probe("avahi-compat-libdns_sd").unwrap(); + #[cfg(target_os = "linux")] { + pkg_config::Config::new().probe("avahi-compat-libdns_sd").unwrap(); + } // FIXME: macOS and Windows // println!("cargo:rustc-link-lib=dns_sd"); @@ -349,111 +356,16 @@ fn main() { private_include("QtQuick"); private_include("QtQml"); - match target_os.as_str() { - "android" => { - println!( - "cargo:rustc-link-search={}/lib/arm64-v8a", - std::env::var("FFMPEG_DIR").unwrap() - ); - println!( - "cargo:rustc-link-search={}/lib", - std::env::var("FFMPEG_DIR").unwrap() - ); - config.include(format!("{}/include", std::env::var("FFMPEG_DIR").unwrap())); - } - "macos" | "ios" => { - println!( - "cargo:rustc-link-search={}/lib", - std::env::var("FFMPEG_DIR").unwrap() - ); - println!("cargo:rustc-link-lib=static:+whole-archive=x264"); - println!("cargo:rustc-link-lib=static=x265"); - } - "linux" => { - // println!( - // "cargo:rustc-link-search={}", - // std::env::var("OPENCV_LINK_PATHS").unwrap() - // // ); - // println!( - // "cargo:rustc-link-search={}/lib/{}", - // std::env::var("FFMPEG_DIR").unwrap(), - // std::env::var("FFMPEG_ARCH").unwrap_or("amd64".into()) - // ); - // println!( - // "cargo:rustc-link-search={}/lib", - // std::env::var("FFMPEG_DIR").unwrap() - // ); - // println!("cargo:rustc-link-lib=static:+whole-archive=z"); - // if std::env::var("OPENCV_LINK_PATHS") - // .unwrap_or_default() - // .contains("vcpkg") - // { - // std::env::var("OPENCV_LINK_LIBS") - // .unwrap() - // .split(',') - // .for_each(|lib| { - // println!("cargo:rustc-link-lib=static:+whole-archive={}", lib.trim()) - // }); - // } else { - // std::env::var("OPENCV_LINK_LIBS") - // .unwrap() - // .split(',') - // .for_each(|lib| println!("cargo:rustc-link-lib={}", lib.trim())); - // } - } - "windows" => { - println!("cargo:rustc-link-arg=/EXPORT:NvOptimusEnablement"); - println!("cargo:rustc-link-arg=/EXPORT:AmdPowerXpressRequestHighPerformance"); - println!( - "cargo:rustc-link-search={}", - std::env::var("OPENCV_LINK_PATHS").unwrap() - ); - println!( - "cargo:rustc-link-search={}\\lib\\{}", - std::env::var("FFMPEG_DIR").unwrap(), - std::env::var("FFMPEG_ARCH").unwrap_or("x64".into()) - ); - println!( - "cargo:rustc-link-search={}\\lib", - std::env::var("FFMPEG_DIR").unwrap() - ); - let mut res = winres::WindowsResource::new(); - res.set_icon("resources/app_icon.ico"); - res.set("FileVersion", env!("CARGO_PKG_VERSION")); - res.set("ProductVersion", env!("CARGO_PKG_VERSION")); - res.set("ProductName", "Gyroflow"); - res.set( - "FileDescription", - &format!("Gyroflow v{}", env!("CARGO_PKG_VERSION")), - ); - res.compile().unwrap(); - } - tos => panic!("unknown target os {:?}!", tos), - } - if let Ok(time) = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) { println!( "cargo:rustc-env=BUILD_TIME={}", (time.as_secs() - 1642516578) / 600 - ); // New version every 10 minutes + ); } - // !IMPORTANT config.include(&qt_include_path).build("src/main.rs"); - if target_os == "ios" { - let out_dir = env::var("OUT_DIR").unwrap(); - for entry in Path::new(&out_dir).read_dir().unwrap() { - let path = entry.unwrap().path(); - if path.is_file() && path.to_string_lossy().contains("qml_plugins.o") { - println!("cargo:rustc-link-arg=-force_load"); - println!("cargo:rustc-link-arg={}", path.to_string_lossy()); - break; - } - } - } - compile_bridge(&qt_include_path); compile_uxplay(); } diff --git a/src/main.rs b/src/main.rs index 66a9ac4..1c7a929 100644 --- a/src/main.rs +++ b/src/main.rs @@ -116,12 +116,13 @@ fn main() { qputenv("QSG_RENDER_LOOP", "basic"); #endif - // FIXME: fluentui example app was forcing OpenGL - // but do we need this ? - // #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) - // QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); + #ifdef Q_OS_WINDOWS + // uxplay now uses qml6glsink so we have to use opengl on Windows + // Linux is fine with QT_QPA_PLATFORM=xcb + QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL); + QQuickStyle::setStyle("FluentWinUI3"); + #endif // QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); - // #endif #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); @@ -228,9 +229,14 @@ fn main() { let engine_ptr = engine.cpp_ptr(); - // cpp!(unsafe [engine_ptr as "QQmlApplicationEngine *"] { - // engine_ptr->rootContext()->setContextProperty("NetworkDeviceProvider", NetworkDeviceProvider::sharedInstance()); - // }); + cpp!(unsafe [engine_ptr as "QQmlApplicationEngine *"] { + // FIXME: workaround to find FluentUI + #ifdef Q_OS_WINDOWS + engine_ptr->addImportPath("C:/Qt/6.9.3/mingw_64/qml"); + #endif + // #endif + // engine_ptr->rootContext()->setContextProperty("NetworkDeviceProvider", NetworkDeviceProvider::sharedInstance()); + }); let service_factory = QObjectBox::new(crate::service_factory::ServiceFactory::new(engine_ptr)); engine.set_object_property("serviceFactory".into(), service_factory.pinned()); @@ -258,8 +264,17 @@ fn main() { engine.load_url(QString::from("qrc:/src/ui/Main.qml").into()); } } else { - engine.load_file(format!("{}/src/ui/Main.qml", env!("CARGO_MANIFEST_DIR")).into()); - let ui_path = QString::from(format!("{}/src/ui", env!("CARGO_MANIFEST_DIR"))); + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + + let main_qml_path = if cfg!(target_os = "windows") { + format!("{}/src/ui/windows/Main.qml", manifest_dir).into() + } else { + format!("{}/src/ui/Main.qml", manifest_dir).into() + }; + + engine.load_file(main_qml_path); + + let ui_path = QString::from(format!("{}/src/ui", manifest_dir)); cpp!(unsafe [engine_ptr as "QQmlApplicationEngine *", ui_path as "QString"] { init_live_reload(engine_ptr, ui_path); }); } diff --git a/src/ui/AppsTab.qml b/src/ui/AppsTab.qml index 95fed0e..3891e47 100644 --- a/src/ui/AppsTab.qml +++ b/src/ui/AppsTab.qml @@ -1,7 +1,7 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 -import Qt5Compat.GraphicalEffects 1.15 +import Qt5Compat.GraphicalEffects import QtQuick.Controls.impl Item { diff --git a/src/ui/DeviceTab.qml b/src/ui/DeviceTab.qml index 11b9272..5309648 100644 --- a/src/ui/DeviceTab.qml +++ b/src/ui/DeviceTab.qml @@ -21,16 +21,16 @@ Item { // Layout.fillHeight : true ColumnLayout { - Layout.fillWidth : true + // Layout.fillWidth : true Layout.fillHeight : true Layout.preferredWidth: 220 Repeater { model: App.DeviceContext.devices - delegate: Item { - SidebarTabButton { - Layout.fillWidth: true - Layout.preferredWidth: 220 - Layout.preferredHeight: 40 + delegate:SidebarTabButton { + Layout.fillHeight : true + Layout.preferredWidth: 200 + Layout.alignment: Qt.AlignHCenter + currentSection: root.currentSection // udid: model.udid // anchors.fill: parent @@ -41,7 +41,6 @@ Item { // root.currentDeviceUdid = udid if (root.currentSection !== sectionIndex) root.currentSection = sectionIndex - } } } } diff --git a/src/ui/IconLoader.qml b/src/ui/IconLoader.qml index 4f9b9ba..1dfc328 100644 --- a/src/ui/IconLoader.qml +++ b/src/ui/IconLoader.qml @@ -1,7 +1,7 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 -import Qt5Compat.GraphicalEffects 1.15 +import Qt5Compat.GraphicalEffects Rectangle { id: root diff --git a/src/ui/SidebarTabButton.qml b/src/ui/SidebarTabButton.qml index 6d3074e..2fec1ff 100644 --- a/src/ui/SidebarTabButton.qml +++ b/src/ui/SidebarTabButton.qml @@ -1,69 +1,89 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 +import FluentUI -ColumnLayout { - id:root - signal sectionChanged(int sectionIndex) - Button { - Layout.preferredWidth: 220 - Layout.fillHeight: true - contentItem : Text { - text: "Info" - color: "Red" - } - background : Rectangle { - color : "transparent" - } - onClicked: { - root.sectionChanged(0) +FluExpander { + id: root + property int currentSection : 1 + signal sectionChanged(int sectionIndex) + + ListModel { + id: nav_model + ListElement { name: qsTr("Info"); sectionIndex: 0 } + ListElement { name: qsTr("Apps"); sectionIndex: 1 } + ListElement { name: qsTr("Gallery"); sectionIndex: 2 } + ListElement { name: qsTr("Files"); sectionIndex: 3 } + } + + implicitWidth: 200 + contentHeight : 40 * 4 + 40 + + headerDelegate: Component { + Item { + FluToggleButton { + anchors.centerIn: parent + text: qsTr("TODO") + } } } - Button { - Layout.preferredWidth: 220 - Layout.fillHeight: true - contentItem : Text { - text: "Apps" - color: "Red" - } - background : Rectangle { - color : "transparent" - } - onClicked: { - root.sectionChanged(1) + content: Item { + anchors.fill: parent + + ListView { + id: nav_list + anchors.fill: parent + anchors.margins : 10 + clip: true + spacing : 5 + + model: nav_model + interactive: false + boundsBehavior: ListView.StopAtBounds + currentIndex : root.currentSection + highlightMoveDuration: FluTheme.animationEnabled ? 167 : 0 + highlight: Item{ + z:99 + clip: true + Rectangle{ + height: 18 + radius: 1.5 + color: FluTheme.primaryColor + width: 3 + anchors{ + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: 6 + } + } + } + delegate: FluButton { + text: name + width: nav_list.width + height: 40 + // verticalPadding: 5 + // horizontalPadding:20 + background : Rectangle { + color : { + if (nav_list.currentIndex == index) { + return FluTheme.itemCheckColor + } + if (hovered) { + return FluTheme.itemHoverColor + } + + return "transparent" + } + radius : 4 + + } + onClicked : { + nav_list.currentIndex = index + root.sectionChanged(sectionIndex) + } + } } } - - Button { - Layout.preferredWidth: 220 - Layout.fillHeight: true - contentItem : Text { - text: "Gallery" - color: "Red" - } - background : Rectangle { - color : "transparent" - } - onClicked: { - root.sectionChanged(2) - } - } - - Button { - Layout.preferredWidth: 220 - Layout.fillHeight: true - contentItem : Text { - text: "Files" - color: "Red" - } - background : Rectangle { - color : "transparent" - } - onClicked: { - root.sectionChanged(3) - } - } - -} \ No newline at end of file +} diff --git a/src/ui/wIndows/Index.qml b/src/ui/wIndows/Index.qml index d5b5fac..7788a50 100644 --- a/src/ui/wIndows/Index.qml +++ b/src/ui/wIndows/Index.qml @@ -2,7 +2,7 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 import FluentUI 1.0 import QtQuick.Layouts 1.15 -import "." +import ".." FluWindow { @@ -55,6 +55,6 @@ FluWindow { Tabs { currentIndex: window.currentIndex anchors.fill: parent - anchors.topMargin: appBar.height + anchors.topMargin: appBar.height + 25 } } diff --git a/src/ui/wIndows/Main.qml b/src/ui/wIndows/Main.qml index d537726..58c25f1 100644 --- a/src/ui/wIndows/Main.qml +++ b/src/ui/wIndows/Main.qml @@ -3,6 +3,7 @@ import QtQuick.Window 2.15 // import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import FluentUI 1.0 +import "../" FluLauncher { id: app @@ -36,8 +37,11 @@ FluLauncher { // FluTheme.darkMode = SettingsHelper.getDarkMode() FluTheme.darkMode = false FluTheme.animationEnabled = true + var indexUrl = Qt.resolvedUrl("Index.qml") + console.log("Index URL =", indexUrl) + FluRouter.routes = { - "/":"qrc:/src/qml/windows/Index.qml", + "/": indexUrl } var args = Qt.application.arguments if(args.length>=2 && args[1].startsWith("-crashed=")){