[niepce] npc-fwk: rgbcolour bindings with Rust



commit b79e1fb09780606ce83356ae1f6574dd9cd51415
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Oct 15 19:38:18 2022 -0400

    npc-fwk: rgbcolour bindings with Rust
    
    - start cxx bindings in npc-eng

 .gitignore                                    |  6 ++-
 Cargo.lock                                    |  1 +
 crates/npc-engine/Cargo.toml                  |  1 +
 crates/npc-engine/build.rs                    |  1 +
 crates/npc-engine/src/db/label.rs             | 41 ++-----------------
 crates/npc-engine/src/lib.rs                  | 21 ++++++++++
 crates/npc-engine/src/library/notification.rs |  6 ++-
 crates/npc-fwk/src/base/rgbcolour.rs          | 58 ++++++++-------------------
 crates/npc-fwk/src/lib.rs                     | 24 +++++++++++
 src/engine/Makefile.am                        |  3 +-
 src/engine/db/label.cpp                       | 35 ----------------
 src/engine/db/label.hpp                       |  8 +---
 src/engine/db/libfile.hpp                     |  2 +-
 src/fwk/Makefile.am                           | 22 +++++++++-
 src/fwk/base/Makefile.am                      |  2 +-
 src/fwk/base/colour.cpp                       | 56 --------------------------
 src/fwk/base/colour.hpp                       | 37 -----------------
 src/fwk/toolkit/Makefile.am                   |  2 +
 src/fwk/toolkit/gdkutils.cpp                  | 13 ++----
 src/fwk/toolkit/gdkutils.hpp                  | 12 ++----
 src/libraryclient/uidataprovider.cpp          | 27 ++++++-------
 src/libraryclient/uidataprovider.hpp          | 13 +++---
 src/niepce/ui/dialogs/editlabels.cpp          | 16 +++-----
 src/niepce/ui/gridviewmodule.cpp              | 21 ++++++----
 src/niepce/ui/gridviewmodule.hpp              |  6 ++-
 src/niepce/ui/niepcewindow.cpp                |  4 +-
 src/rust_bindings.hpp                         |  8 +++-
 27 files changed, 164 insertions(+), 282 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 941714c5..44aace74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,8 +91,12 @@ m4/xsize.m4
 /src/fwk/utils/testufrawmeta
 /src/fwk/utils/testxmp
 /src/fwk/toolkit/testconfigdatabinder
+/src/fwk/cxx_colour_bindings.cpp
+/src/fwk/cxx_colour_bindings.hpp
 /src/fwk/cxx_fwk_bindings.cpp
 /src/fwk/cxx_fwk_bindings.hpp
+/src/fwk/cxx_eng_bindings.cpp
+/src/fwk/cxx_eng_bindings.hpp
 /src/libraryclient/test_worker
 /src/engine/test_library
 /src/engine/test_filebundle
@@ -119,4 +123,4 @@ target/
 **/*.rs.bk
 crates/npc-*/Cargo.lock
 __bindgen.cpp
