...
This commit is contained in:
8841
packages/mme/Cargo.lock
generated
Normal file
8841
packages/mme/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
76
packages/mme/Cargo.toml
Normal file
76
packages/mme/Cargo.toml
Normal file
@@ -0,0 +1,76 @@
|
||||
[package]
|
||||
name = "mme"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
||||
[package.metadata.wasm-pack.profile.dev]
|
||||
wasm-opt = false
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
default = [ "target-os" ]
|
||||
qt = [ "slint", "cpp", "qt_core", "qt_gui", "qt_widgets", "comandr/qt" ]
|
||||
slint = [ "i-slint-backend-qt", "dep:slint", "slint-interpreter", "spin_on", "qt" ]
|
||||
target-os= [ "tao", "wry", "tracing-subscriber", "clap", "webkit2gtk", "mize/target-os", "glib" ]
|
||||
#target-os= [ "tao", "wry", "tracing-subscriber", "clap" ]
|
||||
target-wasm = [ "wasm-bindgen", "console_error_panic_hook", "wasm-bindgen-cli", "web-sys", "comandr/target-wasm ", "mize/wasm-target" ]
|
||||
console_error_panic_hook = ["dep:console_error_panic_hook"]
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
webkit2gtk = { version = "2.0.1", optional = true }
|
||||
|
||||
[dependencies]
|
||||
# core deps
|
||||
colored = "2.1.0"
|
||||
enum_dispatch = "0.3.13"
|
||||
comandr = { git = "https://github.com/c2vi/comandr", default-features = false }
|
||||
#comandr = { path = "../../../dr-comandr" }
|
||||
mize = { git = "https://github.com/c2vi/mize", default-features = false }
|
||||
tracing = "0.1.40"
|
||||
base64 = "0.22.1"
|
||||
|
||||
# wasm dependencies
|
||||
wasm-bindgen = { version = "0.2.84", optional = true }
|
||||
console_error_panic_hook = { version = "0.1.7", optional = true }
|
||||
wasm-bindgen-cli = { version = "0.2.92", optional = true }
|
||||
web-sys = { version = "0.3.70", optional = true, features = ['console'] }
|
||||
|
||||
# os deps
|
||||
tao = { version = "0.28.1", optional = true }
|
||||
wry = { version = "0.41.0", optional = true, features = [ "devtools" ] }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"], optional = true }
|
||||
clap = { version = "4.5.8", features = ["cargo"], optional = true }
|
||||
glib = { version = "0.15.12", optional = true }
|
||||
|
||||
# qt deps
|
||||
#qt_gui = "0.5.0"
|
||||
cpp = { version = "0.5.9", optional = true }
|
||||
qt_gui = { version = "0.5.0", optional = true }
|
||||
qt_core = { version = "0.5.0", optional = true }
|
||||
qt_widgets = { version = "0.5.0", optional = true }
|
||||
|
||||
#slint deps
|
||||
i-slint-backend-qt = { version = "1.7.1", optional = true }
|
||||
slint = { version = "1.7.1", optional = true }
|
||||
slint-interpreter = { version = "1.7.1", optional = true }
|
||||
spin_on = { version = "0.1.1", optional = true }
|
||||
custom-print = "1.0.0"
|
||||
flume = "0.11.1"
|
||||
ciborium = "0.2.2"
|
||||
ciborium-io = { version = "0.2.2", features = ["std", "alloc"] }
|
||||
wasm-bindgen-futures = "0.4.49"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.1.5"
|
||||
cpp_build = "0.5"
|
||||
|
||||
[lib]
|
||||
name = "mize_module_mme"
|
||||
crate-type =["cdylib", "rlib"]
|
||||
|
||||
[target.wasm32-unknown-unknown]
|
||||
rustflags = [
|
||||
"-C", "link-args=--import-memory",
|
||||
]
|
||||
8
packages/mme/build-web.sh
Executable file
8
packages/mme/build-web.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
|
||||
set -e
|
||||
|
||||
wasm-pack build --features wasm-target --no-default-features
|
||||
|
||||
cd /home/me/work/mme-presenters/presenters/mme-js/
|
||||
|
||||
npm run build -- --mode development
|
||||
29
packages/mme/build.rs
Normal file
29
packages/mme/build.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
fn main() {
|
||||
|
||||
#[cfg(feature = "qt")]
|
||||
{
|
||||
let qt_lib_path = env!("MME_QT_LIB");
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.file("src/main.cpp")
|
||||
.flag("-w")
|
||||
.compile("mme");
|
||||
println!("cargo:rustc-link-search={}", qt_lib_path);
|
||||
println!("cargo:rustc-link-lib=Qt5Quick");
|
||||
println!("cargo:rustc-link-lib=Qt5PrintSupport ");
|
||||
println!("cargo:rustc-link-lib=Qt5Qml ");
|
||||
println!("cargo:rustc-link-lib=Qt5Network ");
|
||||
println!("cargo:rustc-link-lib=Qt5Widgets ");
|
||||
println!("cargo:rustc-link-lib=Qt5Gui ");
|
||||
println!("cargo:rustc-link-lib=Qt5Core");
|
||||
println!("cargo:rustc-link-lib=Qt5WebEngine");
|
||||
println!("cargo:rustc-link-lib=Qt5WebEngineCore");
|
||||
println!("cargo:rustc-link-lib=Qt5WebEngineWidgets");
|
||||
|
||||
println!("cargo:rerun-if-changed=src/main.cpp");
|
||||
|
||||
cpp_build::build("src/implementors/qt_widget/mod.rs");
|
||||
}
|
||||
}
|
||||
|
||||
19
packages/mme/dev
Normal file
19
packages/mme/dev
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
export MIZE_MODULE_PATH=/home/me/work/mme:/home/me/work/modules:/home/me/work/mesenters
|
||||
export MIZE_MODULE_NO_REPO=1
|
||||
export MIZE_MODULE_NO_EXTERNALS=1
|
||||
export MIZE_CONFIG=$MIZE_CONFIG:module_dir.mme=/home/me/work/mme/dist:module_dir.String=/home/me/work/modules/modules/String/dist
|
||||
|
||||
function dev() {
|
||||
|
||||
#nix develop /home/me/work/mize#modules.mme --override-input nixpkgs github:nixos/nixpkgs/ea6033ce4ddf2c0ede2ea147a450d4f880796128 --impure
|
||||
nix develop /home/me/work/mize#modules.mme --override-input nixpkgs github:nixos/nixpkgs/10e687235226880ed5e9f33f1ffa71fe60f2638a --impure
|
||||
#nix develop /home/me/work/mize#modules.mme --impure
|
||||
|
||||
}
|
||||
|
||||
if [[ "$1" != "no" ]]
|
||||
then
|
||||
dev
|
||||
fi
|
||||
171
packages/mme/mize.nix
Normal file
171
packages/mme/mize.nix
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
|
||||
|
||||
module = { buildMizeForSystem, mizeBuildConfig, mkMizeRustModule, hostSystem, pkgsCross, mkMizeRustShell, pkgs, pkgsNative, buildNpmPackage, mkSelString, mizeBuildConfigStr, fenix, ... }: let
|
||||
|
||||
selector_string = mkSelString {
|
||||
modName = "mme";
|
||||
};
|
||||
hash = builtins.substring 0 32 (builtins.hashString "sha256" selector_string);
|
||||
url = "file:///home/me/work/mme/dist/mize.js";
|
||||
html = ''
|
||||
<html>
|
||||
<head>
|
||||
<!-- script src="https://c2vi.dev/mize/wasm32-none-unknown/mize.js"></script --!>
|
||||
<!-- script src="${url}"></script --!>
|
||||
<script>
|
||||
console.log("from script")
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
hello world...............
|
||||
</body>
|
||||
</html>
|
||||
'';
|
||||
|
||||
in mkMizeRustModule ({
|
||||
modName = "mme";
|
||||
src = ./.;
|
||||
cargoExtraArgs = "--no-default-features --lib";
|
||||
|
||||
## add the index.html
|
||||
postInstall = ''
|
||||
echo -n '${html}' > $out/index.html
|
||||
'';
|
||||
|
||||
}
|
||||
|
||||
|
||||
// (if hostSystem.name == "wasm32-none-unknown" then {
|
||||
mizeBuildPhase = ''
|
||||
cd $build_dir
|
||||
RUSTFLAGS="-C link-args=--import-memory" RUST_LOG=off wasm-pack build --target no-modules --dev --out-dir $out -- --features wasm-target --no-default-features
|
||||
echo -n 'export function get_wasm_bindgen() { return wasm_bindgen }' >> $out/mize_module_mme.js
|
||||
echo -n '${html}' > $out/index.html
|
||||
'';
|
||||
mizeInstallPhase = "";
|
||||
} else {})
|
||||
|
||||
// (if hostSystem.kernel.name == "linux" then builtins.trace "adding linux stuff" {
|
||||
nativeBuildInputs = with pkgsCross.buildPackages; [
|
||||
pkg-config
|
||||
];
|
||||
buildInputs = with pkgsNative; [
|
||||
webkitgtk_4_1
|
||||
];
|
||||
} else {})
|
||||
|
||||
|
||||
# add the devShell
|
||||
// {
|
||||
devShell = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
#emscripten
|
||||
wasm-pack
|
||||
pkg-config
|
||||
webkitgtk_4_1
|
||||
libsForQt5.full
|
||||
cmake
|
||||
nasm
|
||||
pkg-config
|
||||
nodejs
|
||||
|
||||
(fenix.packages.${system}.combine [
|
||||
fenix.packages.${system}.targets.wasm32-unknown-unknown.latest.toolchain
|
||||
fenix.packages.${system}.latest.toolchain
|
||||
fenix.packages.${system}.latest.rust-src
|
||||
])
|
||||
|
||||
];
|
||||
|
||||
MIZE_BUILD_CONFIG = mizeBuildConfigStr;
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
openssl
|
||||
#pango
|
||||
#libsoup_3
|
||||
webkitgtk_4_1
|
||||
# gobject-introspection gtk4 atkmm
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo hiiiiiiiiiiiiii
|
||||
export LD_LIBRARY_PATH=${pkgs.webkitgtk_4_1}/lib:${pkgs.libsoup_3}/lib:${pkgs.glib.out}/lib:${pkgs.gtk3}/lib:${pkgs.cairo}/lib:${pkgs.gdk-pixbuf}/lib:${pkgs.libxkbcommon}/lib:${pkgs.fontconfig.lib}/lib:${pkgs.libsForQt5.full}/lib:${pkgs.stdenv.cc.cc.lib}/lib:${pkgs.libsForQt5.qt5.qtwebengine}/lib
|
||||
|
||||
export CPLUS_INCLUDE_PATH=${pkgs.libsForQt5.full}/include:${pkgs.libsForQt5.qt5.qtwebengine}/include
|
||||
|
||||
export MME_QT_LIB=${pkgs.libsForQt5.full}/lib
|
||||
|
||||
# i found that this is the env war to set where QT looks for platform plugins
|
||||
# at: https://forums.fedoraforum.org/showthread.php?326508-How-to-set-QT_QPA_PLATFORM_PLUGIN_PATH
|
||||
export QT_QPA_PLATFORM_PLUGIN_PATH=${pkgs.libsForQt5.full}/lib/qt-5.15.14/plugins/platforms/
|
||||
|
||||
alias run="${./.}/run.sh"
|
||||
'';
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
lib = { mkMizeModule, buildNpmPackage, pkgsCross, pkgsNative, ... }: rec {
|
||||
mkMmePresenter = attrs: mkMizeModule (attrs // {
|
||||
src = attrs.src;
|
||||
modName = attrs.name;
|
||||
select = {
|
||||
mme_presenter = true;
|
||||
};
|
||||
});
|
||||
|
||||
mkMmeNpmPresenter = attrs: mkMizeModule (attrs // {
|
||||
drvFunc = buildNpmPackage;
|
||||
mizeBuildPhase = ''
|
||||
cd $build_dir
|
||||
npm i
|
||||
npm run build
|
||||
mv dist tmp
|
||||
mkdir -p $out
|
||||
mv tmp/* $out
|
||||
rm -rf tmp
|
||||
'';
|
||||
mizeInstallPhase = "";
|
||||
select = {
|
||||
mme_presenter = true;
|
||||
};
|
||||
|
||||
devShell = pkgsNative.mkShell {
|
||||
buildInputs = with pkgsNative; [ nodejs_20 ];
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
mkMmeHtmlPresenter = attrs: mkMmePresenter ({
|
||||
dontUnpack = true;
|
||||
dontPath = true;
|
||||
buildPhase = "";
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp -r ${attrs.src}/* $out
|
||||
'';
|
||||
} // attrs);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
externals = { fetchFromGitHub, ... }: [
|
||||
|
||||
(fetchFromGitHub {
|
||||
owner = "c2vi";
|
||||
repo = "mme-presenters";
|
||||
rev = "master";
|
||||
hash = "sha256-FeMBDCJBkw9XOLXC1rfedNk71uyg4OTCHaaO1jAAGto=";
|
||||
})
|
||||
|
||||
];
|
||||
|
||||
|
||||
}
|
||||
|
||||
58
packages/mme/run.sh
Executable file
58
packages/mme/run.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
|
||||
set -e
|
||||
|
||||
# override, where mize loads the mme module from
|
||||
export MIZE_MODULE_PATH=/home/me/work/mme:/home/me/work/modules:/home/me/work/presenters
|
||||
export MIZE_MODULE_NO_REPO=1
|
||||
export MIZE_MODULE_NO_EXTERNALS=1
|
||||
export MIZE_CONFIG=$MIZE_CONFIG:module_dir.mme=/home/me/work/mme/dist:module_dir.String=/home/me/work/modules/modules/String/dist:module_dir.mme_presenter.mme_js=/home/me/work/presenters/presenters/mme_js/dist
|
||||
#export MIZE_CONFIG=$MIZE_CONFIG:module_dir.mme=/home/me/work/mize/result
|
||||
|
||||
|
||||
# build mme for the browser
|
||||
echo '############################# MME for Browser #############################'
|
||||
RUST_LOG=off wasm-pack build --target no-modules --dev --out-dir ./dist -- --features wasm-target --no-default-features
|
||||
|
||||
|
||||
# build mize for the browser
|
||||
echo '############################# mize for Browser #############################'
|
||||
cd /home/me/work/mize
|
||||
RUST_LOG=off wasm-pack build --target no-modules --dev -- --features wasm-target --no-default-features
|
||||
cat /home/me/work/mize/src/platform/wasm/init.js >> /home/me/work/mize/pkg/mize.js
|
||||
|
||||
#--out-dir ~/work/mize/src/platform/wasm/npm_pkg/generated
|
||||
|
||||
#export CARGO_BUILD_RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals'
|
||||
#wasm-pack build --target no-modules --dev . -Z build-std=panic_abort,std --features wasm-target --no-default-features --config 'build.rustflags = "-C target-feature=+atomics,+bulk-memory,+mutable-globals"'
|
||||
#cp -r ~/work/mize/pkg/* ~/work/mize/src/platform/wasm/npm_pkg/generated
|
||||
#RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+mutable-globals' cargo build --target wasm32-unknown-unknown -Z build-std=panic_abort,std --lib --no-default-features
|
||||
#cp ~/work/mize/target/wasm32-unknown-unknown/debug/mize.wasm ~/work/mize/src/platform/wasm/npm_pkg/generated/mize_bg.wasm
|
||||
|
||||
|
||||
# build the mme-js presenter
|
||||
echo '############################# mme-js presenter #############################'
|
||||
cd /home/me/work/presenters/presenters/mme_js/
|
||||
npm run build -- --mode development
|
||||
|
||||
|
||||
# build the mme module
|
||||
echo '############################# mme module for os #############################'
|
||||
cd /home/me/work/mme
|
||||
cargo build --lib
|
||||
mkdir -p /home/me/work/mme/dist/lib
|
||||
cp /home/me/work/mme/target/debug/libmize_module_mme.so /home/me/work/mme/dist/lib
|
||||
nix eval --expr 'import /home/me/work/mme/src/implementors/html/index.nix { mize_url = "file:///home/me/work/mize/pkg/mize.js"; }' --impure --raw > /home/me/work/mme/dist/index.html
|
||||
|
||||
|
||||
# build the String module
|
||||
echo '############################# string module for os #############################'
|
||||
cargo build --manifest-path ~/work/modules/modules/String/Cargo.toml --lib
|
||||
mkdir -p /home/me/work/modules/modules/String/dist/lib
|
||||
cp /home/me/work/modules/modules/String/target/debug/libmize_module_String.so /home/me/work/modules/modules/String/dist/lib
|
||||
|
||||
|
||||
# run mize with gui
|
||||
echo '############################# run mize for os #############################'
|
||||
cargo run --manifest-path ~/work/mize/Cargo.toml -- gui
|
||||
|
||||
|
||||
14
packages/mme/src/core/adapter.rs
Normal file
14
packages/mme/src/core/adapter.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use crate::slot::Slot;
|
||||
|
||||
use mize::MizeResult;
|
||||
|
||||
// A Presenter, that takes not data and produces only one output Space
|
||||
// with that space being of a different type.
|
||||
// In order to put Presenters of different types into one another.
|
||||
// eg a QT-Webview is put into a qt-space ... in order to get a web-space....
|
||||
pub struct Adapter {
|
||||
}
|
||||
|
||||
pub trait AdapterTrait {
|
||||
fn sub_slot() -> MizeResult<Slot>;
|
||||
}
|
||||
5
packages/mme/src/core/layout.rs
Normal file
5
packages/mme/src/core/layout.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
// A Presenter, that takes no data. Just provides sub spaces.
|
||||
pub struct Layout {
|
||||
}
|
||||
557
packages/mme/src/core/mme.rs
Normal file
557
packages/mme/src/core/mme.rs
Normal file
@@ -0,0 +1,557 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{implementors::{html::HtmlPresenter}, presenter};
|
||||
use crate::slot::{Slot, SlotTrait};
|
||||
use crate::presenter::Presenter;
|
||||
use tracing::info;
|
||||
use comandr::Comandr;
|
||||
use flume::{ Receiver, Sender };
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use base64::Engine;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use wasm_bindgen::JsValue;
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use web_sys::js_sys::Function;
|
||||
|
||||
//#[cfg(feature = "target-os")]
|
||||
//use crate::implementors::qt_widget::QtWidgetSlot;
|
||||
#[cfg(feature = "qt")]
|
||||
use qt_core::{qs, QString, QTimer, SlotNoArgs};
|
||||
#[cfg(feature = "qt")]
|
||||
use qt_widgets::{QApplication, QGridLayout, QWidget};
|
||||
#[cfg(feature = "qt")]
|
||||
use qt_gui::{cpp_core::CppBox};
|
||||
|
||||
|
||||
use mize::Module;
|
||||
use mize::MizeResult;
|
||||
use mize::error::MizeResultTrait;
|
||||
use mize::Instance;
|
||||
use mize::mize_err;
|
||||
use mize::MizeError;
|
||||
use mize::proto::MizeMessage;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Mme {
|
||||
pub comandr: Arc<Mutex<Comandr>>,
|
||||
pub mize: Instance,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// console_log macro
|
||||
// that can be copied into other files for debugging purposes
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
#[cfg(feature = "wasm-target")]
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn get_mize_module_mme(empty_module: &mut Box<dyn Module + Send + Sync>, mize: Instance) -> () {
|
||||
#[cfg(feature = "wasm-target")]
|
||||
console_log!("hiiiiiiiiiiiiiiii from inside get_mize_module_mme!!!!!!!!!");
|
||||
let comandr = Comandr::new();
|
||||
let new_box: Box<dyn Module + Send + Sync> = Box::new( Mme { comandr: Arc::new(Mutex::new(comandr)), mize, } );
|
||||
|
||||
*empty_module = new_box
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use mize::platform::wasm::JsInstance;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn wasm_get_mize_module_mme(mut empty_module_ptr: usize, mut mize_ptr: usize) -> () {
|
||||
|
||||
console_log!("hiiiiiiiiiiiiiiiiiiiiiii form wasm_get_mize_module_mme");
|
||||
let empty_module = empty_module_ptr as * mut Box<dyn Module + Send + Sync>;
|
||||
console_log!("here");
|
||||
|
||||
let mize = (*(mize_ptr as * mut Instance)).clone();
|
||||
|
||||
console_log!("here2");
|
||||
|
||||
//(*empty_module).init(&mize);
|
||||
|
||||
console_log!("here3");
|
||||
|
||||
let comandr = Comandr::new();
|
||||
let mut new_box: Box<dyn Module + Send + Sync> = Box::new( Mme { comandr: Arc::new(Mutex::new(comandr)), mize: mize.clone(), } );
|
||||
|
||||
console_log!("before new_box.init()");
|
||||
new_box.init(&mize);
|
||||
|
||||
console_log!("before assignment");
|
||||
|
||||
*empty_module = new_box
|
||||
}
|
||||
/*
|
||||
pub fn wasm_get_mize_module_mme(empty_module_ptr: usize, mize: JsInstance) -> usize {
|
||||
let mut empty_module: Box<dyn Module + Send + Sync> = *(empty_module_ptr as Box<Box<dyn Module + Send + Sync>>);
|
||||
let mize = mize.inner().clone();
|
||||
let comandr = Comandr::new();
|
||||
let new_box: Box<dyn Module + Send + Sync> = Box::new( Mme { comandr: Arc::new(Mutex::new(comandr)), mize, } );
|
||||
|
||||
*empty_module = new_box
|
||||
}
|
||||
*/
|
||||
|
||||
impl Module for Mme {
|
||||
fn init(&mut self, _instance: &Instance) -> MizeResult<()> {
|
||||
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
{
|
||||
// console log
|
||||
use wasm_bindgen::prelude::*;
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
console_log!("mme module inittttttttttttttttttttttt");
|
||||
}
|
||||
|
||||
println!("MmeModule init");
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
{
|
||||
//self.mize.spawn("mme-main", || self.create_x_window());
|
||||
let mut cloned_self = self.clone();
|
||||
// "significant cross-platform compatibility hazard." xD
|
||||
//self.mize.spawn("mme-main", move || cloned_self.create_x_window());
|
||||
|
||||
self.create_x_window();
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
{
|
||||
use web_sys::js_sys::eval;
|
||||
use crate::implementors::html::wasm::MmeJs;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
// create mme module object
|
||||
let mut mme_js = MmeJs {
|
||||
inner: NonNull::from(Box::leak(Box::new(self.clone()))),
|
||||
webview_con_id: 0,
|
||||
};
|
||||
|
||||
let func = Function::new_with_args("mme_js", r#"
|
||||
window.mize.mod.mme = mme_js;
|
||||
"#);
|
||||
func.call1(&JsValue::null(), &JsValue::from(mme_js)).map_err(|e| mize_err!("from js error: {:?}", e));
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(&mut self, _instance: &Instance) -> MizeResult<()> {
|
||||
info!("mme module exit");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clone_module(&self) -> Box<dyn Module + Send + Sync> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "qt")]
|
||||
unsafe fn qstring_to_rust(q_string: CppBox<QString>) -> String {
|
||||
let mut rust_string = String::new();
|
||||
let q_string_size = q_string.size();
|
||||
|
||||
for j in 0..q_string_size {
|
||||
let q_char = q_string.index_int(j);
|
||||
let rust_char = char::from_u32(q_char.unicode() as u32);
|
||||
rust_string.push(rust_char.unwrap());
|
||||
}
|
||||
return rust_string;
|
||||
}
|
||||
|
||||
impl Mme {
|
||||
pub fn new(mize: Instance) -> MizeResult<Mme> {
|
||||
let comandr = Comandr::new();
|
||||
Ok(Mme { comandr: Arc::new(Mutex::new(comandr)), mize, })
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
pub fn create_html_slot() -> MizeResult<()> {
|
||||
println!("hi wasm");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
pub fn create_x_window(&mut self) -> MizeResult<()> {
|
||||
use std::fs;
|
||||
|
||||
use tao::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{self, ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
use wry::{http::{Method, Request, Response}, WebViewBuilder};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use wry::WebViewExtUnix;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use webkit2gtk::{Settings, WebInspectorExt};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use webkit2gtk::WebViewExt;
|
||||
|
||||
use crate::implementors::html::webview_con::{msg_from_string, msg_to_string};
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event().build();
|
||||
let event_loop_proxy: EventLoopProxy<MizeMessage> = event_loop.create_proxy();
|
||||
let window = WindowBuilder::new().build(&event_loop).unwrap();
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
))]
|
||||
let builder = WebViewBuilder::new(&window);
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
)))]
|
||||
let builder = {
|
||||
use tao::platform::unix::WindowExtUnix;
|
||||
use wry::WebViewBuilderExtUnix;
|
||||
let vbox = window.default_vbox().unwrap();
|
||||
WebViewBuilder::new_gtk(vbox)
|
||||
};
|
||||
|
||||
//let html_str = fs::read_to_string(format!("{}/../implementors/html/js-runtime/dist/index.html", file!()))?;
|
||||
//println!("html_str: {}", html_str);
|
||||
|
||||
// get the path of the index.html
|
||||
let test = self.mize.fetch_module("mme")?;
|
||||
let mme_module_path = self.mize.fetch_module("cross.wasm32-none-unknown.mme")?;
|
||||
|
||||
let mize_module_path = self.mize.fetch_module("cross.wasm32-none-unknown.mize")?;
|
||||
|
||||
let init_script = format!(r#"
|
||||
import("{mize_module_path}/mize.js").then( module => module.init_mize({{module_dir: {{mize: "{mize_module_path}"}}}}))
|
||||
"#);
|
||||
|
||||
|
||||
// add the mize connection to the instance inside the webview
|
||||
let (tx, rx): (Sender<MizeMessage>, Receiver<MizeMessage>) = flume::unbounded();
|
||||
let conn_id = self.mize.new_connection(tx)?;
|
||||
|
||||
|
||||
let mut self_clone = self.clone();
|
||||
let mut self_clone_two = self.clone();
|
||||
let webview = builder
|
||||
//.with_url("http://localhost:8000/index.html")
|
||||
//.with_url("file:/
|
||||
//home/me/tmp/rd/test.html")
|
||||
//.with_url(format!("file://{}/index.html", mme_module_path))
|
||||
//.with_html("hello worldddddddddddddddddddddddddddddddddd".to_owned())
|
||||
//.with_initialization_script(init_script.as_str())
|
||||
.with_custom_protocol(
|
||||
"wry".into(),
|
||||
move | request| {
|
||||
|
||||
// the body will be a mize message as a string
|
||||
if request.method() == &Method::POST {
|
||||
let msg_str = request.headers().get("MizeMsg").unwrap().to_str().unwrap();
|
||||
|
||||
println!("webview_con incoming got msg: {}", msg_str);
|
||||
|
||||
let msg = match msg_from_string(msg_str.to_owned(), conn_id) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
self_clone_two.mize.report_err(err.into());
|
||||
return http::Response::builder()
|
||||
.header(CONTENT_TYPE, "text/plain")
|
||||
.status(500)
|
||||
.body("".to_string().as_bytes().to_vec())
|
||||
.unwrap()
|
||||
.map(Into::into);
|
||||
},
|
||||
};
|
||||
|
||||
self_clone_two.mize.got_msg(msg);
|
||||
|
||||
|
||||
return http::Response::builder()
|
||||
.header(CONTENT_TYPE, "text/plain")
|
||||
.status(http::StatusCode::OK)
|
||||
.body("".to_string().as_bytes().to_vec())
|
||||
.unwrap()
|
||||
.map(Into::into);
|
||||
}
|
||||
|
||||
match get_wry_response(request, self_clone_two.clone()) {
|
||||
Ok(r) => r.map(Into::into),
|
||||
Err(e) => {
|
||||
println!("get_wry_response error: {}", e);
|
||||
http::Response::builder()
|
||||
.header(CONTENT_TYPE, "text/plain")
|
||||
.status(500)
|
||||
.body(e.to_string().as_bytes().to_vec())
|
||||
.unwrap()
|
||||
.map(Into::into)
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
// tell the webview to load the custom protocol
|
||||
.with_url("wry://localhost")
|
||||
//.with_ipc_handler(move | res: Request<String> | {
|
||||
//crate::implementors::html::webview_con::ipc_handler(res, self_clone.clone(), conn_id)
|
||||
//})
|
||||
//.with_html(html_str)
|
||||
/*
|
||||
.with_drag_drop_handler(|e| {
|
||||
match e {
|
||||
wry::DragDropEvent::Enter { paths, position } => {
|
||||
println!("DragEnter: {position:?} {paths:?} ")
|
||||
}
|
||||
wry::DragDropEvent::Over { position } => println!("DragOver: {position:?} "),
|
||||
wry::DragDropEvent::Drop { paths, position } => {
|
||||
println!("DragDrop: {position:?} {paths:?} ")
|
||||
}
|
||||
wry::DragDropEvent::Leave => println!("DragLeave"),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
*/
|
||||
.build()?;
|
||||
//_webview.open_devtools();
|
||||
println!("{}", webview.url().unwrap());
|
||||
let req = Request::builder()
|
||||
.uri(webview.url().unwrap().to_string())
|
||||
.body("hooooooooooooo")
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let settings = Settings::builder()
|
||||
.allow_file_access_from_file_urls(true)
|
||||
.enable_developer_extras(true)
|
||||
.build();
|
||||
let __webview = webview.webview();
|
||||
__webview.set_settings(&settings);
|
||||
|
||||
let inspector = __webview.inspector().expect("no inspector");
|
||||
inspector.show();
|
||||
}
|
||||
|
||||
|
||||
crate::implementors::html::webview_con::mme_setup_weview_con_host(self, rx, event_loop_proxy)?;
|
||||
let cloned_self = self.clone();
|
||||
|
||||
|
||||
// this is where we block the main thread....
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => {
|
||||
*control_flow = ControlFlow::Exit
|
||||
},
|
||||
|
||||
Event::UserEvent::<MizeMessage>(msg) => {
|
||||
match msg_to_string(msg) {
|
||||
Ok(msg_string) => {
|
||||
webview.evaluate_script(format!("mize.mod.mme.webview_msg_recv_fn({})", msg_string).as_str());
|
||||
},
|
||||
Err(err) => {
|
||||
cloned_self.mize.report_err(err.into());
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
_ => {},
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#[cfg(features = "qt")]
|
||||
pub fn create_qt_slot(&self) -> MizeResult<()> {
|
||||
unsafe {
|
||||
|
||||
let backend = i_slint_backend_qt::Backend::new();
|
||||
|
||||
|
||||
let main_widget = qt_widgets::QWidget::new_0a();
|
||||
main_widget.show();
|
||||
main_widget.set_window_title(&qs("mme_main"));
|
||||
|
||||
|
||||
|
||||
comandr::platform::qt::init(main_widget.as_ptr());
|
||||
|
||||
//let other_window = OtherWindow::new().unwrap();
|
||||
//other_window.show();
|
||||
|
||||
let presenter: Presenter = Presenter::HtmlPresenter(HtmlPresenter::from_folder(Path::new("/home/me/work/mme-presenters/presenters/hello-world").to_owned())?);
|
||||
|
||||
let mut slot: Slot = Slot::QtWidgetSlot(QtWidgetSlot::from_widget(main_widget)?);
|
||||
|
||||
slot.load(presenter);
|
||||
|
||||
|
||||
println!("run_event_loop");
|
||||
unsafe {
|
||||
qt_core::QCoreApplication::exec();
|
||||
}
|
||||
//backend.run_event_loop();
|
||||
//unsafe {
|
||||
//run_my_event_loop(my_app);
|
||||
//}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
use tao::{
|
||||
event::{Event, WindowEvent},
|
||||
event_loop::{ControlFlow, EventLoop},
|
||||
window::WindowBuilder,
|
||||
};
|
||||
#[cfg(feature = "target-os")]
|
||||
use wry::{
|
||||
http::{self, header::CONTENT_TYPE, Request, Response},
|
||||
WebViewBuilder,
|
||||
};
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
fn get_wry_response(request: Request<Vec<u8>>, mut mme: Mme) -> Result<http::Response<Vec<u8>>, Box<dyn std::error::Error>> {
|
||||
use comandr::core::module;
|
||||
use mize::item::ItemData;
|
||||
use mize::error::MizeResultTrait;
|
||||
|
||||
|
||||
|
||||
|
||||
let mut path = PathBuf::from(request.uri().path());
|
||||
|
||||
let root = if path.starts_with("/modules") {
|
||||
let mod_name = path.iter().nth(2).unwrap().to_str().unwrap();
|
||||
println!("get_wry_response: modname: {}", mod_name);
|
||||
let mod_dir = PathBuf::from(mme.mize.fetch_module(format!("cross.wasm32-none-unknown.{}", mod_name).as_str()).unwrap());
|
||||
mod_dir
|
||||
} else {
|
||||
PathBuf::from(mme.mize.fetch_module("cross.wasm32-none-unknown.mme").unwrap())
|
||||
};
|
||||
|
||||
let mut module_dir_conf: ItemData = mme.mize.get("self/config/module_dir/cross/wasm32-none-unknown").as_std()?.as_data_full().as_std()?;
|
||||
let mut module_dir_str = String::new();
|
||||
if !module_dir_conf.cbor().is_null() {
|
||||
let map = module_dir_conf.cbor().as_map().ok_or(mize_err!("self/config/module_dir was not a map")).as_std()?;
|
||||
for (mod_name, module_dir) in map {
|
||||
let mod_name_str = mod_name.as_text().ok_or(mize_err!("mod_name was not a string")).as_std()?;
|
||||
module_dir_str += format!(r#" "{mod_name_str}": "wry://localhost/modules/{mod_name_str}", "#).as_str();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let index_html = format!(r#"
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
import("/modules/mize/mize.js").then( module => module.init_mize({{
|
||||
module_dir: {{ {module_dir_str} }},
|
||||
load_modules: "mme",
|
||||
module_url: "wry://localhost/modules"
|
||||
}}))
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
MME loading...
|
||||
</body>
|
||||
</html>
|
||||
"#);
|
||||
|
||||
let path = if path == PathBuf::from("/") {
|
||||
// return the index.html
|
||||
return Response::builder()
|
||||
.header(CONTENT_TYPE, "text/html")
|
||||
.body(index_html.into_bytes())
|
||||
.map_err(Into::into);
|
||||
|
||||
} else if path.starts_with("/modules") {
|
||||
path.iter().skip(3).collect()
|
||||
} else {
|
||||
// removing leading slash
|
||||
let mut string = path.into_os_string().into_string().unwrap();
|
||||
string.remove(0);
|
||||
PathBuf::from(string)
|
||||
};
|
||||
|
||||
println!("root: {}", root.display());
|
||||
println!("path: {}", path.display());
|
||||
let content = std::fs::read(std::fs::canonicalize(root.join(path.as_path()))?)?;
|
||||
let path_str = path.as_os_str().to_str().unwrap();
|
||||
|
||||
// Return asset contents and mime types based on file extentions
|
||||
// If you don't want to do this manually, there are some crates for you.
|
||||
// Such as `infer` and `mime_guess`.
|
||||
let mimetype = if path_str.ends_with(".html") || path == PathBuf::from("/") {
|
||||
"text/html"
|
||||
} else if path_str.ends_with(".js") {
|
||||
"text/javascript"
|
||||
} else if path_str.ends_with(".png") {
|
||||
"image/png"
|
||||
} else if path_str.ends_with(".wasm") {
|
||||
"application/wasm"
|
||||
} else {
|
||||
"text/html"
|
||||
};
|
||||
println!("mimetype: {}", mimetype);
|
||||
|
||||
Response::builder()
|
||||
.header(CONTENT_TYPE, mimetype)
|
||||
.body(content)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
|
||||
19
packages/mme/src/core/presenter.rs
Normal file
19
packages/mme/src/core/presenter.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use enum_dispatch::enum_dispatch;
|
||||
|
||||
use crate::implementors::html::HtmlPresenter;
|
||||
|
||||
|
||||
// A Presenter takes data (in the form of MiZe Items) and presents them in the form of a gui.
|
||||
// It can be put into a Space and provide sub Spaces, where other Presenters can be put into.
|
||||
// It can provide different implementations for the different types of spaces
|
||||
#[enum_dispatch]
|
||||
pub trait PresenterTrait {
|
||||
}
|
||||
|
||||
#[enum_dispatch(PresenterTrait)]
|
||||
pub enum Presenter {
|
||||
HtmlPresenter,
|
||||
}
|
||||
|
||||
impl Presenter {
|
||||
}
|
||||
48
packages/mme/src/core/slot.rs
Normal file
48
packages/mme/src/core/slot.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use enum_dispatch::enum_dispatch;
|
||||
|
||||
#[cfg(features = "slint")]
|
||||
use crate::implementors::slint_widget::SlintWidget;
|
||||
|
||||
#[cfg(features = "qt")]
|
||||
use crate::implementors::qt_widget::QtWidgetSlot;
|
||||
|
||||
use crate::implementors::html::HtmlSlot;
|
||||
|
||||
use crate::presenter::Presenter;
|
||||
use mize::MizeResult;
|
||||
|
||||
// common behaviour for all SlotTypes
|
||||
#[enum_dispatch]
|
||||
pub trait SlotTrait {
|
||||
fn load(&mut self, presenter: Presenter) -> MizeResult<()>;
|
||||
|
||||
//pub fn load_html(pressenter: HtmlPresenter) -> MizeResult<()> {}
|
||||
}
|
||||
|
||||
// this is the main type of this project
|
||||
// a Widget represents any kind of "screen realestate"
|
||||
// be it a Webview, slint widget, Xwindow, ...
|
||||
|
||||
// an enum over all of what types such "screen realestate" could have
|
||||
#[enum_dispatch(SlotTrait)]
|
||||
pub enum Slot {
|
||||
//Xwindow {},
|
||||
//WaylandWindow {},
|
||||
//SlintWidget,
|
||||
#[cfg(features = "qt")]
|
||||
QtWidgetSlot,
|
||||
//GtkWidget {},
|
||||
HtmlSlot,
|
||||
//QuarzWindow {},
|
||||
//NtWindow {},
|
||||
//Activity {},
|
||||
}
|
||||
|
||||
|
||||
pub struct Position {
|
||||
x: u32,
|
||||
y: u32,
|
||||
z: u32,
|
||||
}
|
||||
|
||||
|
||||
12
packages/mme/src/implementors/html/index.html
Normal file
12
packages/mme/src/implementors/html/index.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<!-- script src="https://c2vi.dev/mize/wasm32-none-unknown/mize.js"></script --!>
|
||||
<script src="file:///home/me/work/mize/pkg/mize.js"></script>
|
||||
<script>
|
||||
console.log("from script")
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
hello world...............
|
||||
</body>
|
||||
</html>
|
||||
20
packages/mme/src/implementors/html/index.nix
Normal file
20
packages/mme/src/implementors/html/index.nix
Normal file
@@ -0,0 +1,20 @@
|
||||
{ mize_url, ... }: ''
|
||||
<html>
|
||||
<head>
|
||||
<script src="${mize_url}"></script>
|
||||
<script>
|
||||
init_mize({
|
||||
load_modules: "mme",
|
||||
mod: {
|
||||
mme: {
|
||||
webview_con: true
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
hello world...............
|
||||
</body>
|
||||
</html>
|
||||
''
|
||||
162
packages/mme/src/implementors/html/mod.rs
Normal file
162
packages/mme/src/implementors/html/mod.rs
Normal file
@@ -0,0 +1,162 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
use comandr::Comandr;
|
||||
|
||||
use crate::slot::SlotTrait;
|
||||
use crate::mme::Mme;
|
||||
use mize::MizeResult;
|
||||
|
||||
pub mod webview_con;
|
||||
|
||||
|
||||
pub struct HtmlPresenter {
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
impl HtmlPresenter {
|
||||
pub fn from_folder(path: PathBuf) -> MizeResult<HtmlPresenter> {
|
||||
Ok(HtmlPresenter { path })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct HtmlSlot {
|
||||
}
|
||||
|
||||
impl SlotTrait for HtmlSlot {
|
||||
fn load(&mut self,presenter:crate::presenter::Presenter) -> MizeResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
pub mod wasm {
|
||||
|
||||
use comandr::Comandr;
|
||||
use comandr::Command;
|
||||
use web_sys::console;
|
||||
use web_sys::EventTarget;
|
||||
use web_sys::js_sys::Function;
|
||||
use std::panic;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice::Iter;
|
||||
use comandr::Module;
|
||||
use comandr::ComandrResult;
|
||||
|
||||
use crate::mme::Mme;
|
||||
|
||||
// console log
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use super::webview_con::msg_from_string;
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
// end of console log
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
// allocator.
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct MmeJs {
|
||||
pub inner: NonNull<Mme>,
|
||||
pub webview_con_id: u64,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl MmeJs {
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn webview_msg_recv_fn(&mut self, msg_string: String) -> () {
|
||||
|
||||
let mize = &self.inner.as_mut().mize;
|
||||
|
||||
let msg = match msg_from_string(msg_string, self.webview_con_id) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
mize.report_err(err.into());
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
mize.got_msg(msg);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn comandr_search(&mut self, string: String) -> Vec<String> {
|
||||
//self.inner.as_mut().comandr.search(string)
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
pub unsafe fn comandr_list(&mut self) -> Vec<String> {
|
||||
//self.inner.as_mut().comandr.list_commands()
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub unsafe fn comandr_run(&mut self, name: String, args: Vec<String>) -> () {
|
||||
//self.inner.as_mut().comandr.execute(name, args)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub struct MmeComandrModule {
|
||||
commands: Vec<Command>
|
||||
}
|
||||
|
||||
fn reload_page() -> ComandrResult<()>{
|
||||
let js_fn_str = r#"
|
||||
window.location.reload()
|
||||
"#;
|
||||
let js_fn = Function::new_no_args(js_fn_str);
|
||||
|
||||
js_fn.call0(&web_sys::wasm_bindgen::JsValue::NULL);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl MmeComandrModule {
|
||||
pub fn new() -> MmeComandrModule {
|
||||
let commands = vec![
|
||||
Command { name: "reload".to_owned(), closure: Box::new(reload_page) },
|
||||
];
|
||||
MmeComandrModule { commands }
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for MmeComandrModule {
|
||||
fn name(&self) -> String {
|
||||
"mme".to_owned()
|
||||
}
|
||||
|
||||
fn commands(&self) -> Iter<'_, Command> {
|
||||
self.commands.iter()
|
||||
}
|
||||
|
||||
fn get_command(&mut self, name: String) -> Option<&mut Command> {
|
||||
for command in self.commands.iter_mut() {
|
||||
if command.name == name {
|
||||
return Some(command);
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
132
packages/mme/src/implementors/html/webview_con.rs
Normal file
132
packages/mme/src/implementors/html/webview_con.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
use base64::Engine;
|
||||
use mize::{mize_err, MizeResult};
|
||||
use mize::proto::MizeMessage;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use tracing::trace;
|
||||
use ciborium::Value as CborValue;
|
||||
use flume::{ Receiver, Sender };
|
||||
use ciborium_io::Read;
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
use wry::http::Request;
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
use wry::WebView;
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
use tao::event_loop::EventLoopProxy;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use crate::implementors::html::wasm::MmeJs;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use web_sys::js_sys::Function;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
|
||||
|
||||
// console_log macro
|
||||
// that can be copied into other files for debugging purposes
|
||||
#[cfg(feature = "wasm-target")]
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
macro_rules! console_log {
|
||||
// Note that this is using the `log` function imported above during
|
||||
// `bare_bones`
|
||||
($($t:tt)*) => (unsafe { log(&format_args!($($t)*).to_string())})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
use crate::mme::Mme;
|
||||
use mize::MizeError;
|
||||
|
||||
|
||||
|
||||
#[cfg(feature = "target-os")]
|
||||
pub fn mme_setup_weview_con_host(mme: &mut Mme, rx: Receiver<MizeMessage>, event_loop_proxy: EventLoopProxy<MizeMessage>) -> MizeResult<()> {
|
||||
|
||||
let mize_clone = mme.mize.clone();
|
||||
mme.mize.spawn("webview-con-outgoing", move || {
|
||||
for msg in rx {
|
||||
event_loop_proxy.send_event(msg);
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
pub fn mme_setup_webiew_con_js(mme: &mut Mme) -> MizeResult<Sender<MizeMessage>> {
|
||||
let (tx, rx): (Sender<MizeMessage>, Receiver<MizeMessage>) = flume::unbounded();
|
||||
|
||||
// send things from rx out by calling window.ipc.postMessage("msg here as string")
|
||||
wasm_bindgen_futures::spawn_local(webview_con_js_send_out(mme.clone(), rx));
|
||||
|
||||
let conn_id = mme.mize.new_connection_join_namespace(tx.clone())?;
|
||||
|
||||
return Ok(tx);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "wasm-target")]
|
||||
pub async fn webview_con_js_send_out(mme: Mme, rx: Receiver<MizeMessage>) {
|
||||
let func = Function::new_with_args("msg_string", r#"
|
||||
fetch("/msg", { method: "POST", headers: { MizeMsg: msg_string}})
|
||||
"#);
|
||||
|
||||
loop {
|
||||
let msg = match rx.recv_async().await {
|
||||
Ok(val) => val,
|
||||
Err(err) => { mme.mize.report_err(err.into()); continue; },
|
||||
};
|
||||
console_log!("webview_con_js_send_out: got_msg: {:?}", msg);
|
||||
|
||||
let msg_string = match msg_to_string(msg) {
|
||||
Ok(val) => val,
|
||||
Err(err) => { mme.mize.report_err(err.into()); continue; },
|
||||
};
|
||||
|
||||
func.call1(&JsValue::null(), &JsValue::from_str(msg_string.as_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn msg_to_string(msg: MizeMessage) -> MizeResult<String> {
|
||||
|
||||
let mut msg_bytes = Vec::new();
|
||||
|
||||
ciborium::into_writer(&msg.value(), &mut msg_bytes)?;
|
||||
|
||||
let msg_string = STANDARD.encode(msg_bytes);
|
||||
|
||||
return Ok(msg_string)
|
||||
}
|
||||
|
||||
|
||||
pub fn msg_from_string(msg_string: String, conn_id: u64) -> MizeResult<MizeMessage> {
|
||||
|
||||
let msg_bytes = STANDARD.decode(msg_string)?;
|
||||
|
||||
let value: CborValue = ciborium::from_reader(msg_bytes.as_slice())?;
|
||||
|
||||
let msg = MizeMessage::new(value, conn_id);
|
||||
|
||||
return Ok(msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
152
packages/mme/src/implementors/qt_widget/mod.rs
Normal file
152
packages/mme/src/implementors/qt_widget/mod.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
use qt_gui::cpp_core::Ptr;
|
||||
use tracing::{error, debug};
|
||||
use qt_core::{qs, QBox, QPointerOfQObject};
|
||||
use qt_widgets::QWidget;
|
||||
use qt_widgets::cpp_core::CppBox;
|
||||
use cpp::cpp;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use crate::presenter::Presenter;
|
||||
use crate::slot::{Slot, SlotTrait};
|
||||
use mize::MizeResult;
|
||||
|
||||
|
||||
pub struct HtmlAdapter {
|
||||
}
|
||||
|
||||
impl HtmlAdapter {
|
||||
pub fn sub_slot(&self) -> MizeResult<Slot> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct QtWidgetSlot {
|
||||
widget: QBox<QWidget>,
|
||||
}
|
||||
|
||||
impl QtWidgetSlot {
|
||||
pub fn from_widget(widget: QBox<QWidget>) -> MizeResult<QtWidgetSlot> {
|
||||
Ok(QtWidgetSlot { widget })
|
||||
}
|
||||
}
|
||||
|
||||
cpp! {{
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
//#include <QtWebEngine/QtWebEngine>
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
}}
|
||||
|
||||
impl SlotTrait for QtWidgetSlot {
|
||||
fn load(&mut self, presenter: Presenter) -> MizeResult<()> {
|
||||
match presenter {
|
||||
Presenter::HtmlPresenter(html) => {
|
||||
// here would go the code, to load the index.html of the HtmlPresenter's path into
|
||||
// the self.widget....
|
||||
println!("loading html into widget....");
|
||||
let url = format!("file://{}/index.html", html.path.display());
|
||||
|
||||
let c_string: CString = CString::new(url.as_str()).unwrap();
|
||||
let c_str: &CStr = c_string.as_c_str();
|
||||
|
||||
unsafe {
|
||||
create_webview(self.widget.as_ptr(), c_str.as_ptr());
|
||||
|
||||
self.widget.set_style_sheet(&qs("border: 2px solid blue;"));
|
||||
|
||||
|
||||
//let widget_full = QWidget::new_0a();
|
||||
//let widget = widget_full.as_raw_ptr();
|
||||
//
|
||||
//widget_fill(&mut self.widget);
|
||||
|
||||
//cpp_widget_fill(&mut self.widget);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" { fn create_webview(widget: Ptr<QWidget>, url: * const i8); }
|
||||
|
||||
pub unsafe fn widget_fill(widget: &mut QBox<QWidget>) {
|
||||
let grid_layout = unsafe { qt_widgets::QGridLayout::new_0a() };
|
||||
widget.set_layout(&grid_layout);
|
||||
|
||||
let button = unsafe { qt_widgets::QPushButton::new() };
|
||||
button.set_text(&qs("hello from rust button"));
|
||||
|
||||
let button2 = unsafe { qt_widgets::QPushButton::new() };
|
||||
button2.set_text(&qs("hello from another button"));
|
||||
|
||||
grid_layout.add_widget_3a(&button, 0, 1);
|
||||
grid_layout.add_widget_3a(&button2, 1, 0);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
pub unsafe fn cpp_widget_fill(widget: &mut QBox<QWidget>) {
|
||||
let a: i32 = 5;
|
||||
let widget = widget.as_raw_ptr();
|
||||
|
||||
let x: i32 = cpp!(unsafe [widget as "QWidget*", a as "int32_t"] -> i32 as "int32_t" {
|
||||
|
||||
printf("hello from macro\n");
|
||||
|
||||
//QWidget * mywidget = new QWidget();
|
||||
|
||||
//QUrl url;
|
||||
//url.setScheme("http");
|
||||
//url.setHost("www.orf.at");
|
||||
|
||||
//QWebEngineView view = QWebEngineView(widget);
|
||||
//view.setUrl(url);
|
||||
//view.resize(1024, 750);
|
||||
//view.show();
|
||||
|
||||
/*
|
||||
QGridLayout *layout = new QGridLayout(widget);
|
||||
widget->setLayout(layout);
|
||||
|
||||
QPushButton * button = new QPushButton(widget);
|
||||
button->setText("My text");
|
||||
button->setToolTip("A tooltip");
|
||||
|
||||
QPushButton * button2 = new QPushButton(widget);
|
||||
button2->setText("My text 2");
|
||||
button2->setToolTip("A tooltip 2");
|
||||
|
||||
QPushButton * button3 = new QPushButton(widget);
|
||||
button3->setText("My text 3");
|
||||
button3->setToolTip("A tooltip 3");
|
||||
|
||||
layout->addWidget (button, 0, 0);
|
||||
layout->addWidget (button2, 0, 1);
|
||||
layout->addWidget (button3, 1, 1);
|
||||
*/
|
||||
|
||||
widget->show();
|
||||
|
||||
return a;
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
60
packages/mme/src/implementors/slint_widget/mod.rs
Normal file
60
packages/mme/src/implementors/slint_widget/mod.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use qt_gui::q_touch_event::touch_point;
|
||||
use slint_interpreter::{ComponentInstance, ComponentDefinition, ComponentCompiler, Value, SharedString, ComponentHandle};
|
||||
|
||||
use crate::presenter::Presenter;
|
||||
use crate::slot::SlotTrait;
|
||||
use crate::slot::Position;
|
||||
use mize::MizeResult;
|
||||
|
||||
//pub mod qt_backend;
|
||||
|
||||
|
||||
|
||||
pub struct SlintWidget {
|
||||
inner: ComponentInstance,
|
||||
}
|
||||
|
||||
|
||||
impl SlintWidget {
|
||||
fn from_slint_file(path: PathBuf) -> MizeResult<SlintWidget> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn sample() -> MizeResult<SlintWidget> {
|
||||
|
||||
let code = r#"
|
||||
export component MyWin inherits Window {
|
||||
in property <string> my_name;
|
||||
Text {
|
||||
text: "Hello, " + my_name;
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut compiler = ComponentCompiler::default();
|
||||
let definition = spin_on::spin_on(compiler.build_from_source(code.into(), Default::default()));
|
||||
assert!(compiler.diagnostics().is_empty());
|
||||
let instance = definition.unwrap().create().unwrap();
|
||||
instance.set_property("my_name", Value::from(SharedString::from("World"))).unwrap();
|
||||
return SlintWidget::from_instance(instance);
|
||||
}
|
||||
|
||||
fn from_instance(instance: ComponentInstance) -> MizeResult<SlintWidget> {
|
||||
Ok(SlintWidget {
|
||||
inner: instance,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl SlotTrait for SlintWidget {
|
||||
fn load(&mut self,presenter:Presenter) -> MizeResult<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0
packages/mme/src/implementors/x_window/mod.rs
Normal file
0
packages/mme/src/implementors/x_window/mod.rs
Normal file
33
packages/mme/src/lib.rs
Normal file
33
packages/mme/src/lib.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
#![ allow( warnings ) ]
|
||||
|
||||
//#![no_std]
|
||||
//extern crate std;
|
||||
|
||||
mod core {
|
||||
pub mod mme;
|
||||
pub mod slot;
|
||||
pub mod presenter;
|
||||
pub mod layout;
|
||||
pub mod adapter;
|
||||
}
|
||||
|
||||
pub use core::slot;
|
||||
pub use core::presenter;
|
||||
pub use core::layout;
|
||||
pub use core::adapter;
|
||||
pub use core::mme;
|
||||
|
||||
|
||||
pub mod implementors {
|
||||
pub mod html;
|
||||
|
||||
#[cfg(feature = "qt")]
|
||||
pub mod qt_widget;
|
||||
|
||||
#[cfg(feature = "slint")]
|
||||
pub mod slint_widget;
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
pub mod x_window;
|
||||
}
|
||||
254
packages/mme/src/logging.rs
Normal file
254
packages/mme/src/logging.rs
Normal file
@@ -0,0 +1,254 @@
|
||||
use std::path::PathBuf;
|
||||
use clap::{ArgAction, ArgMatches};
|
||||
use clap::{Arg, crate_version, Command};
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::io::Write;
|
||||
use colored::Colorize;
|
||||
use std::env;
|
||||
use tracing_subscriber::fmt::Subscriber;
|
||||
use tracing::Level;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::filter::EnvFilter;
|
||||
use tracing_subscriber::fmt::FormatEvent;
|
||||
use tracing_subscriber::registry::LookupSpan;
|
||||
use tracing_subscriber::fmt::FormatFields;
|
||||
use tracing_subscriber::fmt::FmtContext;
|
||||
use tracing_subscriber::fmt::format;
|
||||
use tracing::Event;
|
||||
use core::fmt;
|
||||
use tracing_subscriber::fmt::FormattedFields;
|
||||
|
||||
use tracing::{trace, debug, info, warn, error};
|
||||
|
||||
use crate::DEFAULT_LOG_LEVEL;
|
||||
|
||||
pub fn init_logger(cli_matches: &ArgMatches) {
|
||||
|
||||
// to save log messages, before the logger is setup
|
||||
let mut log_messages: Vec<(Level, String)> = Vec::new();
|
||||
|
||||
log_messages.push((Level::INFO, "Starting MME".to_owned()));
|
||||
|
||||
// builder with DEFAULT_LOG_LEVEL
|
||||
let mut builder = tracing_subscriber::fmt::Subscriber::builder();
|
||||
|
||||
// set loglevel
|
||||
let mut log_level = DEFAULT_LOG_LEVEL;
|
||||
log_messages.push((Level::TRACE, format!("set log level from DEFAULT_LOG_LEVEL to {}", DEFAULT_LOG_LEVEL)));
|
||||
|
||||
// check env RUST_LOG
|
||||
let mut val_rust_log = level_from_env("RUST_LOG", log_level);
|
||||
if let Some(level_rust_log) = val_rust_log.0 {
|
||||
log_level = level_rust_log;
|
||||
log_messages.push((Level::TRACE, format!("set log level from the Variable RUST_LOG to {}", level_rust_log)));
|
||||
}
|
||||
log_messages.append(&mut val_rust_log.1);
|
||||
|
||||
// check env MME_LOG
|
||||
let mut val_mme_log = level_from_env("MME_LOG", log_level);
|
||||
if let Some(level_mme_log) = val_mme_log.0 {
|
||||
log_level = level_mme_log;
|
||||
log_messages.push((Level::TRACE, format!("set log level from the Variable MME_LOG to {}", level_mme_log)));
|
||||
}
|
||||
log_messages.append(&mut val_mme_log.1);
|
||||
|
||||
// check -vvvvv flags
|
||||
let v_flag_count = cli_matches.get_count("verbose");
|
||||
let default_log_level_as_num = match DEFAULT_LOG_LEVEL {
|
||||
LevelFilter::OFF => 0,
|
||||
LevelFilter::ERROR => 1,
|
||||
LevelFilter::WARN => 2,
|
||||
LevelFilter::INFO => 3,
|
||||
LevelFilter::DEBUG => 4,
|
||||
LevelFilter::TRACE => 5,
|
||||
};
|
||||
let new_log_level_num = default_log_level_as_num + v_flag_count;
|
||||
log_level = match new_log_level_num {
|
||||
0 => LevelFilter::OFF,
|
||||
1 => LevelFilter::ERROR,
|
||||
2 => LevelFilter::WARN,
|
||||
3 => LevelFilter::INFO,
|
||||
4 => LevelFilter::DEBUG,
|
||||
5 => LevelFilter::TRACE,
|
||||
_ => {
|
||||
log_messages.push((Level::TRACE, format!("the number of verbose (-v) flags passed ({}) exeeds the maximumg log_level", v_flag_count)));
|
||||
LevelFilter::TRACE
|
||||
},
|
||||
};
|
||||
log_messages.push((Level::TRACE, format!("set log level from the verbose flags to {}", log_level)));
|
||||
|
||||
// check --log-level arg
|
||||
if let Some(log_level_arg_string) = cli_matches.get_one::<String>("log-level") {
|
||||
let log_level_from_arg = match log_level_arg_string.to_lowercase().as_str() {
|
||||
"none" => LevelFilter::OFF,
|
||||
"trace" => LevelFilter::TRACE,
|
||||
"debug" => LevelFilter::DEBUG,
|
||||
"info" => LevelFilter::INFO,
|
||||
"warn" => LevelFilter::WARN,
|
||||
"error" => LevelFilter::ERROR,
|
||||
_ => {
|
||||
log_messages.push((Level::WARN, format!(
|
||||
"The argument to --log-level \"{}\" is not a valid log-level. loglevel stays at: {}"
|
||||
, log_level_arg_string
|
||||
, log_level
|
||||
)));
|
||||
log_level
|
||||
}
|
||||
};
|
||||
log_level = log_level_from_arg;
|
||||
log_messages.push((Level::TRACE, format!("set log level from the --log-level arg to {}", log_level_from_arg)));
|
||||
}
|
||||
|
||||
// check --silent flag
|
||||
if cli_matches.get_flag("silent") {
|
||||
if log_level != DEFAULT_LOG_LEVEL {
|
||||
log_messages.push((Level::WARN, format!(
|
||||
"The loglevel was set by some method (it's not the DEFAULT_LOG_LEVEL) and is now overwritten by the --siltne to be OFF"
|
||||
)))
|
||||
}
|
||||
log_level = LevelFilter::OFF;
|
||||
}
|
||||
|
||||
// actually set the log_level on the builder
|
||||
log_messages.push((Level::INFO, format!("loglevel is now {}", log_level)));
|
||||
|
||||
// filter loging
|
||||
let mut my_env_filter = tracing_subscriber::filter::EnvFilter::new("")
|
||||
.add_directive("[get_raw_from_cbor]=debug".parse().expect("error parsing log directive"))
|
||||
//.add_directive("[MemStore::get_value_raw]=trace".parse().expect("error parsing log directive"))
|
||||
.add_directive("trace".parse().unwrap())
|
||||
.add_directive("[get_raw_from_cbor]=debug".parse().expect("error parsing log directive"))
|
||||
;
|
||||
|
||||
builder
|
||||
.with_env_filter(my_env_filter)
|
||||
.without_time()
|
||||
.event_format(MyFormatter)
|
||||
//.with_max_level(log_level)
|
||||
.init();
|
||||
|
||||
|
||||
// write out all log messages from log_messages
|
||||
for (level, msg) in log_messages {
|
||||
match level {
|
||||
Level::ERROR => error!("{}", msg),
|
||||
Level::WARN => warn!("{}", msg),
|
||||
Level::INFO => info!("{}", msg),
|
||||
Level::DEBUG => debug!("{}", msg),
|
||||
Level::TRACE => trace!("{}", msg),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn level_from_env(var_name: &str, log_level: LevelFilter) -> (Option<LevelFilter>, Vec<(Level, String)>) {
|
||||
let mut log_messages: Vec<(Level, String)> = Vec::new();
|
||||
let var_value = env::var(var_name);
|
||||
match var_value {
|
||||
Ok(val) => {
|
||||
// set loglevel acording to RUST_LOG
|
||||
let level = match val.to_lowercase().as_str() {
|
||||
"none" => LevelFilter::OFF,
|
||||
"trace" => LevelFilter::TRACE,
|
||||
"debug" => LevelFilter::DEBUG,
|
||||
"info" => LevelFilter::INFO,
|
||||
"warn" => LevelFilter::WARN,
|
||||
"error" => LevelFilter::ERROR,
|
||||
_ => {
|
||||
log_messages.push((Level::WARN, format!(
|
||||
"The value of Environment Variable {}: \"{}\" is not a valid log-level. loglevel stays at: {}"
|
||||
, var_name
|
||||
, val
|
||||
, log_level
|
||||
)));
|
||||
log_level
|
||||
}
|
||||
};
|
||||
return (Some(level), log_messages)
|
||||
},
|
||||
Err(env::VarError::NotPresent) => {},
|
||||
Err(env::VarError::NotUnicode(os_string)) => {
|
||||
|
||||
let os_string_as_hex : String = os_string.clone().into_encoded_bytes().iter()
|
||||
.map(|b| format!("{:02x}", b).to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join("");
|
||||
log_messages.push((Level::DEBUG, format!(
|
||||
"value of Environment Variable {} was not a unicode valid string. Therefore ignoring it.
|
||||
\n value with replacement char U+FFFD: {}
|
||||
\n the WTF-8 raw bytes as hex: {}"
|
||||
, var_name
|
||||
, os_string.to_string_lossy(), os_string_as_hex
|
||||
)));
|
||||
},
|
||||
};
|
||||
return (None, log_messages);
|
||||
}
|
||||
|
||||
|
||||
struct MyFormatter;
|
||||
|
||||
impl<S, N> FormatEvent<S, N> for MyFormatter
|
||||
where
|
||||
S: tracing::Subscriber + for<'a> LookupSpan<'a>,
|
||||
N: for<'a> FormatFields<'a> + 'static,
|
||||
{
|
||||
fn format_event(
|
||||
&self,
|
||||
ctx: &FmtContext<'_, S, N>,
|
||||
mut writer: format::Writer<'_>,
|
||||
event: &Event<'_>,
|
||||
) -> fmt::Result {
|
||||
// Format values from the event's's metadata:
|
||||
|
||||
let metadata = event.metadata();
|
||||
|
||||
// set format
|
||||
/*
|
||||
builder.format(|buf, record| {
|
||||
match record.level() {
|
||||
}
|
||||
});
|
||||
*/
|
||||
let level_str = match metadata.level() {
|
||||
&Level::TRACE => format!("[ {} ]", "TRACE".yellow()),
|
||||
&Level::DEBUG => format!("[ {} ]", "DEBUG".green()),
|
||||
&Level::INFO => format!("[ {} ]", "INFO".blue()),
|
||||
&Level::WARN => format!("[ {} ]", "WARN".truecolor(245, 164, 66)),
|
||||
&Level::ERROR => format!("[ {} ]", "ERROR".red()),
|
||||
};
|
||||
|
||||
// with target
|
||||
// write!(&mut writer, "{} {}: ", level_str, metadata.target())?;
|
||||
|
||||
write!(&mut writer, "{} ", level_str)?;
|
||||
|
||||
// Format all the spans in the event's span context.
|
||||
if let Some(scope) = ctx.event_scope() {
|
||||
for span in scope.from_root() {
|
||||
write!(writer, "{}", span.name())?;
|
||||
|
||||
// `FormattedFields` is a formatted representation of the span's
|
||||
// fields, which is stored in its extensions by the `fmt` layer's
|
||||
// `new_span` method. The fields will have been formatted
|
||||
// by the same field formatter that's provided to the event
|
||||
// formatter in the `FmtContext`.
|
||||
let ext = span.extensions();
|
||||
let fields = &ext
|
||||
.get::<FormattedFields<N>>()
|
||||
.expect("will never be `None`");
|
||||
|
||||
// Skip formatting the fields if the span had no fields.
|
||||
if !fields.is_empty() {
|
||||
//write!(writer, "{{{}}}", fields)?;
|
||||
}
|
||||
write!(writer, ": ")?;
|
||||
}
|
||||
}
|
||||
|
||||
// Write fields on the event
|
||||
ctx.field_format().format_fields(writer.by_ref(), event)?;
|
||||
|
||||
writeln!(writer)
|
||||
}
|
||||
}
|
||||
233
packages/mme/src/main.cpp
Normal file
233
packages/mme/src/main.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QString>
|
||||
|
||||
//#include <QtWebEngine/QtWebEngine>
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
extern "C" void run_my_event_loop( QPointer<QApplication> my_app );
|
||||
extern "C" void hello_two();
|
||||
extern "C" void hello_three();
|
||||
extern "C" QPointer<QWidget> get_stuff();
|
||||
|
||||
extern "C" void create_webview(QWidget *widget, char * url_raw) {
|
||||
|
||||
printf("in create_webview\n");
|
||||
|
||||
QString * url_string = new QString(url_raw);
|
||||
QUrl url = QUrl::fromUserInput(*url_string);
|
||||
|
||||
QWebEngineView * view = new QWebEngineView(widget);
|
||||
view->setUrl(url);
|
||||
//view->resize(1024, 750);
|
||||
|
||||
QGridLayout *layout = new QGridLayout(widget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
widget->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
QWidget * view_widget = (QWidget*) view;
|
||||
view_widget->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
layout->addWidget ((QWidget*)view, 0, 0);
|
||||
|
||||
return;
|
||||
|
||||
|
||||
QPushButton * button = new QPushButton(widget);
|
||||
button->setText("My text");
|
||||
button->setToolTip("A tooltip");
|
||||
|
||||
QPushButton * button2 = new QPushButton(widget);
|
||||
button2->setText("My text 2");
|
||||
button2->setToolTip("A tooltip 2");
|
||||
|
||||
QPushButton * button3 = new QPushButton(widget);
|
||||
button3->setText("My text 3");
|
||||
button3->setToolTip("A tooltip 3");
|
||||
|
||||
layout->addWidget (button, 0, 0);
|
||||
layout->addWidget (button2, 0, 1);
|
||||
layout->addWidget (button3, 1, 1);
|
||||
layout->addWidget ((QWidget*)view, 1, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
class Foo : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Foo( QObject* parent = 0 ) : QObject( parent )
|
||||
{}
|
||||
|
||||
private:
|
||||
void doStuff()
|
||||
{
|
||||
qDebug() << "Emit signal one";
|
||||
emit signal1();
|
||||
|
||||
qDebug() << "Emit finished";
|
||||
emit finished();
|
||||
|
||||
qDebug() << "Emit signal two";
|
||||
emit signal2();
|
||||
}
|
||||
|
||||
signals:
|
||||
void signal1();
|
||||
void signal2();
|
||||
|
||||
void finished();
|
||||
|
||||
public slots:
|
||||
void slot1()
|
||||
{
|
||||
qDebug() << "Execute slot one";
|
||||
}
|
||||
|
||||
void slot2()
|
||||
{
|
||||
qDebug() << "Execute slot two";
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
printf("in start of foo");
|
||||
//doStuff();
|
||||
|
||||
qDebug() << "Bye!";
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
//extern "C" void place_slint_widget(QWidget * slint_widget) {
|
||||
//printf("hello from test\n");
|
||||
//}
|
||||
|
||||
extern "C" QPointer<QApplication> init_app() {
|
||||
int argc = 0;
|
||||
char hi = 'c';
|
||||
char * two = &hi;
|
||||
|
||||
QPointer<QApplication> my_app = new QApplication (argc, &two);
|
||||
|
||||
|
||||
QPointer<QWidget> main_widget = get_stuff();
|
||||
|
||||
QMainWindow * my_window = new QMainWindow();
|
||||
my_window->setCentralWidget(main_widget);
|
||||
//my_window->show();
|
||||
|
||||
//my_app->exec();
|
||||
|
||||
//run_my_event_loop(my_app);
|
||||
|
||||
return my_app;
|
||||
}
|
||||
|
||||
extern "C" QPointer<QWidget> get_stuff() {
|
||||
QPointer<QWidget> centralWidget = new QWidget();
|
||||
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
centralWidget->setLayout(layout);
|
||||
|
||||
QPushButton button;
|
||||
button.setText("My text");
|
||||
button.setToolTip("A tooltip");
|
||||
|
||||
QPushButton button2;
|
||||
button2.setText("My text 2");
|
||||
button2.setToolTip("A tooltip 2");
|
||||
|
||||
QPushButton button3;
|
||||
button3.setText("My text 3");
|
||||
button3.setToolTip("A tooltip 3");
|
||||
|
||||
layout->addWidget (&button, 0, 0);
|
||||
layout->addWidget (&button2, 0, 1);
|
||||
layout->addWidget (&button3, 1, 1);
|
||||
|
||||
return centralWidget;
|
||||
}
|
||||
|
||||
extern "C" void hello_three() {
|
||||
|
||||
QWidget *centralWidget = new QWidget();
|
||||
|
||||
QGridLayout *layout = new QGridLayout();
|
||||
centralWidget->setLayout(layout);
|
||||
|
||||
QPushButton button;
|
||||
button.setText("My text");
|
||||
button.setToolTip("A tooltip");
|
||||
|
||||
QPushButton button2;
|
||||
button2.setText("My text 2");
|
||||
button2.setToolTip("A tooltip 2");
|
||||
|
||||
QPushButton button3;
|
||||
button3.setText("My text 3");
|
||||
button3.setToolTip("A tooltip 3");
|
||||
|
||||
layout->addWidget (&button, 0, 0);
|
||||
layout->addWidget (&button2, 0, 1);
|
||||
layout->addWidget (&button3, 1, 1);
|
||||
|
||||
centralWidget->show();
|
||||
|
||||
}
|
||||
|
||||
extern "C" void hello_two() {
|
||||
|
||||
QCoreApplication * app = QApplication::instance();
|
||||
|
||||
QPushButton button;
|
||||
button.setText("My text");
|
||||
button.setToolTip("A tooltip");
|
||||
|
||||
button.show();
|
||||
|
||||
/*
|
||||
Foo foo;
|
||||
|
||||
QObject::connect( &foo, &Foo::signal1, &foo, &Foo::slot1 );
|
||||
QObject::connect( &foo, &Foo::signal2, &foo, &Foo::slot2 );
|
||||
|
||||
//QObject::connect( &foo, &Foo::finished, app, &QCoreApplication::quit );
|
||||
|
||||
QTimer::singleShot( 0, &foo, &Foo::start );
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
extern "C" void run_my_event_loop( QPointer<QApplication> my_app ) {
|
||||
|
||||
//QCoreApplication * app = QApplication::instance();
|
||||
|
||||
//QPushButton other_button;
|
||||
//other_button.setText("My text");
|
||||
//other_button.setToolTip("A tooltip");
|
||||
|
||||
//other_button.show();
|
||||
|
||||
|
||||
//printf("app exec\n");
|
||||
int result = my_app->exec();
|
||||
|
||||
printf("app exited with: %d\n", result);
|
||||
}
|
||||
|
||||
//#include "main.moc"
|
||||
|
||||
|
||||
|
||||
156
packages/mme/src/main.rs
Normal file
156
packages/mme/src/main.rs
Normal file
@@ -0,0 +1,156 @@
|
||||
#![ allow( warnings ) ]
|
||||
|
||||
use std::path::PathBuf;
|
||||
use clap::{ArgAction, ArgMatches};
|
||||
use clap::{Arg, crate_version, Command};
|
||||
//use cpp::cpp;
|
||||
//use slint::ComponentHandle;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::io::Write;
|
||||
use colored::Colorize;
|
||||
use std::env;
|
||||
use tracing_subscriber::fmt::Subscriber;
|
||||
use tracing::Level;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::filter::EnvFilter;
|
||||
use crate::logging::init_logger;
|
||||
use mize_module_mme::mme::Mme;
|
||||
|
||||
use mize::{mize_err, Instance};
|
||||
use mize::MizeResult;
|
||||
use mize::MizeError;
|
||||
|
||||
use tracing::{trace, debug, info, warn, error};
|
||||
//use slint::platform::Platform;
|
||||
//use qt_core::{qs, QString, QTimer, SlotNoArgs};
|
||||
//use qt_widgets::{QApplication, QGridLayout, QWidget};
|
||||
|
||||
mod cli {
|
||||
}
|
||||
|
||||
mod logging;
|
||||
|
||||
static APPNAME: &str = "mme";
|
||||
static DEFAULT_LOG_LEVEL: LevelFilter = LevelFilter::WARN;
|
||||
|
||||
fn main() {
|
||||
let cli_matches = cli_matches();
|
||||
|
||||
init_logger(&cli_matches);
|
||||
|
||||
// match command
|
||||
let result = match cli_matches.subcommand() {
|
||||
// mi daemon
|
||||
//Some(("run", sub_matches)) => cli::run(sub_matches),
|
||||
// some unknown command passed
|
||||
|
||||
Some((cmd, sub_matches)) => Err(mize_err!("The subcommand: {} is not known. use --help to list availavle commands", cmd)),
|
||||
|
||||
None => {
|
||||
unsafe { default_cmd() }
|
||||
},
|
||||
};
|
||||
|
||||
if let Err(err) = result {
|
||||
err.log();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn default_cmd() -> MizeResult<()> {
|
||||
let mize = Instance::new()?;
|
||||
let mut mme = Mme::new(mize)?;
|
||||
|
||||
mme.create_x_window()?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn place_slint_widget(slint_widget: *mut QWidget) {
|
||||
println!("i am here");
|
||||
let mme_widget = get_widget_by_title("place_slint");
|
||||
println!("mme_widget: {:?}", mme_widget);
|
||||
println!("mme_widget title: {}", qstring_to_rust((*mme_widget).window_title()));
|
||||
|
||||
let layout = (*mme_widget).layout();
|
||||
println!("layout: {:?}", layout);
|
||||
let grid_layout = layout.dynamic_cast::<QGridLayout>();
|
||||
println!("grid_layout: {:?}", grid_layout);
|
||||
println!("slint_widget: {:?}", slint_widget);
|
||||
|
||||
(*grid_layout).add_widget_3a(slint_widget, 0, 0);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn get_widget_by_title(title: &str) -> * mut QWidget {
|
||||
let widgets = QApplication::top_level_widgets();
|
||||
let mut mme_widget: *mut QWidget = *widgets.index_mut(0);
|
||||
|
||||
let widgets_size = widgets.size();
|
||||
for i in 0..widgets_size {
|
||||
let widget = *widgets.index(i);
|
||||
let widget_title = qstring_to_rust((*widget).window_title());
|
||||
println!("get_mme_main_widget: window_title: {}", widget_title);
|
||||
if widget_title == title.to_owned() {
|
||||
println!("found: {:?}", widget);
|
||||
mme_widget = widget
|
||||
}
|
||||
}
|
||||
return mme_widget;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
fn cli_matches() -> clap::ArgMatches {
|
||||
|
||||
|
||||
let main = Command::new(APPNAME)
|
||||
.version(crate_version!())
|
||||
.author("Sebastian Moser")
|
||||
.about("The Main Mize Explorer or Mize Ui Framework")
|
||||
.arg(Arg::new("verbose")
|
||||
.long("verbose")
|
||||
.short('v')
|
||||
.action(ArgAction::Count)
|
||||
.global(true)
|
||||
)
|
||||
.arg(Arg::new("log-level")
|
||||
.long("log-level")
|
||||
.value_name("LOGLEVEL")
|
||||
.help("set the log-level to one of OFF, ERROR, WARN, INFO, DEBUG, TRACE")
|
||||
.global(true)
|
||||
)
|
||||
.arg(Arg::new("silent")
|
||||
.long("silent")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("set the log-level to OFF")
|
||||
.global(true)
|
||||
)
|
||||
.arg(Arg::new("folder")
|
||||
.short('f')
|
||||
.long("folder")
|
||||
.help("The folder the Instance stores all it's data and the socket for connections")
|
||||
.global(true)
|
||||
)
|
||||
.arg(Arg::new("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.help("overwrite config options")
|
||||
.global(true)
|
||||
)
|
||||
.arg(Arg::new("config-file")
|
||||
.long("config-file")
|
||||
.help("specify a config file")
|
||||
.global(true)
|
||||
);
|
||||
|
||||
return main.get_matches();
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
packages/mme/test.html
Normal file
3
packages/mme/test.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<h1>Hello World</h1>
|
||||
|
||||
<p>hiiiiiiiiiiiiiiiii</p>
|
||||
Reference in New Issue
Block a user