Beispiel #1
0
    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
Beispiel #2
0
    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)))
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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