-__bindgen.ii
\ No newline at end of file
+__bindgen.ii
diff --git a/Cargo.lock b/Cargo.lock
index 41782ec3..7d6be421 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -773,6 +773,7 @@ dependencies = [
  "async-channel",
  "cbindgen",
  "chrono",
+ "cxx",
  "exempi",
  "gdk-pixbuf",
  "gdk-pixbuf-sys",
diff --git a/crates/npc-engine/Cargo.toml b/crates/npc-engine/Cargo.toml
index 527d9f2c..2d85fae4 100644
--- a/crates/npc-engine/Cargo.toml
+++ b/crates/npc-engine/Cargo.toml
@@ -10,6 +10,7 @@ build = "build.rs"
 [dependencies]
 async-channel = "1.6.1"
 chrono = "0.4.0"
+cxx = "1.0"
 exempi = { version = "2.6.0", git = "https://github.com/hfiguiere/exempi-rs.git";, rev="99e8ba5" }
 gdk-pixbuf-sys = "*"
 gdk-pixbuf = "*"
diff --git a/crates/npc-engine/build.rs b/crates/npc-engine/build.rs
index 0312e66a..cfa33519 100644
--- a/crates/npc-engine/build.rs
+++ b/crates/npc-engine/build.rs
@@ -29,6 +29,7 @@ fn main() {
             .exclude_item("GtkToolbar")
             .exclude_item("GFileInfo")
             .exclude_item("RgbColour")
+            .exclude_item("Label")
             // Ensure these are opaque as generics are still a problem.
             .exclude_item("NiepcePropertySet")
             .exclude_item("NiepcePropertyBag")
diff --git a/crates/npc-engine/src/db/label.rs b/crates/npc-engine/src/db/label.rs
index b29db23d..b7e17da5 100644
--- a/crates/npc-engine/src/db/label.rs
+++ b/crates/npc-engine/src/db/label.rs
@@ -17,8 +17,6 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-use libc::c_char;
-use std::ffi::CString;
 use std::str::FromStr;
 
 use super::FromDb;
@@ -29,7 +27,6 @@ use npc_fwk::base::rgbcolour::RgbColour;
 pub struct Label {
     id: LibraryId,
     label: String,
-    pub cstr: CString,
     colour: RgbColour,
 }
 
@@ -39,7 +36,6 @@ impl Label {
         Label {
             id,
             label: String::from(label),
-            cstr: CString::new("").unwrap(),
             colour,
         }
     }
@@ -63,6 +59,10 @@ impl Label {
     pub fn set_colour(&mut self, c: &RgbColour) {
         self.colour = c.clone();
     }
+
+    pub fn clone_boxed(l: &Label) -> Box<Label> {
+        Box::new(l.clone())
+    }
 }
 
 impl FromDb for Label {
@@ -84,36 +84,3 @@ impl FromDb for Label {
         Ok(Label::new(row.get(0)?, &label, &colour))
     }
 }
-
-/// # Safety
-/// Dereference raw pointer.
-#[no_mangle]
-pub unsafe extern "C" fn engine_db_label_delete(l: *mut Label) {
-    drop(Box::from_raw(l));
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_label_clone(l: &Label) -> *mut Label {
-    Box::into_raw(Box::new(l.clone()))
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_label_id(l: &Label) -> LibraryId {
-    l.id()
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_label_label(obj: &mut Label) -> *const c_char {
-    let cstr;
-    {
-        let s = obj.label();
-        cstr = CString::new(s).unwrap();
-    }
-    obj.cstr = cstr;
-    obj.cstr.as_ptr()
-}
-
-#[no_mangle]
-pub extern "C" fn engine_db_label_colour(l: &Label) -> *const RgbColour {
-    l.colour()
-}
diff --git a/crates/npc-engine/src/lib.rs b/crates/npc-engine/src/lib.rs
index ece79e10..a84e705f 100644
--- a/crates/npc-engine/src/lib.rs
+++ b/crates/npc-engine/src/lib.rs
@@ -103,3 +103,24 @@ pub extern "C" fn eng_property_bag_set_value(
 ) -> bool {
     b.set_value(key.into(), v.clone())
 }
+
+use crate::db::Label;
+
+#[cxx::bridge(namespace = "eng")]
+mod ffi {
+    #[namespace = "fwk"]
+    extern "C++" {
+        include!("fwk/cxx_colour_bindings.hpp");
+
+        type RgbColour = npc_fwk::base::rgbcolour::RgbColour;
+    }
+
+    extern "Rust" {
+        type Label;
+
+        fn colour(&self) -> &RgbColour;
+        fn label(&self) -> &str;
+        fn id(&self) -> i64;
+        fn clone_boxed(&self) -> Box<Label>;
+    }
+}
diff --git a/crates/npc-engine/src/library/notification.rs b/crates/npc-engine/src/library/notification.rs
index 8e81ea28..b5da0837 100644
--- a/crates/npc-engine/src/library/notification.rs
+++ b/crates/npc-engine/src/library/notification.rs
@@ -216,15 +216,17 @@ pub unsafe extern "C" fn engine_library_notification_get_id(
     }
 }
 
+/// ffi: box the returned label pointer
+///
 /// # Safety
 /// Dereference a pointer.
 #[no_mangle]
 pub unsafe extern "C" fn engine_library_notification_get_label(
     n: *const LibNotification,
-) -> *const Label {
+) -> *mut Label {
     match n.as_ref() {
         Some(&LibNotification::AddedLabel(ref l)) | Some(&LibNotification::LabelChanged(ref l)) => {
-            l
+            Box::into_raw(Box::new(l.clone()))
         }
         _ => unreachable!(),
     }
diff --git a/crates/npc-fwk/src/base/rgbcolour.rs b/crates/npc-fwk/src/base/rgbcolour.rs
index c4fe8052..42bae2e3 100644
--- a/crates/npc-fwk/src/base/rgbcolour.rs
+++ b/crates/npc-fwk/src/base/rgbcolour.rs
@@ -17,19 +17,27 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-use libc::c_char;
-use std::ffi::CString;
 use std::num::ParseIntError;
 use std::str::FromStr;
 
-#[repr(C)]
-#[derive(Clone, Default)]
-pub struct RgbColour {
-    pub r: u16,
-    pub g: u16,
-    pub b: u16,
+#[cxx::bridge(namespace = "fwk")]
+mod ffi {
+    #[derive(Clone, Default)]
+    pub struct RgbColour {
+        pub r: u16,
+        pub g: u16,
+        pub b: u16,
+    }
+
+    extern "Rust" {
+        fn to_string(self: &RgbColour) -> String;
+    }
+
+    impl Box<RgbColour> {}
 }
 
+pub use ffi::RgbColour;
+
 #[derive(Debug)]
 pub enum ColourParseError {
     /// No Error.
@@ -83,37 +91,3 @@ impl From<RgbColour> for gdk4::RGBA {
         )
     }
 }
-
-#[no_mangle]
-pub extern "C" fn fwk_rgbcolour_to_string(c: &RgbColour) -> *mut c_char {
-    CString::new(c.to_string().as_bytes()).unwrap().into_raw()
-}
-
-/// Delete the %RgbColour object
-///
-/// # Safety
-/// Dereference the pointer.
-#[no_mangle]
-pub unsafe extern "C" fn fwk_rgbcolour_delete(c: *mut RgbColour) {
-    drop(Box::from_raw(c));
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_rgbcolour_component(c: &RgbColour, idx: i32) -> u16 {
-    match idx {
-        0 => c.r,
-        1 => c.g,
-        2 => c.b,
-        _ => unreachable!(),
-    }
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_rgbcolour_new(r: u16, g: u16, b: u16) -> *mut RgbColour {
-    Box::into_raw(Box::new(RgbColour::new(r, g, b)))
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_rgbcolour_clone(c: &RgbColour) -> *mut RgbColour {
-    Box::into_raw(Box::new(c.clone()))
-}
diff --git a/crates/npc-fwk/src/lib.rs b/crates/npc-fwk/src/lib.rs
index 9f8d0ada..ee142a67 100644
--- a/crates/npc-fwk/src/lib.rs
+++ b/crates/npc-fwk/src/lib.rs
@@ -51,6 +51,7 @@ use std::ffi::c_char;
 use gdk_pixbuf_sys::GdkPixbuf;
 use glib::translate::*;
 
+use self::base::rgbcolour::RgbColour;
 use crate::base::date::Date;
 use crate::toolkit::thumbnail::Thumbnail;
 use crate::toolkit::Configuration;
@@ -72,6 +73,15 @@ fn exempi_manager_new() -> Box<ExempiManager> {
     Box::new(ExempiManager::new(None))
 }
 
+fn rgbcolour_new(r: u16, g: u16, b: u16) -> Box<RgbColour> {
+    Box::new(RgbColour::new(r, g, b))
+}
+
+fn rgbcolour_to_string(r: u16, g: u16, b: u16) -> String {
+    let colour = RgbColour::new(r, g, b);
+    colour.to_string()
+}
+
 pub fn gps_coord_from_xmp_(value: &str) -> f64 {
     gps_coord_from_xmp(value).unwrap_or(f64::NAN)
 }
@@ -158,6 +168,20 @@ mod ffi {
         fn exempi_manager_new() -> Box<ExempiManager>;
     }
 
+    extern "C++" {
+        include!("fwk/cxx_colour_bindings.hpp");
+
+        type RgbColour = crate::base::rgbcolour::RgbColour;
+    }
+
+    extern "Rust" {
+        #[cxx_name = "RgbColour_new"]
+        fn rgbcolour_new(r: u16, g: u16, b: u16) -> Box<RgbColour>;
+
+        fn rgbcolour_to_string(r: u16, g: u16, b: u16) -> String;
+    }
+
+    #[namespace = "fwk"]
     extern "Rust" {
         #[cxx_name = "gps_coord_from_xmp"]
         fn gps_coord_from_xmp_(value: &str) -> f64;
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
index 5a7abe2f..4c6baa9c 100644
--- a/src/engine/Makefile.am
+++ b/src/engine/Makefile.am
@@ -20,7 +20,7 @@ noinst_LIBRARIES = libniepceengine.a
 
 libniepceengine_a_SOURCES = \
        db/libfile.hpp db/libfile.cpp \
-       db/label.hpp db/label.cpp \
+       db/label.hpp \
        db/libmetadata.hpp db/libmetadata.cpp \
        db/storage.hpp \
        db/fsfile.hpp \
@@ -37,3 +37,4 @@ libniepceengine_a_SOURCES = \
        importer/importedfile.hpp \
        importer/importedfile.cpp \
        $(NULL)
+
diff --git a/src/engine/db/label.hpp b/src/engine/db/label.hpp
index 55b4593c..bf983ed9 100644
--- a/src/engine/db/label.hpp
+++ b/src/engine/db/label.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - engine/db/label.hpp
  *
- * Copyright (C) 2009-2021 Hubert Figuière
+ * Copyright (C) 2009-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,19 +20,13 @@
 #pragma once
 
 #include <memory>
-#include <string>
 #include <vector>
 
 #include "rust_bindings.hpp"
 
 namespace eng {
-
-typedef std::shared_ptr<Label> LabelPtr;
 typedef std::vector<LabelPtr> LabelList;
 typedef std::shared_ptr<LabelList> LabelListPtr;
-
-LabelPtr label_wrap(Label*);
-LabelPtr label_clone(const Label*);
 }
 
 /*
diff --git a/src/engine/db/libfile.hpp b/src/engine/db/libfile.hpp
index eb33dd46..452ea447 100644
--- a/src/engine/db/libfile.hpp
+++ b/src/engine/db/libfile.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - eng/db/libfile.hpp
  *
- * Copyright (C) 2007-2021 Hubert Figuière
+ * Copyright (C) 2007-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fwk/Makefile.am b/src/fwk/Makefile.am
index 86472adc..48f729b8 100644
--- a/src/fwk/Makefile.am
+++ b/src/fwk/Makefile.am
@@ -5,6 +5,14 @@ CARGO_TARGET_DIR=@abs_top_builddir@/target
 RUST_BIN_DIR=$(CARGO_TARGET_DIR)/bin
 RUST_CXXBRIDGE=$(RUST_BIN_DIR)/cxxbridge
 
+cxx_colour_bindings.cpp: $(top_srcdir)/crates/npc-fwk/src/base/rgbcolour.rs
+       @echo "Generating bindings $@..."
+       @$(RUST_CXXBRIDGE) $< > $@
+
+cxx_colour_bindings.hpp: $(top_srcdir)/crates/npc-fwk/src/base/rgbcolour.rs
+       @echo "Generating bindings header $@..."
+       @$(RUST_CXXBRIDGE) --header $< > $@
+
 cxx_fwk_bindings.cpp: $(top_srcdir)/crates/npc-fwk/src/lib.rs
        @echo "Generating bindings $@..."
        @$(RUST_CXXBRIDGE) $< > $@
@@ -13,8 +21,20 @@ cxx_fwk_bindings.hpp: $(top_srcdir)/crates/npc-fwk/src/lib.rs
        @echo "Generating bindings header $@..."
        @$(RUST_CXXBRIDGE) --header $< > $@
 
+cxx_eng_bindings.cpp: $(top_srcdir)/crates/npc-engine/src/lib.rs
+       @echo "Generating bindings $@..."
+       @$(RUST_CXXBRIDGE) $< > $@
+
+cxx_eng_bindings.hpp: $(top_srcdir)/crates/npc-engine/src/lib.rs
+       @echo "Generating bindings header $@..."
+       @$(RUST_CXXBRIDGE) --header $< > $@
+
 BUILT_SOURCES = \
+        cxx_colour_bindings.cpp \
+        cxx_colour_bindings.hpp \
         cxx_fwk_bindings.cpp \
-        cxx_fwk_bindings.hpp
+        cxx_fwk_bindings.hpp \
+        cxx_eng_bindings.cpp \
+        cxx_eng_bindings.hpp
 
 CLEANFILES = $(BUILD_SOURCES)
diff --git a/src/fwk/base/Makefile.am b/src/fwk/base/Makefile.am
index 2ab6e932..0a270d9e 100644
--- a/src/fwk/base/Makefile.am
+++ b/src/fwk/base/Makefile.am
@@ -35,7 +35,7 @@ testoption_SOURCES = t/testoption.cpp
 testoption_CPPFLAGS = $(testing_cppflags)
 testoption_LDADD = $(testing_ldadd)
 
-libfwkbase_a_SOURCES = colour.hpp colour.cpp \
+libfwkbase_a_SOURCES = \
        autoflag.hpp \
        debug.hpp debug.cpp \
        moniker.hpp moniker.cpp \
diff --git a/src/fwk/toolkit/Makefile.am b/src/fwk/toolkit/Makefile.am
index 0a4e7993..41ac621a 100644
--- a/src/fwk/toolkit/Makefile.am
+++ b/src/fwk/toolkit/Makefile.am
@@ -34,7 +34,9 @@ testconfigdatabinder_LDADD = $(testing_ldadd) \
        $(NULL)
 
 libniepceframework_a_SOURCES = \
+       ../cxx_colour_bindings.cpp \
        ../cxx_fwk_bindings.cpp \
+       ../cxx_eng_bindings.cpp \
        application.hpp application.cpp \
        appframe.hpp appframe.cpp \
        dialog.hpp dialog.cpp \
diff --git a/src/fwk/toolkit/gdkutils.cpp b/src/fwk/toolkit/gdkutils.cpp
index a931a54e..d4f47447 100644
--- a/src/fwk/toolkit/gdkutils.cpp
+++ b/src/fwk/toolkit/gdkutils.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - fwk/toolkit/gdkutils.cpp
  *
- * Copyright (C) 2008-2022 Hubert Figuiere
+ * Copyright (C) 2008-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,8 +20,6 @@
 #include "fwk/base/debug.hpp"
 #include "gdkutils.hpp"
 
-
-
 namespace fwk {
 
        Glib::RefPtr<Gdk::Pixbuf> gdkpixbuf_scale_to_fit(const Glib::RefPtr<Gdk::Pixbuf> & pix,
@@ -80,19 +78,16 @@ namespace fwk {
        }
 
 
-  Gdk::RGBA rgbcolour_to_gdkcolor(const fwk::RgbColour & colour)
+  Gdk::RGBA rgbcolour_to_gdkcolor(const fwk::RgbColour& colour)
   {
     Gdk::RGBA gdkcolour;
-    gdkcolour.set_rgba_u(fwk_rgbcolour_component(&colour, 0),
-                         fwk_rgbcolour_component(&colour, 1),
-                         fwk_rgbcolour_component(&colour, 2));
+    gdkcolour.set_rgba_u(colour.r, colour.g, colour.b);
     return gdkcolour;
   }
 
-
   fwk::RgbColourPtr gdkcolor_to_rgbcolour(const Gdk::RGBA & colour)
   {
-    return fwk::rgbcolour_new(colour.get_red_u(), colour.get_green_u(), colour.get_blue_u());
+    return fwk::RgbColour_new(colour.get_red_u(), colour.get_green_u(), colour.get_blue_u());
   }
 
 
diff --git a/src/fwk/toolkit/gdkutils.hpp b/src/fwk/toolkit/gdkutils.hpp
index a1b1f628..56d5f516 100644
--- a/src/fwk/toolkit/gdkutils.hpp
+++ b/src/fwk/toolkit/gdkutils.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - fwk/toolkit/gdkutils.hpp
  *
- * Copyright (C) 2008-2009, 2013 Hubert Figuiere
+ * Copyright (C) 2008-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,14 +17,12 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
-#ifndef __FWK_GDKUTILS_H__
-#define __FWK_GDKUTILS_H__
+#pragma once
 
 #include <gdkmm/pixbuf.h>
 #include <gdkmm/rgba.h>
 
-#include "fwk/base/colour.hpp"
+#include "rust_bindings.hpp"
 
 namespace fwk {
 
@@ -37,8 +35,6 @@ namespace fwk {
        Glib::RefPtr<Gdk::Pixbuf> gdkpixbuf_exif_rotate(const Glib::RefPtr<Gdk::Pixbuf> & pixbuf,
                                                                                                        int 
exif_orientation);
 
-  Gdk::RGBA rgbcolour_to_gdkcolor(const fwk::RgbColour & colour);
+  Gdk::RGBA rgbcolour_to_gdkcolor(const fwk::RgbColour& colour);
   fwk::RgbColourPtr gdkcolor_to_rgbcolour(const Gdk::RGBA & colour);
 }
-
-#endif
diff --git a/src/libraryclient/uidataprovider.cpp b/src/libraryclient/uidataprovider.cpp
index f6f3ce67..fff0b92d 100644
--- a/src/libraryclient/uidataprovider.cpp
+++ b/src/libraryclient/uidataprovider.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - libraryclient/uidataprovider.cpp
  *
- * Copyright (C) 2011-2017 Hubert Figuière
+ * Copyright (C) 2011-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,26 +20,24 @@
 #include <algorithm>
 
 #include "fwk/base/debug.hpp"
-#include "fwk/base/colour.hpp"
 #include "uidataprovider.hpp"
 
-
 namespace libraryclient {
 
-void UIDataProvider::updateLabel(const eng::Label & l)
+void UIDataProvider::updateLabel(const eng::LabelPtr& l)
 {
     // TODO: will work as long as we have 5 labels or something.
     for (auto & label : m_labels) {
-        if (engine_db_label_id(label.get()) == engine_db_label_id(&l)) {
-            label = eng::label_clone(&l);
+        if (label->id() == l->id()) {
+            label = l->clone_boxed();
         }
     }
 }
 
 
-void UIDataProvider::addLabel(const eng::Label & l)
+void UIDataProvider::addLabel(const eng::LabelPtr& l)
 {
-    m_labels.push_back(eng::label_clone(&l));
+    m_labels.push_back(l->clone_boxed());
 }
 
 
@@ -49,7 +47,7 @@ void UIDataProvider::deleteLabel(int id)
     for(auto iter = m_labels.begin();
         iter != m_labels.end(); ++iter) {
 
-        if (engine_db_label_id(iter->get()) == id) {
+        if ((*iter)->id() == id) {
             DBG_OUT("remove label %d", id);
             iter = m_labels.erase(iter);
             break;
@@ -57,15 +55,14 @@ void UIDataProvider::deleteLabel(int id)
     }
 }
 
-fwk::Option<fwk::RgbColour> UIDataProvider::colourForLabel(int32_t id) const
+std::optional<fwk::RgbColourPtr> UIDataProvider::colourForLabel(int32_t id) const
 {
-    for(auto label : m_labels) {
-        if (engine_db_label_id(label.get()) == id) {
-            return fwk::Option<fwk::RgbColour>(
-                *engine_db_label_colour(label.get()));
+    for(auto& label : m_labels) {
+        if (label->id() == id) {
+            return std::optional<fwk::RgbColourPtr>(label->colour());
         }
     }
-    return fwk::Option<fwk::RgbColour>();
+    return std::nullopt;
 }
 
 
diff --git a/src/libraryclient/uidataprovider.hpp b/src/libraryclient/uidataprovider.hpp
index ce3c9a34..d5567865 100644
--- a/src/libraryclient/uidataprovider.hpp
+++ b/src/libraryclient/uidataprovider.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - libraryclient/uidataprovider.hpp
  *
- * Copyright (C) 2011-2020 Hubert Figuière
+ * Copyright (C) 2011-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,11 +21,12 @@
 
 #include <stdint.h>
 #include <memory>
+#include <optional>
 
-#include "fwk/base/option.hpp"
-#include "fwk/base/colour.hpp"
 #include "engine/db/label.hpp"
 
+#include "rust_bindings.hpp"
+
 namespace libraryclient {
 
 class UIDataProvider
@@ -33,10 +34,10 @@ class UIDataProvider
 public:
     // label management
 
-    void updateLabel(const eng::Label &);
-    void addLabel(const eng::Label & l);
+    void updateLabel(const eng::LabelPtr&);
+    void addLabel(const eng::LabelPtr& l);
     void deleteLabel(int id);
-    fwk::Option<fwk::RgbColour> colourForLabel(int32_t id) const;
+    std::optional<fwk::RgbColourPtr> colourForLabel(int32_t id) const;
     const eng::LabelList & getLabels() const
         { return m_labels; }
 private:
diff --git a/src/niepce/ui/dialogs/editlabels.cpp b/src/niepce/ui/dialogs/editlabels.cpp
index 661a3665..784734ce 100644
--- a/src/niepce/ui/dialogs/editlabels.cpp
+++ b/src/niepce/ui/dialogs/editlabels.cpp
@@ -66,10 +66,9 @@ void EditLabels::setup_widget()
         m_entries[i] = labelentry = _builder->get_widget<Gtk::Entry>(str(boost::format(value_fmt) % (i+1)));
 
         if(has_label) {
-            Gdk::RGBA colour = fwk::rgbcolour_to_gdkcolor(
-                *engine_db_label_colour(m_labels[i].get()));
+            Gdk::RGBA colour = fwk::rgbcolour_to_gdkcolor(m_labels[i]->colour());
             colourbutton->set_rgba(colour);
-            labelentry->set_text(engine_db_label_label(m_labels[i].get()));
+            labelentry->set_text(std::string(m_labels[i]->label()));
         }
         colourbutton->signal_color_set().connect(
             sigc::bind(sigc::mem_fun(*this, &EditLabels::label_colour_changed), i));
@@ -105,19 +104,16 @@ void EditLabels::update_labels(int /*response*/)
             if(new_name.empty()) {
                 continue;
             }
-            std::string new_colour
-                = fwk::rgbcolour_to_string(
-                    fwk::gdkcolor_to_rgbcolour(m_colours[i]->get_rgba()).get());
+            std::string new_colour(fwk::gdkcolor_to_rgbcolour(m_colours[i]->get_rgba())->to_string());
             if(!undo) {
                 undo = fwk::Application::app()->begin_undo(_("Change Labels"));
             }
 
             auto libclient = m_lib_client;
             if(has_label) {
-                std::string current_name = engine_db_label_label(m_labels[i].get());
-                std::string current_colour =
-                    fwk::rgbcolour_to_string(engine_db_label_colour(m_labels[i].get()));
-                auto label_id = engine_db_label_id(m_labels[i].get());
+                std::string current_name(m_labels[i]->label());
+                std::string current_colour(m_labels[i]->colour().to_string());
+                auto label_id = m_labels[i]->id();
 
                 undo->new_command<void>(
                     [libclient, new_name, new_colour, label_id] () {
diff --git a/src/niepce/ui/gridviewmodule.cpp b/src/niepce/ui/gridviewmodule.cpp
index 041a26ef..1aef8204 100644
--- a/src/niepce/ui/gridviewmodule.cpp
+++ b/src/niepce/ui/gridviewmodule.cpp
@@ -93,22 +93,27 @@ bool GridViewModule::get_colour_callback_c(int32_t label, ffi::RgbColour* out,
     if (user_data == nullptr) {
         return false;
     }
-    return static_cast<const GridViewModule*>(user_data)->get_colour_callback(label, out);
+
+    std::optional<fwk::RgbColourPtr> colour =
+        static_cast<const GridViewModule*>(user_data)->get_colour_callback(label);
+
+    if (colour.has_value() && out) {
+        *out = *colour.value();
+        return true;
+    }
+
+    return false;
 }
 
-bool GridViewModule::get_colour_callback(int32_t label, ffi::RgbColour* out) const
+std::optional<fwk::RgbColourPtr> GridViewModule::get_colour_callback(int32_t label) const
 {
     libraryclient::UIDataProviderWeakPtr ui_data_provider(m_shell.get_ui_data_provider());
     auto provider = ui_data_provider.lock();
     DBG_ASSERT(static_cast<bool>(provider), "couldn't lock UI provider");
     if (provider) {
-        auto c = provider->colourForLabel(label);
-        if (c.ok() && out) {
-            *out = c.unwrap();
-            return true;
-        }
+        return provider->colourForLabel(label);
     }
-    return false;
+    return std::nullopt;
 }
 
 Gtk::Widget * GridViewModule::buildWidget()
diff --git a/src/niepce/ui/gridviewmodule.hpp b/src/niepce/ui/gridviewmodule.hpp
index 80391a8b..15203958 100644
--- a/src/niepce/ui/gridviewmodule.hpp
+++ b/src/niepce/ui/gridviewmodule.hpp
@@ -19,6 +19,8 @@
 
 #pragma once
 
+#include <optional>
+
 #include <gtkmm/gestureclick.h>
 #include <gtkmm/iconview.h>
 #include <gtkmm/liststore.h>
@@ -33,6 +35,8 @@
 #include "niepce/ui/metadatapanecontroller.hpp"
 #include "niepce/ui/selectioncontroller.hpp"
 
+#include "rust_bindings.hpp"
+
 namespace fwk {
 class Dock;
 }
@@ -76,7 +80,7 @@ protected:
 
 private:
   static bool get_colour_callback_c(int32_t label, ffi::RgbColour* out, const void* user_data);
-  bool get_colour_callback(int32_t label, ffi::RgbColour* out) const;
+  std::optional<fwk::RgbColourPtr> get_colour_callback(int32_t label) const;
   void on_metadata_changed(const fwk::PropertyBagPtr&, const fwk::PropertyBagPtr& old);
   static void on_rating_changed(GtkCellRenderer*, eng::library_id_t id, int rating,
                                 gpointer user_data);
diff --git a/src/niepce/ui/niepcewindow.cpp b/src/niepce/ui/niepcewindow.cpp
index eefb5cf9..e8604af1 100644
--- a/src/niepce/ui/niepcewindow.cpp
+++ b/src/niepce/ui/niepcewindow.cpp
@@ -298,7 +298,7 @@ void NiepceWindow::on_lib_notification(const eng::LibNotification& ln)
     {
         auto l = engine_library_notification_get_label(&ln);
         if (l) {
-            m_libClient->getDataProvider()->addLabel(*l);
+            m_libClient->getDataProvider()->addLabel(eng::LabelPtr::from_raw(l));
         } else {
             ERR_OUT("Invalid label (nullptr)");
         }
@@ -308,7 +308,7 @@ void NiepceWindow::on_lib_notification(const eng::LibNotification& ln)
     {
         auto l = engine_library_notification_get_label(&ln);
         if (l) {
-            m_libClient->getDataProvider()->updateLabel(*l);
+            m_libClient->getDataProvider()->updateLabel(eng::LabelPtr::from_raw(l));
         } else {
             ERR_OUT("Invalid label (nullptr)");
         }
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index f64d91f7..7b1562ef 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -24,6 +24,7 @@
 #include <gtk/gtk.h>
 
 #include "fwk/cxx_fwk_bindings.hpp"
+#include "fwk/cxx_eng_bindings.hpp"
 
 namespace ffi {
 class rust_str;
@@ -33,6 +34,8 @@ struct DateTime;
 typedef fwk::Date Date;
 typedef rust_str str;
 typedef fwk::FileList FileList;
+typedef fwk::RgbColour RgbColour;
+typedef eng::Label Label;
 struct NiepcePropertyBag;
 struct NiepcePropertySet;
 }
@@ -46,14 +49,16 @@ typedef std::shared_ptr<SharedConfiguration> ConfigurationPtr;
 typedef rust::Box<fwk::Date> DatePtr;
 typedef rust::Box<Thumbnail> ThumbnailPtr;
 typedef rust::Box<FileList> FileListPtr;
+typedef rust::Box<RgbColour> RgbColourPtr;
 
 typedef ffi::PropertyValue PropertyValue;
 typedef ffi::NiepcePropertyBag PropertyBag;
 typedef ffi::NiepcePropertySet PropertySet;
-typedef ffi::RgbColour RgbColour;
 }
 
 namespace eng {
+typedef rust::Box<Label> LabelPtr;
+
 typedef ffi::NiepcePropertyIdx Np;
 using NiepcePropertyIdx = ffi::NiepcePropertyIdx;
 typedef ffi::LibraryId library_id_t; // XXX change this to LibraryId
@@ -63,7 +68,6 @@ typedef ffi::Keyword Keyword;
 typedef ffi::LibFile LibFile;
 typedef ffi::LibFolder LibFolder;
 typedef ffi::LibMetadata LibMetadata;
-typedef ffi::Label Label;
 typedef ffi::Managed Managed;
 typedef ffi::LibNotification LibNotification;
 typedef ffi::NotificationType NotificationType;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]