From 741fde42d6cd6a2f4a48446b43612e67a942c2be Mon Sep 17 00:00:00 2001 From: Surferlul Date: Fri, 29 Jul 2022 06:22:25 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + Cargo.toml | 13 ++++ native-ui-gnome.iml | 12 ++++ src/lib.rs | 161 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 Cargo.toml create mode 100644 native-ui-gnome.iml create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore index 088ba6b..cbed4d7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk + +.idea/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4a1f3f7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "native-ui-gnome" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +native-ui-rs = { git = "https://github.com/Surferlul/native-ui-rs" } + +[dependencies.adw] +package = "libadwaita" +version = "0.1.1" diff --git a/native-ui-gnome.iml b/native-ui-gnome.iml new file mode 100644 index 0000000..2fecef3 --- /dev/null +++ b/native-ui-gnome.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..f00c659 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,161 @@ +#![feature(type_alias_impl_trait)] +#![feature(type_ascription)] + +use adw::prelude::*; + +use adw::{ActionRow, Application, ApplicationWindow, HeaderBar}; +use adw::builders; +use adw::builders::ApplicationWindowBuilder; +use adw::gtk::{Box, ListBox, /*Native,*/ Orientation, SelectionMode}; + +pub use native_ui_rs::abstracts; +//use native_ui_rs::abstracts::ApplicationBuilder; + +enum NativeWidgetBuilder { + Window(builders::ApplicationWindowBuilder), +} + +impl Into for NativeWidgetBuilder { + fn into(self) -> ApplicationWindowBuilder { + match self { + NativeWidgetBuilder::Window(window) => window, + _ => panic!("Wrong NativeWidgetBuilder type"), + } + } +} + +//enum NativeWidget { +// Window(ApplicationWindow) +//} + +trait BuildWidget { + type Widget: IsA; + fn build(self) -> Self::Widget; +} + +trait NativeWidgetBuild { + // creates NativeWidgetBuilder from abstracts::Widget + // fills in an many fields as possible + // returns NativeWidgetBuilder + fn native_builder(&self) -> NativeWidgetBuilder; +} + +impl NativeWidgetBuild for abstracts::Window { + fn native_builder(&self) -> NativeWidgetBuilder { + let mut builder = ApplicationWindow::builder() + .title(self.title.as_str()) + .default_width(self.width as i32) + .default_height(self.height as i32); + builder = match self.content.clone() { + Some(widget) => builder.content( + &widget.native_builder().build() + ), + None => builder, + }; + NativeWidgetBuilder::Window(builder) + } +} + +impl NativeWidgetBuild for abstracts::Widget { + #[allow(unconditional_recursion)] + fn native_builder(&self) -> NativeWidgetBuilder { + match self.clone() { + abstracts::Widget::Window(window) => { + window.content.unwrap().native_builder() + }, + #[allow(unreachable_patterns)] + _ => panic!("Widget doesn't implement builder to native yet {:#?}", self) + } + } +} + +impl BuildWidget for NativeWidgetBuilder { + type Widget = impl IsA; + fn build(self) -> Self::Widget { + match self { + NativeWidgetBuilder::Window(window) => window.build(), + #[allow(unreachable_patterns)] + _ => panic!("Native Widget build not implemented yet") + } + } +} + +pub struct NativeApplication { + abst: abstracts::Application +} + +impl NativeApplication { + pub fn new(abst: abstracts::Application) -> NativeApplication { + NativeApplication { + abst + } + } + + pub fn run(&mut self) { + let application: Application = Application::builder() + .application_id("com.example.FirstAdwaitaApp") + .build(); + + let abst = self.abst.clone(); + + application.connect_activate(move |app| activate_application(app, &abst)); + + application.run(); + } + +} + +fn activate_application(app: &Application, abst: &abstracts::Application) { + // ActionRows are only available in Adwaita + let row = ActionRow::builder() + .activatable(true) + .title("Click me") + .build(); + row.connect_activated(|_| { + eprintln!("Clicked!"); + }); + + let list = ListBox::builder() + .margin_top(32) + .margin_end(32) + .margin_bottom(32) + .margin_start(32) + .selection_mode(SelectionMode::None) + // makes the list look nicer + .css_classes(vec![String::from("boxed-list")]) + .build(); + list.append(&row); + + // Combine the content in a box + let content = Box::new(Orientation::Vertical, 0); + // Adwaitas' ApplicationWindow does not include a HeaderBar + content.append(&HeaderBar::new()); + content.append(&list); + + let mut application_windows = Vec::new(); + for window in &abst.main_windows { + let app_window = (window + .native_builder() + .into(): ApplicationWindowBuilder) + .application(app) + .content(&content) + .build(); + app_window.show(); + application_windows.push(app_window); + } +} + +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +}