@@ -130,6 +130,8 @@ class AdditionalFilterPlugin(_StageManagerUSDFilterPlugin):
130130 _modified_filters : list [_StageManagerUSDFilterPlugin ] = PrivateAttr (default = [])
131131
132132 _icon : ui .Image | None = PrivateAttr (default = None )
133+ _counter_circle : ui .Circle | None = PrivateAttr (default = None )
134+ _counter_label : ui .Label | None = PrivateAttr (default = None )
133135
134136 def filter_predicate (self , item : _StageManagerItem ) -> bool :
135137 # This filter is not used, it is only here to satisfy the interface
@@ -228,6 +230,15 @@ def _on_filter_changed(self):
228230 self ._update_active_filters ()
229231 if self ._icon :
230232 self ._icon .name = "FilterActive" if self ._modified_filters else "Filter"
233+ if self ._counter_circle is None or self ._counter_label is None :
234+ return
235+ if self ._modified_filters :
236+ self ._counter_circle .visible = True
237+ self ._counter_label .visible = True
238+ self ._counter_label .text = str (len (self ._modified_filters ))
239+ else :
240+ self ._counter_circle .visible = False
241+ self ._counter_label .visible = False
231242
232243 def _on_button_clicked (self ):
233244 self ._update_active_filters ()
@@ -238,15 +249,39 @@ def build_ui(self): # noqa PLW0221
238249 # Gather available filters and update active filters
239250 if not self ._active_filters :
240251 self ._active_filters = self ._get_available_filters ()
241- else :
242- self ._update_active_filters ()
252+
253+ self ._update_active_filters ()
254+
255+ # Clean up existing UI elements if they exist
256+ if self ._icon :
257+ self ._icon .destroy ()
258+ if self ._counter_circle :
259+ self ._counter_circle .destroy ()
260+ if self ._counter_label :
261+ self ._counter_label .destroy ()
243262
244263 with ui .HStack (height = 0 ):
245- self ._icon = ui .Image (
246- "" ,
247- name = "FilterActive" if self ._modified_filters else "Filter" ,
248- tooltip = "Additional Filters" ,
249- mouse_pressed_fn = lambda x , y , b , m : self ._on_button_clicked (),
250- width = ui .Pixel (24 ),
251- height = ui .Pixel (24 ),
252- )
264+ with ui .ZStack (width = ui .Pixel (24 ), height = ui .Pixel (24 )):
265+ self ._icon = ui .Image (
266+ "" ,
267+ name = "FilterActive" if self ._modified_filters else "Filter" ,
268+ tooltip = "Additional Filters" ,
269+ mouse_pressed_fn = lambda x , y , b , m : self ._on_button_clicked (),
270+ width = ui .Pixel (24 ),
271+ height = ui .Pixel (24 ),
272+ )
273+
274+ # A counter badge to show the number of modified filters.
275+ # It is hidden by default and shown when there are modified filters.
276+ count = len (self ._modified_filters )
277+ with ui .VStack (padding = 8 ):
278+ with ui .HStack (padding = 8 ):
279+ with ui .ZStack (width = ui .Pixel (14 ), height = ui .Pixel (14 )):
280+ self ._counter_circle = ui .Circle (radius = 12 , style = {"background_color" : 0xFF646464 })
281+ self ._counter_circle .visible = bool (self ._modified_filters )
282+ self ._counter_label = ui .Label (
283+ str (count ), alignment = ui .Alignment .CENTER , style = {"font_size" : 10 , "color" : 0xFFFFFFFF }
284+ )
285+ self ._counter_label .visible = bool (self ._modified_filters )
286+ ui .Spacer ()
287+ ui .Spacer ()
0 commit comments