예제 #1
0
    def test_size(self) -> None:
        """
        Test size.
        """
        menu = MenuUtils.generic_menu(title='menu', theme=TEST_THEME.copy())
        menu.render()
        self.assertEqual(menu.get_height(widget=True), 0)

        # Adds a button, hide it, then the height should be 0 as well
        btn = menu.add.button('hidden')
        btn.hide()
        self.assertEqual(menu.get_height(widget=True), 0)
        menu.render()

        # Get the size of the scrollarea
        sa = menu.get_scrollarea()

        sa_height = menu.get_height() - menu.get_menubar().get_height()
        sa_width = menu.get_width()
        self.assertEqual(sa.get_world_size()[0], sa_width)
        self.assertEqual(sa.get_world_size()[1], sa_height)
        rect = sa.get_view_rect()
        self.assertEqual(rect.x, 0)
        self.assertEqual(rect.y, 155)
        self.assertEqual(rect.width, sa_width)
        self.assertEqual(rect.height, sa_height)
        self.assertEqual(sa.get_hidden_width(), 0)
        self.assertEqual(sa.get_hidden_height(), 0)

        rect = sa.to_world_position(btn.get_rect())
        self.assertEqual(rect.x, 0)
        self.assertEqual(rect.y, -155)
        self.assertEqual(rect.width, btn.get_width())
        self.assertEqual(rect.height, btn.get_height())

        pos_rect = sa.to_world_position((10, 10))
        self.assertEqual(pos_rect, (10, -145))

        self.assertFalse(sa.is_scrolling())
        self.assertEqual(sa.get_menu(), menu)

        sa._on_vertical_scroll(50)
        sa._on_horizontal_scroll(50)

        # Remove the world of surface
        world = sa._world
        sa._world = None
        self.assertEqual(sa.get_world_size(), (0, 0))
        sa._world = world

        # Test collide
        event = PygameEventUtils.mouse_click(100, 100, inlist=False)
        self.assertFalse(sa.collide(btn, event))

        # Create virtual rect from button
        rect_virtual = sa.to_real_position(btn.get_rect())
        event_click_widget = PygameEventUtils.middle_rect_click(rect_virtual,
                                                                inlist=False)
        self.assertTrue(sa.collide(btn, event_click_widget))
예제 #2
0
 def test_example_other_scrollbar() -> None:
     """
     Test scrollbar example.
     """
     pygame.event.post(PygameEventUtils.keydown(pygame.K_v, inlist=False))
     pygame.event.post(PygameEventUtils.keydown(pygame.K_h, inlist=False))
     scrollbar.main(test=True)
     scrollbar.h_changed(1)
     scrollbar.v_changed(1)
예제 #3
0
 def test_example_other_calculator(self) -> None:
     """
     Test calculator example.
     """
     app = calculator.main(test=True)
     app.process_events(
         PygameEventUtils.keydown([
             pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5,
             pygame.K_PLUS
         ]))
     self.assertEqual(app.prev, '12345')
     self.assertEqual(app.op, '+')
     app.process_events(
         PygameEventUtils.keydown(
             [pygame.K_6, pygame.K_7, pygame.K_8, pygame.K_9, pygame.K_0]))
     self.assertEqual(app.curr, '67890')
     app.process_events(PygameEventUtils.keydown(pygame.K_EQUALS))
     self.assertEqual(app.op, '')
     self.assertEqual(app.curr, '80235')
     self.assertEqual(app.prev, '')
     app.process_events(PygameEventUtils.keydown([pygame.K_x, pygame.K_2]))
     self.assertEqual(app.op, 'x')
     self.assertEqual(app.curr, '2')
     self.assertEqual(app.prev, '80235')
     app.process_events(PygameEventUtils.keydown([pygame.K_x]))
     self.assertEqual(app.op, 'x')
     self.assertEqual(app.curr, '')
     self.assertEqual(app.prev, '160470')
     app.process_events(
         PygameEventUtils.keydown([pygame.K_PLUS, pygame.K_3, pygame.K_0]))
     self.assertEqual(app.op, '+')
     self.assertEqual(app.curr, '30')
     self.assertEqual(app.prev, '160470')
     app.process_events(PygameEventUtils.keydown(pygame.K_EQUALS))
     self.assertEqual(app.op, '')
     self.assertEqual(app.curr, '160500')
     self.assertEqual(app.prev, '')
     app.process_events(
         PygameEventUtils.keydown(
             [pygame.K_SLASH, pygame.K_5, pygame.K_MINUS]))
     self.assertEqual(app.op, '-')
     self.assertEqual(app.curr, '')
     self.assertEqual(app.prev, '32100')
     app.process_events(
         PygameEventUtils.keydown([
             pygame.K_3, pygame.K_2, pygame.K_1, pygame.K_0, pygame.K_EQUALS
         ]))
     self.assertEqual(app.op, '')
     self.assertEqual(app.curr, '28890')
     self.assertEqual(app.prev, '')
     app.process_events(
         PygameEventUtils.keydown([pygame.K_9, pygame.K_BACKSPACE]))
     self.assertEqual(app.op, '')
     self.assertEqual(app.curr, '')
     self.assertEqual(app.prev, '')
     test_reset_surface()
예제 #4
0
 def test_example_other_ui_solar_system(self) -> None:
     """
     Test solar system.
     """
     app = ui_solarsystem.main(test=True)
     self.assertFalse(app.menu._disable_draw)
     app.process_events(PygameEventUtils.keydown([pygame.K_p]), app.menu)
     self.assertTrue(app.menu._disable_draw)
     app.process_events(
         PygameEventUtils.keydown(
             [pygame.K_p, pygame.K_q, pygame.K_e, pygame.K_s, pygame.K_c]),
         app.menu)
     self.assertFalse(app.menu._disable_draw)
예제 #5
0
 def test_example_other_scrollbar_area() -> None:
     """
     Test scrollbar area example.
     """
     pygame.event.post(
         PygameEventUtils.keydown(pygame.K_ESCAPE, inlist=False))
     scrollbar_area.main(test=True)
예제 #6
0
    def test_double_discrete(self) -> None:
        """
        Test double range slider with discrete values.
        """
        menu = MenuUtils.generic_menu()
        rv = [0, 1, 2, 3, 4, 5]

        # Double slider discrete
        slider = pygame_menu.widgets.RangeSlider(
            'Range',
            range_text_value_tick_number=3,
            range_values=rv,
            default_value=(1, 4))
        menu.add.generic_widget(slider, True)
        slider.draw(surface)

        # Test set values
        slider.set_value([1, 2])
        self.assertEqual(slider.get_value(), (1, 2))

        # Test invalid values
        self.assertRaises(AssertionError, lambda: slider.set_value((1.1, 2.2)))
        self.assertRaises(AssertionError, lambda: slider.set_value((1, 1)))
        self.assertRaises(AssertionError, lambda: slider.set_value((2, 1)))
        self.assertRaises(AssertionError, lambda: slider.set_value(1))

        # Test left/right
        self.assertTrue(
            slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True)))
        self.assertEqual(slider.get_value(), (0, 2))
        self.assertFalse(
            slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True)))
        self.assertEqual(slider.get_value(), (0, 2))
        self.assertTrue(
            slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True)))
        self.assertEqual(slider.get_value(), (1, 2))
        self.assertFalse(
            slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True)))
        self.assertEqual(slider.get_value(), (1, 2))

        slider._update_value(0.99)
        self.assertEqual(slider.get_value(), (1, 2))

        self.assertEqual(
            slider._get_slider_inflate_rect(0, to_absolute_position=True),
            pygame.Rect(301, 209, 15, 28))
예제 #7
0
 def test_example_game_selector(self) -> None:
     """
     Test game selector example.
     """
     game_selector.main(test=True)
     font = MenuUtils.load_font(MenuUtils.random_font(), 5)
     game_selector.play_function(['EASY'], font, test=True)
     pygame.event.post(
         PygameEventUtils.keydown(pygame.K_ESCAPE, inlist=False))
     game_selector.play_function(['MEDIUM'], font, test=True)
     pygame.event.post(
         PygameEventUtils.keydown(pygame.K_ESCAPE, inlist=False))
     game_selector.play_function(['HARD'], font, test=True)
     self.assertRaises(
         ValueError,
         lambda: game_selector.play_function(['U'], font, test=True))
     game_selector.change_difficulty(('HARD', 1), 'HARD')
예제 #8
0
    def test_surface_widget(self) -> None:
        """
        Test surface widget.
        """
        menu = MenuUtils.generic_menu()
        surf = pygame.Surface((150, 150))
        surf.fill((255, 192, 203))
        surf_widget = menu.add.surface(surf, font_color='red')

        self.assertEqual(surf_widget.get_size(), (166, 158))
        self.assertEqual(surf_widget.get_size(apply_padding=False), (150, 150))
        self.assertEqual(surf_widget.get_surface(), surf)
        self.assertEqual(surf_widget._font_color, (70, 70, 70, 255))  # not red

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.rotate(10))
        self.assertEqual(surf_widget._angle, 0)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.resize(10, 10))
        self.assertFalse(surf_widget._scale[0])
        self.assertEqual(surf_widget._scale[1], 1)
        self.assertEqual(surf_widget._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.scale(100, 100))
        self.assertFalse(surf_widget._scale[0])
        self.assertEqual(surf_widget._scale[1], 1)
        self.assertEqual(surf_widget._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.flip(True, True))
        self.assertFalse(surf_widget._flip[0])
        self.assertFalse(surf_widget._flip[1])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.set_max_width(100))
        self.assertIsNone(surf_widget._max_width[0])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: surf_widget.set_max_height(100))
        self.assertIsNone(surf_widget._max_height[0])

        surf_widget.set_title('epic')
        self.assertEqual(surf_widget.get_title(), '')

        new_surface = pygame.Surface((160, 160))
        new_surface.fill((255, 192, 203))
        inner_surface = pygame.Surface((80, 80))
        inner_surface.fill((75, 0, 130))
        new_surface.blit(inner_surface, (40, 40))
        surf_widget.set_surface(new_surface)
        self.assertEqual(surf_widget.get_size(apply_padding=False), (160, 160))
        menu.draw(surface)
        surf_widget.update(PygameEventUtils.mouse_motion(surf_widget))
        surf_widget.draw(surface)
예제 #9
0
    def test_image_widget(self) -> None:
        """
        Test image widget.
        """
        menu = MenuUtils.generic_menu()
        image = menu.add.image(pygame_menu.baseimage.IMAGE_EXAMPLE_GRAY_LINES,
                               font_color=(2, 9))

        image.set_title('epic')
        self.assertEqual(image.get_title(), '')
        self.assertEqual(image.get_image(), image._image)
        image.update(PygameEventUtils.mouse_motion(image))

        self.assertEqual(image.get_height(apply_selection=True), 264)
        self.assertFalse(image._selected)
        self.assertEqual(image.get_selected_time(), 0)

        # Test transformations
        self.assertEqual(image.get_size(), (272, 264))
        image.scale(2, 2)
        self.assertEqual(image.get_size(), (528, 520))
        image.resize(500, 500)

        # Remove padding
        image.set_padding(0)
        self.assertEqual(image.get_size(), (500, 500))

        # Set max width
        image.set_max_width(400)
        self.assertEqual(image.get_size(), (400, 500))
        image.set_max_width(800)
        self.assertEqual(image.get_size(), (400, 500))
        image.set_max_width(300, scale_height=True)
        self.assertEqual(image.get_size(), (300, 375))

        # Set max height
        image.set_max_height(400)
        self.assertEqual(image.get_size(), (300, 375))
        image.set_max_height(300)
        self.assertEqual(image.get_size(), (300, 300))
        image.set_max_height(200, scale_width=True)
        self.assertEqual(image.get_size(), (200, 200))

        self.assertEqual(image.get_angle(), 0)
        image.rotate(90)
        self.assertEqual(image.get_angle(), 90)
        image.rotate(60)
        self.assertEqual(image.get_angle(), 60)

        # Flip
        image.flip(True, True)
        self.assertEqual(image._flip, (True, True))
        image.flip(False, False)
        self.assertEqual(image._flip, (False, False))
        image.draw(surface)
