Exemple #1
0
 def test_aspect_ratio_is_set_in_constructor(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     self.assertEqual([50, 100], card_widget.children[0].size)
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.25)
     self.assertEqual([25, 100], card_widget.children[0].size)
def _get_test_card(ratio=0.5):
    card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                             aspect_ratio=ratio)
    card_widget.do_rotation = False
    card_widget.do_translation = False
    card_widget.do_scaling = False
    return card_widget
Exemple #3
0
 def test_visibility(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     self.assertTrue(card_widget.visible)
     card_front_filename = card_widget.children[0].source
     card_widget.visible = False
     self.assertFalse(card_widget.visible)
     card_back_filename = card_widget.children[0].source
     self.assertNotEqual(card_front_filename, card_back_filename)
     card_widget.visible = True
     self.assertTrue(card_widget.visible)
     self.assertEqual(card_front_filename, card_widget.children[0].source)
 def test_cannot_add_multiple_animations_for_the_same_card(self):
   animation_controller = AnimationController()
   card_widget = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
   animation_controller.add_card_animation(card_widget, Animation(x=10))
   with self.assertRaisesRegex(AssertionError,
                               "already an animation for this CardWidget"):
     animation_controller.add_card_animation(card_widget, Animation(y=10))
Exemple #5
0
 def test_aspect_ratio_is_enforced(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     card_widget.size = 10, 20
     card_widget.size = 25, 50
     card_widget.size = 26, 50
     card_widget.size = 24, 50
     with self.assertRaisesRegex(AssertionError, r"\(\[23, 50\], 0.5\)"):
         card_widget.size = 23, 50
     with self.assertRaisesRegex(AssertionError, r"\(\[27, 50\], 0.5\)"):
         card_widget.size = 27, 50
     card_widget.check_aspect_ratio(False)
     card_widget.size = 23, 50
     card_widget.size = 27, 50
Exemple #6
0
 def _run_flip_animation_test(self, fix_center: bool):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE))
     self.render(card_widget)
     animation = card_widget.get_flip_animation(duration=1,
                                                fixed_center=fix_center)
     on_complete_callback = Mock()
     animation.bind(on_complete=on_complete_callback)
     self.assertTrue(card_widget.visible)
     on_complete_callback.assert_not_called()
     initial_size = card_widget.size
     initial_pos = card_widget.pos
     card_widget.check_aspect_ratio(False)
     animation.start(card_widget)
     self.advance_frames(5)
     on_complete_callback.assert_not_called()
     card_widget.center = 100, 100
     self.wait_for_mock_callback(on_complete_callback)
     self.assertEqual(initial_size, card_widget.size)
     self.assertEqual(fix_center, initial_pos == card_widget.pos)
     self.assertFalse(card_widget.visible)
     animation = card_widget.get_flip_animation(duration=0.5,
                                                fixed_center=fix_center)
     on_complete_callback.reset_mock()
     animation.bind(on_complete=on_complete_callback)
     on_complete_callback.assert_not_called()
     animation.start(card_widget)
     self.wait_for_mock_callback(on_complete_callback)
     self.assertEqual(initial_size, card_widget.size)
     self.assertEqual(fix_center, initial_pos == card_widget.pos)
     self.assertTrue(card_widget.visible)
 def test_can_only_add_animations_in_the_idle_state(self):
   animation_controller = AnimationController()
   animation = Animation(x=10)
   animation.bind(
     on_complete=lambda *_: animation_controller.add_card_animation(
       CardWidget(Card(Suit.SPADES, CardValue.QUEEN)), Animation(y=10)))
   card_widget = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
   animation_controller.add_card_animation(card_widget, animation)
   self.assertFalse(animation_controller.is_running)
   animation_controller.start()
   self.assertTrue(animation_controller.is_running)
   with self.assertRaisesRegex(AssertionError,
                               "add animations in the IDLE state: RUNNING"):
     animation_controller.add_card_animation(
       CardWidget(Card(Suit.SPADES, CardValue.QUEEN)), Animation(y=10))
   with self.assertRaisesRegex(AssertionError,
                               "add animations in the IDLE state: CANCELLED"):
     animation_controller.cancel()
  def test_animate_one_card_no_callback(self):
    card_widget = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
    card_widget.pos = 0, 0
    float_layout = FloatLayout()
    float_layout.add_widget(card_widget)
    self.render(float_layout)

    self.assert_pixels_almost_equal([0, 0], card_widget.pos)
    animation_controller = AnimationController()
    animation = Animation(x=self.window.size[0], y=self.window.size[1])
    on_complete_callback = Mock()
    animation.bind(on_complete=on_complete_callback)
    animation_controller.add_card_animation(card_widget, animation)
    self.assertFalse(animation_controller.is_running)
    animation_controller.start()
    self.assertTrue(animation_controller.is_running)
    self.wait_for_mock_callback(on_complete_callback)
    self.assertFalse(animation_controller.is_running)
    self.assert_pixels_almost_equal(self.window.size, card_widget.pos)
  def test_cancel_two_cards_animation_with_callback(self):
    card_widget_1 = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
    card_widget_1.pos = 0, 0
    card_widget_2 = CardWidget(Card(Suit.SPADES, CardValue.KING))
    card_widget_2.pos = self.window.size[0], 0
    float_layout = FloatLayout()
    float_layout.add_widget(card_widget_1)
    float_layout.add_widget(card_widget_2)
    self.render(float_layout)

    self.assert_pixels_almost_equal([0, 0], card_widget_1.pos)
    self.assert_pixels_almost_equal([self.window.size[0], 0], card_widget_2.pos)
    animation_controller = AnimationController()
    animation_1 = Animation(x=self.window.size[0], y=self.window.size[1],
                            duration=5)
    on_complete_callback_1 = Mock()
    animation_1.bind(on_complete=on_complete_callback_1)
    animation_controller.add_card_animation(card_widget_1, animation_1)
    animation_2 = Animation(x=0, y=self.window.size[1],
                            duration=2 * animation_1.duration)
    on_complete_callback_2 = Mock()
    animation_2.bind(on_complete=on_complete_callback_2)
    animation_controller.add_card_animation(card_widget_2, animation_2)
    on_both_animations_complete_callback = Mock()
    self.assertFalse(animation_controller.is_running)
    animation_controller.start(on_both_animations_complete_callback)
    self.assertTrue(animation_controller.is_running)

    on_complete_callback_1.assert_not_called()
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    # Advance a couple of frames to move the cards a little bit, but not
    # complete any animation.
    self.advance_frames(5)
    self.assertNotEqual(0, card_widget_1.x)
    self.assertNotEqual(0, card_widget_1.y)
    self.assertNotEqual(self.window.size[0], card_widget_2.x)
    self.assertNotEqual(0, card_widget_2.y)

    # No callback should be called.
    on_complete_callback_1.assert_not_called()
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    # Cancel the animations.
    self.assertTrue(animation_controller.is_running)
    animation_controller.cancel()
    self.assertFalse(animation_controller.is_running)

    # All callbacks should be called.
    on_complete_callback_1.assert_called_once()
    on_complete_callback_2.assert_called_once()
    on_both_animations_complete_callback.assert_called_once()

    # Verify that the AnimationController can be reused.
    animation_controller.add_card_animation(card_widget_1, animation_1)
  def test_can_only_cancel_in_running_state(self):
    with self.assertRaisesRegex(AssertionError,
                                r"call cancel\(\) in the RUNNING state: IDLE"):
      AnimationController().cancel()

    animation_controller = AnimationController()
    animation = Animation(x=10)
    animation.bind(on_complete=lambda *_: animation_controller.cancel())
    card_widget = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
    animation_controller.add_card_animation(card_widget, animation)
    self.assertFalse(animation_controller.is_running)
    animation_controller.start()
    self.assertTrue(animation_controller.is_running)
    with self.assertRaisesRegex(AssertionError,
                                r"cancel\(\) in the RUNNING state: CANCELLED"):
      animation_controller.cancel()
  def test_animate_two_cards_with_callback(self):
    card_widget_1 = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
    card_widget_1.pos = 0, 0
    card_widget_2 = CardWidget(Card(Suit.SPADES, CardValue.KING))
    card_widget_2.pos = self.window.size[0], 0
    float_layout = FloatLayout()
    float_layout.add_widget(card_widget_1)
    float_layout.add_widget(card_widget_2)
    self.render(float_layout)

    self.assert_pixels_almost_equal([0, 0], card_widget_1.pos)
    self.assert_pixels_almost_equal([self.window.size[0], 0], card_widget_2.pos)
    animation_controller = AnimationController()
    animation_1 = Animation(x=self.window.size[0], y=self.window.size[1],
                            duration=0.5)
    on_complete_callback_1 = Mock()
    animation_1.bind(on_complete=on_complete_callback_1)
    animation_controller.add_card_animation(card_widget_1, animation_1)
    animation_2 = Animation(x=0, y=self.window.size[1],
                            duration=2 * animation_1.duration)
    on_complete_callback_2 = Mock()
    animation_2.bind(on_complete=on_complete_callback_2)
    animation_controller.add_card_animation(card_widget_2, animation_2)
    on_both_animations_complete_callback = Mock()
    self.assertFalse(animation_controller.is_running)
    animation_controller.start(on_both_animations_complete_callback)
    self.assertTrue(animation_controller.is_running)

    on_complete_callback_1.assert_not_called()
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    self.wait_for_mock_callback(on_complete_callback_1)
    self.assertTrue(animation_controller.is_running)
    self.assert_pixels_almost_equal(self.window.size, card_widget_1.pos)
    on_complete_callback_2.assert_not_called()
    on_both_animations_complete_callback.assert_not_called()

    self.wait_for_mock_callback(on_complete_callback_2)
    self.assertFalse(animation_controller.is_running)
    self.assert_pixels_almost_equal(self.window.size, card_widget_1.pos)
    self.assert_pixels_almost_equal([0, self.window.size[1]], card_widget_2.pos)
    on_both_animations_complete_callback.assert_called_once()

    # Verify that the AnimationController can be reused.
    self.assertFalse(animation_controller.is_running)
    animation_controller.add_card_animation(card_widget_1, animation_1)
