Private
Public Access
1
0

transcript: add copy right click action

This commit is contained in:
2025-06-18 01:36:29 -07:00
parent f0b7cff226
commit d33b50cfb5

View File

@@ -22,12 +22,37 @@ private class TranscriptDrawingArea : Widget
private Adjustment? _viewport = null;
private const float bubble_margin = 18.0f;
private GestureClick _click_gesture = new GestureClick();
private Gdk.Rectangle? _click_bounding_box = null;
private const bool debug_viewport = false;
private uint? _tick_callback_id = null;
private HashMap<string, ChatItemAnimation> _animations = new HashMap<string, ChatItemAnimation>();
public TranscriptDrawingArea() {
add_css_class("transcript-drawing-area");
weak TranscriptDrawingArea self = this;
_click_gesture.button = Gdk.BUTTON_SECONDARY;
_click_gesture.begin.connect(() => {
self.on_right_click();
});
add_controller(_click_gesture);
SimpleAction copy_action = new SimpleAction("copy", null);
copy_action.activate.connect(() => {
if (_click_bounding_box != null) {
copy_message_at(_click_bounding_box);
} else {
GLib.warning("Failed to get bounding box for right click");
}
});
SimpleActionGroup action_group = new SimpleActionGroup();
action_group.add_action(copy_action);
insert_action_group("transcript", action_group);
}
public void set_messages(ArrayList<Message> messages) {
@@ -147,6 +172,39 @@ private class TranscriptDrawingArea : Widget
animation_tick();
}
private void on_right_click() {
var menu_model = new Menu();
menu_model.append("Copy", "transcript.copy");
Gdk.Rectangle? bounding_box = null;
if (_click_gesture.get_bounding_box(out bounding_box)) {
_click_bounding_box = bounding_box;
var menu = new PopoverMenu.from_model(menu_model);
menu.set_position(PositionType.TOP);
menu.pointing_to = bounding_box;
menu.set_parent(this);
menu.popup();
}
}
private void copy_message_at(Gdk.Rectangle bounding_box) {
double y_offset = 0.0;
for (int i = _chat_items.size - 1; i >= 0; i--) {
var chat_item = _chat_items[i];
y_offset += chat_item.get_height() + chat_item.vertical_padding;
if (y_offset > bounding_box.y) {
var text_bubble = chat_item as TextBubbleLayout;
var text = text_bubble.message.text;
var clipboard = get_clipboard();
clipboard.set_text(text);
break;
}
}
}
private bool animation_tick() {
HashSet<string> animations_to_remove = new HashSet<string>();
_animations.foreach(entry => {