MyreMylar / pygame_gui

A GUI system for pygame.
MIT License
698 stars 83 forks source link

HTML styled link click events trigger multiple times after resize #206

Closed RedFlames closed 2 years ago

RedFlames commented 3 years ago

Describe the bug I was looking at the pygame_gui_examples and noticed that styled link click events fire multiple times after resizing the text box.

To Reproduce Steps to reproduce the behaviour:

  1. Run general_ui_test_app.py from the pygame_gui_examples or anything with a resizable HTML styled link.
  2. Resize the UIMessageWindow created by the #hover_me_button
  3. Click a link within the UIMessageWindow and observe the console output triggered by the events.

Expected behaviour Events triggered by HTML links should only ever fire once per click.

Screenshots Not a screenshot but console output:

Time taken to create message window: 0.006
clicked test link at 16:05:10
clicked actually link at 16:05:10
clicked test link at 16:05:10
clicked actually link at 16:05:11

I clicked them alternatingly and it fires as expected.

With some resizing:

clicked test link at 16:06:10
clicked test link at 16:06:10
clicked test link at 16:06:10
clicked test link at 16:06:10
clicked actually link at 16:06:10
clicked test link at 16:06:17
clicked test link at 16:06:17
clicked test link at 16:06:17
clicked test link at 16:06:17
clicked test link at 16:06:17
clicked actually link at 16:06:18
clicked actually link at 16:06:18

Still clicking them alternatingly, i.e. I clicked 'test', 'actually', 'test', 'actually'.

Platform and software (please complete the following information):

Additional context I looked through the code and at elements/ui_text_box.py in particular.

With some good old print statements in process_events() I get this:

Processing event MouseButtonDown (1025) and I have 2 link_hover_chunks:
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
Processing event MouseButtonUp (1026) and I have 2 link_hover_chunks:
     Chunk 'test' is link is hovered is selected
     Chunk 'actually' is link

Processing event UserEvent (32847) and I have 2 link_hover_chunks:
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
clicked test link at 15:39:33

[...]

Processing event MouseButtonDown (1025) and I have 4 link_hover_chunks:
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
Processing event MouseButtonUp (1026) and I have 4 link_hover_chunks:
     Chunk 'test' is link is hovered is selected
     Chunk 'actually' is link  
     Chunk 'test' is link is hovered is selected
     Chunk 'actually' is link

Processing event UserEvent (32847) and I have 4 link_hover_chunks:
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
clicked test link at 15:40:47

Processing event UserEvent (32847) and I have 4 link_hover_chunks:
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
     Chunk 'test' is link is hovered 
     Chunk 'actually' is link  
clicked test link at 15:40:47

(just printing out len(self.link_hover_chunks) and the list's StyledChunk items)


I saw this at line 550 of ui_text_box.py in full_redraw():

        self.link_hover_chunks = []
        self.formatted_text_block.add_chunks_to_hover_group(self.link_hover_chunks)

but at line 282 of ui_text_box.py in rebuild():

        self.formatted_text_block.add_chunks_to_hover_group(self.link_hover_chunks)

without ever clearing self.link_hover_chunks. _(after a call to parse_html_into_style_data() which creates a new self.formatted_text_block = TextBlock(...))_


So I think a fix would be to either put a self.link_hover_chunks = [] at line 281, or into parse_html_into_style_data() or potentially both.

MyreMylar commented 3 years ago

Thanks for not only finding this but also looking into what caused it :) Saves me some time for sure.

I'll roll a fix for this into the next update since it's going over the text boxes anyway.