Exemple #12
0
 def test_grayed_out(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     self.assertFalse(card_widget.grayed_out)
     self.assertEqual(1.0, card_widget.opacity)
     card_widget.grayed_out = False
     self.assertFalse(card_widget.grayed_out)
     self.assertEqual(1.0, card_widget.opacity)
     card_widget.grayed_out = True
     self.assertTrue(card_widget.grayed_out)
     self.assertEqual(0.5, card_widget.opacity)
     card_widget.grayed_out = True
     self.assertTrue(card_widget.grayed_out)
     self.assertEqual(0.5, card_widget.opacity)
     card_widget.grayed_out = False
     self.assertFalse(card_widget.grayed_out)
     self.assertEqual(1.0, card_widget.opacity)
      if self._closed:
        self._trump_card.rotation = 10
        self._trump_card.center = self.to_parent(
          local_talon_pos[0] + self._talon_size[0] / 2,
          local_talon_pos[1] + self._talon_size[1] / 2, True)
      else:
        self._trump_card.rotation = 90
        self._trump_card.pos = self.to_parent((self.width - height) / 2.0,
                                              (self.height - width) / 2.0, True)


if __name__ == "__main__":
  RATIO = 10
  talon_widget = TalonWidget(RATIO)
  talon_widget.pos = 50, 50
  talon_widget.size = 1000, 1000
  talon_widget.size_hint = None, None

  trump_card = CardWidget(Card(Suit.SPADES, CardValue.ACE), aspect_ratio=RATIO)
  talon_widget.set_trump_card(trump_card)

  _card = CardWidget(Card(Suit.SPADES, CardValue.ACE), aspect_ratio=RATIO)
  _card.visible = False
  talon_widget.push_card(_card)

  runTouchApp(talon_widget)

  # noinspection PyStringFormat
  print("(%.1f, (%d, %d), [%d, %d], (%.1f, %.1f), (%.1f, %.1f))" % (
    RATIO, *talon_widget.size, *_card.size, *_card.pos, *trump_card.pos))
                         center_y=_float_layout.height / 4) + \
               Animation(rotation=270) + \
               Animation(center_x=_float_layout.width / 4 * 3,
                         center_y=_float_layout.height / 4) + \
               Animation(rotation=270 + 90) + \
               Animation(center_x=_float_layout.width / 4 * 3,
                         center_y=_float_layout.height / 4 * 3) + \
               Animation(rotation=90) + \
               Animation(center_x=_float_layout.width / 4,
                         center_y=_float_layout.height / 4 * 3) + \
               Animation(rotation=45) + \
               Animation(center_x=_float_layout.width / 2,
                         center_y=_float_layout.height / 2) + \
               Animation(rotation=0)

  _card_widget = CardWidget(Card(Suit.SPADES, CardValue.QUEEN))
  _card_widget.size_hint = None, None
  _card_widget.bind(on_double_tap=lambda *_: _animation_controller.start())
  _float_layout.add_widget(_card_widget)


  def _reset_pos():
    _card_widget.center = _float_layout.center
    _card_widget.visible = True
    _card_widget.rotation = 0
    Clock.schedule_once(
      lambda _: _animation_controller.add_card_animation(_card_widget,
                                                         _animation))


  def _cancel():
