diff --git a/kivy/tests/test_uix_carousel.py b/kivy/tests/test_uix_carousel.py index 34454a833f..fd8811b115 100644 --- a/kivy/tests/test_uix_carousel.py +++ b/kivy/tests/test_uix_carousel.py @@ -1,15 +1,60 @@ import pytest -def test_remove_widget(): +@pytest.fixture( + scope='session', params=(True, False), ids=lambda v: 'loop=' + str(v)) +def loop(request): + return request.param + + +def test_remove_widget(loop): from kivy.uix.carousel import Carousel from kivy.uix.widget import Widget - c = Carousel() - w = Widget() - c.add_widget(w) + c = Carousel(loop=loop) + assert c.index is None + assert c.current_slide is None + assert len(c.children) == 0 + assert len(c.slides) == 0 + + N_SLIDES = 4 + for i in range(N_SLIDES): + c.add_widget(Widget()) + assert c.index == 0 + assert c.current_slide == c.slides[0] + assert len(c.children) == 3 if loop else 2 + assert len(c.slides) == N_SLIDES + + # test issue #6370 + c.index = len(c.slides) - 1 + c.remove_widget(c.slides[0]) + + # remove a slide(smaller index than the current_slide's). + c.index = 1 + old_current_slide = c.current_slide + c.remove_widget(c.slides[c.index - 1]) + assert c.index == 0 + assert c.current_slide is old_current_slide + assert len(c.children) == 2 + assert len(c.slides) == 2 + + # remove a slide(bigger index than the current_slide's). + old_current_slide = c.current_slide + c.remove_widget(c.slides[c.index + 1]) + assert c.index == 0 + assert c.current_slide is old_current_slide assert len(c.children) == 1 assert len(c.slides) == 1 - c.remove_widget(w) + + # remove the current_slide(the last one left). + c.remove_widget(c.current_slide) + assert c.index is None + assert c.current_slide is None assert len(c.children) == 0 assert len(c.slides) == 0 + + +if __name__ == "__main__": + pytest.main(args=[ + __file__, + ]) diff --git a/kivy/uix/carousel.py b/kivy/uix/carousel.py index d27d0a4a6c..1e857d8e05 100644 --- a/kivy/uix/carousel.py +++ b/kivy/uix/carousel.py @@ -649,9 +649,12 @@ def remove_widget(self, widget, *args, **kwargs): # added in add_widget(). But it will break if RelativeLayout # implementation change. # if we passed the real widget - if widget in self.slides: + slides = self.slides + if widget in slides: + if self.index >= slides.index(widget): + self.index = max(0, self.index - 1) container = widget.parent - self.slides.remove(widget) + slides.remove(widget) super(Carousel, self).remove_widget(container) return container.remove_widget(widget, *args, **kwargs) return super(Carousel, self).remove_widget(widget, *args, **kwargs)