Skip to content

Commit

Permalink
progres
Browse files Browse the repository at this point in the history
  • Loading branch information
T-Dynamos committed Mar 9, 2024
1 parent 56bd665 commit 072e6fd
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 89 deletions.
8 changes: 4 additions & 4 deletions kivymd/uix/carousel/arrangement.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ def __init__(

def __str__(self):
return (
f"Arrangement [priority={self.priority}, smallCount={self.small_count},"
f" smallSize={self.small_size}, mediumCount={self.medium_count},"
f" mediumSize={self.medium_size}, largeCount={self.large_count},"
f" largeSize={self.large_size}, cost={self.cost}]"
f"Arrangement [priority={self.priority}, small_count={self.small_count},"
f" small_size={self.small_size}, medium_count={self.medium_count},"
f" medium_size={self.medium_size}, large_count={self.large_count},"
f" large_size={self.large_size}, cost={self.cost}]"
)

def get_space(self):
Expand Down
68 changes: 13 additions & 55 deletions kivymd/uix/carousel/carousel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
StringProperty,
OptionProperty,
NumericProperty,
ListProperty
ListProperty,
)
from kivy.uix.image import AsyncImage
from kivy.uix.recycleboxlayout import RecycleBoxLayout
Expand Down Expand Up @@ -57,65 +57,21 @@ class MDCarousel(RecycleView):
desired_item_size = NumericProperty(140)

_strategy = None
_container = None
_variable_item_size = dp(50)
_scroll_distance = ListProperty([0,0])

_variable_item_size = dp(50)

def __init__(self, *arg, **kwargs):
super().__init__(*arg, **kwargs)
self.bind(data=self.update_strategy)
self.bind(size=self.update_strategy)
self.bind(ids=self.set_container)

def set_container(self, *args):
self._container = self.ids._container

def set_init_size(self, *arg):
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 = self.desired_item_size - dp(30)
Clock.schedule_once(self.set_init_size)
return
item_index = 0
for type_item in ["large", "medium", "small"]:
for _ in range(
getattr(self._strategy, "{}_count".format(type_item))
):
widget = self._container.children[::-1][item_index]
widget.width = getattr(
self._strategy, "{}_size".format(type_item)
) - dp(8) # dp(8) -> spacing
item_index += 1
self._old_children = self._container.children

@staticmethod
def clamp(value, min_val=0, max_val=0):
return min(max(value, min_val), max_val)

def on__scroll_distance(self, instance, distance_coord):
if instance != self:
return
distance = distance_coord[0] - self._last_touch_point[0]
for child in self._container.children[::-1]:
print(distance)
child.width = self.clamp(
child.width + (distance/2),
self._strategy.small_size,
self._strategy.large_size,
)
return
return
self.bind(strategy=self.update_strategy)

def update_strategy(self, *args):
self._strategy = AvaliableStrategies.get(self.strategy).arrange(
self.alignment, self.width, self.desired_item_size, len(self.data)
)
Clock.schedule_once(self.set_init_size)
if self._strategy.__class__.__name__ != self.strategy:
self._strategy = AvaliableStrategies.get(
self.strategy, len(self.data), self.ids._container
)
self._strategy.arrange(self.alignment, self.width, self.desired_item_size)
Clock.schedule_once(self._strategy.set_init_size)
return self._strategy

_last_touch_point = [0, 0]
Expand All @@ -126,4 +82,6 @@ def on_touch_down(self, touch):

def on_touch_move(self, touch):
super().on_touch_move(touch)
self._scroll_distance = list(touch.pos)
self._strategy.tranform_widgets(
touch.pos[0] - self._last_touch_point[0], self.scroll_x
)
102 changes: 74 additions & 28 deletions kivymd/uix/carousel/carousel_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,67 @@

from kivy.metrics import dp
from kivy.uix.widget import Widget
from kivy.clock import Clock

from kivymd.uix.carousel.arrangement import Arrangement


class CarouselStrategy:
small_size_min = dp(40) + dp(8) # dp(8) -> spacing
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

