11use adw:: prelude:: * ;
22use adw:: subclass:: prelude:: * ;
3+ use glib:: clone;
34use gtk:: { gdk, gio, glib, graphene, gsk} ;
45use std:: cell:: { Cell , RefCell } ;
56
@@ -49,7 +50,9 @@ mod imp {
4950
5051 #[ derive( Default ) ]
5152 pub struct Background {
52- pub ( super ) gradient_texture : RefCell < Option < gdk:: Texture > > ,
53+ pub ( super ) background_texture : RefCell < Option < gdk:: Texture > > ,
54+ pub ( super ) message_texture : RefCell < Option < gdk:: Texture > > ,
55+
5356 pub ( super ) last_size : Cell < ( f32 , f32 ) > ,
5457
5558 pub ( super ) shader : RefCell < Option < Option < gsk:: GLShader > > > ,
@@ -61,7 +64,8 @@ mod imp {
6164
6265 pub ( super ) dark : Cell < bool > ,
6366
64- pub ( super ) colors : RefCell < Vec < graphene:: Vec3 > > ,
67+ pub ( super ) bg_colors : RefCell < Vec < graphene:: Vec3 > > ,
68+ pub ( super ) message_colors : RefCell < Vec < graphene:: Vec3 > > ,
6569 }
6670
6771 #[ glib:: object_subclass]
@@ -92,7 +96,7 @@ mod imp {
9296
9397 let target = adw:: CallbackAnimationTarget :: new ( clone ! ( @weak obj => move |progress| {
9498 let imp = obj. imp( ) ;
95- imp. gradient_texture . take( ) ;
99+ imp. background_texture . take( ) ;
96100 let progress = progress as f32 ;
97101 if progress >= 1.0 {
98102 imp. progress. set( 0.0 ) ;
@@ -150,27 +154,25 @@ mod imp {
150154 ) {
151155 if self . progress . get ( ) == 0.0 {
152156 let texture = {
153- let cache = self . gradient_texture . borrow ( ) ;
157+ let cache = self . background_texture . borrow ( ) ;
154158
155159 match & * cache {
156160 Some ( texture) if !size_changed => texture. clone ( ) ,
157161 _ => {
158162 drop ( cache) ;
159163
160- let renderer = self . obj ( ) . native ( ) . unwrap ( ) . renderer ( ) ;
161- let texture = renderer
162- . render_texture ( self . gradient_shader_node ( bounds) , Some ( bounds) ) ;
163-
164- self . gradient_texture . replace ( Some ( texture. clone ( ) ) ) ;
164+ self . render_textures ( bounds) ;
165165
166- texture
166+ self . background_texture . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( )
167167 }
168168 }
169169 } ;
170170
171171 snapshot. append_texture ( & texture, bounds) ;
172172 } else {
173- snapshot. append_node ( self . gradient_shader_node ( bounds) ) ;
173+ self . render_textures ( bounds) ;
174+ let texture = self . background_texture . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( ) ;
175+ snapshot. append_texture ( & texture, bounds) ;
174176 }
175177 }
176178
@@ -189,7 +191,7 @@ mod imp {
189191 let mut offset = [ 0.0 ; 4 ] ;
190192 if self . dark . get ( ) {
191193 matrix[ 15 ] = -0.3 ;
192- offset = [ 0.04 ; 4 ] ;
194+ offset = [ 0.08 ; 4 ] ;
193195 offset[ 3 ] = 1.0 ;
194196 } else {
195197 matrix[ 15 ] = 0.1 ;
@@ -208,7 +210,24 @@ mod imp {
208210 }
209211 }
210212
211- fn gradient_shader_node ( & self , bounds : & graphene:: Rect ) -> gsk:: GLShaderNode {
213+ fn render_textures ( & self , bounds : & graphene:: Rect ) {
214+ let colors = [ self . bg_colors . borrow ( ) , self . message_colors . borrow ( ) ] ;
215+
216+ let renderer = self . obj ( ) . native ( ) . unwrap ( ) . renderer ( ) ;
217+
218+ let mut textures = colors. into_iter ( ) . map ( |color| {
219+ renderer. render_texture ( self . gradient_shader_node ( bounds, & color) , Some ( bounds) )
220+ } ) ;
221+
222+ self . background_texture . replace ( textures. next ( ) ) ;
223+ self . message_texture . replace ( textures. next ( ) ) ;
224+ }
225+
226+ fn gradient_shader_node (
227+ & self ,
228+ bounds : & graphene:: Rect ,
229+ colors : & [ graphene:: Vec3 ] ,
230+ ) -> gsk:: GLShaderNode {
212231 let Some ( Some ( gradient_shader) ) = & * self . shader . borrow ( ) else {
213232 unreachable ! ( )
214233 } ;
@@ -218,10 +237,8 @@ mod imp {
218237 let progress = self . progress . get ( ) ;
219238 let phase = self . phase . get ( ) as usize ;
220239
221- let colors = self . colors . borrow ( ) ;
222-
223- let & [ c1, c2, c3, c4] = & colors[ ..] else {
224- unimplemented ! ( "Unexpected color count" ) ;
240+ let & [ c1, c2, c3, c4] = colors else {
241+ unimplemented ! ( "Unexpected color count" )
225242 } ;
226243
227244 args_builder. set_vec3 ( 0 , & c1) ;
@@ -287,38 +304,19 @@ impl Background {
287304
288305 imp. dark . set ( background. is_dark ) ;
289306
290- let fill = match background. r#type {
307+ let bg_fill = match background. r#type {
291308 tdlib:: enums:: BackgroundType :: Pattern ( pattern) => pattern. fill ,
292309 tdlib:: enums:: BackgroundType :: Fill ( fill) => fill. fill ,
293310 tdlib:: enums:: BackgroundType :: Wallpaper ( _) => {
294311 unimplemented ! ( "Wallpaper chat background" )
295312 }
296313 } ;
297314
298- match fill {
299- tdlib:: enums:: BackgroundFill :: FreeformGradient ( gradient) => {
300- if gradient. colors . len ( ) != 4 {
301- unimplemented ! ( "Unsupported gradient colors count" ) ;
302- }
303-
304- let colors = gradient
305- . colors
306- . into_iter ( )
307- . map ( |int_color| {
308- let r = ( int_color >> 16 ) & 0xFF ;
309- let g = ( int_color >> 8 ) & 0xFF ;
310- let b = int_color & 0xFF ;
311-
312- graphene:: Vec3 :: new ( r as f32 / 255.0 , g as f32 / 255.0 , b as f32 / 255.0 )
313- } )
314- . collect ( ) ;
315+ imp. bg_colors . replace ( fill_colors ( bg_fill) ) ;
316+ imp. message_colors
317+ . replace ( fill_colors ( theme. outgoing_message_fill ) ) ;
315318
316- imp. colors . replace ( colors) ;
317- }
318- _ => unimplemented ! ( "Background fill" ) ,
319- }
320-
321- imp. gradient_texture . take ( ) ;
319+ imp. background_texture . take ( ) ;
322320 self . queue_draw ( ) ;
323321 }
324322
@@ -331,6 +329,29 @@ impl Background {
331329 }
332330 }
333331
332+ pub fn subscribe_to_redraw ( & self , child : & gtk:: Widget ) {
333+ let animation = self . imp ( ) . animation . get ( ) . unwrap ( ) ;
334+ animation. connect_value_notify ( clone ! ( @weak child => move |_| child. queue_draw( ) ) ) ;
335+ }
336+
337+ pub fn bg_texture ( & self ) -> gdk:: Texture {
338+ self . imp ( )
339+ . background_texture
340+ . borrow ( )
341+ . as_ref ( )
342+ . unwrap ( )
343+ . clone ( )
344+ }
345+
346+ pub fn message_texture ( & self ) -> gdk:: Texture {
347+ self . imp ( )
348+ . message_texture
349+ . borrow ( )
350+ . as_ref ( )
351+ . unwrap ( )
352+ . clone ( )
353+ }
354+
334355 fn ensure_shader ( & self ) {
335356 let imp = self . imp ( ) ;
336357 if imp. shader . borrow ( ) . is_none ( ) {
@@ -365,9 +386,28 @@ impl Default for Background {
365386 }
366387}
367388
389+ fn fill_colors ( fill : tdlib:: enums:: BackgroundFill ) -> Vec < graphene:: Vec3 > {
390+ match fill {
391+ tdlib:: enums:: BackgroundFill :: FreeformGradient ( gradient) if gradient. colors . len ( ) == 4 => {
392+ gradient
393+ . colors
394+ . into_iter ( )
395+ . map ( |int_color| {
396+ let r = ( int_color >> 16 ) & 0xFF ;
397+ let g = ( int_color >> 8 ) & 0xFF ;
398+ let b = int_color & 0xFF ;
399+
400+ graphene:: Vec3 :: new ( r as f32 / 255.0 , g as f32 / 255.0 , b as f32 / 255.0 )
401+ } )
402+ . collect ( )
403+ }
404+ _ => unimplemented ! ( "Unsupported background fill: {fill:?}" ) ,
405+ }
406+ }
407+
368408fn hard_coded_themes ( dark : bool ) -> tdlib:: types:: ThemeSettings {
369409 macro_rules! theme {
370- ( $dark: expr, colors => $( $color : expr ) ,+) => { {
410+ ( $dark: expr, background => $( $bg_color : literal ) ,+ , messages => $ ( $m_color : literal ) ,+) => { {
371411 use tdlib:: enums:: { BackgroundFill :: * , BackgroundType :: Fill } ;
372412 use tdlib:: types:: * ;
373413
@@ -377,8 +417,7 @@ fn hard_coded_themes(dark: bool) -> tdlib::types::ThemeSettings {
377417 is_dark: $dark,
378418 r#type: Fill ( BackgroundTypeFill {
379419 fill: FreeformGradient ( BackgroundFillFreeformGradient {
380-
381- colors: vec![ $( $color) ,+] ,
420+ colors: vec![ $( $bg_color) ,+] ,
382421 } ) ,
383422 } ) ,
384423 id: 0 ,
@@ -388,14 +427,18 @@ fn hard_coded_themes(dark: bool) -> tdlib::types::ThemeSettings {
388427 accent_color: 0 ,
389428 animate_outgoing_message_fill: false ,
390429 outgoing_message_accent_color: 0 ,
391- outgoing_message_fill: Solid ( BackgroundFillSolid { color: 0 } ) ,
430+ outgoing_message_fill: FreeformGradient ( BackgroundFillFreeformGradient {
431+ colors: vec![ $( $m_color) ,+] ,
432+ } ) ,
392433 }
393434 } }
394435 }
395436
437+ // tr tl bl br
438+
396439 if dark {
397- theme ! ( dark, colors => 0xd6932e , 0xbc40db , 0x4280d7 , 0x614ed5 )
440+ theme ! ( dark, background => 0xd6932e , 0xbc40db , 0x4280d7 , 0x614ed5 , messages => 0xfc27a6 , 0xff9201 , 0x7827ff , 0x554efe )
398441 } else {
399- theme ! ( dark, colors => 0x94dae9 , 0x9aeddb , 0x94c3f6 , 0xac96f7 )
442+ theme ! ( dark, background => 0x94dae9 , 0x9aeddb , 0x94c3f6 , 0xac96f7 , messages => 0xddffdf , 0xfff0dd , 0xffddfc , 0xddecff )
400443 }
401444}
0 commit comments