예제 #10
0
    def test_overflow_removal(self) -> None:
        """
        Test text with max width and right overflow removal.
        """
        if SYS_PLATFORM_OSX:
            return

        menu = MenuUtils.generic_menu()
        menu._copy_theme()
        menu._theme.widget_font_size = 20
        textinput = menu.add.text_input('Some long text: ',
                                        maxwidth=19,
                                        textinput_id='long_text',
                                        input_underline='_')
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: textinput.resize())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: textinput.set_max_width())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: textinput.set_max_height())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: textinput.scale())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: textinput.rotate())
        textinput.flip(True, True)
        self.assertEqual(textinput._flip, (False, True))
        # noinspection SpellCheckingInspection
        textinput.set_value('aaaaaaaaaaaaaaaaaaaaaaaaaa')
        self.assertEqual(textinput._cursor_position, 26)
        self.assertEqual(textinput._renderbox, [1, 26, 25])
        textinput.update(PygameEventUtils.key(pygame.K_BACKSPACE,
                                              keydown=True))
        self.assertEqual(textinput._cursor_position, 25)
        self.assertEqual(textinput._renderbox, [0, 25, 25])
        textinput.update(
            PygameEventUtils.key(pygame.K_a, keydown=True, char='a'))
        self.assertEqual(textinput._cursor_position, 26)
        self.assertEqual(textinput._renderbox, [1, 26, 25])
        textinput.update(PygameEventUtils.key(pygame.K_BACKSPACE,
                                              keydown=True))
        self.assertEqual(textinput._cursor_position, 25)
        self.assertEqual(textinput._renderbox, [0, 25, 25])
예제 #11
0
    def test_config(self) -> None:
        """
        Configure controls.
        """
        self.assertEqual(ctrl.KEY_APPLY, K_RETURN)

        # Change apply to new key
        ctrl.KEY_APPLY = K_END
        self.assertEqual(ctrl.KEY_APPLY, K_END)

        # Create new button
        menu = MenuUtils.generic_menu()
        test = [False]

        def click_button() -> None:
            """
            Button apply handler.
            """
            test[0] = not test[0]
            print('new test value', test)

        button = menu.add.button('button', click_button)
        self.assertFalse(test[0])
        button.apply()
        self.assertTrue(test[0])
        button.apply()
        self.assertFalse(test[0])

        # Now test new apply button
        button.update(PygameEventUtils.key(K_END, keydown=True))
        self.assertTrue(test[0])

        # Rollback change
        ctrl.KEY_APPLY = K_RETURN

        button.update(PygameEventUtils.key(K_END, keydown=True))
        self.assertTrue(test[0])
        button.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(test[0])
예제 #12
0
 def test_invalid_range(self) -> None:
     """
     Test invalid ranges. #356
     """
     menu = MenuUtils.generic_menu()
     r = menu.add.range_slider('Infection Rate',
                               default=2,
                               increment=0.5,
                               range_values=(2, 10))
     self.assertEqual(r.get_value(), 2)
     self.assertTrue(
         r.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True)))
     self.assertEqual(r.get_value(), 2.5)
     self.assertTrue(
         r.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True)))
     self.assertEqual(r.get_value(), 2)
     self.assertFalse(
         r.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True)))
     self.assertEqual(r.get_value(), 2)
     for _ in range(20):
         r.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
     self.assertEqual(r.get_value(), 10)
예제 #13
0
 def test_example_timer_clock() -> None:
     """
     Test timer clock example.
     """
     pygame.event.post(
         PygameEventUtils.keydown(pygame.K_ESCAPE, inlist=False))
     timer_clock.main(test=True)
     timer_clock.mainmenu_background()
     timer_clock.reset_timer()
     timer_clock.TestCallClassMethod.update_game_settings()
     color = (-1, -1, -1)
     timer_clock.change_color_bg((
         color,
         'random',
     ),
                                 color,
                                 write_on_console=True)
예제 #14
0
    def test_non_ascii(self) -> None:
        """
        Test non-ascii.
        """
        menu = MenuUtils.generic_menu()
        m = MenuUtils.generic_menu(title=u'Ménu')
        m.clear()
        menu.add.button('0', pygame_menu.events.NONE)
        menu.add.button('Test', pygame_menu.events.NONE)
        menu.add.button(u'Menú', pygame_menu.events.NONE)
        menu.add.color_input(u'Cólor', 'rgb')
        text = menu.add.text_input(u'Téxt')
        menu.add.label(u'Téxt')
        menu.add.selector(u'Sélect'.encode('latin1'), [('a', 'a')])
        menu.enable()
        menu.draw(surface)

        # Text text input
        text.set_value('ą, ę, ś, ć, ż, ź, ó, ł, ń')
        self.assertEqual(text.get_value(), 'ą, ę, ś, ć, ż, ź, ó, ł, ń')
        text.set_value('')
        text.update(PygameEventUtils.key(pygame.K_l, char='ł', keydown=True))
        self.assertEqual(text.get_value(), 'ł')
예제 #15
0
    def test_toggleswitch(self) -> None:
        """
        Test toggleswitch widget.
        """
        menu = MenuUtils.generic_menu()

        value = [None]

        def onchange(val) -> None:
            """
            Function executed by toggle.
            """
            value[0] = val

        switch = menu.add.toggle_switch('toggle',
                                        False,
                                        onchange=onchange,
                                        infinite=False,
                                        single_click=False)
        self.assertFalse(switch.get_value())
        self.assertIsNone(value[0])
        switch.apply()
        self.assertFalse(value[0])

        switch.update(PygameEventUtils.key(ctrl.KEY_LEFT,
                                           keydown=True))  # not infinite
        self.assertFalse(value[0])  # as this is false, dont change
        switch.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertTrue(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertFalse(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertFalse(value[0])
        self.assertFalse(
            switch.update(
                PygameEventUtils.key(ctrl.KEY_LEFT,
                                     keydown=True,
                                     testmode=False)))

        switch = menu.add.toggle_switch('toggle',
                                        False,
                                        onchange=onchange,
                                        infinite=True,
                                        single_click=False)
        switch.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertTrue(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertFalse(value[0])

        # As there's only 2 states, return should change too
        switch.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertTrue(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(value[0])

        # Check left/right clicks
        click_pos = switch.get_rect(to_real_position=True,
                                    apply_padding=False).midleft
        switch.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertFalse(value[0])
        switch.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertTrue(value[0])
        switch.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertFalse(value[0])

        # Test left/right touch
        switch._touchscreen_enabled = True
        switch.update(
            PygameEventUtils.touch_click(click_pos[0] + 250,
                                         click_pos[1],
                                         menu=switch.get_menu()))
        self.assertTrue(value[0])
        switch.update(
            PygameEventUtils.touch_click(click_pos[0] + 250,
                                         click_pos[1],
                                         menu=switch.get_menu()))
        self.assertTrue(value[0])
        switch.update(
            PygameEventUtils.touch_click(click_pos[0] + 150,
                                         click_pos[1],
                                         menu=switch.get_menu()))
        self.assertFalse(value[0])

        # Test readonly
        switch.readonly = True
        switch.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(value[0])
        switch._left()
        self.assertFalse(value[0])
        switch._right()
        self.assertFalse(value[0])

        switch.readonly = False
        switch.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertTrue(value[0])
        switch.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertFalse(value[0])

        switch.draw(surface)

        # Test transforms
        switch.set_position(1, 1)
        self.assertEqual(switch.get_position(), (1, 1))

        switch.translate(1, 1)
        self.assertEqual(switch.get_translate(), (1, 1))

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.rotate(10))
        self.assertEqual(switch._angle, 0)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.scale(100, 100))
        self.assertFalse(switch._scale[0])
        self.assertEqual(switch._scale[1], 1)
        self.assertEqual(switch._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.resize(100, 100))
        self.assertFalse(switch._scale[0])
        self.assertEqual(switch._scale[1], 1)
        self.assertEqual(switch._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.flip(True, True))
        self.assertFalse(switch._flip[0])
        self.assertFalse(switch._flip[1])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.set_max_width(100))
        self.assertIsNone(switch._max_width[0])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: switch.set_max_height(100))
        self.assertIsNone(switch._max_height[0])

        # Assert switch values
        self.assertRaises(
            ValueError, lambda: menu.add.toggle_switch(
                'toggle', 'false', onchange=onchange, infinite=False))

        # Test single click toggle
        switch_single = menu.add.toggle_switch('toggle',
                                               False,
                                               onchange=onchange)
        self.assertTrue(switch_single._infinite
                        )  # Infinite sets to True if using single click

        self.assertFalse(switch_single.get_value())
        switch_single._left()
        self.assertTrue(switch_single.get_value())

        click_pos = switch_single.get_rect(to_real_position=True,
                                           apply_padding=False).midleft

        # Test single click toggle between two states
        switch_single.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertFalse(
            switch_single.get_value())  # single_click_dir=True, move to left
        switch_single.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertTrue(switch_single.get_value())
        switch_single.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertFalse(switch_single.get_value())

        switch_single._single_click_dir = False
        switch_single.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertTrue(switch_single.get_value())

        # Create invalid single click params
        self.assertRaises(
            AssertionError, lambda: menu.add.toggle_switch(
                'toggle', False, single_click='true'))
        self.assertRaises(
            AssertionError, lambda: menu.add.toggle_switch(
                'toggle', False, single_click_dir='true'))

        # Test other constructor params
        pygame_menu.widgets.ToggleSwitch(
            'Epic', state_text_font=menu._theme.widget_font)
        self.assertRaises(
            AssertionError,
            lambda: pygame_menu.widgets.ToggleSwitch('Epic',
                                                     state_text_font_size=-1))
