GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
Implement right-click context menu with key path label, Copy Key, and Copy Value on TreeList rows
src/widget/container/treelist.rs | 54 ++++++++++++++++++++++++++++++++++++++++
src/widget/core.rs | 6 +++++
src/widget/mod.rs | 2 ++
3 files changed, 62 insertions(+)
diff --git a/src/widget/container/treelist.rs b/src/widget/container/treelist.rs
index 9d9974b..785a2f8 100644
--- a/src/widget/container/treelist.rs
+++ b/src/widget/container/treelist.rs
@@ -257,6 +257,36 @@ impl Element for TreeList {
}
}
}
+
+ if button == MouseButton::Right && state == ElementState::Pressed {
+ if px >= list_left && px <= list_left + list_width && py >= list_top && py <= list_bottom {
+ self.focus();
+ let relative_y = py - list_top + self.scroll_box.scroll_y;
+ let row_idx = (relative_y / self.item_height) as usize;
+ if row_idx < self.items.len() {
+ let item = self.items[row_idx].clone();
+ if let TreeElement::Leaf { original_idx, ref path, ref name, indent, ref val } = item {
+ self.selected_key_idx = Some(original_idx);
+ self.clicked_item = Some(TreeElement::Leaf {
+ path: path.clone(),
+ name: name.clone(),
+ indent,
+ val: val.clone(),
+ original_idx,
+ });
+
+ let options = vec![
+ path.clone(),
+ "Copy Key".to_string(),
+ "Copy Value".to_string(),
+ ];
+ let scroll_offset = crate::widget::hover_animation::get_scroll_offset();
+ ctx.show_context_menu(px, py - scroll_offset, options, 1, self.as_ptr_mut());
+ changed = true;
+ }
+ }
+ }
+ }
changed
}
@@ -511,6 +541,30 @@ impl Element for TreeList {
fn clear_children(&mut self, _ctx: &mut UiContext) {
self.children.clear();
}
+
+ fn copy_key(&self) {
+ if let Some(idx) = self.selected_key_idx {
+ if idx < self.flat_keys.len() {
+ let key_path = &self.flat_keys[idx].0;
+ clipboard::copy_to_clipboard(key_path);
+ }
+ }
+ }
+
+ fn copy_value(&self) {
+ if let Some(idx) = self.selected_key_idx {
+ if idx < self.flat_keys.len() {
+ let val = &self.flat_keys[idx].1;
+ let val_str = match val {
+ serde_json::Value::String(s) => s.clone(),
+ serde_json::Value::Bool(b) => b.to_string(),
+ serde_json::Value::Number(n) => n.to_string(),
+ other => serde_json::to_string(other).unwrap_or_default(),
+ };
+ clipboard::copy_to_clipboard(&val_str);
+ }
+ }
+ }
}
fn parse_hex_f32(s: &str) -> Option<[f32; 4]> {
diff --git a/src/widget/core.rs b/src/widget/core.rs
index 45ec05e..a402534 100644
--- a/src/widget/core.rs
+++ b/src/widget/core.rs
@@ -546,6 +546,12 @@ pub mod context_menu {
"Select All" => {
target.select_all();
}
+ "Copy Key" => {
+ target.copy_key();
+ }
+ "Copy Value" => {
+ target.copy_value();
+ }
_ => {}
}
}
diff --git a/src/widget/mod.rs b/src/widget/mod.rs
index 3cafa77..110e824 100644
--- a/src/widget/mod.rs
+++ b/src/widget/mod.rs
@@ -293,6 +293,8 @@ pub trait Element {
}
}
fn select_all(&mut self) {}
+ fn copy_key(&self) {}
+ fn copy_value(&self) {}
fn set_rect(&mut self, x: f32, y: f32, w: f32, h: f32) {
if let Some(b) = self.base_mut() {