Exemple #15
0
    def test_dragging_a_card_with_the_mouse(self):
        # pylint: disable=too-many-statements
        window = self.window

        on_card_moved_handler = Mock()

        # Place the card in the center of the window.
        card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                                 aspect_ratio=0.5,
                                 do_translation=True)
        min_dimension = min(window.width, window.height)
        card_widget.size = min_dimension / 4, min_dimension / 2
        window_center = window.width / 2, window.height / 2
        card_widget.center = window_center
        card_widget.bind(on_card_moved=on_card_moved_handler)

        # Place a second card under the first card. Only the first one will be moved
        # and it will be the only one triggering the on_card_moved event.
        another_card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                                         aspect_ratio=0.5)
        another_card_widget.size = card_widget.size
        another_card_widget.center = card_widget.center
        another_card_widget.bind(on_card_moved=on_card_moved_handler)

        float_layout = FloatLayout()
        float_layout.add_widget(another_card_widget)
        float_layout.add_widget(card_widget)
        self.render(float_layout)

        # Touch down on the card, nothing happens to the card.
        touch = UnitTestTouch(*card_widget.center)
        touch.touch_down()
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag in a random direction, check that the card moved accordingly.
        new_position = window.width / 3, window.height / 3
        touch.touch_move(*new_position)
        self.assertAlmostEqual(new_position[0], card_widget.center_x)
        self.assertAlmostEqual(new_position[1], card_widget.center_y)
        on_card_moved_handler.assert_not_called()

        # Drag in another random direction, check that the card moved accordingly.
        new_position = window.width * 0.7, window.height * 0.45
        touch.touch_move(*new_position)
        self.assertAlmostEqual(new_position[0], card_widget.center_x)
        self.assertAlmostEqual(new_position[1], card_widget.center_y)
        on_card_moved_handler.assert_not_called()

        # Touch up, nothing happens to the card. The on_card_moved event is
        # triggered.
        touch.touch_up()
        self.assertAlmostEqual(new_position[0], card_widget.center_x)
        self.assertAlmostEqual(new_position[1], card_widget.center_y)
        on_card_moved_handler.assert_called_once_with(card_widget,
                                                      card_widget.center)
        on_card_moved_handler.reset_mock()

        # Move the card back to the window center.
        card_widget.center = window_center

        # CardWidget's position has changed, but was not dragged by the user. The
        # on_card_moved event should not trigger.
        on_card_moved_handler.assert_not_called()

        # A click on the card, without dragging should not trigger the on_card_moved
        # event.
        touch = UnitTestTouch(*card_widget.center)
        touch.touch_down()
        touch.touch_up()
        on_card_moved_handler.assert_not_called()

        # Touch down in the bottom left corner of the window, outside of the card.
        # Nothing happens to the card.
        touch = UnitTestTouch(window.width * 0.1, window.height * 0.1)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag to the window center, on the card. Nothing happens to the card.
        touch.touch_move(*window_center)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag further to the top right corner of the window. Nothing happens to the
        # card.
        touch.touch_move(window.width * 0.95, window.height * 0.95)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Touch up. Nothing happens to the card.
        touch.touch_up()
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()
Exemple #16
0
 def test_shadow(self):
     card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                              aspect_ratio=0.5)
     self.assertTrue(card_widget.shadow)
     card_widget.shadow = 0
     self.assertFalse(card_widget.shadow)
