.
This commit is contained in:
+10
-14
@@ -8,10 +8,7 @@ use iced::widget::button::Style;
|
||||
use iced::widget::grid::Sizing;
|
||||
use iced::widget::{button, center, column, combo_box, container, grid, mouse_area, opaque, pick_list, row, scrollable, space, stack, table, text, text_input, toggler};
|
||||
use iced::window::Settings;
|
||||
use iced::{Background, Color, Element, Length, Subscription, Task, color, window, keyboard};
|
||||
//use iced::advanced::Widget;
|
||||
use iced::keyboard::{Event, Key};
|
||||
use iced::keyboard::key::Named::Control;
|
||||
use iced::{Background, Color, Element, Length, Subscription, Task, color, window};
|
||||
use iced::widget::text::Wrapping;
|
||||
use ldp::middleware::BasicAuthMiddleware;
|
||||
use ldp::model::{KeyedDataset, QuadKey};
|
||||
@@ -28,7 +25,6 @@ use crate::widget::iri_input::iri_input;
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum Message {
|
||||
None,
|
||||
Foo(QuadKey),
|
||||
Traverse,
|
||||
IndexRdfSource(RdfSource<Dataset>),
|
||||
CommitIndex,
|
||||
@@ -554,7 +550,8 @@ impl Publisher {
|
||||
|
||||
let value = term
|
||||
.value_as_named_node()
|
||||
.map(|node| self.ontology.abbreviate(node))
|
||||
//.map(|node| self.ontology.abbreviate(node))
|
||||
.map(|node| node.as_str().to_string())
|
||||
.unwrap_or(term.value().to_string());
|
||||
|
||||
let value_alignment = term
|
||||
@@ -565,10 +562,10 @@ impl Publisher {
|
||||
})
|
||||
.unwrap_or(Horizontal::Left);
|
||||
|
||||
let value_input_base = text_input("Value", value.as_str())
|
||||
.align_x(value_alignment);
|
||||
/*let value_input_base = text_input("Value", value.as_str())
|
||||
.align_x(value_alignment);*/
|
||||
|
||||
let value_input = if !state.read_only {
|
||||
/*let value_input = if !state.read_only {
|
||||
let is_named_node = term.is_named_node();
|
||||
value_input_base.on_input(move |input| {
|
||||
let expanded_input = if is_named_node {
|
||||
@@ -584,12 +581,11 @@ impl Publisher {
|
||||
})
|
||||
} else {
|
||||
value_input_base
|
||||
};
|
||||
};*/
|
||||
|
||||
let foo = iri_input(value_input)
|
||||
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::Object(
|
||||
key,
|
||||
)));
|
||||
let foo = iri_input(self.ontology.prefixes(), "Object", value.as_str())
|
||||
.on_input(move |value| Message::ValueUpdated(key, value))
|
||||
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::Object(key)));
|
||||
|
||||
/*let search_launcher = if term.is_named_node() && !state.read_only {
|
||||
Some(container(
|
||||
|
||||
+39
-32
@@ -4,43 +4,46 @@ use oxigraph::io::{RdfFormat, RdfParser};
|
||||
use oxigraph::model::vocab::{rdf, rdfs, xsd};
|
||||
use oxigraph::model::{Dataset, GraphName, LiteralRef, NamedNode, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Quad, Term, TermRef, Triple, TripleRef};
|
||||
use oxigraph::sparql::{QueryResults, SparqlEvaluator};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::fmt::Display;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use oxigraph::store::Store;
|
||||
use crate::rdf::materialize;
|
||||
|
||||
const PREFIXES: &[(&str, &str)] = &[
|
||||
("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
|
||||
("rdfs", "http://www.w3.org/2000/01/rdf-schema#"),
|
||||
("owl", "http://www.w3.org/2002/07/owl#"),
|
||||
("xsd", "http://www.w3.org/2001/XMLSchema#"),
|
||||
("ldp", "http://www.w3.org/ns/ldp#"),
|
||||
("dc", "http://purl.org/dc/elements/1.1/"),
|
||||
("posix", "http://www.w3.org/ns/posix/stat#"),
|
||||
(
|
||||
"ebucore",
|
||||
"http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#",
|
||||
),
|
||||
("premis", "http://www.loc.gov/premis/rdf/v1#"),
|
||||
("premis3", "http://www.loc.gov/premis/rdf/v3/"),
|
||||
("dcterms", "http://purl.org/dc/terms/"),
|
||||
("fedora", "http://fedora.info/definitions/v4/repository#"),
|
||||
("rdaa", "http://rdaregistry.info/Elements/a/"),
|
||||
("rdaad", "http://rdaregistry.info/Elements/a/datatype/"),
|
||||
("rdac", "http://rdaregistry.info/Elements/c/"),
|
||||
("rdae", "http://rdaregistry.info/Elements/e/"),
|
||||
("rdai", "http://rdaregistry.info/Elements/i/"),
|
||||
("rdam", "http://rdaregistry.info/Elements/m/"),
|
||||
("rdan", "http://rdaregistry.info/Elements/n/"),
|
||||
("rdap", "http://rdaregistry.info/Elements/p/"),
|
||||
("rdat", "http://rdaregistry.info/Elements/t/"),
|
||||
("rdaw", "http://rdaregistry.info/Elements/w/"),
|
||||
("rdax", "http://rdaregistry.info/Elements/x/"),
|
||||
("schema", "https://schema.org/"),
|
||||
("quill", "http://fedora.quill.lan/rest/"),
|
||||
("gl", "https://graphofliberty.org/2026/04/ont/"),
|
||||
];
|
||||
static PREFIXES: LazyLock<BTreeMap<String, String>> = LazyLock::new(|| {
|
||||
BTreeMap::from_iter([
|
||||
("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
|
||||
("rdfs", "http://www.w3.org/2000/01/rdf-schema#"),
|
||||
("owl", "http://www.w3.org/2002/07/owl#"),
|
||||
("xsd", "http://www.w3.org/2001/XMLSchema#"),
|
||||
("ldp", "http://www.w3.org/ns/ldp#"),
|
||||
("dc", "http://purl.org/dc/elements/1.1/"),
|
||||
("posix", "http://www.w3.org/ns/posix/stat#"),
|
||||
(
|
||||
"ebucore",
|
||||
"http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#",
|
||||
),
|
||||
("premis", "http://www.loc.gov/premis/rdf/v1#"),
|
||||
("premis3", "http://www.loc.gov/premis/rdf/v3/"),
|
||||
("dcterms", "http://purl.org/dc/terms/"),
|
||||
("fedora", "http://fedora.info/definitions/v4/repository#"),
|
||||
("rdaa", "http://rdaregistry.info/Elements/a/"),
|
||||
("rdaad", "http://rdaregistry.info/Elements/a/datatype/"),
|
||||
("rdac", "http://rdaregistry.info/Elements/c/"),
|
||||
("rdae", "http://rdaregistry.info/Elements/e/"),
|
||||
("rdai", "http://rdaregistry.info/Elements/i/"),
|
||||
("rdam", "http://rdaregistry.info/Elements/m/"),
|
||||
("rdan", "http://rdaregistry.info/Elements/n/"),
|
||||
("rdap", "http://rdaregistry.info/Elements/p/"),
|
||||
("rdat", "http://rdaregistry.info/Elements/t/"),
|
||||
("rdaw", "http://rdaregistry.info/Elements/w/"),
|
||||
("rdax", "http://rdaregistry.info/Elements/x/"),
|
||||
("schema", "https://schema.org/"),
|
||||
("quill", "http://fedora.quill.lan/rest/"),
|
||||
("gl", "https://graphofliberty.org/2026/04/ont/"),
|
||||
].map(|(k, v)| (k.to_string(), v.to_string())))
|
||||
});
|
||||
|
||||
pub struct OntologyBuilder {
|
||||
path: Option<PathBuf>,
|
||||
@@ -256,6 +259,10 @@ impl Ontology {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prefixes(&self) -> &BTreeMap<String, String> {
|
||||
&*PREFIXES
|
||||
}
|
||||
|
||||
/*pub fn info(&self, node: NamedNodeRef<'_>) -> Option<&IriInformation> {
|
||||
let node = node.into_owned();
|
||||
self.iri_info.get(&node)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::BTreeMap;
|
||||
use iced::{keyboard, Element, Event, Length, Rectangle, Size};
|
||||
use iced::advanced::{mouse, text, Shell};
|
||||
use iced::advanced::layout::{Limits, Node};
|
||||
@@ -7,28 +8,79 @@ use iced::advanced::widget::{tree, Tree};
|
||||
use iced::mouse::{Cursor, Interaction};
|
||||
use iced::widget::text_input::Catalog;
|
||||
use iced::widget::TextInput;
|
||||
use tracing::info;
|
||||
|
||||
pub struct State {
|
||||
value: String,
|
||||
control: bool,
|
||||
}
|
||||
|
||||
pub struct IriInput<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer>
|
||||
where
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer {
|
||||
text_input: TextInput<'a, Message, Theme, Renderer>,
|
||||
on_control_click: Option<Message>,
|
||||
}
|
||||
|
||||
impl<'a, Message, Theme, Renderer> IriInput<'a, Message, Theme, Renderer>
|
||||
pub struct IriInput<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
prefixes: &'a BTreeMap<String, String>,
|
||||
placeholder: String,
|
||||
iri: String,
|
||||
on_control_click: Option<Message>,
|
||||
on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,
|
||||
text_input: TextInput<'a, Message, Theme, Renderer>,
|
||||
}
|
||||
|
||||
fn abbreviate(prefixes: &BTreeMap<String, String>, iri: &str) -> Option<String> {
|
||||
for (name, base) in prefixes {
|
||||
if let Some(local_name) = iri.strip_prefix(base) {
|
||||
return if local_name.is_empty() {
|
||||
Some(format!("{name}:"))
|
||||
} else {
|
||||
Some(format!("{name}:{local_name}"))
|
||||
};
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn expand(prefixes: &BTreeMap<String, String>, abbreviated_iri: &str) -> Option<String> {
|
||||
let (prefix, name) = abbreviated_iri.split_once(':')?;
|
||||
prefixes
|
||||
.get(prefix)
|
||||
.map(|base| format!("{base}{name}"))
|
||||
}
|
||||
|
||||
impl<'a, Message, Theme, Renderer> IriInput<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Message: Clone,
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
pub fn new(prefixes: &'a BTreeMap<String, String>, placeholder: &str, iri: &str) -> Self {
|
||||
let display_value = abbreviate(prefixes, iri).unwrap_or_else(|| iri.to_string());
|
||||
let text_input = TextInput::new(placeholder, &display_value);
|
||||
Self {
|
||||
prefixes,
|
||||
placeholder: placeholder.to_string(),
|
||||
iri: iri.to_string(),
|
||||
on_control_click: None,
|
||||
on_input: None,
|
||||
text_input,
|
||||
}
|
||||
}
|
||||
pub fn on_control_click(mut self, on_control_click: Message) -> Self {
|
||||
self.on_control_click = Some(on_control_click);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_input(mut self, on_input: impl Fn(String) -> Message + 'a) -> Self {
|
||||
let iri = self.iri.clone();
|
||||
let wrapped = move |value: String| {
|
||||
let expanded_value = expand(self.prefixes, &value);
|
||||
on_input(expanded_value.unwrap_or_else(|| iri.clone()))
|
||||
};
|
||||
|
||||
self.text_input = self.text_input.on_input(wrapped);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Theme, Renderer> From<IriInput<'a, Message, Theme, Renderer>>
|
||||
@@ -43,16 +95,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iri_input<Message, Theme, Renderer>(text_input: TextInput<Message, Theme, Renderer>) -> IriInput<Message, Theme, Renderer>
|
||||
pub fn iri_input<'a, Message, Theme, Renderer>(prefixes: &'a BTreeMap<String, String>, placeholder: &str, iri: &str) -> IriInput<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Message: Clone,
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
IriInput {
|
||||
text_input,
|
||||
on_control_click: None,
|
||||
}
|
||||
IriInput::new(prefixes, placeholder, iri)
|
||||
}
|
||||
|
||||
impl <Message, Theme, Renderer> Widget<Message, Theme, Renderer> for IriInput<'_, Message, Theme, Renderer>
|
||||
@@ -64,6 +113,7 @@ where
|
||||
fn size(&self) -> Size<Length> {
|
||||
Widget::size(&self.text_input)
|
||||
}
|
||||
|
||||
fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &Limits) -> Node {
|
||||
Widget::layout(&mut self.text_input, &mut tree.children[0], renderer, limits)
|
||||
}
|
||||
@@ -78,6 +128,7 @@ where
|
||||
|
||||
fn state(&self) -> tree::State {
|
||||
tree::State::new(State {
|
||||
value: String::new(),
|
||||
control: false,
|
||||
})
|
||||
}
|
||||
@@ -96,6 +147,12 @@ where
|
||||
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
|
||||
if cursor.is_over(layout.bounds()) && state.control && let Some(on_control_click) = &self.on_control_click {
|
||||
shell.publish(on_control_click.clone());
|
||||
shell.capture_event();
|
||||
}
|
||||
}
|
||||
Event::Keyboard(keyboard::Event::KeyPressed { text, .. }) => {
|
||||
if let Some(text) = text {
|
||||
state.value = text.to_string();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -104,12 +161,12 @@ where
|
||||
Widget::update(&mut self.text_input, &mut tree.children[0], event, layout, cursor, renderer, shell, viewport)
|
||||
}
|
||||
|
||||
fn mouse_interaction(&self, tree: &Tree, layout: Layout<'_>, cursor: Cursor, _viewport: &Rectangle, _renderer: &Renderer) -> Interaction {
|
||||
fn mouse_interaction(&self, tree: &Tree, layout: Layout<'_>, cursor: Cursor, viewport: &Rectangle, renderer: &Renderer) -> Interaction {
|
||||
let state = tree.state.downcast_ref::<State>();
|
||||
if cursor.is_over(layout.bounds()) && state.control {
|
||||
Interaction::Pointer
|
||||
} else {
|
||||
Interaction::None
|
||||
Widget::mouse_interaction(&self.text_input, tree, layout, cursor, viewport, renderer)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user