def get_child_mask_percentage(
masked_size: float, unmasked_size: float, child_margins: float
):
return 1 - ((masked_size - child_margins) / (unmasked_size - child_margins))
_container = None
item_len = 0
arrangement = None

def __init__(self, item_len, _container):
self.item_len = item_len
self._container = _container

def arrange(
self,
alignment: str,
available_space: int,
measured_child_size: int,
item_len: int,
) -> Arrangement:
"""Build arrangement based on size"""

def set_init_size(self, *arg) -> None:
"""Set size of visible widgets initially"""

def tranform_widgets(
self,
touch_distance,
scroll,
) -> None:
"""Shift sizes as per scroll and touch distance"""

@staticmethod
def double_counts(count: list):
doubled_count = []
for i in count:
doubled_count.append(i*2)
doubled_count.append(i * 2)
return doubled_count

@staticmethod
def clamp(value, min_val=0, max_val=0):
return min(max(value, min_val), max_val)

def is_contained(self):
return True

def should_refresh_key_line_state(self, carousel: Widget, old_item_count: int):
return False

def set_small_item_size_min(self, min_small_item_size: float):
self.small_size_min = min_small_item_size

def set_small_item_size_max(self, max_small_item_size: float):
self.small_size_max = max_small_item_size


class MultiBrowseCarouselStrategy(CarouselStrategy):
small_counts = [1]
medium_counts = [1, 0]

def arrange(self, alignment, available_space, measured_child_size, item_len):
measured_child_size += dp(8) # dp(8) -> spacing
def arrange(
self,
alignment: str,
available_space: int,
measured_child_size: int,
) -> Arrangement:
# append default padding
measured_child_size += dp(8)

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)
Expand Down Expand Up @@ -77,7 +92,7 @@ def arrange(self, alignment, available_space, measured_child_size, item_len):
large_count_max - i
for i in range(int(large_count_max - large_count_min + 1))
]
return Arrangement.find_lowest_cost_arrangement(
self.arrangement = Arrangement.find_lowest_cost_arrangement(
available_space,
target_small_child_size,
small_child_size_min,
Expand All @@ -89,11 +104,42 @@ def arrange(self, alignment, available_space, measured_child_size, item_len):
large_counts,
)

def set_init_size(self, *arg):
if len(self._container.children) < (
self.arrangement.small_count
+ self.arrangement.medium_count
+ self.arrangement.large_count
):
# Reset the size and then retry
for widget in self._container.children:
widget.width = self.arrangement.large_size - dp(30)
Clock.schedule_once(self.set_init_size)
return

item_index = 0
for type_item in ["large", "medium", "small"]:
for _ in range(getattr(self.arrangement, "{}_count".format(type_item))):
widget = self._container.children[::-1][item_index]
widget.width = getattr(
self.arrangement, "{}_size".format(type_item)
) - dp(8)
item_index += 1

def tranform_widgets(
self,
touch_distance,
scroll,
):
print(touch_distance, scroll * self._container.width)
touch_distance = touch_distance/10
children = self._container.children[::-1]


class AvaliableStrategies:
avaliable = ["MultiBrowseCarouselStrategy"]

@staticmethod
def get(strategy_name):
return {"MultiBrowseCarouselStrategy": MultiBrowseCarouselStrategy}[
strategy_name
]()
def get(strategy_name, item_len, container):
return {
"MultiBrowseCarouselStrategy": MultiBrowseCarouselStrategy,
}[strategy_name](item_len, container)
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def build(self):
def on_start(self):
super().on_start()
self.root.ids.carousel.data = [
{"source":path} for path in glob("/home/tdynamos/Pictures/Screenshots/*")[:20]
# {"source":path} for path in [""] * 20
# {"source":path} for path in glob("/home/tdynamos/Pictures/Screenshots/*")[:20]
{"source":path} for path in [""] * 20
]

Example().run()

0 comments on commit 072e6fd

Please sign in to comment.