예제 #16
0
    def test_scrollbar(self) -> None:
        """
        Test ScrollBar widget.
        """
        screen_size = surface.get_size()
        world = pygame.Surface((WINDOW_SIZE[0] * 2, WINDOW_SIZE[1] * 3))
        world.fill((200, 200, 200))
        for x in range(100, world.get_width(), 200):
            for y in range(100, world.get_height(), 200):
                pygame.draw.circle(world, (225, 34, 43), (x, y), 100, 10)

        # Vertical right scrollbar
        thick = 80
        length = screen_size[1]
        world_range = (50, world.get_height())
        x, y = screen_size[0] - thick, 0

        sb = ScrollBar(
            length, world_range, 'sb2', ORIENTATION_VERTICAL,
            slider_pad=2,
            slider_color=(210, 120, 200),
            page_ctrl_thick=thick,
            page_ctrl_color=(235, 235, 230)
        )
        self.assertEqual(sb.get_thickness(), 80)
        self.assertIsNone(sb.get_scrollarea())

        sb.set_shadow(color=(245, 245, 245), position=POSITION_SOUTHEAST)
        self.assertFalse(sb._font_shadow)

        sb.set_position(x, y)

        self.assertEqual(sb._orientation, 1)
        self.assertEqual(sb.get_orientation(), ORIENTATION_VERTICAL)
        self.assertEqual(sb.get_minimum(), world_range[0])
        self.assertEqual(sb.get_maximum(), world_range[1])

        sb.set_value(80)
        self.assertAlmostEqual(sb.get_value(), 80, delta=2)  # Scaling delta

        sb.update(PygameEventUtils.mouse_click(x + thick / 2, y + 2, evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(sb.get_value(), 50)
        self.assertEqual(sb.get_value_percentage(), 0)

        sb.set_page_step(length)
        self.assertAlmostEqual(sb.get_page_step(), length, delta=2)  # Scaling delta

        sb.draw(surface)

        # Test events
        sb.update(PygameEventUtils.key(pygame.K_PAGEDOWN, keydown=True))
        self.assertEqual(sb.get_value(), 964)
        sb.update(PygameEventUtils.key(pygame.K_PAGEUP, keydown=True))
        self.assertEqual(sb.get_value(), 50)
        self.assertEqual(sb._last_mouse_pos, (-1, -1))
        sb.update(PygameEventUtils.enter_window())
        self.assertEqual(sb._last_mouse_pos, (-1, -1))
        sb.update(PygameEventUtils.leave_window())
        self.assertEqual(sb._last_mouse_pos, pygame.mouse.get_pos())
        self.assertFalse(sb.scrolling)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), evtype=pygame.MOUSEBUTTONDOWN))
        self.assertTrue(sb.scrolling)
        sb.update(PygameEventUtils.mouse_click(1, 1))
        self.assertFalse(sb.scrolling)
        self.assertEqual(sb.get_value(), 50)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_rect(to_absolute_position=True),
                                                     evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(sb.get_value(), 964)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), evtype=pygame.MOUSEBUTTONDOWN))
        self.assertTrue(sb.scrolling)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=4,
                                                     evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(sb.get_value(), 875)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=5,
                                                     evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(sb.get_value(), 964)
        self.assertEqual(sb.get_value_percentage(), 0.522)

        # Test mouse motion while scrolling
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=5, delta=(0, 50), rel=(0, 10),
                                                     evtype=pygame.MOUSEMOTION))
        self.assertEqual(sb.get_value_percentage(), 0.547)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=5, delta=(0, 50), rel=(0, -10),
                                                     evtype=pygame.MOUSEMOTION))
        self.assertEqual(sb.get_value_percentage(), 0.522)
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=5, delta=(0, 50), rel=(0, 999),
                                                     evtype=pygame.MOUSEMOTION))
        self.assertEqual(sb.get_value_percentage(), 1)
        sb.readonly = True
        self.assertFalse(sb.update([]))

        # Ignore events if mouse outside the region
        sb.update(PygameEventUtils.middle_rect_click(sb.get_slider_rect(), button=5, delta=(0, 999), rel=(0, -10),
                                                     evtype=pygame.MOUSEMOTION))
        self.assertIn(sb.get_value_percentage(), (0.976, 1))

        # Test remove onreturn
        sb = ScrollBar(length, world_range, 'sb', ORIENTATION_VERTICAL, onreturn=-1)
        self.assertIsNone(sb._onreturn)
        self.assertTrue(sb._kwargs.get('onreturn', 0))

        # Scrollbar ignores scaling
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.scale(2, 2))
        self.assertFalse(sb._scale[0])
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.resize(2, 2))
        self.assertFalse(sb._scale[0])
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.set_max_width(10))
        self.assertIsNone(sb._max_width[0])
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.set_max_height(10))
        self.assertIsNone(sb._max_height[0])
        sb._apply_font()
        sb.set_padding(10)
        self.assertEqual(sb._padding[0], 0)
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.rotate(10))
        self.assertEqual(sb._angle, 0)
        self.assertRaises(WidgetTransformationNotImplemented, lambda: sb.flip(True, True))
        self.assertFalse(sb._flip[0])
        self.assertFalse(sb._flip[1])

        # Set minimum
        sb.set_minimum(0.5 * sb._values_range[1])

        # Test hide
        sb._mouseover = True
        sb.hide()
예제 #17
0
    def test_single_rangeslider(self) -> None:
        """
        Test single range slider.
        """
        menu = MenuUtils.generic_menu()

        # Single slider
        slider = pygame_menu.widgets.RangeSlider('Range S')

        test = [0, 0]

        def onchange(x: float) -> None:
            """
            Change slider.
            """
            # noinspection PyTypeChecker
            test[0] = x

        def onreturn(x: float) -> None:
            """
            Return slider.
            """
            # noinspection PyTypeChecker
            test[1] = x

        slider.set_onchange(onchange)
        slider.set_onreturn(onreturn)

        menu.add.generic_widget(slider, True)
        self.assertEqual(slider.get_value(), 0)
        slider.set_value(0.5)
        self.assertEqual(slider.get_value(), 0.5)
        self.assertEqual(slider._value, [0.5, 0])

        self.assertEqual(test[0], 0)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(test[0], 0.4)
        self.assertEqual(slider.get_value(), 0.4)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertAlmostEqual(slider.get_value(), 0.3)
        for _ in range(10):
            slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(slider.get_value(), 0)
        self.assertTrue(
            slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True)))
        self.assertEqual(slider.get_value(), 0.1)
        self.assertEqual(test[1], 0)
        slider.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(test[1], 0.1)

        # Ignore invalid key
        self.assertFalse(
            slider.update(
                PygameEventUtils.key(ctrl.KEY_LEFT,
                                     keydown=True,
                                     testmode=False)))

        # Ignore for readonly
        slider.draw(surface)
        slider.draw_after_if_selected(surface)
        slider.readonly = True
        self.assertFalse(
            slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True)))
        self.assertEqual(slider.get_value(), 0.1)
        slider._update_value(0)
        self.assertEqual(slider.get_value(), 0.1)
        slider.readonly = False

        # Test invalid values
        self.assertRaises(AssertionError, lambda: slider.set_value(-1))
        self.assertRaises(AssertionError, lambda: slider.set_value([0.4, 0.5]))

        # Test invalid transforms
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.rotate())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.flip())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.scale())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.resize())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.set_max_width())
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: slider.set_max_height())

        # Test mouse click
        self.assertFalse(slider._selected_mouse)
        pos = slider._test_get_pos_value(0.5)
        slider.update(
            PygameEventUtils.middle_rect_click(pos,
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(slider.get_value(), 0.1)
        self.assertTrue(slider._selected_mouse)
        self.assertFalse(slider._scrolling)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertFalse(slider._scrolling)
        self.assertEqual(slider.get_value(), 0.5)
        self.assertFalse(slider._selected_mouse)

        # Mouse click out of range
        slider._selected_mouse = True
        pos = slider._test_get_pos_value(1, dx=100)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 0.5)
        self.assertFalse(slider._selected_mouse)

        slider._selected_mouse = True
        pos = slider._test_get_pos_value(0, dx=-100)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 0.5)
        self.assertFalse(slider._selected_mouse)

        # Test extremes
        slider._selected_mouse = True
        pos = slider._test_get_pos_value(0)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 0)
        slider._selected_mouse = True
        pos = slider._test_get_pos_value(1)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 1)

        # Scroll to 0.5
        pos2 = slider._test_get_pos_value(0.5)
        self.assertFalse(slider._scrolling)
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        slider.update(
            PygameEventUtils.middle_rect_click(slider_rect,
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertTrue(slider._scrolling)
        self.assertTrue(slider._selected_mouse)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), 0.5)
        self.assertTrue(slider._scrolling)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertFalse(slider._scrolling)

        # Check invalid constructor for single slider
        self.assertRaises(
            AssertionError, lambda: pygame_menu.widgets.RangeSlider(
                'Range S', default_value=2))
        self.assertRaises(
            AssertionError, lambda: pygame_menu.widgets.RangeSlider(
                'Range S', default_value=1, range_values=[1, 0]))
        self.assertRaises(
            AssertionError, lambda: pygame_menu.widgets.RangeSlider(
                'Range S', default_value=1, range_values=[1, 1]))
        self.assertRaises(
            AssertionError,
            lambda: pygame_menu.widgets.RangeSlider('Range S',
                                                    default_value='a'))

        # Ignore tabs
        self.assertFalse(
            slider.update(PygameEventUtils.key(ctrl.KEY_TAB, keydown=True)))

        # Check LEFT key in repeat
        self.assertIn(ctrl.KEY_RIGHT, slider._keyrepeat_counters.keys())
        self.assertEqual(slider.get_value(), 0.5)

        # Make left repeat
        slider._keyrepeat_counters[ctrl.KEY_RIGHT] += 1e4
        self.assertEqual(len(slider._events), 0)
        self.assertFalse(slider.update([]))
        self.assertEqual(len(slider._events), 1)
        self.assertFalse(slider.update(
            []))  # As key is not pressed, event continues
        self.assertEqual(len(slider._events), 0)

        # Keyup, removes counters
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keyup=True))
        self.assertNotIn(ctrl.KEY_RIGHT, slider._keyrepeat_counters.keys())
        self.assertFalse(hasattr(slider, '_range_box'))

        # Single slider with range box
        slider_rb = pygame_menu.widgets.RangeSlider(
            'Range', range_box_single_slider=True)
        menu.add.generic_widget(slider_rb, True)
        slider_rb.draw(surface)
        self.assertTrue(hasattr(slider_rb, '_range_box'))
        self.assertEqual(slider_rb._range_box.get_width(), 0)
        slider_rb.set_value(1)
        self.assertEqual(slider_rb._range_box.get_width(), 150)
