def _process_ok_cancel_events(self, event): """ Handle what happens when you press OK and Cancel. :param event: event to check. """ if event.type == UI_BUTTON_PRESSED and event.ui_element == self.cancel_button: self.kill() if (event.type == UI_BUTTON_PRESSED and event.ui_element == self.ok_button and self._validate_file_path(self.current_file_path)): # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_FILE_DIALOG_PATH_PICKED), 'text': str(self.current_file_path), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'text': str(self.current_file_path), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_FILE_DIALOG_PATH_PICKED, event_data)) self.kill()
def _set_value_from_slider(self, new_value: int): """ For updating the value in the text entry element when we've moved the slider. Also sends out an event for the color picker. :param new_value: The new value to set. """ clipped_value = min(self.range[1], max(self.range[0], new_value)) if clipped_value != self.current_value: self.current_value = clipped_value self.entry.set_text(str(self.current_value)) # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED), 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data))
def on_unhovered(self): """ Called when we leave the hover state. Resets the colours and images to normal and kills any tooltip that was created while we were hovering the button. """ self.drawable_shape.set_active_state( self._get_appropriate_state_name()) if self.tool_tip is not None: self.tool_tip.kill() self.tool_tip = None # old event to remove in 0.8.0 event_data = { 'user_type': OldType(UI_BUTTON_ON_UNHOVERED), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_BUTTON_ON_UNHOVERED, event_data))
def on_moved_to_front(self): """ Called when a window is moved to the front of the stack. """ # old event - to be removed in 0.8.0 window_front_event = pygame.event.Event(pygame.USEREVENT, {'user_type': OldType(UI_WINDOW_MOVED_TO_FRONT), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id}) pygame.event.post(window_front_event) # new event window_front_event = pygame.event.Event(UI_WINDOW_MOVED_TO_FRONT, {'ui_element': self, 'ui_object_id': self.most_specific_combined_id}) pygame.event.post(window_front_event)
def process_event(self, event: pygame.event.Event) -> bool: """ Allows the text entry box to react to input events, which is it's primary function. The entry element reacts to various types of mouse clicks (double click selecting words, drag select), keyboard combos (CTRL+C, CTRL+V, CTRL+X, CTRL+A), individual editing keys (Backspace, Delete, Left & Right arrows) and other keys for inputting letters, symbols and numbers. :param event: The current event to consider reacting to. :return: Returns True if we've done something with the input event. """ consumed_event = False initial_text_state = self.text if self._process_mouse_button_event(event): consumed_event = True if self.is_enabled and self.is_focused and event.type == pygame.KEYDOWN: if self._process_keyboard_shortcut_event(event): consumed_event = True elif self._process_action_key_event(event): consumed_event = True elif self._process_text_entry_key(event): consumed_event = True if self.is_enabled and self.is_focused and event.type == pygame.KEYUP: if event.key == pygame.K_RETURN or event.key == pygame.K_KP_ENTER: self.text_entered = False # reset text input entry if self.text != initial_text_state: # old event to be removed in 0.8.0 event_data = {'user_type': OldType(UI_TEXT_ENTRY_CHANGED), 'text': self.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = {'text': self.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(UI_TEXT_ENTRY_CHANGED, event_data)) return consumed_event
def kill(self): """ Overrides the basic kill() method of a pygame sprite so that we also kill all the UI elements in this window, and remove if from the window stack. """ # old event - to be removed in 0.8.0 window_close_event = pygame.event.Event(pygame.USEREVENT, {'user_type': OldType(UI_WINDOW_CLOSE), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id}) pygame.event.post(window_close_event) # new event window_close_event = pygame.event.Event(UI_WINDOW_CLOSE, {'ui_element': self, 'ui_object_id': self.most_specific_combined_id}) pygame.event.post(window_close_event) self.window_stack.remove_window(self) self._window_root_container.kill() super().kill()
def on_hovered(self): """ Called when we enter the hover state, it sets the colours and image of the button to the appropriate values and redraws it. """ self.drawable_shape.set_active_state('hovered') self.hover_time = 0.0 # old event to remove in 0.8.0 event_data = { 'user_type': OldType(UI_BUTTON_ON_HOVERED), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(UI_BUTTON_ON_HOVERED, event_data))
def process_event(self, event: pygame.event.Event) -> bool: """ Processes events for the closed state of the drop down. :param event: The event to process. :return: Return True if we want to consume this event so it is not passed on to the rest of the UI. """ if event.type == UI_BUTTON_PRESSED and event.ui_element in self.active_buttons: self.should_transition = True if (event.type == UI_SELECTION_LIST_NEW_SELECTION and event.ui_element == self.options_selection_list): selection = self.options_selection_list.get_single_selection() self.drop_down_menu_ui.selected_option = selection self.should_transition = True # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_DROP_DOWN_MENU_CHANGED), 'text': self.drop_down_menu_ui.selected_option, 'ui_element': self.drop_down_menu_ui, 'ui_object_id': self.drop_down_menu_ui.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'text': self.drop_down_menu_ui.selected_option, 'ui_element': self.drop_down_menu_ui, 'ui_object_id': self.drop_down_menu_ui.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_DROP_DOWN_MENU_CHANGED, event_data)) return False # don't consume any events
def _set_value_from_entry(self, new_value: int): """ For updating the value the slider element is set to when we've edited the text entry. The slider may have much less precision than the text entry depending on it's available width so we need to be careful to make the change one way. Also sends out an event for the color picker and clips the value to within the allowed value range. :param new_value: The new value to set. """ clipped_value = min(self.range[1], max(self.range[0], new_value)) if clipped_value != new_value: self.entry.set_text(str(clipped_value)) if clipped_value != self.current_value: self.current_value = clipped_value self.slider.set_current_value(self.current_value) # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED), 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } colour_channel_changed_event = pygame.event.Event( pygame.USEREVENT, event_data) pygame.event.post(colour_channel_changed_event) event_data = { 'value': self.current_value, 'channel_index': self.channel_index, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } colour_channel_changed_event = pygame.event.Event( UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED, event_data) pygame.event.post(colour_channel_changed_event)
def process_event(self, event: pygame.event.Event) -> bool: """ Handles events that this UI element is interested in. In this case we are responding to the colour channel elements being changed, the OK or Cancel buttons being pressed or the user clicking the mouse inside of the Saturation & Value picking square. :param event: The pygame Event to process. :return: True if event is consumed by this element and should not be passed on to other elements. """ consumed_event = super().process_event(event) if event.type == UI_BUTTON_PRESSED and event.ui_element == self.cancel_button: self.kill() if event.type == UI_BUTTON_PRESSED and event.ui_element == self.ok_button: # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_COLOUR_PICKER_COLOUR_PICKED), 'colour': self.current_colour, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'colour': self.current_colour, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_COLOUR_PICKER_COLOUR_PICKED, event_data)) self.kill() if event.type == UI_COLOUR_PICKER_COLOUR_CHANNEL_CHANGED: if event.ui_element in [ self.hue_channel, self.sat_channel, self.value_channel ]: self.current_colour.hsva = (self.hue_channel.current_value, self.sat_channel.current_value, self.value_channel.current_value, 100) self.changed_hsv_update_rgb() self.update_current_colour_image() self.update_saturation_value_square() elif event.ui_element in [ self.red_channel, self.green_channel, self.blue_channel ]: self.current_colour[event.channel_index] = event.value self.changed_rgb_update_hsv() self.update_current_colour_image() self.update_saturation_value_square() if event.type == pygame.MOUSEBUTTONDOWN and event.button == pygame.BUTTON_LEFT: scaled_mouse_pos = self.ui_manager.calculate_scaled_mouse_position( event.pos) if self.sat_value_square.rect.collidepoint(scaled_mouse_pos): relative_click_pos = [ scaled_mouse_pos[0] - self.sat_value_square.rect.left, scaled_mouse_pos[1] - self.sat_value_square.rect.top ] # put in range 0 - 100 and reverse y x_value = int( (relative_click_pos[0] / self.sat_value_square.rect.width) * 100) y_value = int( (relative_click_pos[1] / self.sat_value_square.rect.height) * 100) value = min(100, max(0, x_value)) saturation = min(100, max(0, 100 - y_value)) self.sat_channel.set_value(saturation) self.value_channel.set_value(value) self.current_colour.hsva = (self.hue_channel.current_value, self.sat_channel.current_value, self.value_channel.current_value, 100) self.changed_hsv_update_rgb() self.update_current_colour_image() return consumed_event
def process_event(self, event: pygame.event.Event) -> bool: """ Deals with input events. In this case we just handle clicks on any links in the text. :param event: A pygame event to check for a reaction to. :return: Returns True if we consumed this event. """ consumed_event = False should_redraw_from_layout = False if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: scaled_mouse_pos = self.ui_manager.calculate_scaled_mouse_position( event.pos) if self.hover_point(scaled_mouse_pos[0], scaled_mouse_pos[1]): consumed_event = True if self.is_enabled: if self.scroll_bar is not None: text_block_full_height = self.text_box_layout.layout_rect.height height_adjustment = (self.scroll_bar.start_percentage * text_block_full_height) else: height_adjustment = 0 base_x = int(self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset) base_y = int(self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset - height_adjustment) for chunk in self.link_hover_chunks: hover_rect = pygame.Rect( (base_x + chunk.x, base_y + chunk.y), chunk.size) if hover_rect.collidepoint(scaled_mouse_pos[0], scaled_mouse_pos[1]): consumed_event = True if not chunk.is_active: chunk.set_active() should_redraw_from_layout = True if self.is_enabled and event.type == pygame.MOUSEBUTTONUP and event.button == 1: if self.scroll_bar is not None: height_adjustment = (self.scroll_bar.start_percentage * self.text_box_layout.layout_rect.height) else: height_adjustment = 0 base_x = int(self.rect[0] + self.padding[0] + self.border_width + self.shadow_width + self.rounded_corner_offset) base_y = int(self.rect[1] + self.padding[1] + self.border_width + self.shadow_width + self.rounded_corner_offset - height_adjustment) scaled_mouse_pos = self.ui_manager.calculate_scaled_mouse_position( event.pos) for chunk in self.link_hover_chunks: hover_rect = pygame.Rect((base_x + chunk.x, base_y + chunk.y), chunk.size) if (hover_rect.collidepoint(scaled_mouse_pos[0], scaled_mouse_pos[1]) and self.rect.collidepoint(scaled_mouse_pos[0], scaled_mouse_pos[1])): consumed_event = True if chunk.is_active: # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_TEXT_BOX_LINK_CLICKED), 'link_target': chunk.href, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'link_target': chunk.href, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_TEXT_BOX_LINK_CLICKED, event_data)) if chunk.is_active: chunk.set_inactive() should_redraw_from_layout = True if should_redraw_from_layout: self.redraw_from_text_block() return consumed_event
def update(self, time_delta: float): """ Takes care of actually moving the slider based on interactions reported by the buttons or based on movement of the mouse if we are gripping the slider itself. :param time_delta: the time in seconds between calls to update. """ super().update(time_delta) if not (self.alive() and self.is_enabled): return moved_this_frame = False moved_this_frame = self._update_arrow_buttons(moved_this_frame, time_delta) mouse_x, mouse_y = self.ui_manager.get_mouse_position() if self.sliding_button.held and self.sliding_button.in_hold_range( (mouse_x, mouse_y)): if not self.grabbed_slider: self.grabbed_slider = True real_scroll_pos = self.sliding_button.rect.left self.starting_grab_x_difference = mouse_x - real_scroll_pos real_scroll_pos = self.sliding_button.rect.left current_grab_difference = mouse_x - real_scroll_pos adjustment_required = current_grab_difference - self.starting_grab_x_difference self.scroll_position = self.scroll_position + adjustment_required self.scroll_position = min( max(self.scroll_position, self.left_limit_position), self.right_limit_position) x_pos = (self.scroll_position + self.arrow_button_width) y_pos = 0 self.sliding_button.set_relative_position((x_pos, y_pos)) moved_this_frame = True elif not self.sliding_button.held: self.grabbed_slider = False if moved_this_frame: self.current_percentage = self.scroll_position / self.scrollable_width self.current_value = self.value_range[0] + ( self.current_percentage * (self.value_range[1] - self.value_range[0])) if self.use_integers_for_value: self.current_value = int(self.current_value) if not self.has_moved_recently: self.has_moved_recently = True if not self.has_been_moved_by_user_recently: self.has_been_moved_by_user_recently = True # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_HORIZONTAL_SLIDER_MOVED), 'value': self.current_value, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'value': self.current_value, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(UI_HORIZONTAL_SLIDER_MOVED, event_data))
def _process_action_key_event(self, event: pygame.event.Event) -> bool: """ Check if event is one of the keys that triggers an action like deleting, or moving the edit position. :param event: The event to check. :return: True if event is consumed. """ consumed_event = False if ((event.key == pygame.K_RETURN or event.key == pygame.K_KP_ENTER) and not self.text_entered): # old event - to be removed in 0.8.0 event_data = {'user_type': OldType(UI_TEXT_ENTRY_FINISHED), 'text': self.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = {'text': self.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(UI_TEXT_ENTRY_FINISHED, event_data)) consumed_event = True self.text_entered = True elif event.key == pygame.K_BACKSPACE: if abs(self.select_range[0] - self.select_range[1]) > 0: if self.drawable_shape is not None: self.drawable_shape.text_box_layout.delete_selected_text() self.drawable_shape.apply_active_text_changes() low_end = min(self.select_range[0], self.select_range[1]) high_end = max(self.select_range[0], self.select_range[1]) self.text = self.text[:low_end] + self.text[high_end:] self.edit_position = low_end self.select_range = [0, 0] self.cursor_has_moved_recently = True if self.drawable_shape is not None: self.drawable_shape.text_box_layout.set_cursor_position(self.edit_position) self.drawable_shape.apply_active_text_changes() elif self.edit_position > 0 and self.font is not None: if self.start_text_offset > 0: self.start_text_offset -= self.font.get_rect( self.text[self.edit_position - 1]).width self.text = self.text[:self.edit_position - 1] + self.text[self.edit_position:] self.edit_position -= 1 self.cursor_has_moved_recently = True if self.drawable_shape is not None: self.drawable_shape.text_box_layout.backspace_at_cursor() self.drawable_shape.text_box_layout.set_cursor_position(self.edit_position) self.drawable_shape.apply_active_text_changes() consumed_event = True elif event.key == pygame.K_DELETE: if abs(self.select_range[0] - self.select_range[1]) > 0: if self.drawable_shape is not None: self.drawable_shape.text_box_layout.delete_selected_text() self.drawable_shape.apply_active_text_changes() low_end = min(self.select_range[0], self.select_range[1]) high_end = max(self.select_range[0], self.select_range[1]) self.text = self.text[:low_end] + self.text[high_end:] self.edit_position = low_end self.select_range = [0, 0] self.cursor_has_moved_recently = True if self.drawable_shape is not None: self.drawable_shape.text_box_layout.set_cursor_position(self.edit_position) self.drawable_shape.apply_active_text_changes() elif self.edit_position < len(self.text): self.text = self.text[:self.edit_position] + self.text[self.edit_position + 1:] self.edit_position = self.edit_position self.cursor_has_moved_recently = True if self.drawable_shape is not None: self.drawable_shape.text_box_layout.delete_at_cursor() self.drawable_shape.apply_active_text_changes() consumed_event = True elif self._process_edit_pos_move_key(event): consumed_event = True return consumed_event
def process_event(self, event: pygame.event.Event) -> bool: """ Handles various interactions with the button. :param event: The event to process. :return: Return True if we want to consume this event so it is not passed on to the rest of the UI. """ consumed_event = False if event.type == pygame.MOUSEBUTTONDOWN and event.button in self.generate_click_events_from: scaled_mouse_pos = self.ui_manager.calculate_scaled_mouse_position( event.pos) if self.hover_point(scaled_mouse_pos[0], scaled_mouse_pos[1]): if self.is_enabled: if (self.allow_double_clicks and self.last_click_button == event.button and self.double_click_timer <= self.ui_manager.get_double_click_time()): # old event to remove in 0.8.0 event_data = { 'user_type': OldType(UI_BUTTON_DOUBLE_CLICKED), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'ui_element': self, 'ui_object_id': self.most_specific_combined_id, 'mouse_button': event.button } pygame.event.post( pygame.event.Event(UI_BUTTON_DOUBLE_CLICKED, event_data)) else: # old event to remove in 0.8.0 event_data = { 'user_type': OldType(UI_BUTTON_START_PRESS), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'ui_element': self, 'ui_object_id': self.most_specific_combined_id, 'mouse_button': event.button } pygame.event.post( pygame.event.Event(UI_BUTTON_START_PRESS, event_data)) self.double_click_timer = 0.0 self.last_click_button = event.button self.held = True self._set_active() self.hover_time = 0.0 if self.tool_tip is not None: self.tool_tip.kill() self.tool_tip = None consumed_event = True if event.type == pygame.MOUSEBUTTONUP and event.button in self.generate_click_events_from: scaled_mouse_pos = self.ui_manager.calculate_scaled_mouse_position( event.pos) if (self.is_enabled and self.drawable_shape.collide_point(scaled_mouse_pos) and self.held): self.held = False self._set_inactive() consumed_event = True self.pressed_event = True # old event event_data = { 'user_type': OldType(UI_BUTTON_PRESSED), 'ui_element': self, 'ui_object_id': self.most_specific_combined_id } pygame.event.post( pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'ui_element': self, 'ui_object_id': self.most_specific_combined_id, 'mouse_button': event.button } pygame.event.post( pygame.event.Event(UI_BUTTON_PRESSED, event_data)) if self.is_enabled and self.held: self.held = False self._set_inactive() consumed_event = True return consumed_event
def process_event(self, event: pygame.event.Event) -> bool: """ Can be overridden, also handle resizing windows. Gives UI Windows access to pygame events. Currently just blocks mouse click down events from passing through the panel. :param event: The event to process. :return: Should return True if this element makes use of this event. """ if self.is_enabled and ( event.type in [UI_BUTTON_PRESSED, UI_BUTTON_DOUBLE_CLICKED] and event.ui_element in self.item_list_container.elements): for item in self.item_list: if item['button_element'] == event.ui_element: if event.type == UI_BUTTON_DOUBLE_CLICKED: # old event - to be removed in 0.8.0 event_data = { 'user_type': OldType(UI_SELECTION_LIST_DOUBLE_CLICKED_SELECTION), 'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = { 'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post( pygame.event.Event(UI_SELECTION_LIST_DOUBLE_CLICKED_SELECTION, event_data)) else: if item['selected']: item['selected'] = False event.ui_element.unselect() # old event - to be removed in 0.8.0 event_data = {'user_type': OldType(UI_SELECTION_LIST_DROPPED_SELECTION), 'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = {'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post( pygame.event.Event(UI_SELECTION_LIST_DROPPED_SELECTION, event_data)) else: item['selected'] = True event.ui_element.select() # old event - to be removed in 0.8.0 event_data = {'user_type': OldType(UI_SELECTION_LIST_NEW_SELECTION), 'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(pygame.USEREVENT, event_data)) # new event event_data = {'text': event.ui_element.text, 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} pygame.event.post(pygame.event.Event(UI_SELECTION_LIST_NEW_SELECTION, event_data)) elif not self.allow_multi_select: if item['selected']: item['selected'] = False if item['button_element'] is not None: item['button_element'].unselect() # old event - to be removed in 0.8.0 event_data = {'user_type': OldType(UI_SELECTION_LIST_DROPPED_SELECTION), 'text': item['text'], 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} drop_down_changed_event = pygame.event.Event(pygame.USEREVENT, event_data) pygame.event.post(drop_down_changed_event) # new event event_data = {'text': item['text'], 'ui_element': self, 'ui_object_id': self.most_specific_combined_id} drop_down_changed_event = pygame.event.Event( UI_SELECTION_LIST_DROPPED_SELECTION, event_data) pygame.event.post(drop_down_changed_event) return False # Don't consume any events