diff --git a/src/rust/file_helper.rs b/src/rust/file_helper.rs index a8b002a..a3bcfe7 100644 --- a/src/rust/file_helper.rs +++ b/src/rust/file_helper.rs @@ -2,10 +2,6 @@ // of whether or not a file exists #[cxx_qt::bridge] mod file_helper { - use rfd::FileDialog; - use std::path::Path; - use tracing::{debug, debug_span, error, info, instrument}; - unsafe extern "C++" { include!("cxx-qt-lib/qstring.h"); type QString = cxx_qt_lib::QString; @@ -14,128 +10,134 @@ mod file_helper { include!("cxx-qt-lib/qvariant.h"); type QVariant = cxx_qt_lib::QVariant; } - - #[derive(Clone)] - #[cxx_qt::qobject] - pub struct FileHelper { - #[qproperty] - name: QString, - #[qproperty] - file_path: QString, - } - - impl Default for FileHelper { - fn default() -> Self { - Self { - name: QString::from(""), - file_path: QString::from(""), - } - } - } - - impl qobject::FileHelper { - // #[qinvokable] - // pub fn save(self: Pin<&mut Self>, file: QUrl, service_list: QVariant) -> bool { - // println!("{}", file); - // match service_list.value() { - // QVariantValue::(..) => println!("string"), - // QVariantValue::(..) => println!("url"), - // QVariantValue::(..) => println!("date"), - // _ => println!("QVariant is..."), - // } - // return true; - // } + unsafe extern "RustQt" { + #[qobject] + #[qml_element] + #[qproperty(QString, name)] + #[qproperty(QString, file_path)] + type FileHelper = super::FileHelperRust; #[qinvokable] - pub fn load(self: Pin<&mut Self>, file: QUrl) -> Vec { - println!("{file}"); - vec!["hi".to_string()] - } + fn load( + self: Pin<&mut FileHelper>, + file: QUrl, + ) -> Vec; #[qinvokable] - pub fn validate(self: Pin<&mut Self>, file: QUrl) -> bool { - let file_string = file.to_string(); - let file_string = file_string.strip_prefix("file://"); - match file_string { - Some(file) => { - let exists = Path::new(&file).exists(); - println!("{file} exists? {exists}"); - exists - } - None => { - let exists = - Path::new(&file.to_string()).exists(); - println!("{file} exists? {exists}"); - exists - } - } - } - + fn validate(self: Pin<&mut FileHelper>, file: QUrl) -> bool; #[qinvokable] - pub fn save_file(self: Pin<&mut Self>) -> QUrl { - let file = FileDialog::new() - .set_file_name("NVTFC.pres") - .set_title("Save Presentation") - .save_file(); - if let Some(file) = file { - println!("saving-file: {:?}", file); - let mut string = - String::from(file.to_str().unwrap_or("")); - if string.is_empty() { - QUrl::default() - } else { - string.insert_str(0, "file://"); - QUrl::from(string.as_str()) - } - } else { - QUrl::default() - } - } - + fn save_file(self: Pin<&mut FileHelper>) -> QUrl; #[qinvokable] - pub fn load_file( - self: Pin<&mut Self>, + fn load_file( + self: Pin<&mut FileHelper>, title: QString, filter: QString, - ) -> QUrl { - let video_filters = [ - "mp4", "webm", "avi", "mkv", "MP4", "WEBM", "AVI", - "MKV", - ]; - let image_filters = [ - "jpg", "png", "gif", "jpeg", "JPG", "PNG", "webp", - "gif", - ]; - let audio_filters = ["mp3", "opus", "ogg", "flac", "wav"]; - let title = title.to_string(); - let filter = filter.to_string(); - let mut file = FileDialog::new().set_title(title); - match filter.as_str() { - "video" => { - file = file.add_filter(filter, &video_filters); - } - "image" => { - file = file.add_filter(filter, &image_filters); - } - "audio" => { - file = file.add_filter(filter, &audio_filters); - } - _ => debug!("nothing"), - }; - let file = file.pick_file(); - if let Some(file) = file { - println!("loading-file: {:?}", file); - let mut string = - String::from(file.to_str().unwrap_or("")); - if string.is_empty() { - QUrl::default() - } else { - string.insert_str(0, "file://"); - QUrl::from(string.as_str()) - } - } else { - QUrl::default() - } + ) -> QUrl; + } +} + +use rfd::FileDialog; +use std::path::Path; +use tracing::{debug, debug_span, error, info, instrument}; + +#[derive(Clone)] +pub struct FileHelperRust { + name: QString, + file_path: QString, +} + +impl Default for FileHelperRust { + fn default() -> Self { + Self { + name: QString::from(""), + file_path: QString::from(""), + } + } +} + +impl qobject::FileHelper { + pub fn load(self: Pin<&mut Self>, file: QUrl) -> Vec { + println!("{file}"); + vec!["hi".to_string()] + } + + pub fn validate(self: Pin<&mut Self>, file: QUrl) -> bool { + let file_string = file.to_string(); + let file_string = file_string.strip_prefix("file://"); + match file_string { + Some(file) => { + let exists = Path::new(&file).exists(); + println!("{file} exists? {exists}"); + exists + } + None => { + let exists = Path::new(&file.to_string()).exists(); + println!("{file} exists? {exists}"); + exists + } + } + } + + pub fn save_file(self: Pin<&mut Self>) -> QUrl { + let file = FileDialog::new() + .set_file_name("NVTFC.pres") + .set_title("Save Presentation") + .save_file(); + if let Some(file) = file { + println!("saving-file: {:?}", file); + let mut string = + String::from(file.to_str().unwrap_or("")); + if string.is_empty() { + QUrl::default() + } else { + string.insert_str(0, "file://"); + QUrl::from(string.as_str()) + } + } else { + QUrl::default() + } + } + + pub fn load_file( + self: Pin<&mut Self>, + title: QString, + filter: QString, + ) -> QUrl { + let video_filters = [ + "mp4", "webm", "avi", "mkv", "MP4", "WEBM", "AVI", "MKV", + ]; + let image_filters = [ + "jpg", "png", "gif", "jpeg", "JPG", "PNG", "webp", "gif", + ]; + let audio_filters = ["mp3", "opus", "ogg", "flac", "wav"]; + let title = title.to_string(); + let filter = filter.to_string(); + let mut file = FileDialog::new().set_title(title); + match filter.as_str() { + "video" => { + file = file.add_filter(filter, &video_filters); + } + "image" => { + file = file.add_filter(filter, &image_filters); + } + "audio" => { + file = file.add_filter(filter, &audio_filters); + } + _ => debug!("nothing"), + }; + let file = file.pick_file(); + if let Some(file) = file { + println!("loading-file: {:?}", file); + let mut string = + String::from(file.to_str().unwrap_or("")); + if string.is_empty() { + QUrl::default() + } else { + string.insert_str(0, "file://"); + QUrl::from(string.as_str()) + } + } else { + QUrl::default() } } } diff --git a/src/rust/service_thing.rs b/src/rust/service_thing.rs index c9e7fbb..a46fbd6 100644 --- a/src/rust/service_thing.rs +++ b/src/rust/service_thing.rs @@ -64,7 +64,6 @@ impl Default for ServiceThingRust { } impl qobject::ServiceThing { - #[qinvokable] pub fn activate(self: Pin<&mut Self>) { println!("{}", self.active()); let active: bool = *self.active(); @@ -72,7 +71,6 @@ impl qobject::ServiceThing { println!("{}", !active); } - #[qinvokable] pub fn check_active(self: Pin<&mut Self>) { println!("Are we active?: {}", self.active()); } diff --git a/src/rust/settings.rs b/src/rust/settings.rs index d167a6f..6c36de9 100644 --- a/src/rust/settings.rs +++ b/src/rust/settings.rs @@ -15,6 +15,12 @@ mod settings { #[qproperty(QUrl, last_save_file)] #[qproperty(QUrl, loaded_file)] type Settings = super::SettingsRust; + + #[qinvokable] + fn setup(self: Pin<&mut Settings>); + + #[qinvokable] + fn set_save_file(self: Pin<&mut Settings>, file: QUrl); } } @@ -28,13 +34,9 @@ use std::path::PathBuf; pub struct SettingsRust { config: Ini, - #[qproperty] screen: QString, - #[qproperty] sound_effect: QString, - #[qproperty] last_save_file: QUrl, - #[qproperty] loaded_file: QUrl, } @@ -51,15 +53,6 @@ impl Default for SettingsRust { } impl qobject::Settings { - #[qinvokable] - pub fn print_sound(self: Pin<&mut Self>) { - let mut config = Ini::new(); - let _map = config.load("~/.config/lumina/lumina.conf"); - - println!("{}", self.sound_effect()); - } - - #[qinvokable] pub fn setup(mut self: Pin<&mut Self>) { let home = dirs::config_dir(); println!("{:?}", home); @@ -92,7 +85,6 @@ impl qobject::Settings { } } - #[qinvokable] pub fn set_save_file(mut self: Pin<&mut Self>, file: QUrl) { println!("{file}"); match self.as_mut().config_mut().set( diff --git a/src/rust/slide_model.rs b/src/rust/slide_model.rs index 195df8d..bceb436 100644 --- a/src/rust/slide_model.rs +++ b/src/rust/slide_model.rs @@ -1,7 +1,5 @@ #[cxx_qt::bridge] mod slide_model { - use cxx_qt_lib::CaseSensitivity; - use tracing::{debug, debug_span, error, info, instrument}; unsafe extern "C++" { include!(< QAbstractListModel >); include!("cxx-qt-lib/qhash.h"); @@ -28,1077 +26,1179 @@ mod slide_model { // type QVector_Slidey = cxx_qt_lib::QVector; } - #[cxx_qt::qobject] - #[derive(Clone, Debug)] - pub struct Slidey { - text: QString, - ty: QString, - audio: QString, - image_background: QString, - video_background: QString, - htext_alignment: QString, - vtext_alignment: QString, - font: QString, - font_size: i32, - slide_count: i32, - slide_index: i32, - service_item_id: i32, - active: bool, - selected: bool, - looping: bool, - video_thumbnail: QString, - video_start_time: f32, - video_end_time: f32, - html: bool, - } - - impl Default for Slidey { - fn default() -> Self { - Self { - text: QString::default(), - ty: QString::default(), - audio: QString::default(), - image_background: QString::default(), - video_background: QString::default(), - htext_alignment: QString::default(), - vtext_alignment: QString::default(), - font: QString::default(), - font_size: 50, - slide_count: 1, - slide_index: 0, - service_item_id: 0, - active: false, - selected: false, - looping: false, - video_thumbnail: QString::default(), - video_start_time: 0.0, - video_end_time: 0.0, - html: false, - } - } - } - - #[cxx_qt::qobject(base = "QAbstractListModel")] - #[derive(Default, Debug)] - pub struct SlideyMod { - id: i32, - slides: Vec, - } - - #[cxx_qt::qsignals(SlideyMod)] - pub enum Signals<'a> { - #[inherit] - DataChanged { - top_left: &'a QModelIndex, - bottom_right: &'a QModelIndex, - roles: &'a QVector_i32, - }, - ActiveChanged { - index: &'a i32, - }, - } - + #[qenum(SlideModel)] enum Role { - ActiveRole, - SelectedRole, - LoopingRole, - TextRole, - VideoThumbnailRole, - VideoStartTimeRole, - VideoEndTimeRole, + Ty, + Text, + Audio, + ImageBackground, + VideoBackground, + HTextAlignment, + VTextAlignment, + Font, + FontSize, + ServiceItemId, + SlideIndex, + ImageCount, + Active, + Selected, + Looping, + VideoThumbnail, + VideoStartTime, + VideoEndTime, + Html, } - // use crate::video_thumbnail; - // use image::{ImageBuffer, Rgba}; - use crate::ffmpeg; - use std::path::PathBuf; - use std::thread; - impl qobject::SlideyMod { + unsafe extern "RustQt" { + #[qobject] + #[base = "QAbstractListModel"] + #[qml_element] + type SlideModel = super::SlideModelRust; + + #[inherit] + #[qsignal] + fn data_changed( + self: Pin<&mut SlideModel>, + top_left: &QModelIndex, + bottom_right: &QModelIndex, + roles: &QVector_i32, + ); + + #[qsignal] + fn active_change(self: Pin<&mut SlideModel>, index: &i32); + #[qinvokable] - pub fn add_video_thumbnail( - mut self: Pin<&mut Self>, + fn add_video_thumbnail( + self: Pin<&mut SlideModel>, index: i32, - ) -> bool { - let mut vector_roles = QVector_i32::default(); - vector_roles - .append(self.get_role(Role::VideoThumbnailRole)); - - let model_index = - &self.index(index, 0, &QModelIndex::default()); - if let Some(slide) = - self.as_mut().slides_mut().get_mut(index as usize) - { - if !slide.video_background.is_empty() { - let path = PathBuf::from( - slide.video_background.to_string(), - ); - let video = QString::from( - ffmpeg::bg_from_video(&path) - .to_str() - .unwrap(), - ) - .insert(0, &QString::from("file://")) - .to_owned(); - slide.video_thumbnail = video; - self.as_mut().emit_data_changed( - model_index, - model_index, - &vector_roles, - ); - } - } - true - } + ) -> bool; #[qinvokable] - pub fn clear(mut self: Pin<&mut Self>) { - println!("CLEARING ALL SLIDES"); - unsafe { - self.as_mut().begin_reset_model(); - self.as_mut().slides_mut().clear(); - self.as_mut().end_reset_model(); - } - } + fn clear(self: Pin<&mut SlideModel>); #[qinvokable] - pub fn remove_item_from_service( - mut self: Pin<&mut Self>, + fn remove_item_from_service( + self: Pin<&mut SlideModel>, index: i32, _service_item: &QMap_QString_QVariant, - ) { - println!("Rusty-Removal-Time: {:?}", index); - let slides = self.slides().clone(); - let slides_iter = slides.iter(); - for (i, slide) in slides_iter.enumerate().rev() { - if slide.service_item_id == index { - self.as_mut().remove_item(i as i32); - println!("Removing-slide: {:?}", i); - } else if slide.service_item_id > index { - if let Some(slide) = - self.as_mut().slides_mut().get_mut(i) - { - println!("changing-serviceid-of: {:?}", i); - println!( - "changing-serviceid-fromandto: {:?}-{:?}", - slide.service_item_id, - slide.service_item_id - 1 - ); - slide.service_item_id -= 1; - } - } - } - } + ); #[qinvokable] - pub fn remove_item(mut self: Pin<&mut Self>, index: i32) { - if index < 0 || (index as usize) >= self.slides().len() { - return; - } - - unsafe { - self.as_mut().begin_remove_rows( - &QModelIndex::default(), - index, - index, - ); - self.as_mut().slides_mut().remove(index as usize); - self.as_mut().end_remove_rows(); - } - println!("removed-row: {:?}", index); - } - - fn add_slide(mut self: Pin<&mut Self>, slide: &Slidey) { - let index = self.as_ref().slides().len() as i32; - println!("{:?}", slide); - let slide = slide.clone(); - - unsafe { - self.as_mut().begin_insert_rows( - &QModelIndex::default(), - index, - index, - ); - self.as_mut().slides_mut().push(slide); - self.as_mut().end_insert_rows(); - } - let thread = self.qt_thread(); - thread::spawn(move || { - thread - .queue(move |slidemodel| { - slidemodel.add_video_thumbnail(index); - }) - .unwrap(); - }); - // self.as_mut().add_video_thumbnail(index); - } - - fn insert_slide( - mut self: Pin<&mut Self>, - slide: &Slidey, - index: i32, - ) { - let mut slide = slide.clone(); - // slide.slide_index = index; - - unsafe { - self.as_mut().begin_insert_rows( - &QModelIndex::default(), - index, - index, - ); - self.as_mut() - .slides_mut() - .insert(index as usize, slide); - self.as_mut().end_insert_rows(); - } - let thread = self.qt_thread(); - thread::spawn(move || { - thread - .queue(move |slidemodel| { - slidemodel.add_video_thumbnail(index); - }) - .unwrap(); - }); - } + fn remove_item(self: Pin<&mut SlideModel>, index: i32); #[qinvokable] - pub fn insert_item_from_service( - mut self: Pin<&mut Self>, + fn insert_item_from_service( + self: Pin<&mut SlideModel>, index: i32, service_item: &QMap_QString_QVariant, - ) { - for (key, data) in service_item.iter() { - debug!( - ?key, - data = data - .value_or_default::() - .to_string() - ); - } - let ty = service_item - .get(&QString::from("ty")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::(); - - let background = service_item - .get(&QString::from("background")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let background_type = service_item - .get(&QString::from("backgroundType")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let textlist = service_item - .get(&QString::from("text")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let text_vec = - Vec::::from(&QList_QString::from(&textlist)); - // let vec_slize: &[usize] = &text_vec; - - let mut slide = Slidey::default(); - - slide.ty = service_item - .get(&QString::from("type")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.text = service_item - .get(&QString::from("text")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.image_background = service_item - .get(&QString::from("imageBackground")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.video_background = service_item - .get(&QString::from("videoBackground")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.audio = service_item - .get(&QString::from("audio")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.font = service_item - .get(&QString::from("font")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.font_size = service_item - .get(&QString::from("fontSize")) - .unwrap_or(QVariant::from(&50)) - .value() - .unwrap_or(50); - slide.htext_alignment = service_item - .get(&QString::from("vtextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))) - .value() - .unwrap_or(QString::from("center")); - slide.vtext_alignment = service_item - .get(&QString::from("vtextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))) - .value() - .unwrap_or(QString::from("center")); - slide.service_item_id = index; - slide.slide_index = service_item - .get(&QString::from("slideNumber")) - .unwrap_or(QVariant::from(&0)) - .value() - .unwrap_or(0); - slide.slide_count = service_item - .get(&QString::from("slideCount")) - .unwrap_or(QVariant::from(&1)) - .value() - .unwrap_or(1); - slide.looping = service_item - .get(&QString::from("loop")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.active = service_item - .get(&QString::from("active")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.selected = service_item - .get(&QString::from("selected")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.video_thumbnail = QString::from(""); - - let slides_iter = self.as_mut().slides_mut().iter_mut(); - let mut slide_index = 0; - for (i, slide) in slides_iter.enumerate().rev() { - if slide.service_item_id == index { - slide_index = i as i32; - break; - } - } - - // We need to move all the current slides service_item_id's up by one. - let slides_iter = self.as_mut().slides_mut().iter_mut(); - for slide in - slides_iter.filter(|x| x.service_item_id >= index) - { - slide.service_item_id += 1; - } - - match ty { - Some(ty) if ty == QString::from("image") => { - slide.ty = ty; - slide.image_background = background; - slide.video_background = QString::from(""); - slide.slide_index = 0; - self.as_mut().insert_slide(&slide, slide_index); - println!("Image added to slide model!"); - } - Some(ty) if ty == QString::from("song") => { - let count = text_vec.len(); - for (i, text) in text_vec.iter().enumerate() { - println!( - "rust: add song of {:?} length at index {:?}", - &count, &slide_index - ); - slide.ty = ty.clone(); - // println!("{:?}", text_vec[i].clone()); - slide.text = text.clone(); - slide.slide_count = count as i32; - slide.slide_index = i as i32; - if background_type == QString::from("image") { - slide.image_background = - background.clone(); - slide.video_background = - QString::from(""); - } else { - slide.video_background = - background.clone(); - slide.image_background = - QString::from(""); - } - self.as_mut().insert_slide( - &slide, - slide_index + i as i32, - ); - } - } - Some(ty) if ty == QString::from("video") => { - slide.ty = ty; - slide.image_background = QString::from(""); - slide.video_background = background; - slide.slide_index = 0; - self.as_mut().insert_slide(&slide, slide_index); - } - Some(ty) if ty == QString::from("presentation") => { - for i in 0..slide.slide_count { - slide.ty = ty.clone(); - if background.ends_with( - &QString::from(".html"), - CaseSensitivity::CaseInsensitive, - ) { - slide.html = true; - } - slide.image_background = background.clone(); - slide.video_background = QString::from(""); - slide.slide_index = i; - self.as_mut().insert_slide( - &slide, - slide_index + i as i32, - ); - } - } - _ => println!("It's somethign else!"), - }; - - println!("Item added in slide model!"); - } + ); #[qinvokable] - pub fn add_item_from_service( - mut self: Pin<&mut Self>, + fn add_item_from_service( + self: Pin<&mut SlideModel>, index: i32, service_item: &QMap_QString_QVariant, - ) { - println!("add rust slide {:?}", index); - let ty = service_item - .get(&QString::from("ty")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::(); - - let background = service_item - .get(&QString::from("background")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let background_type = service_item - .get(&QString::from("backgroundType")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let textlist = service_item - .get(&QString::from("text")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value::() - .unwrap_or_default(); - - let text_vec = - Vec::::from(&QList_QString::from(&textlist)); - // let vec_slize: &[usize] = &text_vec; - - let mut slide = Slidey::default(); - - slide.ty = service_item - .get(&QString::from("type")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.text = service_item - .get(&QString::from("text")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.image_background = service_item - .get(&QString::from("imageBackground")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.video_background = service_item - .get(&QString::from("videoBackground")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.audio = service_item - .get(&QString::from("audio")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.font = service_item - .get(&QString::from("font")) - .unwrap_or(QVariant::from(&QString::from(""))) - .value() - .unwrap_or(QString::from("")); - slide.font_size = service_item - .get(&QString::from("fontSize")) - .unwrap_or(QVariant::from(&50)) - .value() - .unwrap_or(50); - slide.htext_alignment = service_item - .get(&QString::from("vtextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))) - .value() - .unwrap_or(QString::from("center")); - slide.vtext_alignment = service_item - .get(&QString::from("vtextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))) - .value() - .unwrap_or(QString::from("center")); - slide.service_item_id = index; - slide.slide_index = service_item - .get(&QString::from("slideNumber")) - .unwrap_or(QVariant::from(&0)) - .value() - .unwrap_or(0); - slide.slide_count = service_item - .get(&QString::from("imageCount")) - .unwrap_or(QVariant::from(&1)) - .value() - .unwrap_or(1); - slide.looping = service_item - .get(&QString::from("loop")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.active = service_item - .get(&QString::from("active")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.selected = service_item - .get(&QString::from("selected")) - .unwrap_or(QVariant::from(&false)) - .value() - .unwrap_or(false); - slide.video_thumbnail = QString::from(""); - - match ty { - Some(ty) if ty == QString::from("image") => { - slide.ty = ty; - slide.image_background = background; - slide.video_background = QString::from(""); - slide.slide_index = 0; - self.as_mut().add_slide(&slide); - } - Some(ty) if ty == QString::from("song") => { - for (i, text) in text_vec.iter().enumerate() { - slide.ty = ty.clone(); - // println!("{:?}", text_vec[i].clone()); - slide.text = text.clone(); - slide.slide_count = text_vec.len() as i32; - slide.slide_index = i as i32; - if background_type == QString::from("image") { - slide.image_background = - background.clone(); - slide.video_background = - QString::from(""); - } else { - slide.video_background = - background.clone(); - slide.image_background = - QString::from(""); - } - self.as_mut().add_slide(&slide); - } - } - Some(ty) if ty == QString::from("video") => { - slide.ty = ty; - slide.image_background = QString::from(""); - slide.video_background = background; - slide.slide_index = 0; - self.as_mut().add_slide(&slide); - } - Some(ty) if ty == QString::from("presentation") => { - for i in 0..slide.slide_count { - slide.ty = ty.clone(); - slide.image_background = background.clone(); - slide.video_background = QString::from(""); - slide.slide_index = i; - self.as_mut().add_slide(&slide); - } - } - _ => println!("It's somethign else!"), - }; - - println!("Item added in rust model!"); - } + ); #[qinvokable] - pub fn move_item_from_service( - mut self: Pin<&mut Self>, + fn move_item_from_service( + self: Pin<&mut SlideModel>, source_index: i32, destination_index: i32, _service_item: &QMap_QString_QVariant, - ) { - if source_index == destination_index { - return; - } - - let move_down = source_index < destination_index; - let slides = self.slides().clone(); - let slides_iter = slides.iter(); - - let mut first_slide = 0; - let mut dest_slide = 0; - let mut count = 0; - let mut dest_count = 0; - - for (i, slide) in slides_iter.clone().enumerate() { - if slide.service_item_id == source_index { - first_slide = i as i32; - count = slide.slide_count; - break; - } - } - - if move_down { - for (i, slide) in slides_iter.enumerate().rev() { - if slide.service_item_id == destination_index { - // if count > 1 { - // dest_slide = i as i32 - count - // } else { - dest_slide = i as i32; - dest_count = slide.slide_count; - println!( - "RUST_dest_slide: {:?} with {:?} slides", - dest_slide, dest_count - ); - // } - break; - } - } - } else { - for (i, slide) in slides_iter.enumerate() { - if slide.service_item_id == destination_index { - // if count > 1 { - // dest_slide = i as i32 - count - // } else { - dest_slide = i as i32; - println!("RUST_dest_slide: {:?}", dest_slide); - // } - break; - } - } - } - - println!("RUST_COUNT: {:?}", count); - println!("RUST_first_slide: {:?}", first_slide); - println!("RUST_dest_slide: {:?}", dest_slide); - println!("RUST_len: {:?}", self.rust().slides.len()); - - let slides = self.slides().clone(); - let slides_iter = slides.iter(); - - unsafe { - self.as_mut().begin_reset_model(); - } - self.as_mut().move_items( - first_slide as usize, - dest_slide as usize, - count as usize, - ); - - if count > 1 { - if move_down { - for (i, slide) in slides_iter - .clone() - .enumerate() - .filter(|x| { - x.0 >= (first_slide + dest_count) as usize - }) - .filter(|x| { - x.0 < (first_slide + dest_count + count) - as usize - }) - { - if let Some(slide) = - self.as_mut().slides_mut().get_mut(i) - { - println!( - "rust: these ones right here officer. from {:?} to {:?}", - slide.service_item_id, destination_index - ); - slide.service_item_id = destination_index; - } - } - } else { - for (i, slide) in slides_iter - .clone() - .enumerate() - .filter(|x| x.0 >= dest_slide as usize) - .filter(|x| { - x.0 < (dest_slide + count) as usize - }) - { - if let Some(slide) = - self.as_mut().slides_mut().get_mut(i) - { - println!( - "rust: these ones right here officer. from {:?} to {:?}", - slide.service_item_id, destination_index - ); - slide.service_item_id = destination_index; - } - } - } - } else { - if let Some(slide) = self - .as_mut() - .slides_mut() - .get_mut(dest_slide as usize) - { - println!( - "rust: this one right here officer. {:?} from {:?} to {:?}", - slide.slide_index, slide.service_item_id, destination_index - ); - slide.service_item_id = destination_index; - } - } - - if move_down { - for (i, slide) in slides_iter - .enumerate() - .filter(|x| { - x.0 < (first_slide + dest_count) as usize - }) - .filter(|x| { - x.1.service_item_id <= destination_index - }) - .filter(|x| x.1.service_item_id >= source_index) - { - if let Some(slide) = - self.as_mut().slides_mut().get_mut(i) - { - println!( - "rust-switching-service: {:?} to {:?}", - slide.service_item_id, - slide.service_item_id - 1 - ); - slide.service_item_id -= 1; - } - println!("rust-did:"); - } - } else { - for (i, slide) in slides_iter - .enumerate() - .filter(|x| { - x.0 >= (dest_slide as usize + count as usize) - }) - .filter(|x| { - x.1.service_item_id >= destination_index - }) - .filter(|x| x.1.service_item_id <= source_index) - { - if let Some(slide) = - self.as_mut().slides_mut().get_mut(i) - { - println!( - "rust-switching-service-of: {:?} to {:?}", - slide.service_item_id, - slide.service_item_id + 1 - ); - slide.service_item_id += 1; - } - println!("rust-did:"); - } - } - - unsafe { - self.as_mut().end_reset_model(); - } - - println!("rust-move: {first_slide} to {dest_slide} with {count} slides"); - } - - fn move_items( - mut self: Pin<&mut Self>, - source_index: usize, - dest_index: usize, - count: usize, - ) { - let end_slide = source_index + count - 1; - println!("rust-end-slide: {:?}", end_slide); - println!("rust-dest-slide: {:?}", dest_index); - unsafe { - self.as_mut().begin_reset_model(); - if source_index < dest_index { - let move_amount = - dest_index - source_index - count + 1; - // println!("rust-move_amount: {:?}", move_amount); - self.as_mut().slides_mut() - [source_index..=dest_index] - .rotate_right(move_amount); - } else { - let move_amount = - end_slide - dest_index - count + 1; - println!("rust-move_amount: {:?}", move_amount); - self.as_mut().slides_mut() - [dest_index..=end_slide] - .rotate_left(move_amount); - } - self.as_mut().end_reset_model(); - } - } + ); #[qinvokable] - pub fn get_item( - self: Pin<&mut Self>, + fn get_item( + self: Pin<&mut SlideModel>, index: i32, - ) -> QMap_QString_QVariant { - println!("{index}"); - let mut qvariantmap = QMap_QString_QVariant::default(); - let idx = self.index(index, 0, &QModelIndex::default()); - if !idx.is_valid() { - return qvariantmap; - } - let rn = self.as_ref().role_names(); - let rn_iter = rn.iter(); - if let Some(slide) = - self.rust().slides.get(index as usize) - { - for i in rn_iter { - qvariantmap.insert( - QString::from(&i.1.to_string()), - self.as_ref().data(&idx, *i.0), - ); - } - }; - qvariantmap - } + ) -> QMap_QString_QVariant; #[qinvokable] - pub fn get_slide_from_service( - self: Pin<&mut Self>, + fn get_slide_from_service( + self: Pin<&mut SlideModel>, index: i32, - ) -> i32 { - let slides = self.slides().clone(); - let slides_iter = slides.iter(); - debug!( - service_item = index, - "Getting slide from this item" - ); - let mut id = 0; - for (i, slide) in slides_iter - .enumerate() - .filter(|(i, slide)| slide.service_item_id == index) - { - debug!(slide_id = i, ?slide); - id = i as i32; - break; - } - id - } + ) -> i32; #[qinvokable] - pub fn activate( - mut self: Pin<&mut Self>, - index: i32, - ) -> bool { - let rc = self.as_ref().count() - 1; - let tl = - &self.as_ref().index(0, 0, &QModelIndex::default()); - let br = - &self.as_ref().index(rc, 0, &QModelIndex::default()); - let mut vector_roles = QVector_i32::default(); - vector_roles.append(self.get_role(Role::ActiveRole)); - for slide in self.as_mut().slides_mut().iter_mut() { - // println!("slide is deactivating {:?}", i); - slide.active = false; - } - if let Some(slide) = - self.as_mut().slides_mut().get_mut(index as usize) - { - debug!( - slide = index, - service_item = slide.service_item_id, - "This slide is activating" - ); - // println!("slide is activating {:?}", index); - // println!("slide-title: {:?}", slide.service_item_id); - // println!( - // "slide-image-background: {:?}", - // slide.image_background - // ); - // println!( - // "slide-video-background: {:?}", - // slide.video_background - // ); - slide.active = true; - self.as_mut().emit_data_changed( - tl, - br, - &vector_roles, - ); - // We use this signal generated by our signals enum to tell QML that - // the active slide has changed which is used to reposition views. - self.as_mut().emit_active_changed(&index); - true - } else { - false - } - } - - fn get_role(&self, role: Role) -> i32 { - match role { - Role::TextRole => 1, - Role::ActiveRole => 12, - Role::SelectedRole => 13, - Role::LoopingRole => 14, - Role::VideoThumbnailRole => 15, - Role::VideoStartTimeRole => 16, - Role::VideoEndTimeRole => 17, - _ => 0, - } - } + fn activate(self: Pin<&mut SlideModel>, index: i32) -> bool; } - // Create Rust bindings for C++ functions of the base class (QAbstractItemModel) - #[cxx_qt::inherit] - extern "C++" { + impl cxx_qt::Threading for SlideModel {} + + unsafe extern "RustQt" { + #[inherit] unsafe fn begin_insert_rows( - self: Pin<&mut qobject::SlideyMod>, + self: Pin<&mut SlideModel>, parent: &QModelIndex, first: i32, last: i32, ); - unsafe fn end_insert_rows(self: Pin<&mut qobject::SlideyMod>); + #[inherit] + unsafe fn end_insert_rows(self: Pin<&mut SlideModel>); + + #[inherit] unsafe fn begin_remove_rows( - self: Pin<&mut qobject::SlideyMod>, + self: Pin<&mut SlideModel>, parent: &QModelIndex, first: i32, last: i32, ); - unsafe fn end_remove_rows(self: Pin<&mut qobject::SlideyMod>); - unsafe fn begin_reset_model( - self: Pin<&mut qobject::SlideyMod>, - ); - unsafe fn end_reset_model(self: Pin<&mut qobject::SlideyMod>); - } + #[inherit] + unsafe fn end_remove_rows(self: Pin<&mut SlideModel>); - #[cxx_qt::inherit] - unsafe extern "C++" { - #[cxx_name = "canFetchMore"] - fn base_can_fetch_more( - self: &qobject::SlideyMod, + #[inherit] + unsafe fn begin_reset_model(self: Pin<&mut SlideModel>); + + #[inherit] + unsafe fn end_reset_model(self: Pin<&mut SlideModel>); + + #[inherit] + fn can_fetch_more( + self: &SlideModel, parent: &QModelIndex, ) -> bool; + #[inherit] fn index( - self: &qobject::SlideyMod, + self: &SlideModel, row: i32, column: i32, parent: &QModelIndex, ) -> QModelIndex; - } - - // QAbstractListModel implementation - impl qobject::SlideyMod { - #[qinvokable(cxx_override)] - fn data(&self, index: &QModelIndex, role: i32) -> QVariant { - if let Some(slide) = - self.slides().get(index.row() as usize) - { - return match role { - 0 => QVariant::from(&slide.ty), - 1 => QVariant::from(&slide.text), - 2 => QVariant::from(&slide.audio), - 3 => QVariant::from(&slide.image_background), - 4 => QVariant::from(&slide.video_background), - 5 => QVariant::from(&slide.htext_alignment), - 6 => QVariant::from(&slide.vtext_alignment), - 7 => QVariant::from(&slide.font), - 8 => QVariant::from(&slide.font_size), - 9 => QVariant::from(&slide.service_item_id), - 10 => QVariant::from(&slide.slide_index), - 11 => QVariant::from(&slide.slide_count), - 12 => QVariant::from(&slide.active), - 13 => QVariant::from(&slide.selected), - 14 => QVariant::from(&slide.looping), - 15 => QVariant::from(&slide.video_thumbnail), - 16 => QVariant::from(&slide.video_start_time), - 17 => QVariant::from(&slide.video_end_time), - 18 => QVariant::from(&slide.html), - _ => QVariant::default(), - }; - } - - QVariant::default() - } - - // Example of overriding a C++ virtual method and calling the base class implementation. - #[qinvokable(cxx_override)] - pub fn can_fetch_more(&self, parent: &QModelIndex) -> bool { - self.base_can_fetch_more(parent) - } - - #[qinvokable(cxx_override)] - pub fn role_names(&self) -> QHash_i32_QByteArray { - let mut roles = QHash_i32_QByteArray::default(); - roles.insert(0, cxx_qt_lib::QByteArray::from("type")); - roles.insert(1, cxx_qt_lib::QByteArray::from("text")); - roles.insert(2, cxx_qt_lib::QByteArray::from("audio")); - roles.insert( - 3, - cxx_qt_lib::QByteArray::from("imageBackground"), - ); - roles.insert( - 4, - cxx_qt_lib::QByteArray::from("videoBackground"), - ); - roles.insert( - 5, - cxx_qt_lib::QByteArray::from("hTextAlignment"), - ); - roles.insert( - 6, - cxx_qt_lib::QByteArray::from("vTextAlignment"), - ); - roles.insert(7, cxx_qt_lib::QByteArray::from("font")); - roles.insert(8, cxx_qt_lib::QByteArray::from("fontSize")); - roles.insert( - 9, - cxx_qt_lib::QByteArray::from("serviceItemId"), - ); - roles.insert( - 10, - cxx_qt_lib::QByteArray::from("slideIndex"), - ); - roles.insert( - 11, - cxx_qt_lib::QByteArray::from("imageCount"), - ); - roles.insert(12, cxx_qt_lib::QByteArray::from("active")); - roles - .insert(13, cxx_qt_lib::QByteArray::from("selected")); - roles.insert(14, cxx_qt_lib::QByteArray::from("looping")); - roles.insert( - 15, - cxx_qt_lib::QByteArray::from("videoThumbnail"), - ); - roles.insert( - 16, - cxx_qt_lib::QByteArray::from("videoStartTime"), - ); - roles.insert( - 17, - cxx_qt_lib::QByteArray::from("videoEndTime"), - ); - roles.insert(18, cxx_qt_lib::QByteArray::from("html")); - roles - } - - #[qinvokable(cxx_override)] - pub fn row_count(&self, _parent: &QModelIndex) -> i32 { - let cnt = self.rust().slides.len() as i32; - // println!("row count is {cnt}"); - cnt - } #[qinvokable] - pub fn count(&self) -> i32 { - self.rust().slides.len() as i32 + #[cxx_override] + fn data( + self: &SlideModel, + index: &QModelIndex, + role: i32, + ) -> QVariant; + + #[qinvokable] + #[cxx_override] + fn role_names(self: &SlideModel) -> QHash_i32_QByteArray; + + #[qinvokable] + #[cxx_override] + fn row_count(self: &SlideModel, _parent: &QModelIndex) + -> i32; + + #[qinvokable] + fn count(self: &SlideModel) -> i32; + } +} + +use crate::ffmpeg; +use cxx_qt_lib::CaseSensitivity; +use std::path::PathBuf; +use std::thread; +use tracing::{debug, debug_span, error, info, instrument}; + +#[derive(Clone, Debug)] +pub struct Slide { + text: QString, + ty: QString, + audio: QString, + image_background: QString, + video_background: QString, + htext_alignment: QString, + vtext_alignment: QString, + font: QString, + font_size: i32, + slide_count: i32, + slide_index: i32, + service_item_id: i32, + active: bool, + selected: bool, + looping: bool, + video_thumbnail: QString, + video_start_time: f32, + video_end_time: f32, + html: bool, +} + +impl Default for Slide { + fn default() -> Self { + Self { + text: QString::default(), + ty: QString::default(), + audio: QString::default(), + image_background: QString::default(), + video_background: QString::default(), + htext_alignment: QString::default(), + vtext_alignment: QString::default(), + font: QString::default(), + font_size: 50, + slide_count: 1, + slide_index: 0, + service_item_id: 0, + active: false, + selected: false, + looping: false, + video_thumbnail: QString::default(), + video_start_time: 0.0, + video_end_time: 0.0, + html: false, } } } + +#[derive(Default, Debug)] +pub struct SlideModelRust { + id: i32, + slides: Vec, +} + +impl qobject::SlideModel { + #[qinvokable] + pub fn add_video_thumbnail( + mut self: Pin<&mut Self>, + index: i32, + ) -> bool { + let mut vector_roles = QVector_i32::default(); + vector_roles.append(self.get_role(Role::VideoThumbnailRole)); + + let model_index = + &self.index(index, 0, &QModelIndex::default()); + if let Some(slide) = + self.as_mut().slides_mut().get_mut(index as usize) + { + if !slide.video_background.is_empty() { + let path = + PathBuf::from(slide.video_background.to_string()); + let video = QString::from( + ffmpeg::bg_from_video(&path).to_str().unwrap(), + ) + .insert(0, &QString::from("file://")) + .to_owned(); + slide.video_thumbnail = video; + self.as_mut().emit_data_changed( + model_index, + model_index, + &vector_roles, + ); + } + } + true + } + + #[qinvokable] + pub fn clear(mut self: Pin<&mut Self>) { + println!("CLEARING ALL SLIDES"); + unsafe { + self.as_mut().begin_reset_model(); + self.as_mut().slides_mut().clear(); + self.as_mut().end_reset_model(); + } + } + + #[qinvokable] + pub fn remove_item_from_service( + mut self: Pin<&mut Self>, + index: i32, + _service_item: &QMap_QString_QVariant, + ) { + println!("Rusty-Removal-Time: {:?}", index); + let slides = self.slides().clone(); + let slides_iter = slides.iter(); + for (i, slide) in slides_iter.enumerate().rev() { + if slide.service_item_id == index { + self.as_mut().remove_item(i as i32); + println!("Removing-slide: {:?}", i); + } else if slide.service_item_id > index { + if let Some(slide) = + self.as_mut().slides_mut().get_mut(i) + { + println!("changing-serviceid-of: {:?}", i); + println!( + "changing-serviceid-fromandto: {:?}-{:?}", + slide.service_item_id, + slide.service_item_id - 1 + ); + slide.service_item_id -= 1; + } + } + } + } + + #[qinvokable] + pub fn remove_item(mut self: Pin<&mut Self>, index: i32) { + if index < 0 || (index as usize) >= self.slides().len() { + return; + } + + unsafe { + self.as_mut().begin_remove_rows( + &QModelIndex::default(), + index, + index, + ); + self.as_mut().slides_mut().remove(index as usize); + self.as_mut().end_remove_rows(); + } + println!("removed-row: {:?}", index); + } + + fn add_slide(mut self: Pin<&mut Self>, slide: &Slide) { + let index = self.as_ref().slides().len() as i32; + println!("{:?}", slide); + let slide = slide.clone(); + + unsafe { + self.as_mut().begin_insert_rows( + &QModelIndex::default(), + index, + index, + ); + self.as_mut().slides_mut().push(slide); + self.as_mut().end_insert_rows(); + } + let thread = self.qt_thread(); + thread::spawn(move || { + thread + .queue(move |slidemodel| { + slidemodel.add_video_thumbnail(index); + }) + .unwrap(); + }); + // self.as_mut().add_video_thumbnail(index); + } + + fn insert_slide( + mut self: Pin<&mut Self>, + slide: &Slide, + index: i32, + ) { + let mut slide = slide.clone(); + // slide.slide_index = index; + + unsafe { + self.as_mut().begin_insert_rows( + &QModelIndex::default(), + index, + index, + ); + self.as_mut().slides_mut().insert(index as usize, slide); + self.as_mut().end_insert_rows(); + } + let thread = self.qt_thread(); + thread::spawn(move || { + thread + .queue(move |slidemodel| { + slidemodel.add_video_thumbnail(index); + }) + .unwrap(); + }); + } + + #[qinvokable] + pub fn insert_item_from_service( + mut self: Pin<&mut Self>, + index: i32, + service_item: &QMap_QString_QVariant, + ) { + for (key, data) in service_item.iter() { + debug!( + ?key, + data = data.value_or_default::().to_string() + ); + } + let ty = service_item + .get(&QString::from("ty")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::(); + + let background = service_item + .get(&QString::from("background")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let background_type = service_item + .get(&QString::from("backgroundType")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let textlist = service_item + .get(&QString::from("text")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let text_vec = + Vec::::from(&QList_QString::from(&textlist)); + // let vec_slize: &[usize] = &text_vec; + + let mut slide = Slide::default(); + + slide.ty = service_item + .get(&QString::from("type")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.text = service_item + .get(&QString::from("text")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.image_background = service_item + .get(&QString::from("imageBackground")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.video_background = service_item + .get(&QString::from("videoBackground")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.audio = service_item + .get(&QString::from("audio")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.font = service_item + .get(&QString::from("font")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.font_size = service_item + .get(&QString::from("fontSize")) + .unwrap_or(QVariant::from(&50)) + .value() + .unwrap_or(50); + slide.htext_alignment = service_item + .get(&QString::from("vtextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))) + .value() + .unwrap_or(QString::from("center")); + slide.vtext_alignment = service_item + .get(&QString::from("vtextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))) + .value() + .unwrap_or(QString::from("center")); + slide.service_item_id = index; + slide.slide_index = service_item + .get(&QString::from("slideNumber")) + .unwrap_or(QVariant::from(&0)) + .value() + .unwrap_or(0); + slide.slide_count = service_item + .get(&QString::from("slideCount")) + .unwrap_or(QVariant::from(&1)) + .value() + .unwrap_or(1); + slide.looping = service_item + .get(&QString::from("loop")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.active = service_item + .get(&QString::from("active")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.selected = service_item + .get(&QString::from("selected")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.video_thumbnail = QString::from(""); + + let slides_iter = self.as_mut().slides_mut().iter_mut(); + let mut slide_index = 0; + for (i, slide) in slides_iter.enumerate().rev() { + if slide.service_item_id == index { + slide_index = i as i32; + break; + } + } + + // We need to move all the current slides service_item_id's up by one. + let slides_iter = self.as_mut().slides_mut().iter_mut(); + for slide in + slides_iter.filter(|x| x.service_item_id >= index) + { + slide.service_item_id += 1; + } + + match ty { + Some(ty) if ty == QString::from("image") => { + slide.ty = ty; + slide.image_background = background; + slide.video_background = QString::from(""); + slide.slide_index = 0; + self.as_mut().insert_slide(&slide, slide_index); + println!("Image added to slide model!"); + } + Some(ty) if ty == QString::from("song") => { + let count = text_vec.len(); + for (i, text) in text_vec.iter().enumerate() { + println!( + "rust: add song of {:?} length at index {:?}", + &count, &slide_index + ); + slide.ty = ty.clone(); + // println!("{:?}", text_vec[i].clone()); + slide.text = text.clone(); + slide.slide_count = count as i32; + slide.slide_index = i as i32; + if background_type == QString::from("image") { + slide.image_background = background.clone(); + slide.video_background = QString::from(""); + } else { + slide.video_background = background.clone(); + slide.image_background = QString::from(""); + } + self.as_mut() + .insert_slide(&slide, slide_index + i as i32); + } + } + Some(ty) if ty == QString::from("video") => { + slide.ty = ty; + slide.image_background = QString::from(""); + slide.video_background = background; + slide.slide_index = 0; + self.as_mut().insert_slide(&slide, slide_index); + } + Some(ty) if ty == QString::from("presentation") => { + for i in 0..slide.slide_count { + slide.ty = ty.clone(); + if background.ends_with( + &QString::from(".html"), + CaseSensitivity::CaseInsensitive, + ) { + slide.html = true; + } + slide.image_background = background.clone(); + slide.video_background = QString::from(""); + slide.slide_index = i; + self.as_mut() + .insert_slide(&slide, slide_index + i as i32); + } + } + _ => println!("It's somethign else!"), + }; + + println!("Item added in slide model!"); + } + + #[qinvokable] + pub fn add_item_from_service( + mut self: Pin<&mut Self>, + index: i32, + service_item: &QMap_QString_QVariant, + ) { + println!("add rust slide {:?}", index); + let ty = service_item + .get(&QString::from("ty")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::(); + + let background = service_item + .get(&QString::from("background")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let background_type = service_item + .get(&QString::from("backgroundType")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let textlist = service_item + .get(&QString::from("text")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value::() + .unwrap_or_default(); + + let text_vec = + Vec::::from(&QList_QString::from(&textlist)); + // let vec_slize: &[usize] = &text_vec; + + let mut slide = Slide::default(); + + slide.ty = service_item + .get(&QString::from("type")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.text = service_item + .get(&QString::from("text")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.image_background = service_item + .get(&QString::from("imageBackground")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.video_background = service_item + .get(&QString::from("videoBackground")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.audio = service_item + .get(&QString::from("audio")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.font = service_item + .get(&QString::from("font")) + .unwrap_or(QVariant::from(&QString::from(""))) + .value() + .unwrap_or(QString::from("")); + slide.font_size = service_item + .get(&QString::from("fontSize")) + .unwrap_or(QVariant::from(&50)) + .value() + .unwrap_or(50); + slide.htext_alignment = service_item + .get(&QString::from("vtextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))) + .value() + .unwrap_or(QString::from("center")); + slide.vtext_alignment = service_item + .get(&QString::from("vtextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))) + .value() + .unwrap_or(QString::from("center")); + slide.service_item_id = index; + slide.slide_index = service_item + .get(&QString::from("slideNumber")) + .unwrap_or(QVariant::from(&0)) + .value() + .unwrap_or(0); + slide.slide_count = service_item + .get(&QString::from("imageCount")) + .unwrap_or(QVariant::from(&1)) + .value() + .unwrap_or(1); + slide.looping = service_item + .get(&QString::from("loop")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.active = service_item + .get(&QString::from("active")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.selected = service_item + .get(&QString::from("selected")) + .unwrap_or(QVariant::from(&false)) + .value() + .unwrap_or(false); + slide.video_thumbnail = QString::from(""); + + match ty { + Some(ty) if ty == QString::from("image") => { + slide.ty = ty; + slide.image_background = background; + slide.video_background = QString::from(""); + slide.slide_index = 0; + self.as_mut().add_slide(&slide); + } + Some(ty) if ty == QString::from("song") => { + for (i, text) in text_vec.iter().enumerate() { + slide.ty = ty.clone(); + // println!("{:?}", text_vec[i].clone()); + slide.text = text.clone(); + slide.slide_count = text_vec.len() as i32; + slide.slide_index = i as i32; + if background_type == QString::from("image") { + slide.image_background = background.clone(); + slide.video_background = QString::from(""); + } else { + slide.video_background = background.clone(); + slide.image_background = QString::from(""); + } + self.as_mut().add_slide(&slide); + } + } + Some(ty) if ty == QString::from("video") => { + slide.ty = ty; + slide.image_background = QString::from(""); + slide.video_background = background; + slide.slide_index = 0; + self.as_mut().add_slide(&slide); + } + Some(ty) if ty == QString::from("presentation") => { + for i in 0..slide.slide_count { + slide.ty = ty.clone(); + slide.image_background = background.clone(); + slide.video_background = QString::from(""); + slide.slide_index = i; + self.as_mut().add_slide(&slide); + } + } + _ => println!("It's somethign else!"), + }; + + println!("Item added in rust model!"); + } + + #[qinvokable] + pub fn move_item_from_service( + mut self: Pin<&mut Self>, + source_index: i32, + destination_index: i32, + _service_item: &QMap_QString_QVariant, + ) { + if source_index == destination_index { + return; + } + + let move_down = source_index < destination_index; + let slides = self.slides().clone(); + let slides_iter = slides.iter(); + + let mut first_slide = 0; + let mut dest_slide = 0; + let mut count = 0; + let mut dest_count = 0; + + for (i, slide) in slides_iter.clone().enumerate() { + if slide.service_item_id == source_index { + first_slide = i as i32; + count = slide.slide_count; + break; + } + } + + if move_down { + for (i, slide) in slides_iter.enumerate().rev() { + if slide.service_item_id == destination_index { + // if count > 1 { + // dest_slide = i as i32 - count + // } else { + dest_slide = i as i32; + dest_count = slide.slide_count; + println!( + "RUST_dest_slide: {:?} with {:?} slides", + dest_slide, dest_count + ); + // } + break; + } + } + } else { + for (i, slide) in slides_iter.enumerate() { + if slide.service_item_id == destination_index { + // if count > 1 { + // dest_slide = i as i32 - count + // } else { + dest_slide = i as i32; + println!("RUST_dest_slide: {:?}", dest_slide); + // } + break; + } + } + } + + println!("RUST_COUNT: {:?}", count); + println!("RUST_first_slide: {:?}", first_slide); + println!("RUST_dest_slide: {:?}", dest_slide); + println!("RUST_len: {:?}", self.rust().slides.len()); + + let slides = self.slides().clone(); + let slides_iter = slides.iter(); + + unsafe { + self.as_mut().begin_reset_model(); + } + self.as_mut().move_items( + first_slide as usize, + dest_slide as usize, + count as usize, + ); + + if count > 1 { + if move_down { + for (i, slide) in slides_iter + .clone() + .enumerate() + .filter(|x| { + x.0 >= (first_slide + dest_count) as usize + }) + .filter(|x| { + x.0 < (first_slide + dest_count + count) + as usize + }) + { + if let Some(slide) = + self.as_mut().slides_mut().get_mut(i) + { + println!( + "rust: these ones right here officer. from {:?} to {:?}", + slide.service_item_id, destination_index + ); + slide.service_item_id = destination_index; + } + } + } else { + for (i, slide) in slides_iter + .clone() + .enumerate() + .filter(|x| x.0 >= dest_slide as usize) + .filter(|x| x.0 < (dest_slide + count) as usize) + { + if let Some(slide) = + self.as_mut().slides_mut().get_mut(i) + { + println!( + "rust: these ones right here officer. from {:?} to {:?}", + slide.service_item_id, destination_index + ); + slide.service_item_id = destination_index; + } + } + } + } else { + if let Some(slide) = self + .as_mut() + .slides_mut() + .get_mut(dest_slide as usize) + { + println!( + "rust: this one right here officer. {:?} from {:?} to {:?}", + slide.slide_index, slide.service_item_id, destination_index + ); + slide.service_item_id = destination_index; + } + } + + if move_down { + for (i, slide) in slides_iter + .enumerate() + .filter(|x| x.0 < (first_slide + dest_count) as usize) + .filter(|x| x.1.service_item_id <= destination_index) + .filter(|x| x.1.service_item_id >= source_index) + { + if let Some(slide) = + self.as_mut().slides_mut().get_mut(i) + { + println!( + "rust-switching-service: {:?} to {:?}", + slide.service_item_id, + slide.service_item_id - 1 + ); + slide.service_item_id -= 1; + } + println!("rust-did:"); + } + } else { + for (i, slide) in slides_iter + .enumerate() + .filter(|x| { + x.0 >= (dest_slide as usize + count as usize) + }) + .filter(|x| x.1.service_item_id >= destination_index) + .filter(|x| x.1.service_item_id <= source_index) + { + if let Some(slide) = + self.as_mut().slides_mut().get_mut(i) + { + println!( + "rust-switching-service-of: {:?} to {:?}", + slide.service_item_id, + slide.service_item_id + 1 + ); + slide.service_item_id += 1; + } + println!("rust-did:"); + } + } + + unsafe { + self.as_mut().end_reset_model(); + } + + println!("rust-move: {first_slide} to {dest_slide} with {count} slides"); + } + + fn move_items( + mut self: Pin<&mut Self>, + source_index: usize, + dest_index: usize, + count: usize, + ) { + let end_slide = source_index + count - 1; + println!("rust-end-slide: {:?}", end_slide); + println!("rust-dest-slide: {:?}", dest_index); + unsafe { + self.as_mut().begin_reset_model(); + if source_index < dest_index { + let move_amount = + dest_index - source_index - count + 1; + // println!("rust-move_amount: {:?}", move_amount); + self.as_mut().slides_mut()[source_index..=dest_index] + .rotate_right(move_amount); + } else { + let move_amount = end_slide - dest_index - count + 1; + println!("rust-move_amount: {:?}", move_amount); + self.as_mut().slides_mut()[dest_index..=end_slide] + .rotate_left(move_amount); + } + self.as_mut().end_reset_model(); + } + } + + #[qinvokable] + pub fn get_item( + self: Pin<&mut Self>, + index: i32, + ) -> QMap_QString_QVariant { + println!("{index}"); + let mut qvariantmap = QMap_QString_QVariant::default(); + let idx = self.index(index, 0, &QModelIndex::default()); + if !idx.is_valid() { + return qvariantmap; + } + let rn = self.as_ref().role_names(); + let rn_iter = rn.iter(); + if let Some(slide) = self.rust().slides.get(index as usize) { + for i in rn_iter { + qvariantmap.insert( + QString::from(&i.1.to_string()), + self.as_ref().data(&idx, *i.0), + ); + } + }; + qvariantmap + } + + #[qinvokable] + pub fn get_slide_from_service( + self: Pin<&mut Self>, + index: i32, + ) -> i32 { + let slides = self.slides().clone(); + let slides_iter = slides.iter(); + debug!(service_item = index, "Getting slide from this item"); + let mut id = 0; + for (i, slide) in slides_iter + .enumerate() + .filter(|(i, slide)| slide.service_item_id == index) + { + debug!(slide_id = i, ?slide); + id = i as i32; + break; + } + id + } + + #[qinvokable] + pub fn activate(mut self: Pin<&mut Self>, index: i32) -> bool { + let rc = self.as_ref().count() - 1; + let tl = &self.as_ref().index(0, 0, &QModelIndex::default()); + let br = &self.as_ref().index(rc, 0, &QModelIndex::default()); + let mut vector_roles = QVector_i32::default(); + vector_roles.append(self.get_role(Role::ActiveRole)); + for slide in self.as_mut().slides_mut().iter_mut() { + // println!("slide is deactivating {:?}", i); + slide.active = false; + } + if let Some(slide) = + self.as_mut().slides_mut().get_mut(index as usize) + { + debug!( + slide = index, + service_item = slide.service_item_id, + "This slide is activating" + ); + // println!("slide is activating {:?}", index); + // println!("slide-title: {:?}", slide.service_item_id); + // println!( + // "slide-image-background: {:?}", + // slide.image_background + // ); + // println!( + // "slide-video-background: {:?}", + // slide.video_background + // ); + slide.active = true; + self.as_mut().emit_data_changed(tl, br, &vector_roles); + // We use this signal generated by our signals enum to tell QML that + // the active slide has changed which is used to reposition views. + self.as_mut().emit_active_changed(&index); + true + } else { + false + } + } + + fn get_role(&self, role: Role) -> i32 { + match role { + Role::TextRole => 1, + Role::ActiveRole => 12, + Role::SelectedRole => 13, + Role::LoopingRole => 14, + Role::VideoThumbnailRole => 15, + Role::VideoStartTimeRole => 16, + Role::VideoEndTimeRole => 17, + _ => 0, + } + } +} + +// QAbstractListModel implementation +impl qobject::SlideModel { + pub fn data(&self, index: &QModelIndex, role: i32) -> QVariant { + let role = qobject::Roles { repr: role }; + if let Some(slide) = self.slides().get(index.row() as usize) { + return match role { + qobject::Roles::Ty => QVariant::from(&slide.ty), + qobject::Roles::Text => QVariant::from(&slide.text), + qobject::Roles::Audio => QVariant::from(&slide.audio), + qobject::Roles::ImageBackground => { + QVariant::from(&slide.image_background) + } + qobject::Roles::VideoBackground => { + QVariant::from(&slide.video_background) + } + qobject::Roles::HTextAlignment => { + QVariant::from(&slide.htext_alignment) + } + qobject::Roles::VTextAlignment => { + QVariant::from(&slide.vtext_alignment) + } + qobject::Roles::Font => QVariant::from(&slide.font), + qobject::Roles::FontSize => { + QVariant::from(&slide.font_size) + } + qobject::Roles::ServiceItemId => { + QVariant::from(&slide.service_item_id) + } + qobject::Roles::SlideIndex => { + QVariant::from(&slide.slide_index) + } + qobject::Roles::SlideCount => { + QVariant::from(&slide.slide_count) + } + qobject::Roles::Active => { + QVariant::from(&slide.active) + } + qobject::Roles::Selected => { + QVariant::from(&slide.selected) + } + qobject::Roles::Looping => { + QVariant::from(&slide.looping) + } + qobject::Roles::VideoThumbnail => { + QVariant::from(&slide.video_thumbnail) + } + qobject::Roles::VideoStartTime => { + QVariant::from(&slide.video_start_time) + } + qobject::Roles::VideoEndTime => { + QVariant::from(&slide.video_end_time) + } + qobject::Roles::Html => QVariant::from(&slide.html), + _ => QVariant::default(), + }; + } + + QVariant::default() + } + + // Example of overriding a C++ virtual method and calling the base class implementation. + pub fn can_fetch_more(&self, parent: &QModelIndex) -> bool { + self.base_can_fetch_more(parent) + } + + pub fn role_names(&self) -> QHash_i32_QByteArray { + let mut roles = QHash_i32_QByteArray::default(); + roles.insert( + qobject::Roles::Ty.repr, + cxx_qt_lib::QByteArray::from("type"), + ); + roles.insert( + qobject::Roles::Text.repr, + cxx_qt_lib::QByteArray::from("text"), + ); + roles.insert( + qobject::Roles::Audio.repr, + cxx_qt_lib::QByteArray::from("audio"), + ); + roles.insert( + qobject::Roles::ImageBackground.repr, + cxx_qt_lib::QByteArray::from("imageBackground"), + ); + roles.insert( + qobject::Roles::VideoBackground.repr, + cxx_qt_lib::QByteArray::from("videoBackground"), + ); + roles.insert( + qobject::Roles::HTextAlignment.repr, + cxx_qt_lib::QByteArray::from("hTextAlignment"), + ); + roles.insert( + qobject::Roles::VTextAlignment.repr, + cxx_qt_lib::QByteArray::from("vTextAlignment"), + ); + roles.insert( + qobject::Roles::Font.repr, + cxx_qt_lib::QByteArray::from("font"), + ); + roles.insert( + qobject::Roles::FontSize.repr, + cxx_qt_lib::QByteArray::from("fontSize"), + ); + roles.insert( + qobject::Roles::ServiceItemId.repr, + cxx_qt_lib::QByteArray::from("serviceItemId"), + ); + roles.insert( + qobject::Roles::SlideIndex.repr, + cxx_qt_lib::QByteArray::from("slideIndex"), + ); + roles.insert( + qobject::Roles::ImageCount.repr, + cxx_qt_lib::QByteArray::from("imageCount"), + ); + roles.insert( + qobject::Roles::Active.repr, + cxx_qt_lib::QByteArray::from("active"), + ); + roles.insert( + qobject::Roles::Selected.repr, + cxx_qt_lib::QByteArray::from("selected"), + ); + roles.insert( + qobject::Roles::Looping.repr, + cxx_qt_lib::QByteArray::from("looping"), + ); + roles.insert( + qobject::Roles::VideoThumbnail.repr, + cxx_qt_lib::QByteArray::from("videoThumbnail"), + ); + roles.insert( + qobject::Roles::VideoStartTime.repr, + cxx_qt_lib::QByteArray::from("videoStartTime"), + ); + roles.insert( + qobject::Roles::VideoEndTime.repr, + cxx_qt_lib::QByteArray::from("videoEndTime"), + ); + roles.insert( + qobject::Roles::Html.repr, + cxx_qt_lib::QByteArray::from("html"), + ); + roles + } + + pub fn row_count(&self, _parent: &QModelIndex) -> i32 { + let cnt = self.rust().slides.len() as i32; + // println!("row count is {cnt}"); + cnt + } + + pub fn count(&self) -> i32 { + self.rust().slides.len() as i32 + } +} diff --git a/src/rust/slide_object.rs b/src/rust/slide_object.rs index 976da6e..739d274 100644 --- a/src/rust/slide_object.rs +++ b/src/rust/slide_object.rs @@ -1,11 +1,5 @@ #[cxx_qt::bridge] mod slide_object { - // use cxx_qt_lib::QVariantValue; - // use std::path::Path; - // use std::task::Context; - - use tracing::debug; - unsafe extern "C++" { include!("cxx-qt-lib/qstring.h"); type QString = cxx_qt_lib::QString; @@ -16,322 +10,341 @@ mod slide_object { type QVariant = cxx_qt_lib::QVariant; } - #[derive(Debug)] - #[cxx_qt::qsignals(SlideObject)] - pub enum Signals<'a> { - PlayingChanged { is_playing: &'a bool }, - SlideIndexChanged { slide_index: &'a i32 }, - SlideSizeChanged { slide_size: &'a i32 }, - SlideChanged { slide: &'a i32 }, - LoopChanged { looping: &'a bool }, - RevealNext, - RevealPrev, - } + unsafe extern "RustQt" { + #[qsignal] + fn playing_changed( + self: Pin<&mut SlideObject>, + is_playing: bool, + ); + // #[qsignal] + // fn slide_index_changed( + // self: Pin<&mut SlideObject>, + // slide_index: i32, + // ); + // #[qsignal] + // fn slide_size_changed( + // self: Pin<&mut SlideObject>, + // slide_size: i32, + // ); + #[qsignal] + fn slide_changed(self: Pin<&mut SlideObject>, slide: i32); + #[qsignal] + fn loop_changed(self: Pin<&mut SlideObject>, looping: bool); + #[qsignal] + fn reveal_next(self: Pin<&mut SlideObject>); + #[qsignal] + fn reveal_prev(self: Pin<&mut SlideObject>); - #[derive(Clone, Debug)] - #[cxx_qt::qobject] - pub struct SlideObject { - #[qproperty] - slide_index: i32, - #[qproperty] - slide_size: i32, - #[qproperty] - image_count: i32, - #[qproperty] - is_playing: bool, - #[qproperty] - looping: bool, - #[qproperty] - text: QString, - #[qproperty] - ty: QString, - #[qproperty] - audio: QString, - #[qproperty] - image_background: QString, - #[qproperty] - video_background: QString, - #[qproperty] - html: QString, - #[qproperty] - vtext_alignment: QString, - #[qproperty] - htext_alignment: QString, - #[qproperty] - font: QString, - #[qproperty] - font_size: i32, - #[qproperty] - video_start_time: f32, - #[qproperty] - video_end_time: f32, - } + #[qobject] + #[qml_element] + #[qproperty(i32, slide_index)] + #[qproperty(i32, slide_size)] + #[qproperty(i32, image_count)] + #[qproperty(bool, is_playing)] + #[qproperty(bool, looping)] + #[qproperty(QString, text)] + #[qproperty(QString, ty)] + #[qproperty(QString, audio)] + #[qproperty(QString, image_background)] + #[qproperty(QString, video_background)] + #[qproperty(QString, html)] + #[qproperty(QString, vtext_alignment)] + #[qproperty(QString, htext_alignment)] + #[qproperty(QString, font)] + #[qproperty(bool, font_size)] + #[qproperty(f32, video_start_time)] + #[qproperty(f32, video_end_time)] + type SlideObject = super::SlideObjectRust; - impl Default for SlideObject { - fn default() -> Self { - Self { - slide_index: 0, - slide_size: 0, - is_playing: false, - looping: false, - text: QString::from(""), - ty: QString::from(""), - audio: QString::from(""), - image_background: QString::from(""), - html: QString::from(""), - video_background: QString::from(""), - vtext_alignment: QString::from(""), - htext_alignment: QString::from(""), - font: QString::from(""), - font_size: 50, - image_count: 0, - video_start_time: 0.0, - video_end_time: 0.0, - } - } - } - - impl qobject::SlideObject { #[qinvokable] - pub fn change_slide( - mut self: Pin<&mut Self>, + fn change_slide( + self: Pin<&mut SlideObject>, item: QMap_QString_QVariant, index: i32, - ) { - let current_index = self.as_ref().get_ref().slide_index(); - let icount_variant = item - .get(&QString::from("imageCount")) - .unwrap_or(QVariant::from(&1)); - let count = - icount_variant.value::().unwrap_or_default(); - - let slindex = item - .get(&QString::from("slideIndex")) - .unwrap_or(QVariant::from(&0)); - let slide_index = - slindex.value::().unwrap_or_default(); - - let html = item - .get(&QString::from("html")) - .unwrap_or(QVariant::from(&false)); - if let Some(html) = html.value::() { - if html { - debug!(?html, count, slide_index); - if slide_index > 0 && slide_index < count - 1 { - if current_index < &index { - self.as_mut().emit(Signals::RevealNext); - debug!(signal = ?Signals::RevealNext); - return; - } else if slide_index > 0 { - self.as_mut().emit(Signals::RevealPrev); - debug!(signal = ?Signals::RevealPrev); - return; - } - } - } - } - - println!("## Slide Details ##"); - let text = item - .get(&QString::from("text")) - .unwrap_or(QVariant::from(&QString::from(""))); - if let Some(txt) = text.value::() { - if &txt != self.as_ref().text() { - println!("text: {txt}"); - self.as_mut().set_text(txt); - }; - } else { - println!("text: empty"); - } - let audio = item - .get(&QString::from("audio")) - .unwrap_or(QVariant::from(&QString::from(""))); - if let Some(audio) = audio.value::() { - if &audio != self.as_ref().audio() { - println!("audio: {audio}"); - self.as_mut().set_audio(audio); - } - } else { - println!("audio: empty"); - } - let ty = item - .get(&QString::from("type")) - .unwrap_or(QVariant::from(&QString::from(""))); - if let Some(ty) = ty.value::() { - if &ty != self.as_ref().ty() { - println!("type: {ty}"); - self.as_mut().set_ty(ty); - } - } else { - println!("type: empty"); - } - - let image_background = item - .get(&QString::from("imageBackground")) - .unwrap_or(QVariant::from(&QString::from(""))); - if let Some(image_background) = - image_background.value::() - { - if &image_background - != self.as_ref().image_background() - { - println!("image-bg: {image_background}"); - self.as_mut() - .set_image_background(image_background); - } - } else { - println!("image-bg: empty"); - } - let video_background = item - .get(&QString::from("videoBackground")) - .unwrap_or(QVariant::from(&QString::from(""))); - if let Some(video_background) = - video_background.value::() - { - if &video_background - != self.as_ref().video_background() - { - println!("video-bg: {video_background}"); - self.as_mut() - .set_video_background(video_background); - } - } else { - println!("video-bg: empty"); - } - let font = item.get(&QString::from("font")).unwrap_or( - QVariant::from(&QString::from("Quicksand")), - ); - if let Some(font) = font.value::() { - if &font != self.as_ref().font() { - println!("font: {font}"); - self.as_mut().set_font(font); - } - } else { - println!("font: empty"); - } - let vtext_alignment = item - .get(&QString::from("verticalTextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))); - if let Some(vtext_alignment) = - vtext_alignment.value::() - { - if &vtext_alignment != self.as_ref().vtext_alignment() - { - println!( - "vertical-text-align: {vtext_alignment}" - ); - self.as_mut() - .set_vtext_alignment(vtext_alignment); - } - } else { - println!("vertical-text-align: empty"); - } - let htext_alignment = item - .get(&QString::from("horizontalTextAlignment")) - .unwrap_or(QVariant::from(&QString::from("center"))); - if let Some(htext_alignment) = - htext_alignment.value::() - { - if &htext_alignment != self.as_ref().htext_alignment() - { - println!( - "horizontal-text-align: {htext_alignment}" - ); - self.as_mut() - .set_htext_alignment(htext_alignment); - } - } else { - println!("horizontal-text-align: empty"); - } - let font_size = item - .get(&QString::from("fontSize")) - .unwrap_or(QVariant::from(&50)); - if let Some(font_size) = font_size.value::() { - if &font_size != self.as_ref().font_size() { - println!("font-size: {font_size}"); - self.as_mut().set_font_size(font_size); - } - } else { - println!("font-size: empty"); - } - let looping = item - .get(&QString::from("looping")) - .unwrap_or(QVariant::from(&false)); - if let Some(looping) = looping.value::() { - if &looping != self.as_ref().looping() { - println!("looping: {looping}"); - self.as_mut().set_looping(looping); - let lp = looping; - self.as_mut() - .emit(Signals::LoopChanged { looping: &lp }); - } - } else { - println!("looping: empty") - } - let slide_size = item - .get(&QString::from("slide_size")) - .unwrap_or(QVariant::from(&1)); - if let Some(slide_size) = slide_size.value::() { - if &slide_size != self.as_ref().slide_size() { - println!("slide-size: {slide_size}"); - self.as_mut().set_slide_size(slide_size); - } - } - let video_start_time = item - .get(&QString::from("videoStartTime")) - .unwrap_or(QVariant::from(&0.0)); - if let Some(int) = video_start_time.value::() { - self.as_mut().set_video_start_time(int) - } - - self.as_mut().set_image_count(count); - - self.as_mut().set_slide_index(slide_index); - - self.as_mut() - .emit(Signals::SlideChanged { slide: &index }); - println!("## Slide End ##"); - } - + ); #[qinvokable] - pub fn next( - mut self: Pin<&mut Self>, + fn next( + self: Pin<&mut SlideObject>, next_item: QMap_QString_QVariant, - ) -> bool { - let new_id = self.as_ref().slide_index() + 1; - self.as_mut().change_slide(next_item, new_id); - true - } + ) -> bool; #[qinvokable] - pub fn previous( - mut self: Pin<&mut Self>, - prev_item: QMap_QString_QVariant, - ) -> bool { - let new_id = self.as_ref().slide_index() - 1; - self.as_mut().change_slide(prev_item, new_id); - true - } + fn previous( + self: Pin<&mut SlideObject>, + next_item: QMap_QString_QVariant, + ) -> bool; #[qinvokable] - pub fn play(mut self: Pin<&mut Self>) -> bool { - self.as_mut().set_is_playing(true); - self.as_mut().emit_playing_changed(&true); - true - } + pub fn play(self: Pin<&mut SlideObject>) -> bool; #[qinvokable] - pub fn pause(mut self: Pin<&mut Self>) -> bool { - self.as_mut().set_is_playing(false); - self.as_mut().emit_playing_changed(&false); - false - } + pub fn pause(self: Pin<&mut SlideObject>) -> bool; #[qinvokable] - pub fn play_pause(mut self: Pin<&mut Self>) -> bool { - let playing = self.as_ref().is_playing().clone(); - match playing { - true => self.as_mut().set_is_playing(false), - false => self.as_mut().set_is_playing(true), - } - self.as_mut().emit_playing_changed(&!playing); - !playing + pub fn play_pause(self: Pin<&mut SlideObject>) -> bool; + } +} + +use tracing::debug; + +#[derive(Clone, Debug)] +pub struct SlideObjectRust { + slide_index: i32, + slide_size: i32, + image_count: i32, + is_playing: bool, + looping: bool, + text: QString, + ty: QString, + audio: QString, + image_background: QString, + video_background: QString, + html: QString, + vtext_alignment: QString, + htext_alignment: QString, + font: QString, + font_size: i32, + video_start_time: f32, + video_end_time: f32, +} + +impl Default for SlideObjectRust { + fn default() -> Self { + Self { + slide_index: 0, + slide_size: 0, + is_playing: false, + looping: false, + text: QString::from(""), + ty: QString::from(""), + audio: QString::from(""), + image_background: QString::from(""), + html: QString::from(""), + video_background: QString::from(""), + vtext_alignment: QString::from(""), + htext_alignment: QString::from(""), + font: QString::from(""), + font_size: 50, + image_count: 0, + video_start_time: 0.0, + video_end_time: 0.0, } } } + +impl qobject::SlideObject { + pub fn change_slide( + mut self: Pin<&mut Self>, + item: QMap_QString_QVariant, + index: i32, + ) { + let current_index = self.as_ref().get_ref().slide_index(); + let icount_variant = item + .get(&QString::from("imageCount")) + .unwrap_or(QVariant::from(&1)); + let count = icount_variant.value::().unwrap_or_default(); + + let slindex = item + .get(&QString::from("slideIndex")) + .unwrap_or(QVariant::from(&0)); + let slide_index = slindex.value::().unwrap_or_default(); + + let html = item + .get(&QString::from("html")) + .unwrap_or(QVariant::from(&false)); + if let Some(html) = html.value::() { + if html { + debug!(?html, count, slide_index); + if slide_index > 0 && slide_index < count - 1 { + if current_index < &index { + self.as_mut().emit(Signals::RevealNext); + debug!(signal = ?Signals::RevealNext); + return; + } else if slide_index > 0 { + self.as_mut().emit(Signals::RevealPrev); + debug!(signal = ?Signals::RevealPrev); + return; + } + } + } + } + + println!("## Slide Details ##"); + let text = item + .get(&QString::from("text")) + .unwrap_or(QVariant::from(&QString::from(""))); + if let Some(txt) = text.value::() { + if &txt != self.as_ref().text() { + println!("text: {txt}"); + self.as_mut().set_text(txt); + }; + } else { + println!("text: empty"); + } + let audio = item + .get(&QString::from("audio")) + .unwrap_or(QVariant::from(&QString::from(""))); + if let Some(audio) = audio.value::() { + if &audio != self.as_ref().audio() { + println!("audio: {audio}"); + self.as_mut().set_audio(audio); + } + } else { + println!("audio: empty"); + } + let ty = item + .get(&QString::from("type")) + .unwrap_or(QVariant::from(&QString::from(""))); + if let Some(ty) = ty.value::() { + if &ty != self.as_ref().ty() { + println!("type: {ty}"); + self.as_mut().set_ty(ty); + } + } else { + println!("type: empty"); + } + + let image_background = item + .get(&QString::from("imageBackground")) + .unwrap_or(QVariant::from(&QString::from(""))); + if let Some(image_background) = + image_background.value::() + { + if &image_background != self.as_ref().image_background() { + println!("image-bg: {image_background}"); + self.as_mut().set_image_background(image_background); + } + } else { + println!("image-bg: empty"); + } + let video_background = item + .get(&QString::from("videoBackground")) + .unwrap_or(QVariant::from(&QString::from(""))); + if let Some(video_background) = + video_background.value::() + { + if &video_background != self.as_ref().video_background() { + println!("video-bg: {video_background}"); + self.as_mut().set_video_background(video_background); + } + } else { + println!("video-bg: empty"); + } + let font = item + .get(&QString::from("font")) + .unwrap_or(QVariant::from(&QString::from("Quicksand"))); + if let Some(font) = font.value::() { + if &font != self.as_ref().font() { + println!("font: {font}"); + self.as_mut().set_font(font); + } + } else { + println!("font: empty"); + } + let vtext_alignment = item + .get(&QString::from("verticalTextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))); + if let Some(vtext_alignment) = + vtext_alignment.value::() + { + if &vtext_alignment != self.as_ref().vtext_alignment() { + println!("vertical-text-align: {vtext_alignment}"); + self.as_mut().set_vtext_alignment(vtext_alignment); + } + } else { + println!("vertical-text-align: empty"); + } + let htext_alignment = item + .get(&QString::from("horizontalTextAlignment")) + .unwrap_or(QVariant::from(&QString::from("center"))); + if let Some(htext_alignment) = + htext_alignment.value::() + { + if &htext_alignment != self.as_ref().htext_alignment() { + println!("horizontal-text-align: {htext_alignment}"); + self.as_mut().set_htext_alignment(htext_alignment); + } + } else { + println!("horizontal-text-align: empty"); + } + let font_size = item + .get(&QString::from("fontSize")) + .unwrap_or(QVariant::from(&50)); + if let Some(font_size) = font_size.value::() { + if &font_size != self.as_ref().font_size() { + println!("font-size: {font_size}"); + self.as_mut().set_font_size(font_size); + } + } else { + println!("font-size: empty"); + } + let looping = item + .get(&QString::from("looping")) + .unwrap_or(QVariant::from(&false)); + if let Some(looping) = looping.value::() { + if &looping != self.as_ref().looping() { + println!("looping: {looping}"); + self.as_mut().set_looping(looping); + let lp = looping; + self.as_mut() + .emit(Signals::LoopChanged { looping: &lp }); + } + } else { + println!("looping: empty") + } + let slide_size = item + .get(&QString::from("slide_size")) + .unwrap_or(QVariant::from(&1)); + if let Some(slide_size) = slide_size.value::() { + if &slide_size != self.as_ref().slide_size() { + println!("slide-size: {slide_size}"); + self.as_mut().set_slide_size(slide_size); + } + } + let video_start_time = item + .get(&QString::from("videoStartTime")) + .unwrap_or(QVariant::from(&0.0)); + if let Some(int) = video_start_time.value::() { + self.as_mut().set_video_start_time(int) + } + + self.as_mut().set_image_count(count); + + self.as_mut().set_slide_index(slide_index); + + self.as_mut().emit(Signals::SlideChanged { slide: &index }); + println!("## Slide End ##"); + } + + pub fn next( + mut self: Pin<&mut Self>, + next_item: QMap_QString_QVariant, + ) -> bool { + let new_id = self.as_ref().slide_index() + 1; + self.as_mut().change_slide(next_item, new_id); + true + } + pub fn previous( + mut self: Pin<&mut Self>, + prev_item: QMap_QString_QVariant, + ) -> bool { + let new_id = self.as_ref().slide_index() - 1; + self.as_mut().change_slide(prev_item, new_id); + true + } + pub fn play(mut self: Pin<&mut Self>) -> bool { + self.as_mut().set_is_playing(true); + self.as_mut().emit_playing_changed(&true); + true + } + pub fn pause(mut self: Pin<&mut Self>) -> bool { + self.as_mut().set_is_playing(false); + self.as_mut().emit_playing_changed(&false); + false + } + pub fn play_pause(mut self: Pin<&mut Self>) -> bool { + let playing = self.as_ref().is_playing().clone(); + match playing { + true => self.as_mut().set_is_playing(false), + false => self.as_mut().set_is_playing(true), + } + self.as_mut().emit_playing_changed(&!playing); + !playing + } +}