예제 #18
0
    def test_unicode(self) -> None:
        """
        Test unicode support.
        """
        menu = MenuUtils.generic_menu()
        textinput = menu.add.text_input('title', input_underline='_')
        textinput.set_value('tk')

        # Test alt+x
        textinput.update(PygameEventUtils.key(pygame.K_SPACE, keydown=True))
        textinput.update(
            PygameEventUtils.key(pygame.K_2, keydown=True, char='2'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='5'))
        self.assertEqual(textinput.get_value(), 'tk 215')
        textinput.update(PygameEventUtils.keydown_mod_alt(
            pygame.K_x))  # convert 215 to unicode
        self.assertEqual(textinput.get_value(), 'tkȕ')
        textinput.update(PygameEventUtils.key(pygame.K_SPACE, keydown=True))
        textinput.update(PygameEventUtils.key(pygame.K_SPACE, keydown=True))
        textinput.update(
            PygameEventUtils.key(pygame.K_b, keydown=True, char='B'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        textinput.update(PygameEventUtils.keydown_mod_alt(
            pygame.K_x))  # convert 215 to unicode
        self.assertEqual(textinput.get_value(), 'tkȕ ±')

        # Remove all
        textinput.clear()
        textinput.update(
            PygameEventUtils.key(pygame.K_b, keydown=True, char='B'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        textinput.update(PygameEventUtils.keydown_mod_alt(
            pygame.K_x))  # convert 215 to unicode
        self.assertEqual(textinput.get_value(), '±')
        textinput.update(PygameEventUtils.keydown_mod_alt(
            pygame.K_x))  # convert same to unicode, do nothing
        self.assertEqual(textinput.get_value(), '±')

        # Test consecutive
        textinput.update(
            PygameEventUtils.key(pygame.K_2, keydown=True, char='2'))
        textinput.update(
            PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        textinput.update(
            PygameEventUtils.key(pygame.K_3, keydown=True, char='3'))
        textinput.update(PygameEventUtils.keydown_mod_alt(
            pygame.K_x))  # convert 215 to unicode
        self.assertEqual(textinput.get_value(), '±–')

        # Test 0x
        textinput.clear()
        PygameEventUtils.release_key_mod()
        textinput.update(
            PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(textinput.get_value(), '0')
        textinput.update(
            PygameEventUtils.key(pygame.K_x, keydown=True, char='x'))
        self.assertEqual(textinput.get_value(), '0x')
        textinput.update(PygameEventUtils.keydown_mod_alt(pygame.K_x))
        self.assertEqual(textinput.get_value(), '0x')
        textinput.update(
            PygameEventUtils.key(pygame.K_b, keydown=True, char='B'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        self.assertEqual(textinput.get_value(), '0xB1')
        textinput.update(PygameEventUtils.keydown_mod_alt(pygame.K_x))
        self.assertEqual(textinput.get_value(), '±')
        PygameEventUtils.release_key_mod()

        textinput.update(
            PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        textinput.update(
            PygameEventUtils.key(pygame.K_x, keydown=True, char='x'))
        textinput.update(
            PygameEventUtils.key(pygame.K_b, keydown=True, char='B'))
        textinput.update(
            PygameEventUtils.key(pygame.K_1, keydown=True, char='1'))
        textinput.update(PygameEventUtils.keydown_mod_alt(pygame.K_x))
        self.assertEqual(textinput.get_value(), '±±')

        # Test keyup
        self.assertIn(pygame.K_1, textinput._keyrepeat_counters.keys())
        self.assertFalse(
            textinput.update(
                PygameEventUtils.key(pygame.K_1, keyup=True, char='1')))
        self.assertNotIn(pygame.K_1, textinput._keyrepeat_counters.keys())

        # Test tab
        self.assertEqual(textinput._tab_size, 4)
        textinput.update(PygameEventUtils.key(pygame.K_TAB, keydown=True))
        self.assertEqual(textinput.get_value(), '±±    ')

        # Test invalid unicode
        self.assertFalse(
            textinput.update(PygameEventUtils.key(pygame.K_1, keydown=True)))

        # Test others
        textinput._input_type = 'other'
        self.assertTrue(textinput._check_input_type('-'))
        self.assertFalse(textinput._check_input_type('x'))
        textinput._maxwidth_update = None
        self.assertIsNone(textinput._update_maxlimit_renderbox())
예제 #19
0
    def test_size(self) -> None:
        """
        Test size.
        """
        if SYS_PLATFORM_OSX:
            return

        menu = MenuUtils.generic_menu(title='menu', theme=TEST_THEME.copy())
        menu.render()
        self.assertEqual(menu.get_height(widget=True), 0)

        # Adds a button, hide it, then the height should be 0 as well
        btn = menu.add.button('hidden')
        btn.hide()
        self.assertEqual(menu.get_height(widget=True), 0)
        menu.render()

        # Get the size of the scrollarea
        sa = menu.get_scrollarea()

        sa_height = menu.get_height() - menu.get_menubar().get_height()
        sa_width = menu.get_width()
        self.assertEqual(sa.get_world_size()[0], sa_width)
        self.assertEqual(sa.get_world_size()[1], sa_height)
        rect = sa.get_view_rect()
        self.assertEqual(rect.x, 0)
        self.assertEqual(rect.y, 155)
        self.assertEqual(rect.width, sa_width)
        self.assertEqual(rect.height, sa_height)
        self.assertEqual(sa.get_hidden_width(), 0)
        self.assertEqual(sa.get_hidden_height(), 0)

        rect = sa.to_world_position(btn.get_rect())
        self.assertEqual(rect.x, 0)
        self.assertEqual(rect.y, -155)
        self.assertEqual(rect.width, btn.get_width())
        self.assertEqual(rect.height, btn.get_height())

        pos_rect = sa.to_world_position((10, 10))
        self.assertEqual(pos_rect, (10, -145))

        self.assertFalse(sa.is_scrolling())
        self.assertEqual(sa.get_menu(), menu)

        sa._on_vertical_scroll(50)
        sa._on_horizontal_scroll(50)

        # Remove the world of surface
        world = sa._world
        sa._world = None
        self.assertEqual(sa.get_world_size(), (0, 0))
        sa._world = world

        # Test collide
        event = PygameEventUtils.mouse_click(100, 100, inlist=False)
        self.assertFalse(sa.collide(btn, event))

        # Create virtual rect from button
        rect_virtual = sa.to_real_position(btn.get_rect())
        event_click_widget = PygameEventUtils.middle_rect_click(rect_virtual, inlist=False)
        self.assertTrue(sa.collide(btn, event_click_widget))
        self.assertEqual(sa.get_world_rect(absolute=True),
                         pygame.Rect(0, 0, 600, 345))
        self.assertEqual(sa.get_size(), (600, 345))
        self.assertIsInstance(sa.mouse_is_over(), bool)

        # Append many items within menu, thus, scrollbars will appear
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_VERTICAL), 0)
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_HORIZONTAL), 0)

        sa._scrollbar_positions = (POSITION_NORTH, POSITION_EAST, POSITION_WEST, POSITION_SOUTH)
        self.assertEqual(sa.get_view_rect(), pygame.Rect(0, 155, 600, 345))

        for i in range(10):
            menu.add.button('b{0}'.format(i)).scale(20, 1)

        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_VERTICAL), 20)
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_HORIZONTAL), 20)

        sa._on_vertical_scroll(0.5)
        sa._on_horizontal_scroll(0.5)

        self.assertEqual(sa.to_real_position((10, 10)), (10, 165))
        sa.get_view_rect()

        # Test rect
        sa = pygame_menu._scrollarea.ScrollArea(100, 100)
        self.assertEqual(sa.get_rect(to_real_position=True),
                         pygame.Rect(0, 0, 100, 100))
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_VERTICAL, visible=False), 0)
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_HORIZONTAL, visible=False), 0)
        self.assertEqual(sa.get_scrollbar_thickness(ORIENTATION_VERTICAL, visible=False), 0)
        self.assertRaises(AssertionError, lambda: sa.get_scrollbar_thickness('fake', visible=False))
예제 #20
0
    def test_dropselect_multiple(self) -> None:
        """
        Test dropselect multiple widget.
        """
        theme = pygame_menu.themes.THEME_DEFAULT.copy()
        theme.widget_font_size = 25
        menu = MenuUtils.generic_menu(mouse_motion_selection=True, theme=theme)
        items = [('This is a really long selection item', 1), ('epic', 2)]
        for i in range(10):
            items.append(('item{}'.format(i + 1), i + 1))
        # noinspection SpellCheckingInspection
        drop = pygame_menu.widgets.DropSelectMultiple('dropsel',
                                                      items,
                                                      open_middle=True,
                                                      selection_box_height=5)
        self.assertNotEqual(id(items), id(drop._items))
        menu.add.generic_widget(drop, configure_defaults=True)
        self.assertEqual(drop._selection_box_width,
                         225 if not SYS_PLATFORM_OSX else 226)

        # Check drop is empty
        self.assertEqual(drop.get_value(), ([], []))
        self.assertEqual(drop.get_index(), [])
        self.assertEqual(drop._get_current_selected_text(), 'Select an option')

        # Check events
        self.assertFalse(drop.active)
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertTrue(drop.active)
        self.assertEqual(drop._index, -1)
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY,
                                         keydown=True))  # Index is -1
        self.assertFalse(drop.active)
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertTrue(drop.active)
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        self.assertEqual(drop._index, 0)
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        self.assertEqual(drop._index, 1)

        # Apply on current
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(drop.get_value(), ([('epic', 2)], [1]))
        self.assertEqual(drop.get_index(), [1])
        self.assertEqual(drop._get_current_selected_text(), '1 selected')
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(drop.get_value(), ([('epic', 2),
                                             ('item2', 2)], [1, 3]))
        self.assertEqual(drop._get_current_selected_text(), '2 selected')

        # Change selection type
        drop._selection_placeholder_format = DROPSELECT_MULTIPLE_SFORMAT_LIST_COMMA
        self.assertEqual(drop._get_current_selected_text(),
                         'epic,item2 selected')
        drop._selection_placeholder_format = DROPSELECT_MULTIPLE_SFORMAT_LIST_HYPHEN
        self.assertEqual(drop._get_current_selected_text(),
                         'epic-item2 selected')
        drop._selection_placeholder_format = '+'
        self.assertEqual(drop._get_current_selected_text(),
                         'epic+item2 selected')

        def format_string_list(items_list) -> str:
            """
            Receives the items list string and returns a function.

            :param items_list: Items list
            :return: Join string
            """
            if len(items_list) == 1:
                return items_list[0]
            elif len(items_list) == 2:
                return items_list[0] + ' and ' + items_list[1]
            return 'overflow'

        drop._selection_placeholder_format = format_string_list
        self.assertEqual(drop._get_current_selected_text(),
                         'epic and item2 selected')

        # Invalid format
        drop._selection_placeholder_format = 1
        self.assertRaises(ValueError,
                          lambda: drop._get_current_selected_text())
        drop._selection_placeholder_format = lambda: print('nice')
        self.assertRaises(ValueError,
                          lambda: drop._get_current_selected_text())
        drop._selection_placeholder_format = lambda x: 1
        self.assertRaises(AssertionError,
                          lambda: drop._get_current_selected_text())

        # Back to default
        drop._selection_placeholder_format = DROPSELECT_MULTIPLE_SFORMAT_TOTAL

        # Click item 2, this should unselect
        self.assertTrue(drop.active)
        drop.update(PygameEventUtils.middle_rect_click(
            drop._option_buttons[3]))
        self.assertEqual(drop.get_value(), ([('epic', 2)], [1]))
        self.assertEqual(drop._get_current_selected_text(), '1 selected')
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        self.assertEqual(drop._index, 4)
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(drop.get_value(), ([('epic', 2),
                                             ('item3', 3)], [1, 4]))
        self.assertEqual(drop._get_current_selected_text(), '2 selected')

        # Close
        drop.update(PygameEventUtils.key(pygame.K_ESCAPE, keydown=True))
        self.assertFalse(drop.active)
        self.assertEqual(drop.get_value(), ([('epic', 2),
                                             ('item3', 3)], [1, 4]))
        self.assertEqual(drop._get_current_selected_text(), '2 selected')

        # Change drop selected text method

        # Set max limit
        drop._max_selected = 3
        self.assertEqual(drop.get_total_selected(), 2)
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(drop.get_total_selected(), 3)
        self.assertTrue(drop.active)
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertEqual(drop.get_total_selected(), 3)  # Limit reached
        self.assertEqual(drop.get_value(), ([('epic', 2), ('item3', 3),
                                             ('item4', 4)], [1, 4, 5]))
        drop.update(PygameEventUtils.key(ctrl.KEY_MOVE_DOWN, keydown=True))
        drop.update(PygameEventUtils.key(ctrl.KEY_APPLY,
                                         keydown=True))  # Unselect previous
        self.assertEqual(drop.get_total_selected(), 2)  # Limit reached
        self.assertEqual(drop.get_value(), ([('epic', 2),
                                             ('item3', 3)], [1, 4]))

        # Update elements
        drop.update_items([('This is a really long selection item', 1),
                           ('epic', 2)])
        self.assertEqual(drop.get_value(), ([], []))
        self.assertEqual(drop._get_current_selected_text(), 'Select an option')
        drop.set_value(1, process_index=True)
        self.assertEqual(drop.get_value(), ([('epic', 2)], [1]))
        drop.set_value('This is a really long selection item',
                       process_index=True)
        self.assertEqual(drop.get_value(),
                         ([('This is a really long selection item', 1),
                           ('epic', 2)], [0, 1]))
        self.assertEqual(drop._get_current_selected_text(), '2 selected')
        drop.set_default_value(1)
        self.assertEqual(drop.get_value(), ([('epic', 2)], [1]))
        self.assertEqual(drop._get_current_selected_text(), '1 selected')

        # Use manager
        drop2 = menu.add.dropselect_multiple(
            'nice', [('This is a really long selection item', 1), ('epic', 2)],
            placeholder_selected='nice {0}',
            placeholder='epic',
            max_selected=1)
        self.assertEqual(drop2._selection_box_width,
                         134 if not SYS_PLATFORM_OSX else 135)
        self.assertEqual(drop2._get_current_selected_text(), 'epic')
        drop2.set_value('epic', process_index=True)
        self.assertEqual(drop2.get_index(), [1])
        self.assertEqual(drop2._get_current_selected_text(), 'nice 1')
        drop2.set_value(0, process_index=True)
        self.assertEqual(drop2.get_index(), [1])
        self.assertEqual(drop2._get_current_selected_text(), 'nice 1')
        self.assertEqual(drop2._default_value, [])
        self.assertEqual(drop2._index, 0)
        self.assertRaises(ValueError, lambda: drop2.set_value('not epic'))

        # Reset
        drop2.reset_value()
        self.assertEqual(drop2._get_current_selected_text(), 'epic')
        self.assertEqual(drop2._default_value, [])
        self.assertEqual(drop2._index, -1)
        self.assertEqual(drop2.get_index(), [])
        self.assertNotEqual(id(drop2._default_value),
                            id(drop2._selected_indices))

        menu.select_widget(drop2)
        self.assertTrue(
            drop2.update(PygameEventUtils.key(pygame.K_TAB, keydown=True)))

        # Test hide
        self.assertTrue(drop2._drop_frame.is_visible())
        self.assertTrue(drop2.active)
        drop2.hide()  # Hiding selects the other widget
        self.assertEqual(menu.get_selected_widget(), drop)
        self.assertFalse(drop2._drop_frame.is_visible())
        self.assertFalse(drop2.active)
        drop2.show()
        self.assertFalse(drop2._drop_frame.is_visible())
        self.assertFalse(drop2.active)
        self.assertEqual(menu.get_selected_widget(), drop)
        menu.select_widget(drop2)
        drop2._toggle_drop()
        self.assertTrue(drop2.active)
        self.assertTrue(drop2._drop_frame.is_visible())

        # Test change
        test = [-1]

        def onchange(value) -> None:
            """
            Test onchange.
            """
            test[0] = value[1]

        drop2.set_onchange(onchange)

        # Pick any option
        menu.render()
        self.assertEqual(test, [-1])
        drop2._option_buttons[0].apply()
        self.assertEqual(test[0], [0])
        drop2._option_buttons[0].apply()
        self.assertEqual(test[0], [])
        drop2._option_buttons[0].apply()
        drop2._option_buttons[1].apply()
        self.assertEqual(test[0], [0])  # As max selected is only 1
        drop2._max_selected = 2
        drop2._option_buttons[1].apply()
        self.assertEqual(test[0], [0, 1])

        # Test none drop frame
        drop2._drop_frame = None
        self.assertEqual(drop2.get_scroll_value_percentage('any'), -1)

        # Test format option from manager
        menu._theme.widget_background_inflate_to_selection = True
        menu._theme.widget_background_inflate = 0
        # menu._theme.widget_border_inflate = 0
        menu._theme.widget_margin = 0
        drop2 = menu.add.dropselect_multiple(
            'nice', [('This is a really long selection item', 1), ('epic', 2)],
            placeholder_selected='nice {0}',
            placeholder='epic',
            max_selected=1,
            selection_placeholder_format=lambda x: 'not EPIC')
        self.assertEqual(drop2._get_current_selected_text(), 'epic')
        drop2.set_value('epic', process_index=True)
        self.assertEqual(drop2._get_current_selected_text(), 'nice not EPIC')
        self.assertEqual(drop2.get_margin(), (0, 0))
        self.assertEqual(drop2._background_inflate, (0, 0))
        self.assertEqual(drop2._border_inflate, (0, 0))
        menu._theme.widget_background_inflate_to_selection = False

        # Process index
        drop2._index = -1
        drop2._process_index()
