Skip to content

Commit 434b705

Browse files
authored
Handle custom icons for connections. (#243)
* Handle custom icons for connections. * lenght(path) == 0 is just fine, as it means that we are at root level and it might actually provide an icon. * Actually at root level we want the global connection icon.
1 parent 30df1c8 commit 434b705

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

crates/ark/src/connections/r_connection.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crossbeam::channel::Sender;
1212
use harp::exec::RFunction;
1313
use harp::exec::RFunctionExt;
1414
use harp::object::RObject;
15+
use harp::utils::r_is_null;
1516
use libr::R_NilValue;
1617
use libr::SEXP;
1718
use serde::Deserialize;
@@ -48,6 +49,9 @@ pub enum ConnectionResponse {
4849
fields: Vec<ConnectionTableField>,
4950
},
5051
PreviewResponse,
52+
IconResponse {
53+
icon: Option<String>,
54+
},
5155
}
5256

5357
#[derive(Debug, Serialize, Deserialize)]
@@ -59,6 +63,8 @@ pub enum ConnectionRequest {
5963
FieldsRequest { path: Vec<ConnectionTable> },
6064
// The UI asks for a DataViewer preview of the table.
6165
PreviewTable { path: Vec<ConnectionTable> },
66+
// The UI asks for an icon for a given element
67+
IconRequest { path: Vec<ConnectionTable> },
6268
}
6369

6470
#[derive(Deserialize, Serialize)]
@@ -112,7 +118,6 @@ impl RConnection {
112118
// Notify the frontend that a new connection has been opened.
113119
let event = CommManagerEvent::Opened(self.comm.clone(), comm_open_json);
114120
self.comm_manager_tx.send(event)?;
115-
116121
Ok(())
117122
}
118123

@@ -209,6 +214,27 @@ impl RConnection {
209214
})?;
210215
Ok(ConnectionResponse::PreviewResponse)
211216
},
217+
ConnectionRequest::IconRequest { path } => {
218+
// Calls back into R to get the icon.
219+
let icon_path = r_task(|| -> Result<_, anyhow::Error> {
220+
unsafe {
221+
let mut call = RFunction::from(".ps.connection_icon");
222+
call.add(RObject::from(self.comm.comm_id.clone()));
223+
for obj in path {
224+
call.param(obj.kind.as_str(), obj.name);
225+
}
226+
227+
let icon = call.call()?;
228+
229+
if r_is_null(*icon) {
230+
Ok(None)
231+
} else {
232+
Ok(Some(RObject::to::<String>(icon)?))
233+
}
234+
}
235+
})?;
236+
Ok(ConnectionResponse::IconResponse { icon: icon_path })
237+
},
212238
}
213239
}
214240

crates/ark/src/modules/positron/connection.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,23 @@ options("connectionObserver" = .ps.connection_observer())
104104
# will remove the connection from the list of connections
105105
con$disconnect(...)
106106
}
107+
108+
#' @export
109+
.ps.connection_icon <- function(id, ...) {
110+
con <- get(id, getOption("connectionObserver")$.connections)
111+
path <- names(list(...))
112+
113+
if (length(path) == 0) {
114+
# we are at the root of the connection
115+
return(con$icon)
116+
}
117+
118+
object_types <- con$listObjectTypes()
119+
object_types <- object_types[[1]] # root is always element 1
120+
121+
for (p in path) {
122+
object_types <- object_types$contains[[p]]
123+
}
124+
125+
object_types$icon
126+
}

0 commit comments

Comments
 (0)