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: # Check mouse over if self._backbox_visible(): self._check_mouseover(event) # User clicks/touches the backbox rect; don't consider the mouse wheel (button 4 & 5) if 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 self._backbox_rect and self._backbox_rect.collidepoint(*event_pos): self._sound.play_click_mouse() self.apply() updated = True # User applies joy back button elif event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled: if event.button == JOY_BUTTON_BACK: self._sound.play_key_del() self.apply() updated = True return updated
def collide(self, widget: Union['pygame_menu.widgets.Widget', 'pygame.Rect'], event: EventType) -> bool: """ If user event collides a widget within the ScrollArea respect to the relative position. :param widget: Widget or rect :param event: Pygame event :return: ``True`` if collide """ if not isinstance(widget, pygame.Rect): widget_rect = widget.get_rect(to_real_position=True) else: widget_rect = widget return bool( widget_rect.collidepoint(*get_finger_pos(self._menu, event)))
def update(self, events: EventVectorType) -> bool: self.apply_update_callbacks(events) if self.readonly or not self.is_visible(): return False rect = self.get_rect(to_real_position=True) for event in events: # Check mouse over self._check_mouseover(event, rect) # User applies with key if event.type == pygame.KEYDOWN and self._keyboard_enabled and \ event.key == ctrl.KEY_APPLY or \ event.type == pygame.JOYBUTTONDOWN and self._joystick_enabled and \ event.button == ctrl.JOY_BUTTON_SELECT: if self.to_menu: self._sound.play_open_menu() else: self._sound.play_key_add() self.apply() return True # User clicks the button; 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: if event.type == pygame.MOUSEBUTTONUP: self._sound.play_click_mouse() else: self._sound.play_click_touch() event_pos = get_finger_pos(self._menu, event) if rect.collidepoint(*event_pos): self.apply() return True return False
def update(self, events: EventVectorType) -> bool: self.apply_update_callbacks(events) if self.readonly or not self.is_visible(): return False rect = self.get_rect(to_absolute_position=True) for event in events: # Check mouse over self._check_mouseover(event) # User press PAGEUP or PAGEDOWN if event.type == pygame.KEYDOWN and \ event.key in (pygame.K_PAGEUP, pygame.K_PAGEDOWN) and \ self._keyboard_enabled and self._orientation == 1 and \ not self.scrolling: direction = 1 if event.key == pygame.K_PAGEDOWN else -1 keys_pressed = pygame.key.get_pressed() step = self._page_step if keys_pressed[pygame.K_LSHIFT] or keys_pressed[pygame.K_RSHIFT]: step *= 0.35 pixels = direction * step if self._scroll(rect, pixels): self.change() return True # User moves mouse while scrolling elif (event.type == pygame.MOUSEMOTION and self._mouse_enabled and hasattr(event, 'rel') or event.type == FINGERMOTION and self._touchscreen_enabled and self._menu is not None) and \ self.scrolling: # Get relative movement h = self.get_orientation() == ORIENTATION_HORIZONTAL rel = event.rel[self._orientation] if event.type == pygame.MOUSEMOTION else ( event.dx * 2 * self._menu.get_window_size()[0] if h else event.dy * 2 * self._menu.get_window_size()[1] ) # If mouse outside region and scroll is on limits, ignore mx, my = event.pos if event.type == pygame.MOUSEMOTION else \ get_finger_pos(self._menu, event) if self.get_value_percentage() in (0, 1) and \ self.get_scrollarea() is not None and \ self.get_scrollarea().get_parent() is not None: if self._orientation == 1: # Vertical h = self._slider_rect.height / 2 if my > (rect.bottom - h) or my < (rect.top + h): continue elif self._orientation == 0: # Horizontal w = self._slider_rect.width / 2 if mx > (rect.right - w) or mx < (rect.left + w): continue # Check scrolling if self._scroll(rect, rel): self.change() return True # Mouse enters or leaves the window elif event.type == pygame.ACTIVEEVENT: mx, my = pygame.mouse.get_pos() if event.gain != 1: # Leave self._last_mouse_pos = (mx, my) else: lmx, lmy = self._last_mouse_pos self._last_mouse_pos = (-1, -1) if lmx == -1 or lmy == -1: continue if self.scrolling: if self._orientation == 0: # Horizontal self._scroll(rect, mx - lmx) else: self._scroll(rect, my - lmy) # User clicks the slider rect elif event.type == pygame.MOUSEBUTTONDOWN and self._mouse_enabled or \ event.type == FINGERDOWN and self._touchscreen_enabled and \ self._menu is not None: # Vertical bar: scroll down (4) or up (5). Mouse must be placed # over the area to enable this feature if not event.type == FINGERDOWN and \ event.button in (4, 5) and self._orientation == 1 and \ (self._scrollarea is not None and self._scrollarea.mouse_is_over() or self._scrollarea is None): direction = -1 if event.button == 4 else 1 if self._scroll(rect, direction * self._single_step): self.change() return True # Click button (left, middle, right) elif event.type == FINGERDOWN or event.button in (1, 2, 3): event_pos = get_finger_pos(self._menu, event) # The _slider_rect origin is related to the widget surface if self.get_slider_rect().collidepoint(*event_pos): # Initialize scrolling self.scrolling = True self._clicked = True self._render() return True elif rect.collidepoint(*event_pos): # Moves towards the click by one "page" (= slider length without pad) s_rect = self.get_slider_rect() pos = (s_rect.x, s_rect.y) direction = 1 if event_pos[self._orientation] > pos[self._orientation] else -1 if self._scroll(rect, direction * self._page_step): self.change() return True # User releases mouse button if scrolling elif (event.type == pygame.MOUSEBUTTONUP and self._mouse_enabled or event.type == FINGERUP and self._touchscreen_enabled) and self.scrolling: self._clicked = False self.scrolling = False self._render() return True return False
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: 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