teksilo_core/off_thread/
live_image.rs1use std::cell::Cell;
8use std::rc::Rc;
9
10use teksilo_canvas::live_image::{LiveImageConsumer, LiveImageSource, LiveImageStatus};
11use teksilo_canvas::{ImageGeometry, Transform2D};
12
13use crate::signal::Signal;
14use crate::widget_id::WidgetId;
15
16#[derive(Clone)]
21pub struct LiveImageSignals {
22 pub frame_size: Signal<Option<(u32, u32)>>,
26 pub status: Signal<LiveImageStatus>,
30}
31
32impl LiveImageSignals {
33 pub fn new(source: &LiveImageSource) -> Self {
35 Self {
36 frame_size: Signal::new(source.size()),
37 status: Signal::new(source.status()),
38 }
39 }
40}
41
42impl Default for LiveImageSignals {
43 fn default() -> Self {
46 Self {
47 frame_size: Signal::new(None),
48 status: Signal::new(LiveImageStatus::Disconnected),
49 }
50 }
51}
52
53impl std::fmt::Debug for LiveImageSignals {
54 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55 f.debug_struct("LiveImageSignals")
56 .field("frame_size", &self.frame_size.get())
57 .field("status", &self.status.get())
58 .finish()
59 }
60}
61
62#[derive(Clone)]
66pub struct LiveImageAttachment {
67 pub(crate) entry: Rc<AttachmentEntry>,
68}
69
70pub(crate) struct AttachmentEntry {
71 pub(crate) consumer: LiveImageConsumer,
72 pub(crate) signals: LiveImageSignals,
73 pub(crate) widget: WidgetId,
74 geometry: Cell<Option<ImageGeometry>>,
75 snapped_under: Cell<Option<Transform2D>>,
77}
78
79impl AttachmentEntry {
80 pub(crate) fn new(
81 consumer: LiveImageConsumer,
82 signals: LiveImageSignals,
83 widget: WidgetId,
84 ) -> Self {
85 Self {
86 consumer,
87 signals,
88 widget,
89 geometry: Cell::new(None),
90 snapped_under: Cell::new(None),
91 }
92 }
93}
94
95impl AttachmentEntry {
96 pub(crate) fn geometry(&self) -> Option<ImageGeometry> {
97 self.geometry.get()
98 }
99
100 pub(crate) fn snapped_under(&self) -> Option<Transform2D> {
101 self.snapped_under.get()
102 }
103}
104
105impl LiveImageAttachment {
106 pub fn consumer(&self) -> &LiveImageConsumer {
108 &self.entry.consumer
109 }
110
111 pub fn signals(&self) -> &LiveImageSignals {
112 &self.entry.signals
113 }
114
115 pub fn widget_id(&self) -> WidgetId {
116 self.entry.widget
117 }
118
119 pub fn set_geometry(&self, geometry: ImageGeometry) {
122 self.entry.geometry.set(Some(geometry));
123 }
124
125 pub fn geometry(&self) -> Option<ImageGeometry> {
127 self.entry.geometry()
128 }
129
130 pub fn set_snapped_under(&self, transform: Option<Transform2D>) {
138 self.entry.snapped_under.set(transform);
139 }
140
141 pub fn is_detached(&self) -> bool {
144 self.entry.consumer.is_detached()
145 }
146}
147
148impl std::fmt::Debug for LiveImageAttachment {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 f.debug_struct("LiveImageAttachment")
151 .field("widget", &self.entry.widget)
152 .field("consumer", &self.entry.consumer)
153 .finish()
154 }
155}