Exemple #17
0
 def test_create_widgets_for_all_cards(self):
     card_dict = CardWidget.create_widgets_for_all_cards()
     self.assertEqual(20, len(card_dict.keys()))
     for card, card_widget in card_dict.items():
         self.assertEqual(card, card_widget.card)
Exemple #18
0
    def test_dragging_a_card_with_the_mouse_translations_disabled(self):
        window = self.window

        on_card_moved_handler = Mock()

        # Place the card in the center of the window.
        card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                                 aspect_ratio=0.5,
                                 do_translation=False)
        min_dimension = min(window.width, window.height)
        card_widget.size = min_dimension / 4, min_dimension / 2
        window_center = window.width / 2, window.height / 2
        card_widget.center = window_center
        card_widget.bind(on_card_moved=on_card_moved_handler)

        self.render(card_widget)

        # Touch down on the card, nothing happens to the card.
        touch = UnitTestTouch(*card_widget.center)
        touch.touch_down()
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag in a random direction, the card should not move.
        new_position = window.width / 3, window.height / 3
        touch.touch_move(*new_position)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Touch up, nothing happens to the card.
        touch.touch_up()
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Move the card to a new position. Since it was not dragged by the user, the
        # on_card_moved event should not trigger.
        card_widget.center = window.width / 3, window.height / 3
        on_card_moved_handler.assert_not_called()

        # A click on the card, without dragging should not trigger the on_card_moved
        # event.
        card_widget.center = window_center
        touch = UnitTestTouch(*card_widget.center)
        touch.touch_down()
        touch.touch_up()
        on_card_moved_handler.assert_not_called()

        # Touch down in the bottom left corner of the window, outside of the card.
        # Nothing happens to the card.
        touch = UnitTestTouch(window.width * 0.1, window.height * 0.1)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag to the window center, on the card. Nothing happens to the card.
        touch.touch_move(*window_center)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Drag further to the top right corner of the window. Nothing happens to the
        # card.
        touch.touch_move(window.width * 0.95, window.height * 0.95)
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()

        # Touch up. Nothing happens to the card.
        touch.touch_up()
        self.assertEqual(window_center, card_widget.center)
        on_card_moved_handler.assert_not_called()
 def _init_cards(self):
     self._cards = CardWidget.create_widgets_for_all_cards(
         path=self._game_options.cards_path)
     for card_widget in self._cards.values():
         card_widget.bind(on_card_moved=self._on_card_moved)
 def _bind_card_action(self, card: CardWidget,
                       action: PlayerAction) -> None:
     self._actions[card] = action
     card.bind(on_double_tap=self._card_action_callback)