예제 #21
0
    def test_single_discrete(self) -> None:
        """
        Test single range slider with discrete values.
        """
        menu = MenuUtils.generic_menu()

        # Single slider with discrete values
        rv = [0, 1, 2, 3, 4, 5]
        slider = pygame_menu.widgets.RangeSlider('Range', range_values=rv)
        menu.add.generic_widget(slider, True)

        self.assertRaises(
            AssertionError, lambda: pygame_menu.widgets.RangeSlider(
                'Range', default_value=0.5, range_values=rv))
        self.assertRaises(
            AssertionError, lambda: pygame_menu.widgets.RangeSlider(
                'Range', default_value=-1, range_values=rv))

        self.assertRaises(AssertionError, lambda: slider.set_value(-1))
        self.assertRaises(AssertionError, lambda: slider.set_value([0, 1]))
        self.assertRaises(AssertionError, lambda: slider.set_value((0, 1)))

        # Test key events
        self.assertFalse(
            slider.update(PygameEventUtils.key(ctrl.KEY_TAB, keydown=True)))
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertEqual(slider.get_value(), 1)
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertEqual(slider.get_value(), 2)
        slider._increment = 0
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        self.assertEqual(slider.get_value(), 3)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(slider.get_value(), 2)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(slider.get_value(), 1)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(slider.get_value(), 0)
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(slider.get_value(), 0)

        # Test click mouse
        slider._selected_mouse = True
        pos = slider._test_get_pos_value(2)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 2)
        self.assertFalse(slider._selected_mouse)

        # Test invalid click
        slider._selected_mouse = True
        pos = slider._test_get_pos_value(2, dx=1000)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertEqual(slider.get_value(), 2)
        self.assertFalse(slider._selected_mouse)

        # Scroll to 4
        pos = slider._test_get_pos_value(2)
        pos2 = slider._test_get_pos_value(4)
        self.assertFalse(slider._scrolling)
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        slider.update(
            PygameEventUtils.middle_rect_click(slider_rect,
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertTrue(slider._scrolling)
        self.assertTrue(slider._selected_mouse)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), 4)
        self.assertTrue(slider._scrolling)
        slider.update(PygameEventUtils.middle_rect_click(pos))
        self.assertFalse(slider._scrolling)

        # Back to 2
        slider.set_value(2)

        # Invalid scrolling if clicked outside the slider
        slider.update(
            PygameEventUtils.middle_rect_click(slider._test_get_pos_value(0),
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertFalse(slider._scrolling)
예제 #22
0
    def test_menubar(self) -> None:
        """
        Test menubar widget.
        """
        menu = MenuUtils.generic_menu()
        for mode in (MENUBAR_STYLE_ADAPTIVE, MENUBAR_STYLE_NONE,
                     MENUBAR_STYLE_SIMPLE, MENUBAR_STYLE_UNDERLINE,
                     MENUBAR_STYLE_UNDERLINE_TITLE, MENUBAR_STYLE_TITLE_ONLY,
                     MENUBAR_STYLE_TITLE_ONLY_DIAGONAL):
            mb = MenuBar('Menu', 500, (0, 0, 0), back_box=True, mode=mode)
            menu.add.generic_widget(mb)
        mb = MenuBar('Menu', 500, (0, 0, 0), back_box=True)
        mb.set_backbox_border_width(2)
        self.assertRaises(AssertionError,
                          lambda: mb.set_backbox_border_width(1.5))
        self.assertRaises(AssertionError,
                          lambda: mb.set_backbox_border_width(0))
        self.assertRaises(AssertionError,
                          lambda: mb.set_backbox_border_width(-1))
        self.assertEqual(mb._backbox_border_width, 2)
        menu.draw(surface)
        menu.disable()

        # Test unknown mode
        mb = MenuBar('Menu', 500, (0, 0, 0), back_box=True, mode='unknown')
        mb.set_menu(menu)
        self.assertRaises(ValueError, lambda: mb._render())

        # Check margins
        mb = MenuBar('Menu',
                     500, (0, 0, 0),
                     back_box=True,
                     mode=MENUBAR_STYLE_ADAPTIVE)
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 0)))
        mb.set_menu(menu)
        mb._render()
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTHWEST),
                         (0, (0, 0)))

        # Test displacements
        theme = pygame_menu.themes.THEME_DEFAULT.copy()
        theme.title_bar_style = MENUBAR_STYLE_TITLE_ONLY
        menu = MenuUtils.generic_menu(theme=theme, title='my title')
        mb = menu.get_menubar()
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (-55, (0, 55)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 55)))

        # Test with close button
        menu = MenuUtils.generic_menu(theme=theme,
                                      title='my title',
                                      onclose=pygame_menu.events.CLOSE,
                                      touchscreen=True)
        theme.widget_border_inflate = 0
        mb = menu.get_menubar()
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (-33, (0, 33)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (-55, (0, 55)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 55)))

        # Hide the title, and check
        mb.hide()
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 0)))

        mb.show()
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (-33, (0, 33)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (-55, (0, 55)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 55)))

        # Floating
        mb.set_float(True)
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 0)))

        mb.set_float(False)
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (-33, (0, 33)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (-55, (0, 55)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 55)))

        # Fixed
        mb.fixed = False
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_SOUTH),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_EAST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_WEST),
                         (0, (0, 0)))
        self.assertEqual(mb.get_scrollbar_style_change(POSITION_NORTH),
                         (0, (0, 0)))

        # Test menubar
        self.assertFalse(
            mb.update(PygameEventUtils.middle_rect_click(mb._rect)))
        self.assertTrue(
            mb.update(PygameEventUtils.middle_rect_click(mb._backbox_rect)))
        self.assertTrue(
            mb.update(
                PygameEventUtils.middle_rect_click(mb._backbox_rect,
                                                   evtype=pygame.FINGERUP,
                                                   menu=menu)))
        self.assertFalse(
            mb.update(
                PygameEventUtils.middle_rect_click(
                    mb._backbox_rect, evtype=pygame.MOUSEBUTTONDOWN)))
        self.assertTrue(
            mb.update(PygameEventUtils.joy_button(ctrl.JOY_BUTTON_BACK)))
        mb.readonly = True
        self.assertFalse(
            mb.update(PygameEventUtils.joy_button(ctrl.JOY_BUTTON_BACK)))
        mb.readonly = False

        # Test none methods
        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.rotate(10))
        self.assertEqual(mb._angle, 0)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.resize(10, 10))
        self.assertFalse(mb._scale[0])
        self.assertEqual(mb._scale[1], 1)
        self.assertEqual(mb._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.scale(100, 100))
        self.assertFalse(mb._scale[0])
        self.assertEqual(mb._scale[1], 1)
        self.assertEqual(mb._scale[2], 1)

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.flip(True, True))
        self.assertFalse(mb._flip[0])
        self.assertFalse(mb._flip[1])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.set_max_width(100))
        self.assertIsNone(mb._max_width[0])

        self.assertRaises(WidgetTransformationNotImplemented,
                          lambda: mb.set_max_height(100))
        self.assertIsNone(mb._max_height[0])

        # Ignore others
        mb.set_padding()
        mb.set_border()
        mb.set_selection_effect()
        menu.add.button('nice')
예제 #23
0
    def test_example_other_calculator(self) -> None:
        """
        Test calculator example.
        """
        app = calculator.main(test=True)

        # Process events
        app.process_events(
            PygameEventUtils.keydown([
                pygame.K_1, pygame.K_2, pygame.K_3, pygame.K_4, pygame.K_5,
                pygame.K_PLUS
            ]))
        self.assertEqual(app.prev, '12345')
        self.assertEqual(app.op, '+')
        app.process_events(
            PygameEventUtils.keydown(
                [pygame.K_6, pygame.K_7, pygame.K_8, pygame.K_9, pygame.K_0]))
        self.assertEqual(app.curr, '67890')
        app.process_events(PygameEventUtils.keydown(pygame.K_EQUALS))
        self.assertEqual(app.op, '')
        self.assertEqual(app.curr, '80235')
        self.assertEqual(app.prev, '')
        app.process_events(PygameEventUtils.keydown([pygame.K_x, pygame.K_2]))
        self.assertEqual(app.op, 'x')
        self.assertEqual(app.curr, '2')
        self.assertEqual(app.prev, '80235')
        app.process_events(PygameEventUtils.keydown([pygame.K_x]))
        self.assertEqual(app.op, 'x')
        self.assertEqual(app.curr, '')
        self.assertEqual(app.prev, '160470')
        app.process_events(
            PygameEventUtils.keydown([pygame.K_PLUS, pygame.K_3, pygame.K_0]))
        self.assertEqual(app.op, '+')
        self.assertEqual(app.curr, '30')
        self.assertEqual(app.prev, '160470')
        app.process_events(PygameEventUtils.keydown(pygame.K_EQUALS))
        self.assertEqual(app.op, '')
        self.assertEqual(app.curr, '160500')
        self.assertEqual(app.prev, '')
        app.process_events(
            PygameEventUtils.keydown(
                [pygame.K_SLASH, pygame.K_5, pygame.K_MINUS]))
        self.assertEqual(app.op, '-')
        self.assertEqual(app.curr, '')
        self.assertEqual(app.prev, '32100')
        app.process_events(
            PygameEventUtils.keydown([
                pygame.K_3, pygame.K_2, pygame.K_1, pygame.K_0, pygame.K_EQUALS
            ]))
        self.assertEqual(app.op, '')
        self.assertEqual(app.curr, '28890')
        self.assertEqual(app.prev, '')
        app.process_events(
            PygameEventUtils.keydown([pygame.K_9, pygame.K_BACKSPACE]))
        self.assertEqual(app.op, '')
        self.assertEqual(app.curr, '')
        self.assertEqual(app.prev, '')

        # Test methods
        self.assertRaises(ValueError, lambda: app._format('n'))
        self.assertEqual(app._format('1.2'), '1')
        self.assertEqual(app._format('2.0'), '2')

        # Test selection
        app.menu._test_print_widgets()
        b1 = app.menu.get_widgets()[4]
        b1d = b1.get_decorator()
        lay = b1.get_attribute('on_layer')
        self.assertFalse(b1d.is_enabled(lay))
        b1.select()
        self.assertTrue(b1d.is_enabled(lay))
        b1.select(False)
        self.assertFalse(b1d.is_enabled(lay))
