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 ( crate ) 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 < 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]
@@ -102,7 +106,7 @@ mod imp {
102106
103107 let target = adw:: CallbackAnimationTarget :: new ( clone ! ( @weak obj => move |progress| {
104108 let imp = obj. imp( ) ;
105- imp. gradient_texture . take( ) ;
109+ imp. background_texture . take( ) ;
106110 let progress = progress as f32 ;
107111 if progress >= 1.0 {
108112 imp. progress. set( 0.0 ) ;
@@ -171,18 +175,20 @@ mod imp {
171175 size_changed : bool ,
172176 ) {
173177 if self . progress . get ( ) == 0.0 {
174- let texture = match self . gradient_texture . take ( ) {
175- Some ( texture) if !size_changed => texture,
178+ let texture = match self . background_texture . take ( ) {
179+ Some ( texture) if !size_changed => texture. clone ( ) ,
176180 _ => {
177- let renderer = self . obj ( ) . native ( ) . unwrap ( ) . renderer ( ) ;
178- renderer . render_texture ( self . gradient_shader_node ( bounds ) , Some ( bounds ) )
181+ self . render_textures ( bounds ) ;
182+ self . background_texture . take ( ) . unwrap ( )
179183 }
180184 } ;
181185
182186 snapshot. append_texture ( & texture, bounds) ;
183- self . gradient_texture . replace ( Some ( texture) ) ;
187+ self . background_texture . replace ( Some ( texture) ) ;
184188 } else {
185- snapshot. append_node ( self . gradient_shader_node ( bounds) ) ;
189+ self . render_textures ( bounds) ;
190+ let texture = self . background_texture . borrow ( ) . as_ref ( ) . unwrap ( ) . clone ( ) ;
191+ snapshot. append_texture ( & texture, bounds) ;
186192 }
187193 }
188194
@@ -220,7 +226,24 @@ mod imp {
220226 }
221227 }
222228
223- fn gradient_shader_node ( & self , bounds : & graphene:: Rect ) -> gsk:: GLShaderNode {
229+ fn render_textures ( & self , bounds : & graphene:: Rect ) {
230+ let colors = [ self . bg_colors . borrow ( ) , self . message_colors . borrow ( ) ] ;
231+
232+ let renderer = self . obj ( ) . native ( ) . unwrap ( ) . renderer ( ) ;
233+
234+ let mut textures = colors. into_iter ( ) . map ( |color| {
235+ renderer. render_texture ( self . gradient_shader_node ( bounds, & color) , Some ( bounds) )
236+ } ) ;
237+
238+ self . background_texture . replace ( textures. next ( ) ) ;
239+ self . message_texture . replace ( textures. next ( ) ) ;
240+ }
241+
242+ fn gradient_shader_node (
243+ & self ,
244+ bounds : & graphene:: Rect ,
245+ colors : & [ graphene:: Vec3 ] ,
246+ ) -> gsk:: GLShaderNode {
224247 let Some ( gradient_shader) = & * self . shader . borrow ( ) else {
225248 unreachable ! ( )
226249 } ;
@@ -230,10 +253,8 @@ mod imp {
230253 let progress = self . progress . get ( ) ;
231254 let phase = self . phase . get ( ) as usize ;
232255
233- let colors = self . colors . borrow ( ) ;
234-
235- let & [ c1, c2, c3, c4] = & colors[ ..] else {
236- unimplemented ! ( "Unexpected color count" ) ;
256+ let & [ c1, c2, c3, c4] = colors else {
257+ unimplemented ! ( "Unexpected color count" )
237258 } ;
238259
239260 args_builder. set_vec3 ( 0 , & c1) ;
@@ -299,38 +320,19 @@ impl Background {
299320
300321 imp. dark . set ( background. is_dark ) ;
301322
302- let fill = match background. r#type {
323+ let bg_fill = match background. r#type {
303324 tdlib:: enums:: BackgroundType :: Pattern ( pattern) => pattern. fill ,
304325 tdlib:: enums:: BackgroundType :: Fill ( fill) => fill. fill ,
305326 tdlib:: enums:: BackgroundType :: Wallpaper ( _) => {
306327 unimplemented ! ( "Wallpaper chat background" )
307328 }
308329 } ;
309330
310- match fill {
311- tdlib:: enums:: BackgroundFill :: FreeformGradient ( gradient) => {
312- if gradient. colors . len ( ) != 4 {
313- unimplemented ! ( "Unsupported gradient colors count" ) ;
314- }
315-
316- let colors = gradient
317- . colors
318- . into_iter ( )
319- . map ( |int_color| {
320- let r = ( int_color >> 16 ) & 0xFF ;
321- let g = ( int_color >> 8 ) & 0xFF ;
322- let b = int_color & 0xFF ;
331+ imp. bg_colors . replace ( fill_colors ( bg_fill) ) ;
332+ imp. message_colors
333+ . replace ( fill_colors ( theme. outgoing_message_fill ) ) ;
323334
324- graphene:: Vec3 :: new ( r as f32 / 255.0 , g as f32 / 255.0 , b as f32 / 255.0 )
325- } )
326- . collect ( ) ;
327-
328- imp. colors . replace ( colors) ;
329- }
330- _ => unimplemented ! ( "Background fill" ) ,
331- }
332-
333- imp. gradient_texture . take ( ) ;
335+ imp. background_texture . take ( ) ;
334336 self . queue_draw ( ) ;
335337 }
336338
@@ -343,6 +345,29 @@ impl Background {
343345 }
344346 }
345347
348+ pub fn subscribe_to_redraw ( & self , child : & gtk:: Widget ) {
349+ let animation = self . imp ( ) . animation . get ( ) . unwrap ( ) ;
350+ animation. connect_value_notify ( clone ! ( @weak child => move |_| child. queue_draw( ) ) ) ;
351+ }
352+
353+ pub fn bg_texture ( & self ) -> gdk:: Texture {
354+ self . imp ( )
355+ . background_texture
356+ . borrow ( )
357+ . as_ref ( )
358+ . unwrap ( )
359+ . clone ( )
360+ }
361+
362+ pub fn message_texture ( & self ) -> gdk:: Texture {
363+ self . imp ( )
364+ . message_texture
365+ . borrow ( )
366+ . as_ref ( )
367+ . unwrap ( )
368+ . clone ( )
369+ }
370+
346371 fn ensure_shader ( & self ) {
347372 let imp = self . imp ( ) ;
348373 if imp. shader . borrow ( ) . is_none ( ) {
@@ -370,8 +395,31 @@ impl Default for Background {
370395 }
371396}
372397
398+ fn fill_colors ( fill : tdlib:: enums:: BackgroundFill ) -> Vec < graphene:: Vec3 > {
399+ match fill {
400+ tdlib:: enums:: BackgroundFill :: FreeformGradient ( gradient) if gradient. colors . len ( ) == 4 => {
401+ gradient
402+ . colors
403+ . into_iter ( )
404+ . map ( |int_color| {
405+ let r = ( int_color >> 16 ) & 0xFF ;
406+ let g = ( int_color >> 8 ) & 0xFF ;
407+ let b = int_color & 0xFF ;
408+
409+ graphene:: Vec3 :: new ( r as f32 / 255.0 , g as f32 / 255.0 , b as f32 / 255.0 )
410+ } )
411+ . collect ( )
412+ }
413+ _ => unimplemented ! ( "Unsupported background fill: {fill:?}" ) ,
414+ }
415+ }
416+
373417fn hard_coded_themes ( dark : bool ) -> tdlib:: types:: ThemeSettings {
374- fn theme ( dark : bool , colors : Vec < i32 > ) -> tdlib:: types:: ThemeSettings {
418+ fn theme (
419+ dark : bool ,
420+ bg_colors : Vec < i32 > ,
421+ message_colors : Vec < i32 > ,
422+ ) -> tdlib:: types:: ThemeSettings {
375423 use tdlib:: enums:: BackgroundFill :: * ;
376424 use tdlib:: enums:: BackgroundType :: Fill ;
377425 use tdlib:: types:: * ;
@@ -381,7 +429,7 @@ fn hard_coded_themes(dark: bool) -> tdlib::types::ThemeSettings {
381429 is_default : true ,
382430 is_dark : dark,
383431 r#type : Fill ( BackgroundTypeFill {
384- fill : FreeformGradient ( BackgroundFillFreeformGradient { colors } ) ,
432+ fill : FreeformGradient ( BackgroundFillFreeformGradient { colors : bg_colors } ) ,
385433 } ) ,
386434 id : 0 ,
387435 name : String :: new ( ) ,
@@ -390,13 +438,25 @@ fn hard_coded_themes(dark: bool) -> tdlib::types::ThemeSettings {
390438 accent_color : 0 ,
391439 animate_outgoing_message_fill : false ,
392440 outgoing_message_accent_color : 0 ,
393- outgoing_message_fill : Solid ( BackgroundFillSolid { color : 0 } ) ,
441+ outgoing_message_fill : FreeformGradient ( BackgroundFillFreeformGradient {
442+ colors : message_colors,
443+ } ) ,
394444 }
395445 }
396446
447+ // tr tl bl br
448+
397449 if dark {
398- theme ( dark, vec ! [ 0xd6932e , 0xbc40db , 0x4280d7 , 0x614ed5 ] )
450+ theme (
451+ dark,
452+ vec ! [ 0xd6932e , 0xbc40db , 0x4280d7 , 0x614ed5 ] ,
453+ vec ! [ 0xfc27a6 , 0xff9201 , 0x7827ff , 0x554efe ] ,
454+ )
399455 } else {
400- theme ( dark, vec ! [ 0x94dae9 , 0x9aeddb , 0x94c3f6 , 0xac96f7 ] )
456+ theme (
457+ dark,
458+ vec ! [ 0x94dae9 , 0x9aeddb , 0x94c3f6 , 0xac96f7 ] ,
459+ vec ! [ 0xddffdf , 0xfff0dd , 0xffddfc , 0xddecff ] ,
460+ )
401461 }
402462}
0 commit comments