Exemple #21
0
    def _run_test_on_double_tap_with_init_args(self, *args, **kwargs):
        """
    The args passed to this function are forwarded to the constructor of the
    CardWidget used in the test.
    """
        window = self.window

        # Place the card in the center of the window.
        card_widget = CardWidget(*args, **kwargs)
        min_dimension = min(window.width, window.height)
        card_widget.size = min_dimension / 4, min_dimension / 2
        window_center = window.width / 2, window.height / 2
        card_widget.center = window_center

        float_layout = FloatLayout()
        float_layout.add_widget(card_widget)
        self.render(float_layout)

        on_double_tap_handler = Mock()
        card_widget.bind(on_double_tap=on_double_tap_handler)

        # Normal click on the card does not trigger on_double_tap.
        touch = UnitTestTouch(*card_widget.center)
        touch.touch_down()
        touch.touch_up()
        on_double_tap_handler.assert_not_called()

        # Double click on the card triggers on_double_tap.
        touch.is_double_tap = True
        touch.touch_down()
        touch.touch_up()
        on_double_tap_handler.assert_called_once_with(card_widget)
        on_double_tap_handler.reset_mock()

        # Double click outside of the card does not trigger on_double_tap.
        touch = UnitTestTouch(0, 0)
        touch.is_double_tap = True
        touch.touch_down()
        touch.touch_up()
        on_double_tap_handler.assert_not_called()

        # Two cards on top of each other. Only the top one triggers on_double_tap.
        another_card_widget = CardWidget(Card(Suit.SPADES, CardValue.ACE),
                                         aspect_ratio=0.5)
        another_card_widget.size = card_widget.size
        another_card_widget.center = card_widget.center
        another_card_widget.bind(on_double_tap=on_double_tap_handler)
        float_layout.add_widget(another_card_widget)

        touch = UnitTestTouch(*card_widget.center)
        touch.is_double_tap = True
        touch.touch_down()
        touch.touch_up()
        on_double_tap_handler.assert_called_once_with(another_card_widget)