예제 #24
0
    def test_update_callback(self) -> None:
        """
        Test update callback.
        """
        def update(event, widget, _) -> None:
            """
            Callback.
            """
            assert isinstance(event, list)
            widget.set_attribute('attr', True)

        menu = MenuUtils.generic_menu(theme=TEST_THEME.copy())
        btn = menu.add.button('button', lambda: print('Clicked'))
        call_id = btn.add_update_callback(update)
        self.assertFalse(btn.get_attribute('attr', False))
        click_pos = btn.get_rect(to_real_position=True).center
        deco = menu.get_decorator()
        test_draw_rects = True

        def draw_rect() -> None:
            """
            Draw absolute rect on surface for testing purposes.
            """
            if not test_draw_rects:
                return
            surface.fill((0, 255, 0), btn.get_rect(to_real_position=True))

        deco.add_callable(draw_rect, prev=False, pass_args=False)
        click_pos_absolute = btn.get_rect(to_absolute_position=True).center
        self.assertNotEqual(click_pos, click_pos_absolute)
        self.assertEqual(menu.get_scrollarea()._view_rect,
                         menu.get_scrollarea().get_absolute_view_rect())
        self.assertEqual(btn.get_scrollarea(),
                         menu.get_current().get_scrollarea())
        if PYGAME_V2:
            self.assertEqual(btn.get_rect(), pygame.Rect(253, 153, 94, 41))
            self.assertEqual(btn.get_rect(to_real_position=True),
                             pygame.Rect(253, 308, 94, 41))

        else:
            self.assertEqual(btn.get_rect(), pygame.Rect(253, 152, 94, 42))
            self.assertEqual(btn.get_rect(to_real_position=True),
                             pygame.Rect(253, 307, 94, 42))

        self.assertEqual(len(menu._update_frames), 0)
        self.assertEqual(len(menu.get_current()._update_frames), 0)
        btn.update(PygameEventUtils.mouse_click(click_pos[0],
                                                click_pos[1]))  # MOUSEBUTTONUP
        self.assertTrue(btn.get_attribute('attr', False))
        btn.set_attribute('attr', False)
        btn.remove_update_callback(call_id)
        self.assertRaises(IndexError,
                          lambda: btn.remove_update_callback(call_id))
        self.assertFalse(btn.get_attribute('attr', False))
        btn.update(PygameEventUtils.mouse_click(click_pos[0], click_pos[1]))
        self.assertFalse(btn.get_attribute('attr', False))

        def update2(event, widget, _) -> None:
            """
            Callback.
            """
            assert isinstance(event, list)
            widget.set_attribute('epic', 'bass')

        btn.add_update_callback(update2)
        self.assertFalse(btn.has_attribute('epic'))
        btn.draw(surface)
        self.assertFalse(btn.has_attribute('epic'))
        btn.update(PygameEventUtils.mouse_click(click_pos[0], click_pos[1]))
        self.assertTrue(btn.has_attribute('epic'))
        btn.remove_attribute('epic')
        self.assertRaises(IndexError, lambda: btn.remove_attribute('epic'))
        self.assertFalse(btn.has_attribute('epic'))
