def update(self, events): updated = False for event in events: # type: pygame.event.Event if event.type == pygame.KEYDOWN: # Check key is valid if not check_key_pressed_valid(event): continue # Events keydown = event.type == pygame.KEYDOWN joy_hatmotion = self.joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self.joystick_enabled and event.type == pygame.JOYAXISMOTION joy_button_down = self.joystick_enabled and event.type == pygame.JOYBUTTONDOWN if keydown and event.key == _controls.KEY_LEFT or \ joy_hatmotion and event.value == _controls.JOY_LEFT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value < _controls.JOY_DEADZONE: self.sound.play_key_add() self.left() updated = True elif keydown and event.key == _controls.KEY_RIGHT or \ joy_hatmotion and event.value == _controls.JOY_RIGHT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value > -_controls.JOY_DEADZONE: self.sound.play_key_add() self.right() updated = True elif keydown and event.key == _controls.KEY_APPLY or \ joy_button_down and event.button == _controls.JOY_BUTTON_SELECT: self.sound.play_open_menu() self.apply(*self._elements[self._index][1:]) updated = True elif self.mouse_enabled and event.type == pygame.MOUSEBUTTONUP: if self._rect.collidepoint(*event.pos): # Check if mouse collides left or right as percentage, use only X coordinate mousex, _ = event.pos topleft, _ = self._rect.topleft topright, _ = self._rect.topright dist = mousex - (topleft + self._title_size ) # Distance from label if dist > 0: # User clicked the options, not label # Position in percentage, if <0.5 user clicked left pos = dist / float(topright - topleft - self._title_size) if pos <= 0.5: self.left() else: self.right() updated = True return updated
def update( self, events: Union[List['pygame.event.Event'], Tuple['pygame.event.Event']] ) -> bool: if self.readonly: return False updated = False for event in events: if event.type == pygame.KEYDOWN: # Check key is valid if not check_key_pressed_valid(event): continue # Events keydown = event.type == pygame.KEYDOWN joy_hatmotion = self._joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION joy_button_down = self._joystick_enabled and event.type == pygame.JOYBUTTONDOWN # Left button if keydown and event.key == _controls.KEY_LEFT or \ joy_hatmotion and event.value == _controls.JOY_LEFT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value < _controls.JOY_DEADZONE: self._sound.play_key_add() self._left() updated = True # Right button elif keydown and event.key == _controls.KEY_RIGHT or \ joy_hatmotion and event.value == _controls.JOY_RIGHT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value > -_controls.JOY_DEADZONE: self._sound.play_key_add() self._right() updated = True # Press enter elif keydown and event.key == _controls.KEY_APPLY or \ joy_button_down and event.button == _controls.JOY_BUTTON_SELECT: self._sound.play_open_menu() self.apply(*self._elements[self._index][1:]) updated = True # Click on selector elif self._mouse_enabled and event.type == pygame.MOUSEBUTTONUP or \ self._touchscreen_enabled and event.type == pygame.FINGERUP: # Get event position based on input type if self._touchscreen_enabled and event.type == pygame.FINGERUP: window_size = self.get_menu().get_window_size() event_pos = (event.x * window_size[0], event.y * window_size[1]) else: event_pos = event.pos # If collides rect = self.get_rect() if rect.collidepoint(*event_pos): # Check if mouse collides left or right as percentage, use only X coordinate mousex, _ = event.pos topleft, _ = rect.topleft topright, _ = rect.topright dist = mousex - (topleft + self._title_size ) # Distance from title if dist > 0: # User clicked the options, not title # Position in percentage, if <0.5 user clicked left pos = dist / float(topright - topleft - self._title_size) if pos <= 0.5: self._left() else: self._right() updated = True if updated: self.apply_update_callbacks() return updated
def update(self, events): _input = self._input_string _curpos = self._cursor_position _disable_remove_separator = True key = '' # Pressed key if self._color_type == TYPE_RGB: for event in events: # type: pygame.event.Event if event.type == pygame.KEYDOWN: # Check if any key is pressed, if True the event is invalid if not check_key_pressed_valid(event): return True if _disable_remove_separator and len(_input) > 0 and len( _input) > _curpos and ( '{0}{0}'.format(self._separator) not in _input or _input[_curpos] == self._separator and len(_input) == _curpos + 1): # Backspace button, delete text from right if event.key == pygame.K_BACKSPACE: if len(_input) >= 1 and _input[ _curpos - 1] == self._separator: return True # Delete button, delete text from left elif event.key == pygame.K_DELETE: if _input[_curpos] == self._separator: return True # Verify only on user key input, the rest of events are checked by TextInput on super call key = str(event.unicode) if key in self._valid_chars: _new_string = ( self._input_string[:self._cursor_position] + key + self._input_string[self._cursor_position:]) # Cannot be separator at first if len(_input) == 0 and key == self._separator: return False if len(_input) > 1: # Check separators if key == self._separator: # If more than 2 separators _total_separator = 0 for _ch in _input: if _ch == self._separator: _total_separator += 1 if _total_separator >= 2: return False # Check the number between the current separators, this number must be between 0-255 if key != self._separator: _pos_before = 0 _pos_after = 0 for _i in range(_curpos): if _new_string[_curpos - _i - 1] == self._separator: _pos_before = _curpos - _i break for _i in range(len(_new_string) - _curpos): if _new_string[_curpos + _i] == self._separator: _pos_after = _curpos + _i break if _pos_after == 0: _pos_after = len(_new_string) _num = _new_string[ _pos_before:_pos_after].replace(',', '') if _num == '': _num = '0' if int(_num) > 255: # Number exceeds 25X return False if _num != str( int(_num) ) and key == '0': # User adds 0 at left, example: 12 -> 012 return False if len(_num) > 3: # Number like 0XXX return False elif self._color_type == TYPE_HEX: for event in events: # type: pygame.event.Event if event.type == pygame.KEYDOWN: # Check if any key is pressed, if True the event is invalid if not check_key_pressed_valid(event): return True # Backspace button, delete text from right if event.key == pygame.K_BACKSPACE: if _curpos == 1: return True # Delete button, delete text from left elif event.key == pygame.K_DELETE: if _curpos == 0: return True # Verify only on user key input, the rest of events are checked by TextInput on super call key = str(event.unicode) if key in self._valid_chars: if key == '#': return True if _curpos == 0: return True # Update updated = super(ColorInput, self).update(events) # After if self._color_type == TYPE_RGB: _total_separator = 0 for _ch in _input: if _ch == self._separator: _total_separator += 1 # Adds auto separator if key == '0' and len(self._input_string) == self._cursor_position and _total_separator < 2 and \ (len(self._input_string) == 1 or (len(self._input_string) > 2 and self._input_string[ self._cursor_position - 2] == self._separator)): self._push_key_input(self._separator, sounds=False) # This calls .onchange() # Check number is valid (fix) because sometimes the user can type # too fast and avoid analysis of the text colors = self._input_string.split(self._separator) for c in colors: if len(c) > 0 and (int(c) > 255 or int(c) < 0): self._input_string = _input self._cursor_position = _curpos break if len(colors) == 3: self._auto_separator_pos = [0, 1] # Add an auto separator if the number can't continue growing and the cursor # is at the end of the line if _total_separator < 2 and len( self._input_string) == self._cursor_position: autopos = len(colors) - 1 last_num = colors[autopos] if (len(last_num) == 2 and int(last_num) > 25 or len(last_num) == 3 and int(last_num) <= 255) and \ autopos not in self._auto_separator_pos: self._push_key_input( self._separator, sounds=False) # This calls .onchange() self._auto_separator_pos.append(autopos) # If the user cleared all the string, reset auto separator if _total_separator == 0 and \ (len(self._input_string) < 2 or len(self._input_string) == 2 and int(colors[0]) <= 25): self._auto_separator_pos = [] return updated
def update(self, events: EventVectorType) -> bool: if self.readonly or not self.is_visible(): return False input_str = self._input_string cursor_pos = self._cursor_position disable_remove_separator = True key = '' # Pressed key if self._color_type == COLORINPUT_TYPE_RGB: for event in events: # User writes if event.type == pygame.KEYDOWN and self._keyboard_enabled: # Check if any key is pressed, if True the event is invalid if not check_key_pressed_valid(event): return True if disable_remove_separator and len(input_str) > 0 and len(input_str) > cursor_pos and ( '{0}{0}'.format(self._separator) not in input_str or input_str[cursor_pos] == self._separator and len(input_str) == cursor_pos + 1 ): # Backspace button, delete text from right if event.key == pygame.K_BACKSPACE: if len(input_str) >= 1 and input_str[cursor_pos - 1] == self._separator: return True # Delete button, delete text from left elif event.key == pygame.K_DELETE: if input_str[cursor_pos] == self._separator: return True # Verify only on user key input, the rest of events are checked by TextInput on super call key = str(event.unicode) if key in self._valid_chars: new_string = ( self._input_string[:self._cursor_position] + key + self._input_string[self._cursor_position:] ) # Cannot be separator at first if len(input_str) == 0 and key == self._separator: return False if len(input_str) > 1: # Check separators if key == self._separator: # If more than 2 separators total_separator = 0 for ch in input_str: if ch == self._separator: total_separator += 1 if total_separator >= 2: return False # Check the number between the current separators, this number must be between 0-255 if key != self._separator: pos_before = 0 pos_after = 0 for i in range(cursor_pos): if new_string[cursor_pos - i - 1] == self._separator: pos_before = cursor_pos - i break for i in range(len(new_string) - cursor_pos): if new_string[cursor_pos + i] == self._separator: pos_after = cursor_pos + i break if pos_after == 0: pos_after = len(new_string) num = new_string[pos_before:pos_after].replace(',', '') if num == '': num = '0' if int(num) > 255: # Number exceeds 25X return False if num != str(int(num)) and key == '0': # User adds 0 at left, example: 12 -> 012 return False if len(num) > 3: # Number like 0XXX return False elif self._color_type == COLORINPUT_TYPE_HEX: self._format_hex() for event in events: # User writes if event.type == pygame.KEYDOWN and self._keyboard_enabled: # Check if any key is pressed, if True the event is invalid if not check_key_pressed_valid(event): return True # Backspace button, delete text from right if event.key == pygame.K_BACKSPACE: if cursor_pos == 1: return True # Delete button, delete text from left elif event.key == pygame.K_DELETE: if cursor_pos == 0: return True # Verify only on user key input, the rest of events are checked by TextInput on super call key = str(event.unicode) if key in self._valid_chars: if key == '#': return True if cursor_pos == 0: return True # Update updated = super(ColorInput, self).update(events) # After if self._color_type == COLORINPUT_TYPE_RGB: total_separator = 0 for ch in input_str: if ch == self._separator: total_separator += 1 # Adds auto separator if key == '0' and len(self._input_string) == self._cursor_position and total_separator < 2 and \ (len(self._input_string) == 1 or (len(self._input_string) > 2 and self._input_string[ self._cursor_position - 2] == self._separator)): self._push_key_input(self._separator, sounds=False) # This calls .onchange() # Check number is valid (fix) because sometimes the user can type # too fast and avoid analysis of the text colors = self._input_string.split(self._separator) for c in colors: if len(c) > 0 and (int(c) > 255 or int(c) < 0): self._input_string = input_str self._cursor_position = cursor_pos break if len(colors) == 3: self._auto_separator_pos = [0, 1] # Add an auto separator if the number can't continue growing and the cursor # is at the end of the line if total_separator < 2 and len(self._input_string) == self._cursor_position: auto_pos = len(colors) - 1 last_num = colors[auto_pos] if (len(last_num) == 2 and int(last_num) > 25 or len(last_num) == 3 and int(last_num) <= 255) and \ auto_pos not in self._auto_separator_pos: self._push_key_input(self._separator, sounds=False) # This calls .onchange() self._auto_separator_pos.append(auto_pos) # If the user cleared all the string, reset auto separator if total_separator == 0 and \ (len(self._input_string) < 2 or len(self._input_string) == 2 and int(colors[0]) <= 25): self._auto_separator_pos = [] if updated: self.apply_update_callbacks() return updated
def update(self, events: EventVectorType) -> bool: self.apply_update_callbacks(events) if self.readonly or not self.is_visible(): return False updated = False for event in events: if event.type == pygame.KEYDOWN: # Check key is valid if not check_key_pressed_valid(event): continue # Check mouse over self._check_mouseover(event) # Events keydown = self._keyboard_enabled and event.type == pygame.KEYDOWN joy_hatmotion = self._joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION joy_button_down = self._joystick_enabled and event.type == pygame.JOYBUTTONDOWN # Left button if keydown and event.key == ctrl.KEY_LEFT or \ joy_hatmotion and event.value == ctrl.JOY_LEFT or \ joy_axismotion and event.axis == ctrl.JOY_AXIS_X and event.value < ctrl.JOY_DEADZONE: self._left() updated = True # Right button elif keydown and event.key == ctrl.KEY_RIGHT or \ joy_hatmotion and event.value == ctrl.JOY_RIGHT or \ joy_axismotion and event.axis == ctrl.JOY_AXIS_X and event.value > -ctrl.JOY_DEADZONE: self._right() updated = True # Press enter elif keydown and event.key == ctrl.KEY_APPLY or \ joy_button_down and event.button == ctrl.JOY_BUTTON_SELECT: self._sound.play_key_add() self.apply(*self._items[self._index][1:]) updated = True # Click on selector; don't consider the mouse wheel (button 4 & 5) elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ event.button in (1, 2, 3) or \ event.type == FINGERUP and self._touchscreen_enabled and \ self._menu is not None: event_pos = get_finger_pos(self._menu, event) # If collides rect = self.get_rect(to_real_position=True, apply_padding=False) if rect.collidepoint(*event_pos): # Check if mouse collides left or right as percentage, use only X coordinate mouse_x, _ = event.pos topleft, _ = rect.topleft topright, _ = rect.topright dist = mouse_x - (topleft + self._title_size ) # Distance from title if dist > 0: # User clicked the options, not title # Position in percentage, if <0.5 user clicked left pos = dist / float(topright - topleft - self._title_size) if pos <= 0.5: self._left() else: self._right() updated = True return updated
def update(self, events: EventVectorType) -> bool: self.apply_update_callbacks(events) if self.readonly or not self.is_visible(): return False updated = False for event in events: if event.type == pygame.KEYDOWN: # Check key is valid if not check_key_pressed_valid(event): continue # Check mouse over self._check_mouseover(event) # Events keydown = self._keyboard_enabled and event.type == pygame.KEYDOWN joy_hatmotion = self._joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION # Left button if keydown and event.key == KEY_LEFT or \ joy_hatmotion and event.value == JOY_LEFT or \ joy_axismotion and event.axis == JOY_AXIS_X and event.value < JOY_DEADZONE: self._left() updated = True # Right button elif keydown and event.key == KEY_RIGHT or \ joy_hatmotion and event.value == JOY_RIGHT or \ joy_axismotion and event.axis == JOY_AXIS_X and event.value > -JOY_DEADZONE: self._right() updated = True # Press enter elif keydown and event.key == KEY_APPLY and self._total_states == 2 or \ event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and \ event.button == JOY_BUTTON_SELECT and self._total_states == 2: self._sound.play_key_add() self._state = int(not self._state) self.change() updated = True self.active = not self.active # Click on switch; don't consider the mouse wheel (button 4 & 5) elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and event.button in (1, 2, 3) or \ event.type == FINGERUP and self._touchscreen_enabled and self._menu is not None: event_pos = get_finger_pos(self._menu, event) # If collides rect = self.get_rect(to_real_position=True, apply_padding=False) if rect.collidepoint(*event_pos): # Check if mouse collides left or right as percentage, use only X coordinate mouse_x, _ = event.pos topleft, _ = rect.topleft topright, _ = rect.topright dist = mouse_x - ( topleft + self._switch_margin[0] + self._switch_pos[0] ) # Distance from title if dist > 0: # User clicked the options, not title target_index = 0 best = 1e6 # Find the closest position for i in range(self._total_states): dx = abs(self._state_width_accum[i] - dist) if dx < best: target_index = i best = dx if target_index != self._state: self._sound.play_key_add() self._state = target_index self.change() updated = True return updated
def update( self, events: Union[List['pygame.event.Event'], Tuple['pygame.event.Event']] ) -> bool: if self.readonly: return False updated = False for event in events: if event.type == pygame.KEYDOWN: # Check key is valid if not check_key_pressed_valid(event): continue # Events keydown = self._keyboard_enabled and event.type == pygame.KEYDOWN joy_hatmotion = self._joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION # Left button if keydown and event.key == _controls.KEY_LEFT or \ joy_hatmotion and event.value == _controls.JOY_LEFT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value < _controls.JOY_DEADZONE: self._sound.play_key_add() self._left() updated = True # Right button elif keydown and event.key == _controls.KEY_RIGHT or \ joy_hatmotion and event.value == _controls.JOY_RIGHT or \ joy_axismotion and event.axis == _controls.JOY_AXIS_X and event.value > -_controls.JOY_DEADZONE: self._sound.play_key_add() self._right() updated = True # Press enter elif keydown and event.key == _controls.KEY_APPLY and self._total_states == 2: self._sound.play_key_add() self._state = int(not self._state) self.change() updated = True self.active = not self.active # Click on switch elif self._mouse_enabled and event.type == pygame.MOUSEBUTTONUP and event.button in (1, 2, 3) or \ self._touchscreen_enabled and event.type == pygame.FINGERUP: # Don't consider the mouse wheel (button 4 & 5) # Get event position based on input type if self._touchscreen_enabled and event.type == pygame.FINGERUP: window_size = self.get_menu().get_window_size() event_pos = (event.x * window_size[0], event.y * window_size[1]) else: event_pos = event.pos # If collides rect = self.get_rect() if rect.collidepoint(*event_pos): # Check if mouse collides left or right as percentage, use only X coordinate mousex, _ = event.pos topleft, _ = rect.topleft topright, _ = rect.topright dist = mousex - ( topleft + self._switch_margin[0] + self._switch_pos[0] ) # Distance from title if dist > 0: # User clicked the options, not title target_index = 0 best = 1e6 # Find the closest position for i in range(self._total_states): dx = abs(self._state_width_accum[i] - dist) if dx < best: target_index = i best = dx if target_index != self._state: self._sound.play_key_add() self._state = target_index self.change() if updated: self.apply_update_callbacks() return updated
def update(self, events: EventVectorType) -> bool: self.apply_update_callbacks(events) if self.readonly or not self.is_visible(): self._readonly_check_mouseover(events) return False for event in events: if event.type == pygame.KEYDOWN: # Check key is valid if self._ignores_keyboard_nonphysical( ) and not check_key_pressed_valid(event): continue # Check mouse over self._check_mouseover(event) # Events keydown = self._keyboard_enabled and event.type == pygame.KEYDOWN joy_hatmotion = self._joystick_enabled and event.type == pygame.JOYHATMOTION joy_axismotion = self._joystick_enabled and event.type == pygame.JOYAXISMOTION # Left button if keydown and self._ctrl.left(event, self) or \ joy_hatmotion and self._ctrl.joy_left(event, self) or \ joy_axismotion and self._ctrl.joy_axis_x_left(event, self): self._left() return True # Right button elif keydown and self._ctrl.right(event, self) or \ joy_hatmotion and self._ctrl.joy_right(event, self) or \ joy_axismotion and self._ctrl.joy_axis_x_right(event, self): self._right() return True # Press enter elif keydown and self._ctrl.apply(event, self) and self._total_states == 2 or \ event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and \ self._ctrl.joy_select(event, self) and self._total_states == 2: self._sound.play_key_add() self._state = int(not self._state) self.change() self.active = not self.active return True # Click on switch; don't consider the mouse wheel (button 4 & 5) elif event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled and \ event.button in (1, 2, 3) or \ event.type == FINGERUP and self._touchscreen_enabled and \ self._menu is not None: event_pos = get_finger_pos(self._menu, event) # If collides rect = self.get_rect(to_real_position=True, apply_padding=False) if rect.collidepoint(*event_pos): # Check if mouse collides left or right as percentage, use # only X coordinate mouse_x, _ = event_pos topleft, _ = rect.topleft topright, _ = rect.topright # Distance from title dist = mouse_x - (topleft + self._switch_margin[0] + self._switch_pos[0]) if dist > 0: # User clicked the options, not title # Toggle with only 1 click if self._single_click: if self._single_click_dir: self._left() else: self._right() return True else: target_index = 0 best = 1e6 # Find the closest position for i in range(self._total_states): dx = abs(self._state_width_accum[i] - dist) if dx < best: target_index = i best = dx if target_index != self._state: self._sound.play_key_add() self._state = target_index self.change() return True return False