diff cagou/core/common.py @ 422:efee0e0afb78

core (common): moved simple_xhtml's image code to a generic "SizedImage" widget
author Goffi <goffi@goffi.org>
date Wed, 26 Feb 2020 16:41:27 +0100
parents 3e2333a11f61
children 1dd6db69406a
line wrap: on
line diff
--- a/cagou/core/common.py	Wed Feb 26 16:39:17 2020 +0100
+++ b/cagou/core/common.py	Wed Feb 26 16:41:27 2020 +0100
@@ -23,7 +23,7 @@
 from sat.core.i18n import _
 from sat.core import log as logging
 from kivy.uix.widget import Widget
-from kivy.uix.image import Image
+from kivy.uix.image import Image, AsyncImage
 from kivy.uix.label import Label
 from kivy.uix.behaviors import ButtonBehavior
 from kivy.uix.behaviors import ToggleButtonBehavior
@@ -196,6 +196,54 @@
             self.add_widget(icon_wid)
 
 
+class SizedImage(AsyncImage):
+    """AsyncImage sized according to C.IMG_MAX_WIDTH and C.IMG_MAX_HEIGHT"""
+    # following properties are desired height/width
+    # i.e. the ones specified in height/width attributes of <img>
+    # (or wanted for whatever reason)
+    # set to None to ignore them
+    target_height = properties.NumericProperty(allownone=True)
+    target_width = properties.NumericProperty(allownone=True)
+
+    def __init__(self, **kwargs):
+        # best calculated size
+        self._best_width = self._best_height = 100
+        super().__init__(**kwargs)
+
+    def on_texture(self, instance, texture):
+        """Adapt the size according to max size and target_*"""
+        if texture is None:
+            return
+        max_width, max_height = dp(C.IMG_MAX_WIDTH), dp(C.IMG_MAX_HEIGHT)
+        width, height = texture.size
+        if self.target_width:
+            width = min(width, self.target_width)
+        if width > max_width:
+            width = C.IMG_MAX_WIDTH
+
+        height = width / self.image_ratio
+
+        if self.target_height:
+            height = min(height, self.target_height)
+
+        if height > max_height:
+            height = max_height
+            width = height * self.image_ratio
+
+        self.width, self.height = self._best_width, self._best_height = width, height
+
+    def on_parent(self, instance, parent):
+        if parent is not None:
+            parent.bind(width=self.on_parent_width)
+
+    def on_parent_width(self, instance, width):
+        if self._best_width > width:
+            self.width = width
+            self.height = width / self.image_ratio
+        else:
+            self.width, self.height = self._best_width, self._best_height
+
+
 class JidSelectorCategoryLayout(StackLayout):
     pass