@@ -220,3 +220,167 @@ impl eframe::App for MyApp {
220
220
} ) ;
221
221
}
222
222
}
223
+
224
+ /// Demo of a widget that highlights its background all the way to the edge of its container when
225
+ /// hovered.
226
+ fn full_span_widget ( ui : & mut egui:: Ui , permanent : bool ) {
227
+ let bg_shape_idx = ui. painter ( ) . add ( Shape :: Noop ) ;
228
+ let response = ui. label ( "Full span test" ) ;
229
+ let ui_stack = ui. stack ( ) ;
230
+
231
+ let rect = egui:: Rect :: from_x_y_ranges (
232
+ full_span_horizontal_range ( ui_stack) ,
233
+ response. rect . y_range ( ) ,
234
+ ) ;
235
+
236
+ if permanent || response. hovered ( ) {
237
+ ui. painter ( ) . set (
238
+ bg_shape_idx,
239
+ Shape :: rect_filled ( rect, 0.0 , ui. visuals ( ) . selection . bg_fill ) ,
240
+ ) ;
241
+ }
242
+ }
243
+
244
+ /// Find the horizontal range of the enclosing container.
245
+ fn full_span_horizontal_range ( ui_stack : & egui:: UiStack ) -> Rangef {
246
+ for node in ui_stack. iter ( ) {
247
+ if node. has_visible_frame ( )
248
+ || node. is_panel_ui ( )
249
+ || node. is_root_ui ( )
250
+ || node. kind ( ) == Some ( UiKind :: TableCell )
251
+ {
252
+ return ( node. max_rect + node. frame ( ) . inner_margin ) . x_range ( ) ;
253
+ }
254
+ }
255
+
256
+ // should never happen
257
+ Rangef :: EVERYTHING
258
+ }
259
+
260
+ fn stack_ui ( ui : & mut egui:: Ui ) {
261
+ let ui_stack = ui. stack ( ) . clone ( ) ;
262
+ ui. scope ( |ui| {
263
+ stack_ui_impl ( ui, & ui_stack) ;
264
+ } ) ;
265
+ }
266
+
267
+ fn stack_ui_impl ( ui : & mut egui:: Ui , stack : & egui:: UiStack ) {
268
+ egui:: Frame {
269
+ stroke : ui. style ( ) . noninteractive ( ) . fg_stroke ,
270
+ inner_margin : egui:: Margin :: same ( 4.0 ) ,
271
+ ..Default :: default ( )
272
+ }
273
+ . show ( ui, |ui| {
274
+ ui. style_mut ( ) . wrap_mode = Some ( egui:: TextWrapMode :: Extend ) ;
275
+
276
+ egui_extras:: TableBuilder :: new ( ui)
277
+ . column ( Column :: auto ( ) )
278
+ . column ( Column :: auto ( ) )
279
+ . column ( Column :: auto ( ) )
280
+ . column ( Column :: auto ( ) )
281
+ . column ( Column :: auto ( ) )
282
+ . column ( Column :: auto ( ) )
283
+ . header ( 20.0 , |mut header| {
284
+ header. col ( |ui| {
285
+ ui. strong ( "id" ) ;
286
+ } ) ;
287
+ header. col ( |ui| {
288
+ ui. strong ( "kind" ) ;
289
+ } ) ;
290
+ header. col ( |ui| {
291
+ ui. strong ( "stroke" ) ;
292
+ } ) ;
293
+ header. col ( |ui| {
294
+ ui. strong ( "inner" ) ;
295
+ } ) ;
296
+ header. col ( |ui| {
297
+ ui. strong ( "outer" ) ;
298
+ } ) ;
299
+ header. col ( |ui| {
300
+ ui. strong ( "direction" ) ;
301
+ } ) ;
302
+ } )
303
+ . body ( |mut body| {
304
+ for node in stack. iter ( ) {
305
+ body. row ( 20.0 , |mut row| {
306
+ row. col ( |ui| {
307
+ if ui. label ( format ! ( "{:?}" , node. id) ) . hovered ( ) {
308
+ ui. ctx ( ) . debug_painter ( ) . debug_rect (
309
+ node. max_rect ,
310
+ egui:: Color32 :: GREEN ,
311
+ "max" ,
312
+ ) ;
313
+ ui. ctx ( ) . debug_painter ( ) . circle_filled (
314
+ node. min_rect . min ,
315
+ 2.0 ,
316
+ egui:: Color32 :: RED ,
317
+ ) ;
318
+ }
319
+ } ) ;
320
+ row. col ( |ui| {
321
+ let s = if let Some ( kind) = node. kind ( ) {
322
+ format ! ( "{kind:?}" )
323
+ } else {
324
+ "-" . to_owned ( )
325
+ } ;
326
+
327
+ ui. label ( s) ;
328
+ } ) ;
329
+ row. col ( |ui| {
330
+ let frame = node. frame ( ) ;
331
+ if frame. stroke == egui:: Stroke :: NONE {
332
+ ui. label ( "-" ) ;
333
+ } else {
334
+ let mut layout_job = egui:: text:: LayoutJob :: default ( ) ;
335
+ layout_job. append (
336
+ "⬛ " ,
337
+ 0.0 ,
338
+ egui:: TextFormat :: simple (
339
+ egui:: TextStyle :: Body . resolve ( ui. style ( ) ) ,
340
+ frame. stroke . color ,
341
+ ) ,
342
+ ) ;
343
+ layout_job. append (
344
+ format ! ( "{}px" , frame. stroke. width) . as_str ( ) ,
345
+ 0.0 ,
346
+ egui:: TextFormat :: simple (
347
+ egui:: TextStyle :: Body . resolve ( ui. style ( ) ) ,
348
+ ui. style ( ) . visuals . text_color ( ) ,
349
+ ) ,
350
+ ) ;
351
+ ui. style_mut ( ) . wrap_mode = Some ( egui:: TextWrapMode :: Extend ) ;
352
+ ui. label ( layout_job) ;
353
+ }
354
+ } ) ;
355
+ row. col ( |ui| {
356
+ ui. label ( print_margin ( & node. frame ( ) . inner_margin ) ) ;
357
+ } ) ;
358
+ row. col ( |ui| {
359
+ ui. label ( print_margin ( & node. frame ( ) . outer_margin ) ) ;
360
+ } ) ;
361
+ row. col ( |ui| {
362
+ ui. label ( format ! ( "{:?}" , node. layout_direction) ) ;
363
+ } ) ;
364
+ } ) ;
365
+ }
366
+ } ) ;
367
+ } ) ;
368
+ }
369
+
370
+ fn print_margin ( margin : & egui:: Margin ) -> String {
371
+ if margin. is_same ( ) {
372
+ format ! ( "{}px" , margin. left)
373
+ } else {
374
+ let s1 = if margin. left == margin. right {
375
+ format ! ( "H: {}px" , margin. left)
376
+ } else {
377
+ format ! ( "L: {}px R: {}px" , margin. left, margin. right)
378
+ } ;
379
+ let s2 = if margin. top == margin. bottom {
380
+ format ! ( "V: {}px" , margin. top)
381
+ } else {
382
+ format ! ( "T: {}px B: {}px" , margin. top, margin. bottom)
383
+ } ;
384
+ format ! ( "{s1} / {s2}" )
385
+ }
386
+ }
0 commit comments