From 1c91f1509949a967c78984218a1914e29164c87e Mon Sep 17 00:00:00 2001 From: Ansh Dadwal Date: Mon, 4 Mar 2024 20:43:33 +0530 Subject: [PATCH] day 2.8 progress --- kivymd/uix/carousel/carousel.kv | 4 +- kivymd/uix/carousel/carousel.py | 70 ++++++++++++++---------- kivymd/uix/carousel/carousel_strategy.py | 57 +++---------------- main.py | 1 + 4 files changed, 52 insertions(+), 80 deletions(-) diff --git a/kivymd/uix/carousel/carousel.kv b/kivymd/uix/carousel/carousel.kv index 969755a89..1f3cb6a3a 100644 --- a/kivymd/uix/carousel/carousel.kv +++ b/kivymd/uix/carousel/carousel.kv @@ -15,5 +15,5 @@ default_size_hint:[None, 1] size_hint:[None, 1] width:self.minimum_width - #spacing:dp(8) - #padding:[dp(16), dp(8)] + spacing:dp(8) + padding:[0, dp(8)] diff --git a/kivymd/uix/carousel/carousel.py b/kivymd/uix/carousel/carousel.py index c07ab80ca..0b9d71aca 100644 --- a/kivymd/uix/carousel/carousel.py +++ b/kivymd/uix/carousel/carousel.py @@ -34,7 +34,7 @@ class MDCarouselImageItem(AsyncImage, StencilBehavior): def __init__(self, *arg, **kwargs): super().__init__(*arg, **kwargs) self.fit_mode = "cover" - self.radius = [10] * 4 + self.radius = [30] * 4 class MDCarouselContainer( @@ -53,12 +53,11 @@ class MDCarousel(RecycleView): ) is_horizontal = BooleanProperty(True) alignment = StringProperty("default") - desired_item_size = NumericProperty(120) + desired_item_size = NumericProperty(140) _strategy = None _container = None - _distance_scroll = NumericProperty(0.0) - _variable_item_size = dp(50) + _variable_item_size = dp(50) def __init__(self, *arg, **kwargs): super().__init__(*arg, **kwargs) @@ -69,42 +68,53 @@ def __init__(self, *arg, **kwargs): def set_container(self, *args): self._container = self.ids._container - def fit_count(self, type_item, child_count): - suitable_count = getattr(self._strategy, f"{type_item}_count") - #if type_item == "large": - #if (self.width-dp(32))/getattr(self._strategy, f"{type_item}_size") <= suitable_count: - # suitable_count -= self._strategy.small_count - self._strategy.medium_count -1 - return range(suitable_count) - def set_init_size(self, *arg): - predicted_size = (self._strategy.large_count*self._strategy.large_size) + (self._strategy.medium_count*self._strategy.medium_size) + (self._strategy.small_count*self._strategy.small_size) - - print(predicted_size) - print(self.size,self._strategy, len(self._container.children)) - - child_count = len(self._container.children) - if child_count < ( + if len(self._container.children) < ( self._strategy.small_count + self._strategy.medium_count + self._strategy.large_count ): + # Reset the size and then retry + for widget in self._container.children: + widget.width = dp(40) + Clock.schedule_once(self.set_init_size) return - index = 0 + + # For debugging only! + # assert round(self.width) == round( + # (self._strategy.large_count * self._strategy.large_size) + # + (self._strategy.medium_count * self._strategy.medium_size) + # + (self._strategy.small_count * self._strategy.small_size) + # ) + + _index = 0 for type_item in ["large", "medium", "small"]: - item_size = getattr(self._strategy, f"{type_item}_size") - for widget_index in ( - self.fit_count(type_item, child_count) + for _ in range( + getattr(self._strategy, "{}_count".format(type_item)) ): - widget = self._container.children[::-1][index] - widget.width = item_size - index += 1 - - def on__distance_scroll(self, instance, distance): - pass + widget = self._container.children[::-1][_index] + widget.width = getattr( + self._strategy, "{}_size".format(type_item) + ) - dp(8) + _index += 1 + + state_ = "no" + def cover_distance_scroll(self, touch): + distance = touch.pos[0] - self._last_touch_point[0] + if self.state_ == "break": + return True + + for index, child in enumerate(self._container.children[::-1]): + if child.width >= self._strategy.small_size: + child.width += distance + break + else: + self.state_ = "break" + return False def update_strategy(self, *args): self._strategy = AvaliableStrategies.get(self.strategy).arrange( - self.width, self.desired_item_size, len(self.data) + self.alignment, self.width, self.desired_item_size, len(self.data) ) Clock.schedule_once(self.set_init_size) return self._strategy @@ -117,4 +127,4 @@ def on_touch_down(self, touch): def on_touch_move(self, touch): super().on_touch_move(touch) - self._distance_scroll = touch.pos[0] - self._last_touch_point[0] + self.cover_distance_scroll(touch) diff --git a/kivymd/uix/carousel/carousel_strategy.py b/kivymd/uix/carousel/carousel_strategy.py index d9b9b9ab5..fe156fa20 100644 --- a/kivymd/uix/carousel/carousel_strategy.py +++ b/kivymd/uix/carousel/carousel_strategy.py @@ -7,8 +7,8 @@ class CarouselStrategy: - small_size_min = dp(40) - small_size_max = dp(56) + small_size_min = dp(40) + dp(8) # dp(8) -> spacing + small_size_max = dp(56) + dp(8) def on_first_child_measured_with_margins(carousel: Widget, child: Widget): pass @@ -20,9 +20,9 @@ def get_child_mask_percentage( @staticmethod def double_counts(count: list): - doubled_count = list() - for i in range(len(count)): - doubled_count[i] = count[i] * 2 + doubled_count = [] + for i in count: + doubled_count.append(i*2) return doubled_count @staticmethod @@ -46,7 +46,8 @@ class MultiBrowseCarouselStrategy(CarouselStrategy): small_counts = [1] medium_counts = [1, 0] - def arrange(self, available_space, measured_child_size, item_len): + def arrange(self, alignment, available_space, measured_child_size, item_len): + measured_child_size += dp(8) # dp(8) -> spacing small_child_size_min = self.small_size_min small_child_size_max = max(self.small_size_max, small_child_size_min) target_large_child_size = min(measured_child_size, available_space) @@ -61,7 +62,7 @@ def arrange(self, available_space, measured_child_size, item_len): small_counts = [0] medium_counts = self.medium_counts - if False:#carousel.alignment == "center": + if alignment == "center": small_counts = self.double_counts(small_counts) medium_counts = self.double_counts(medium_counts) @@ -76,7 +77,7 @@ def arrange(self, available_space, measured_child_size, item_len): large_count_max - i for i in range(int(large_count_max - large_count_min + 1)) ] - arrangement = Arrangement.find_lowest_cost_arrangement( + return Arrangement.find_lowest_cost_arrangement( available_space, target_small_child_size, small_child_size_min, @@ -88,46 +89,6 @@ def arrange(self, available_space, measured_child_size, item_len): large_counts, ) - keyline_count = arrangement.get_item_count() - if self.ensure_arrangement_fits_item_count(arrangement, item_len): - arrangement = Arrangement.find_lowest_cost_arrangement( - available_space, - target_small_child_size, - small_child_size_min, - small_child_size_max, - [arrangement.small_count], - target_medium_child_size, - [arrangement.medium_count], - target_large_child_size, - [arrangement.large_count], - ) - return arrangement - - def ensure_arrangement_fits_item_count( - self, arrangement: Arrangement, carousel_item_count: int - ): - keyline_surplus = arrangement.get_item_count() - carousel_item_count - changed = keyline_surplus > 0 and ( - arrangement.small_count > 0 or arrangement.medium_count > 1 - ) - while keyline_surplus > 0: - if arrangement.small_count > 0: - arrangement.small_count -= 1 - elif arrangement.medium_count > 1: - arrangement.medium_count -= 1 - keyline_surplus -= 1 - return changed - - def should_refresh_keyline_state(carousel: Widget, old_item_count: int): - return ( - old_item_count < keyline_count - and carousel.get_item_count() >= keyline_count - ) or ( - old_item_count >= keyline_count - and carousel.get_item_count() < keyline_count - ) - - class AvaliableStrategies: avaliable = ["MultiBrowseCarouselStrategy"] diff --git a/main.py b/main.py index 590401205..0763fce65 100644 --- a/main.py +++ b/main.py @@ -11,6 +11,7 @@ md_bg_color: app.theme_cls.backgroundColor BoxLayout: orientation:"vertical" + padding:[dp(16),0] MDCarousel: id:carousel size_hint_y:None