예제 #25
0
    def test_textinput(self) -> None:
        """
        Test TextInput widget.
        """
        menu = MenuUtils.generic_menu()

        # Assert bad settings
        self.assertRaises(
            ValueError, lambda: menu.add.text_input('title',
                                                    input_type=pygame_menu.
                                                    locals.INPUT_FLOAT,
                                                    default='bad'))
        self.assertRaises(
            ValueError,  # Default and password cannot coexist
            lambda: menu.add.text_input('title', password=True, default='bad'))

        # Create text input widget
        textinput = menu.add.text_input('title', input_underline='_')
        textinput.set_value('new_value')  # No error
        textinput._selected = False
        textinput.draw(surface)
        textinput.select(update_menu=True)
        textinput.draw(surface)
        self.assertEqual(textinput.get_value(), 'new_value')
        textinput.clear()
        self.assertEqual(textinput.get_value(), '')

        # Create selection box
        string = 'the text'
        textinput._cursor_render = True
        textinput.set_value(string)
        textinput._select_all()
        self.assertEqual(textinput._get_selected_text(), 'the text')
        textinput.draw(surface)
        textinput._unselect_text()
        textinput.draw(surface)

        # Assert events
        textinput.update(PygameEventUtils.key(0, keydown=True, testmode=False))
        PygameEventUtils.test_widget_key_press(textinput)
        textinput.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        textinput.update(PygameEventUtils.key(pygame.K_LSHIFT, keydown=True))
        textinput.clear()

        # Type
        textinput.update(
            PygameEventUtils.key(pygame.K_t, keydown=True, char='t'))
        textinput.update(
            PygameEventUtils.key(pygame.K_e, keydown=True, char='e'))
        textinput.update(
            PygameEventUtils.key(pygame.K_s, keydown=True, char='s'))
        textinput.update(
            PygameEventUtils.key(pygame.K_t, keydown=True, char='t'))

        # Keyup
        textinput.update(PygameEventUtils.key(pygame.K_a, keyup=True,
                                              char='a'))
        self.assertEqual(textinput.get_value(), 'test')  # The text we typed

        # Ctrl events
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_c))  # copy
        textinput.update(PygameEventUtils.keydown_mod_ctrl(
            pygame.K_v))  # paste
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_z))  # undo
        self.assertEqual(textinput.get_value(), 'tes')
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_y))  # redo
        self.assertEqual(textinput.get_value(), 'test')
        textinput._select_all()
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_x))  # cut
        self.assertEqual(textinput.get_value(), '')
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_z))  # undo
        self.assertEqual(textinput.get_value(), 'test')
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_y))  # redo
        self.assertEqual(textinput.get_value(), '')
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_z))  # undo
        self.assertEqual(textinput.get_value(), 'test')

        # Test ignore ctrl events
        textinput._copy_paste_enabled = False
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_c)))
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_v)))
        max_history = textinput._max_history
        textinput._max_history = 0
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_z)))
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_y)))
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_x)))
        textinput._selection_enabled = False
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_a)))
        self.assertFalse(
            textinput.update(PygameEventUtils.keydown_mod_ctrl(
                pygame.K_r)))  # invalid

        # Reset
        textinput._copy_paste_enabled = True
        textinput._max_history = max_history
        textinput._selection_enabled = True

        # Test selection, if user selects all and types anything the selected
        # text must be destroyed
        textinput.update(PygameEventUtils.keydown_mod_ctrl(
            pygame.K_a))  # select all
        textinput._unselect_text()
        self.assertEqual(textinput._get_selected_text(), '')
        textinput._select_all()
        self.assertEqual(textinput._get_selected_text(), 'test')
        textinput._unselect_text()
        self.assertEqual(textinput._get_selected_text(), '')
        textinput.update(PygameEventUtils.keydown_mod_ctrl(pygame.K_a))
        self.assertEqual(textinput._get_selected_text(), 'test')
        textinput.update(
            PygameEventUtils.key(pygame.K_t, keydown=True, char='t'))
        textinput._select_all()
        self.assertTrue(
            textinput.update(
                PygameEventUtils.key(pygame.K_ESCAPE, keydown=True)))
        textinput._select_all()
        self.assertTrue(
            textinput.update(
                PygameEventUtils.key(pygame.K_BACKSPACE, keydown=True)))
        self.assertEqual(textinput.get_value(), '')
        textinput.set_value('t')

        # Releasing shift disable selection
        textinput._selection_active = True
        textinput.update(PygameEventUtils.key(pygame.K_LSHIFT, keyup=True))
        self.assertFalse(textinput._selection_active)

        # Arrows while selection
        textinput._select_all()
        self.assertIsNotNone(textinput._selection_surface)
        textinput.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        self.assertIsNone(textinput._selection_surface)
        textinput._select_all()
        self.assertIsNotNone(textinput._selection_surface)
        textinput.update(PygameEventUtils.key(pygame.K_RIGHT, keydown=True))
        self.assertIsNone(textinput._selection_surface)

        textinput._select_all()
        textinput._selection_active = True
        self.assertEqual(textinput._selection_box, [0, 1])
        textinput.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        self.assertEqual(textinput._selection_box, [0, 0])
        textinput._select_all()
        textinput._selection_active = True
        textinput.update(PygameEventUtils.key(pygame.K_RIGHT, keydown=True))
        self.assertEqual(textinput._selection_box, [0, 1])

        # Remove while selection
        textinput._select_all()
        textinput.update(PygameEventUtils.key(pygame.K_DELETE, keydown=True))
        self.assertEqual(textinput.get_value(), '')
        textinput.set_value('t')

        # Now the value must be t
        self.assertEqual(textinput._get_selected_text(), '')
        self.assertEqual(textinput.get_value(), 't')

        # Test readonly
        textinput.update(
            PygameEventUtils.key(pygame.K_t, keydown=True, char='k'))
        self.assertEqual(textinput.get_value(), 'tk')
        textinput.readonly = True
        textinput.update(
            PygameEventUtils.key(pygame.K_t, keydown=True, char='k'))
        self.assertEqual(textinput.get_value(), 'tk')
        textinput.readonly = False

        # Test keyup
        self.assertIn(pygame.K_t, textinput._keyrepeat_counters.keys())
        self.assertFalse(
            textinput.update(
                PygameEventUtils.key(pygame.K_t, keyup=True, char='1')))
        self.assertNotIn(pygame.K_t, textinput._keyrepeat_counters.keys())

        # Test tab
        self.assertEqual(textinput._tab_size, 4)
        textinput.update(PygameEventUtils.key(pygame.K_TAB, keydown=True))
        self.assertEqual(textinput.get_value(), 'tk    ')

        # Test invalid unicode
        self.assertFalse(
            textinput.update(PygameEventUtils.key(pygame.K_1, keydown=True)))

        # Up/Down disable active status
        textinput.active = True
        textinput.update(PygameEventUtils.key(ctrl.KEY_MOVE_UP, keydown=True))
        self.assertFalse(textinput.active)
        textinput.active = True
        textinput.update(PygameEventUtils.key(ctrl.KEY_MOVE_DOWN,
                                              keydown=True))
        self.assertFalse(textinput.active)
        textinput.active = True
        self.assertTrue(
            textinput.update(
                PygameEventUtils.key(pygame.K_ESCAPE, keydown=True)))
        self.assertFalse(textinput.active)

        # Test mouse
        textinput._selected = True
        textinput._selection_time = 0
        textinput.update(PygameEventUtils.middle_rect_click(textinput))
        self.assertTrue(textinput._cursor_visible)
        textinput._select_all()
        textinput._selection_active = True
        self.assertEqual(textinput._cursor_position, 6)
        self.assertEqual(textinput._selection_box, [0, 6])
        textinput.update(
            PygameEventUtils.middle_rect_click(textinput,
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertEqual(textinput._selection_box, [0, 0])

        # Check click pos
        textinput._check_mouse_collide_input(
            PygameEventUtils.middle_rect_click(textinput)[0].pos)
        self.assertEqual(textinput._cursor_position, 6)

        # Test touch
        textinput._cursor_position = 0
        textinput._check_touch_collide_input(
            PygameEventUtils.middle_rect_click(textinput)[0].pos)
        self.assertEqual(textinput._cursor_position, 6)

        # Update mouse
        for i in range(50):
            textinput.update(
                PygameEventUtils.key(pygame.K_t, keydown=True, char='t'))
        textinput._update_cursor_mouse(50)
        textinput._cursor_render = True
        textinput._render_cursor()

        # Test multiple are selected
        menu.add.text_input('title', password=True,
                            input_underline='_').select()
        self.assertRaises(
            pygame_menu.menu._MenuMultipleSelectedWidgetsException,
            lambda: menu.draw(surface))
        textinput.clear()
        textinput.select(update_menu=True)
        menu.draw(surface)

        # Clear the menu
        self.assertEqual(menu._stats.removed_widgets, 0)
        self.assertEqual(textinput.get_menu(), menu)
        menu.clear()
        self.assertIsNone(textinput.get_menu())
        self.assertEqual(menu._stats.removed_widgets, 3)
        menu.add.generic_widget(textinput)
        self.assertEqual(textinput.get_menu(), menu)
        menu.clear()
        self.assertEqual(menu._stats.removed_widgets, 4)
예제 #26
0
    def test_config(self) -> None:
        """
        Configure controls.
        """
        self.assertEqual(ctrl.KEY_APPLY, pygame.K_RETURN)

        # Change apply to new key
        ctrl.KEY_APPLY = pygame.K_END
        self.assertEqual(ctrl.KEY_APPLY, pygame.K_END)

        # Create new button
        menu = MenuUtils.generic_menu()
        test = [False]

        def click_button() -> None:
            """
            Button apply handler.
            """
            test[0] = not test[0]
            print('new test value', test)

        button = menu.add.button('button', click_button)
        self.assertFalse(test[0])
        button.apply()
        self.assertTrue(test[0])
        button.apply()
        self.assertFalse(test[0])

        # Now test new apply button
        button.update(PygameEventUtils.key(pygame.K_END, keydown=True))
        self.assertTrue(test[0])
        button.update(PygameEventUtils.key(pygame.K_END, keydown=True))
        self.assertFalse(test[0])

        # Rollback change
        ctrl.KEY_APPLY = pygame.K_RETURN

        # Create new controller object
        new_ctrl = ctrl.Controller()
        test_apply = [0]

        def new_apply(event, _) -> bool:
            """
            Updates apply.
            """
            test_apply[0] += 1
            return event.key == pygame.K_a

        new_ctrl.apply = new_apply
        button.set_controller(new_ctrl)

        # Now test new apply button
        button.update(PygameEventUtils.key(pygame.K_a, keydown=True))
        self.assertTrue(test[0])
        button.update(PygameEventUtils.key(pygame.K_a, keydown=True))
        self.assertFalse(test[0])
        self.assertEqual(test_apply[0], 2)

        button.update(PygameEventUtils.key(pygame.K_END, keydown=True))
        self.assertFalse(test[0])
        button.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        self.assertFalse(
            test[0])  # It should do nothing as object has new controller

        # The same can be done with menu
        menu.set_controller(new_ctrl)
예제 #27
0
    def test_colorinput(self) -> None:
        """
        Test ColorInput widget.
        """
        def _assert_invalid_color(widg) -> None:
            """
            Assert that the widget color is invalid.
            :param widg: Widget object
            """
            r, g, b = widg.get_value()
            self.assertEqual(r, -1)
            self.assertEqual(g, -1)
            self.assertEqual(b, -1)

        def _assert_color(widg, cr, cg, cb) -> None:
            """
            Assert that the widget color is invalid.
            :param widg: Widget object
            :param cr: Red channel, number between 0 and 255
            :param cg: Green channel, number between 0 and 255
            :param cb: Blue channel, number between 0 and 255
            """
            r, g, b = widg.get_value()
            self.assertEqual(r, cr)
            self.assertEqual(g, cg)
            self.assertEqual(b, cb)

        menu = MenuUtils.generic_menu(theme=TEST_THEME.copy())

        # Base rgb
        widget = menu.add.color_input('title',
                                      color_type='rgb',
                                      input_separator=',')
        widget.set_value((123, 234, 55))
        self.assertRaises(AssertionError, lambda: widget.set_value('0,0,0'))
        self.assertRaises(AssertionError, lambda: widget.set_value((
            255,
            0,
        )))
        self.assertRaises(AssertionError, lambda: widget.set_value(
            (255, 255, -255)))
        _assert_color(widget, 123, 234, 55)

        # Test separator
        widget = menu.add.color_input('color',
                                      color_type='rgb',
                                      input_separator='+')
        widget.set_value((34, 12, 12))
        self.assertEqual(widget._input_string, '34+12+12')
        self.assertRaises(
            AssertionError, lambda: menu.add.color_input(
                'title', color_type='rgb', input_separator=''))
        self.assertRaises(
            AssertionError, lambda: menu.add.color_input(
                'title', color_type='rgb', input_separator='  '))
        self.assertRaises(
            AssertionError,
            lambda: menu.add.color_input('title', color_type='unknown'))
        for i in range(10):
            self.assertRaises(
                AssertionError, lambda: menu.add.color_input(
                    'title', color_type='rgb', input_separator=str(i)))

        # Empty rgb
        widget = menu.add.color_input('color',
                                      color_type='rgb',
                                      input_separator=',')

        PygameEventUtils.test_widget_key_press(widget)
        self.assertEqual(widget._cursor_position, 0)
        widget.update(PygameEventUtils.key(pygame.K_RIGHT, keydown=True))
        self.assertEqual(widget._cursor_position, 0)
        _assert_invalid_color(widget)

        # Write sequence: 2 -> 25 -> 25, -> 25,0,
        # The comma after the zero must be automatically set
        self.assertFalse(
            widget.update(PygameEventUtils.key(0, keydown=True,
                                               testmode=False)))
        widget.update(PygameEventUtils.key(pygame.K_2, keydown=True, char='2'))
        widget.update(PygameEventUtils.key(pygame.K_5, keydown=True, char='5'))
        widget.update(
            PygameEventUtils.key(pygame.K_COMMA, keydown=True, char=','))
        self.assertEqual(widget._input_string, '25,')
        widget.update(PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(widget._input_string, '25,0,')
        _assert_invalid_color(widget)

        # Now, sequence: 25,0,c -> 25c,0, with cursor c
        widget.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        self.assertEqual(widget._cursor_position, 2)

        # Sequence. 25,0, -> 255,0, -> 255,0, trying to write another 5 in the same position
        # That should be cancelled because 2555 > 255
        widget.update(PygameEventUtils.key(pygame.K_5, keydown=True, char='5'))
        self.assertEqual(widget._input_string, '255,0,')
        widget.update(PygameEventUtils.key(pygame.K_5, keydown=True, char='5'))
        self.assertEqual(widget._input_string, '255,0,')

        # Invalid left zeros, try to write 255,0, -> 255,00, but that should be disabled
        widget.update(PygameEventUtils.key(pygame.K_RIGHT, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(widget._input_string, '255,0,')

        # Second comma cannot be deleted because there's a number between ,0,
        widget.update(PygameEventUtils.key(pygame.K_BACKSPACE, keydown=True))
        self.assertEqual(widget._input_string, '255,0,')
        widget.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_DELETE, keydown=True))
        self.assertEqual(widget._input_string, '255,0,')

        # Current cursor is at 255c,0,
        # Now right comma and 0 can be deleted
        widget.update(PygameEventUtils.key(pygame.K_END, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_BACKSPACE, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_BACKSPACE, keydown=True))
        self.assertEqual(widget._input_string, '255,')

        # Fill with zeros, then number with 2 consecutive 0 types must be 255,0,0
        # Commas should be inserted automatically
        widget.readonly = True
        widget.update(PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(widget._input_string, '255,')
        widget.readonly = False
        widget.update(PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        widget.update(PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(widget._input_string, '255,0,0')
        _assert_color(widget, 255, 0, 0)

        # At this state, user cannot add more zeros at right
        for i in range(5):
            widget.update(
                PygameEventUtils.key(pygame.K_0, keydown=True, char='0'))
        self.assertEqual(widget._input_string, '255,0,0')
        widget.get_rect()

        widget.clear()
        self.assertEqual(widget._input_string, '')

        # Assert invalid defaults rgb
        self.assertRaises(
            AssertionError, lambda: menu.add.color_input(
                'title', color_type='rgb', default=(
                    255,
                    255,
                )))
        self.assertRaises(
            AssertionError, lambda: menu.add.color_input(
                'title', color_type='rgb', default=(255, 255)))
        self.assertRaises(
            AssertionError, lambda: menu.add.color_input(
                'title', color_type='rgb', default=(255, 255, 255, 255)))

        # Assert hex widget
        widget = menu.add.color_input('title', color_type='hex')
        self.assertEqual(widget._input_string, '#')
        self.assertEqual(widget._cursor_position, 1)
        _assert_invalid_color(widget)
        self.assertRaises(AssertionError, lambda: widget.set_value('#FF'))
        self.assertRaises(AssertionError, lambda: widget.set_value('#FFFFF<'))
        self.assertRaises(AssertionError, lambda: widget.set_value('#FFFFF'))
        self.assertRaises(AssertionError, lambda: widget.set_value('#F'))
        # noinspection SpellCheckingInspection
        self.assertRaises(AssertionError, lambda: widget.set_value('FFFFF'))
        self.assertRaises(AssertionError, lambda: widget.set_value('F'))
        widget.set_value('FF00FF')
        _assert_color(widget, 255, 0, 255)
        widget.set_value('#12FfAa')
        _assert_color(widget, 18, 255, 170)
        widget.set_value('   59C1e5')
        _assert_color(widget, 89, 193, 229)

        widget.render()
        widget.draw(surface)

        widget.clear()
        self.assertEqual(widget._input_string, '#')  # This cannot be empty
        self.assertEqual(widget._cursor_position, 1)

        # In hex widget # cannot be deleted
        widget.update(PygameEventUtils.key(pygame.K_BACKSPACE, keydown=True))
        self.assertEqual(widget._cursor_position, 1)
        widget.update(PygameEventUtils.key(pygame.K_LEFT, keydown=True))
        widget.update(PygameEventUtils.key(pygame.K_DELETE, keydown=True))
        self.assertEqual(widget._input_string, '#')
        widget.update(PygameEventUtils.key(pygame.K_END, keydown=True))
        for i in range(10):
            widget.update(
                PygameEventUtils.key(pygame.K_f, keydown=True, char='f'))
        self.assertEqual(widget._input_string, '#ffffff')
        _assert_color(widget, 255, 255, 255)

        # Test hex formats
        widget = menu.add.color_input('title',
                                      color_type='hex',
                                      hex_format='none')
        widget.set_value('#ff00ff')
        self.assertFalse(
            widget.update(PygameEventUtils.key(0, keydown=True,
                                               testmode=False)))
        self.assertEqual(widget.get_value(as_string=True), '#ff00ff')
        widget.set_value('#FF00ff')
        self.assertEqual(widget.get_value(as_string=True), '#FF00ff')

        widget = menu.add.color_input('title',
                                      color_type='hex',
                                      hex_format='lower')
        widget.set_value('#FF00ff')
        self.assertEqual(widget.get_value(as_string=True), '#ff00ff')
        widget.set_value('AABBcc')
        self.assertEqual(widget.get_value(as_string=True), '#aabbcc')

        widget = menu.add.color_input('title',
                                      color_type='hex',
                                      hex_format='upper')
        widget.set_value('#FF00ff')
        self.assertEqual(widget.get_value(as_string=True), '#FF00FF')
        widget.set_value('AABBcc')
        self.assertEqual(widget.get_value(as_string=True), '#AABBCC')

        # Test dynamic sizing
        widget = menu.add.color_input('title',
                                      color_type='hex',
                                      hex_format='upper',
                                      dynamic_width=True)
        self.assertEqual(widget.get_width(), 200)
        widget.set_value('#ffffff')
        width = 342 if PYGAME_V2 else 345
        self.assertEqual(widget.get_width(), width)
        widget.set_value(None)
        self.assertEqual(widget.get_width(), 200)
        self.assertEqual(widget.get_value(as_string=True), '#')
        widget.set_value('#ffffff')
        self.assertEqual(widget.get_width(), width)
        widget.update(PygameEventUtils.key(
            pygame.K_BACKSPACE,
            keydown=True))  # remove the last character, now color is invalid
        self.assertEqual(widget.get_value(as_string=True),
                         '#FFFFF')  # is upper
        widget.render()
        self.assertEqual(widget.get_width(), 200)

        widget = menu.add.color_input('title',
                                      color_type='hex',
                                      hex_format='upper',
                                      dynamic_width=False)
        self.assertEqual(widget.get_width(), width)
        widget.set_value('#ffffff')
        self.assertEqual(widget.get_width(), width)
예제 #28
0
    def test_double(self) -> None:
        """
        Test double range slider.
        """
        menu = MenuUtils.generic_menu()

        # Double slider
        slider = pygame_menu.widgets.RangeSlider(
            'Range',
            range_text_value_tick_number=3,
            default_value=(0.2, 1.0),
            slider_text_value_font=pygame_menu.font.FONT_BEBAS,
            range_text_value_font=pygame_menu.font.FONT_8BIT,
            slider_text_value_triangle=False)
        slider._slider_text_value_vmargin = -2
        menu.add.generic_widget(slider, True)
        slider.draw(surface)
        slider.draw_after_if_selected(surface)

        self.assertEqual(slider.get_value(), (0.2, 1.0))
        self.assertRaises(AssertionError, lambda: slider.set_value(0.2))
        self.assertRaises(AssertionError, lambda: slider.set_value((0.2, 0.2)))
        self.assertRaises(AssertionError, lambda: slider.set_value((1.0, 0.2)))
        self.assertRaises(AssertionError, lambda: slider.set_value(
            (0.2, 0.5, 1.0)))

        # Test slider selection
        self.assertTrue(slider._slider_selected[0])
        self.assertTrue(
            slider.update(PygameEventUtils.key(ctrl.KEY_TAB, keydown=True)))
        self.assertFalse(slider._slider_selected[0])
        slider.draw(surface)
        slider.draw_after_if_selected(surface)

        # Test click sliders
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        self.assertTrue(
            slider.update(
                PygameEventUtils.middle_rect_click(
                    slider_rect, evtype=pygame.MOUSEBUTTONDOWN)))
        self.assertTrue(slider._slider_selected[0])
        self.assertFalse(
            slider.update(  # Slider already selected
                PygameEventUtils.middle_rect_click(
                    slider_rect, evtype=pygame.MOUSEBUTTONDOWN)))

        # Click if sliders are colliding
        slider.set_value((0.5, 0.50000001))
        slider_rect = slider._get_slider_inflate_rect(1, to_real_position=True)
        self.assertFalse(
            slider.update(
                PygameEventUtils.middle_rect_click(
                    slider_rect, evtype=pygame.MOUSEBUTTONDOWN)))
        self.assertTrue(slider._slider_selected[0])
        slider.set_value((0.5, 0.7))
        slider_rect = slider._get_slider_inflate_rect(1, to_real_position=True)
        self.assertTrue(
            slider.update(
                PygameEventUtils.middle_rect_click(
                    slider_rect, evtype=pygame.MOUSEBUTTONDOWN)))
        self.assertTrue(slider._slider_selected[1])

        # Test left slider
        pos = slider._test_get_pos_value(0.5)
        pos2 = slider._test_get_pos_value(0.6)
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        self.assertEqual(slider_rect, pygame.Rect(344, 311, 15, 28))
        slider.update(
            PygameEventUtils.middle_rect_click(slider_rect,
                                               evtype=pygame.MOUSEBUTTONDOWN))
        self.assertTrue(slider._slider_selected[0])
        self.assertTrue(slider._scrolling)
        self.assertTrue(slider._selected_mouse)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), (0.6, 0.7))

        # As slider moved, ignore this
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), (0.6, 0.7))
        self.assertTrue(slider._scrolling)
        self.assertTrue(slider._slider_selected[0])

        # Move to 0
        self.assertTrue(slider._selected_mouse)
        pos = slider._test_get_pos_value(0)
        pos2 = slider._test_get_pos_value(0.6)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), (0, 0.7))

        # Move more than 0.7
        pos = slider._test_get_pos_value(0)
        pos2 = slider._test_get_pos_value(0.75)
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertEqual(slider.get_value(), (0, 0.7))

        # Move to 0.7 - eps
        pos = slider._test_get_pos_value(0)
        pos2 = slider._test_get_pos_value(0.7 - 1e-6)
        slider_rect = slider._get_slider_inflate_rect(0, to_real_position=True)
        dx = pos[0] - pos2[0]
        slider.update(
            PygameEventUtils.mouse_motion(slider_rect,
                                          rel=(-dx, pos[1]),
                                          update_mouse=True))
        self.assertAlmostEqual(slider.get_value()[0], 0.7 - 1e-7, places=1)

        # Ignore if move 0.7 + eps
        self.assertFalse(
            slider.update(
                PygameEventUtils.mouse_motion(slider_rect,
                                              rel=(1, pos[1]),
                                              update_mouse=True)))

        # Change to right
        slider_rect = slider._get_slider_inflate_rect(1, to_real_position=True)
        self.assertTrue(
            slider.update(PygameEventUtils.key(ctrl.KEY_TAB, keydown=True)))
        pos = slider._test_get_pos_value(0.7)
        pos2 = slider._test_get_pos_value(0.8)
        dx = pos[0] - pos2[0]
        self.assertFalse(
            slider.update(
                PygameEventUtils.mouse_motion(slider_rect,
                                              rel=(-1, pos[1]),
                                              update_mouse=True)))
        self.assertTrue(
            slider.update(
                PygameEventUtils.mouse_motion(slider_rect,
                                              rel=(-dx, pos[1]),
                                              update_mouse=True)))
        self.assertAlmostEqual(slider.get_value()[1], 0.8)

        # Test left/right
        slider.set_value((0.7, 0.8))
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        slider.set_value((0.7, 0.8))  # Ignored
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        slider.set_value((0.7, 0.9))
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        slider.set_value((0.7, 1.0))
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        slider.set_value((0.7, 1.0))
        slider.set_value((0.7, 0.8))
        slider.update(PygameEventUtils.key(ctrl.KEY_TAB, keydown=True))
        slider.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        slider.set_value((0.7, 0.8))
        slider.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        slider.set_value((0.6, 0.8))

        # Reset value
        slider.reset_value()
        self.assertEqual(slider.get_value(), (0.2, 1.0))
