Private
Public Access
1
0

Enables selection of bubbles using an invisible text view

This commit is contained in:
2025-06-18 16:50:14 -07:00
parent 3b6666cfc2
commit ccfea2883c
6 changed files with 170 additions and 28 deletions

View File

@@ -16,6 +16,9 @@ private class TranscriptDrawingArea : Widget
}
}
public signal void on_text_bubble_hover(VisibleTextLayout? text_bubble);
public signal void on_text_bubble_click(VisibleTextLayout? text_bubble);
private ArrayList<Message> _messages = new ArrayList<Message>();
private ArrayList<ChatItemLayout> _chat_items = new ArrayList<ChatItemLayout>();
@@ -26,6 +29,7 @@ private class TranscriptDrawingArea : Widget
private Gdk.Rectangle? _click_bounding_box = null;
private EventControllerMotion _motion_controller = new EventControllerMotion();
private ArrayList<VisibleTextLayout?> _visible_text_layouts = new ArrayList<VisibleTextLayout?>();
private const bool debug_viewport = false;
private uint? _tick_callback_id = null;
@@ -36,9 +40,9 @@ private class TranscriptDrawingArea : Widget
weak TranscriptDrawingArea self = this;
_click_gesture.button = Gdk.BUTTON_SECONDARY;
_click_gesture.button = Gdk.BUTTON_SECONDARY | Gdk.BUTTON_PRIMARY;
_click_gesture.begin.connect(() => {
self.on_right_click();
self.on_click(self._click_gesture.get_button());
});
add_controller(_click_gesture);
@@ -129,6 +133,7 @@ private class TranscriptDrawingArea : Widget
// Draw each item in reverse order, since the messages are in reverse order
float y_offset = 0;
int container_width = get_width();
_visible_text_layouts.clear();
for (int i = _chat_items.size - 1; i >= 0; i--) {
var chat_item = _chat_items[i];
var item_width = chat_item.get_width();
@@ -152,6 +157,10 @@ private class TranscriptDrawingArea : Widget
// Skip drawing if this item is not in the viewport
float height_offset = 0.0f;
if (viewport_rect.intersection(rect, null)) {
if (chat_item is TextBubbleLayout) {
_visible_text_layouts.add(VisibleTextLayout(chat_item as TextBubbleLayout, rect));
}
snapshot.save();
var pushed_opacity = false;
@@ -190,8 +199,35 @@ private class TranscriptDrawingArea : Widget
animation_tick();
}
private VisibleTextLayout? get_text_bubble_at(double x, double y) {
foreach (var layout in _visible_text_layouts) {
if (layout.rect.contains_point(Graphene.Point() { x = (float)x, y = (float)y })) {
return layout;
}
}
return null;
}
private void on_mouse_motion(double x, double y) {
// TODO: Will be making temporary text views here.
VisibleTextLayout? hovered_text_bubble = get_text_bubble_at(x, y);
on_text_bubble_hover(hovered_text_bubble);
}
private void on_click(uint button) {
if (button == Gdk.BUTTON_SECONDARY) {
on_right_click();
} else if (button == Gdk.BUTTON_PRIMARY) {
on_left_click();
}
}
private void on_left_click() {
Gdk.Rectangle? bounding_box = null;
if (_click_gesture.get_bounding_box(out bounding_box)) {
var text_bubble = get_text_bubble_at(bounding_box.x, bounding_box.y);
on_text_bubble_click(text_bubble);
}
}
private void on_right_click() {
@@ -372,4 +408,14 @@ private class ChatItemAnimation
private static double ease_out_quart(double t) {
return 1.0 - Math.pow(1.0 - t, 4);
}
}
public struct VisibleTextLayout {
public weak TextBubbleLayout text_bubble;
public Graphene.Rect rect;
public VisibleTextLayout(TextBubbleLayout text_bubble, Graphene.Rect rect) {
this.text_bubble = text_bubble;
this.rect = rect;
}
}