예제 #29
0
    def test_selector(self) -> None:
        """
        Test selector widget.
        """
        menu = MenuUtils.generic_menu()
        selector = menu.add.selector('selector', [('1 - Easy', 'EASY'),
                                                  ('2 - Medium', 'MEDIUM'),
                                                  ('3 - Hard', 'HARD')],
                                     default=1)
        menu.enable()
        menu.draw(surface)

        selector.draw(surface)
        selector._selected = False
        selector.draw(surface)

        # Test events
        selector.update(PygameEventUtils.key(0, keydown=True, testmode=False))
        selector.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        selector.update(PygameEventUtils.key(ctrl.KEY_RIGHT, keydown=True))
        selector.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))
        selector.update(PygameEventUtils.joy_hat_motion(ctrl.JOY_LEFT))
        selector.update(PygameEventUtils.joy_hat_motion(ctrl.JOY_RIGHT))
        selector.update(PygameEventUtils.joy_motion(1, 0))
        selector.update(PygameEventUtils.joy_motion(-1, 0))
        click_pos = selector.get_rect(to_real_position=True,
                                      apply_padding=False).center
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0], click_pos[1]))

        # Check left/right clicks
        self.assertEqual(selector.get_index(), 0)
        click_pos = selector.get_rect(to_real_position=True,
                                      apply_padding=False).midleft
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertEqual(selector.get_index(), 2)
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertEqual(selector.get_index(), 1)
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 150, click_pos[1]))
        self.assertEqual(selector.get_index(), 0)
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertEqual(selector.get_index(), 1)
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertEqual(selector.get_index(), 2)
        selector.update(
            PygameEventUtils.mouse_click(click_pos[0] + 250, click_pos[1]))
        self.assertEqual(selector.get_index(), 0)

        # Test left/right touch
        click_pos = selector.get_rect(to_real_position=True,
                                      apply_padding=False).midleft
        selector._touchscreen_enabled = True
        selector.update(
            PygameEventUtils.touch_click(click_pos[0] + 150,
                                         click_pos[1],
                                         menu=selector.get_menu()))
        self.assertEqual(selector.get_index(), 2)
        selector.update(
            PygameEventUtils.touch_click(click_pos[0] + 250,
                                         click_pos[1],
                                         menu=selector.get_menu()))
        self.assertEqual(selector.get_index(), 0)
        selector.update(
            PygameEventUtils.touch_click(click_pos[0] + 250,
                                         click_pos[1],
                                         menu=selector.get_menu()))
        self.assertEqual(selector.get_index(), 1)

        # Update elements
        new_elements = [('4 - Easy', 'EASY'), ('5 - Medium', 'MEDIUM'),
                        ('6 - Hard', 'HARD')]
        selector.update_items(new_elements)
        selector.set_value('6 - Hard')
        self.assertEqual(selector.get_value()[1], 2)
        self.assertRaises(AssertionError, lambda: selector.set_value(bool))
        self.assertRaises(AssertionError, lambda: selector.set_value(200))
        selector.set_value(1)
        self.assertEqual(selector.get_value()[1], 1)
        self.assertEqual(selector.get_value()[0][0], '5 - Medium')
        selector.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(selector.get_value()[0][0], '4 - Easy')
        selector.readonly = True
        selector.update(PygameEventUtils.key(ctrl.KEY_LEFT, keydown=True))
        self.assertEqual(selector.get_value()[0][0], '4 - Easy')
        selector._left()
        self.assertEqual(selector.get_value()[0][0], '4 - Easy')
        selector._right()
        self.assertEqual(selector.get_value()[0][0], '4 - Easy')

        # Test fancy selector
        sel_fancy = menu.add.selector(
            'Fancy ', [('1 - Easy', 'EASY'), ('2 - Medium', 'MEDIUM'),
                       ('3 - Hard', 'HARD')],
            default=1,
            style=pygame_menu.widgets.widget.selector.SELECTOR_STYLE_FANCY)
        self.assertEqual(sel_fancy.get_items(), [('1 - Easy', 'EASY'),
                                                 ('2 - Medium', 'MEDIUM'),
                                                 ('3 - Hard', 'HARD')])
        self.assertRaises(
            AssertionError, lambda: menu.add.selector('title', [('a', 'a'),
                                                                ('b', 'b')],
                                                      default=2))
예제 #30
0
    def test_menu_link(self) -> None:
        """
        Test menu link.
        """
        menu = MenuUtils.generic_menu()
        menu1 = MenuUtils.generic_menu(title='Menu1',
                                       theme=pygame_menu.themes.THEME_BLUE)
        menu1.add.button('Back', pygame_menu.events.BACK)
        menu2 = MenuUtils.generic_menu(title='Menu2',
                                       theme=pygame_menu.themes.THEME_ORANGE)
        menu2.add.button('Back', pygame_menu.events.BACK)
        menu3 = MenuUtils.generic_menu(title='Menu3',
                                       theme=pygame_menu.themes.THEME_GREEN)
        menu3.add.button('Back', pygame_menu.events.BACK)
        btn1 = menu.add.button('menu1', menu1)
        btn2 = menu.add.button('menu2', menu2)
        btn3 = menu.add.button('menu3', menu3)

        # Hide the buttons
        btn1.hide()
        btn2.hide()
        btn3.hide()

        # Now open menu with the button, this should open Menu1 by default
        self.assertEqual(menu.get_current(), menu)
        btn1.apply()
        self.assertEqual(menu.get_current(), menu1)
        menu.full_reset()
        self.assertEqual(menu.get_current(), menu)

        # Add menu link
        link_test = menu.add.menu_link(menu2)
        link_test.open()
        self.assertEqual(menu.get_current(), menu2)
        menu.full_reset()
        self.assertEqual(menu.get_current(), menu)

        self.assertFalse(link_test.is_visible())
        link_test.hide()
        self.assertFalse(link_test.is_visible())
        link_test.show()
        self.assertFalse(link_test.is_visible())

        self.assertRaises(ValueError, lambda: menu.add.menu_link(menu))

        # Invalid objects
        self.assertRaises(ValueError, lambda: menu.add.menu_link(True))

        # noinspection PyMissingTypeHints,PyMissingOrEmptyDocstring
        def open_link(*args) -> None:
            link: 'pygame_menu.widgets.MenuLink' = args[-1]
            self.assertIsInstance(link, pygame_menu.widgets.MenuLink)
            link.open()

        # Add a selection object, which opens the links
        sel = menu.add.selector('Change menu ',
                                [('Menu 1', menu.add.menu_link(menu1)),
                                 ('Menu 2', menu.add.menu_link(menu2)),
                                 ('Menu 3', menu.add.menu_link(menu3))],
                                onreturn=open_link,
                                style=pygame_menu.widgets.SELECTOR_STYLE_FANCY)

        sel.update(PygameEventUtils.key(ctrl.KEY_APPLY, keydown=True))