flet-pdfview 0.1.2__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
flet_pdfview/main.py CHANGED
@@ -1,4 +1,4 @@
1
- from flet import Column,Image,ScrollMode,BoxFit
1
+ from flet import Column,Image,ScrollMode,BoxFit,InteractiveViewer
2
2
  import asyncio , os,pymupdf,gc
3
3
  from typing import Optional
4
4
  class PdfColumn(Column):
@@ -15,7 +15,8 @@ def main(page:Page):
15
15
  src="you/pdf/path",
16
16
  expand=True,
17
17
  dpi=300,
18
- fitImage=BoxFit.FILL
18
+ fitImage=BoxFit.FILL,
19
+ enable_zoom=True
19
20
  )
20
21
  )
21
22
  run(main)
@@ -23,7 +24,7 @@ run(main)
23
24
 
24
25
  make sure if the path do not end with .pdf or the path not exists the PdfColumn will do not show anything !
25
26
  """
26
- def __init__(self,src:str="",widht:Optional[int]=None,height:Optional[int]=None,spacing:Optional[int]=None,expand_loose:Optional[bool]=False,expand:Optional[bool]=False,scroll:ScrollMode=ScrollMode.ADAPTIVE,dpi:int=150,fitImage:BoxFit=BoxFit.FILL,visible:Optional[bool]=True):
27
+ def __init__(self,src:str="",enable_zoom:Optional[bool]=False,max_zoom:float=2.5,min_zoom:float=0.8,trackpad_scroll_causes_scale:Optional[bool]=True,widht:Optional[int]=None,height:Optional[int]=None,spacing:Optional[int]=None,expand_loose:Optional[bool]=False,expand:Optional[bool]=False,scroll:ScrollMode=ScrollMode.ADAPTIVE,dpi:int=150,fitImage:BoxFit=BoxFit.FILL,visible:Optional[bool]=True):
27
28
  super().__init__()
28
29
  self._src=src
29
30
  self.expand=expand
@@ -36,57 +37,120 @@ make sure if the path do not end with .pdf or the path not exists the PdfColumn
36
37
  self._fitImage=fitImage
37
38
  self._dpi=dpi
38
39
  self.visible=visible
39
- asyncio.create_task(self.__start_converte(src))
40
- async def __start_converte(self,path:str="",dpi:int=150):
41
- self.controls.clear()
42
- if os.path.exists(path) and path.endswith(".pdf"):
43
-
44
- pdf_pages = pymupdf.open(path)
45
-
46
- for pdf_page in pdf_pages:
47
- if self.src==path:
48
- pix = pdf_page.get_pixmap(dpi=dpi)
49
-
50
- # pix.save(filename="file.png",output=ram)
51
- self.controls.append(
52
- Image(
53
- expand=self.expand,
54
- expand_loose=self.expand_loose,
55
- width=self.widht,
56
- height=self.height,
57
- src=pix.tobytes(),
58
- fit=self.fitImage
59
- )
60
-
61
- )
62
-
63
- self.update()
64
- gc.collect()
65
- await asyncio.sleep(0.3)
66
- else:
67
- break
68
-
40
+ self._enable_zoom=enable_zoom
41
+ self._min_zoom=min_zoom
42
+ self._max_zoom=max_zoom
43
+ self._trackpad_scroll_causes_scale=trackpad_scroll_causes_scale
44
+ # self.page.run_task
69
45
 
46
+ async def __start_converte(self,path:str="",dpi:int=150):
47
+ try:
48
+ self.controls.clear()
49
+ if os.path.exists(path) and path.endswith(".pdf"):
50
+
51
+ pdf_pages = pymupdf.open(path)
52
+
53
+ for pdf_page in pdf_pages:
54
+ if self.src==path:
55
+ pix = pdf_page.get_pixmap(dpi=dpi)
56
+
57
+ # pix.save(filename="file.png",output=ram)
58
+ self.controls.append(
59
+ InteractiveViewer(
60
+ expand=self.expand,
61
+ expand_loose=self.expand_loose,
62
+ width=self.widht,
63
+ height=self.height,
64
+ content=Image(
65
+ expand=self.expand,
66
+ expand_loose=self.expand_loose,
67
+ width=self.widht,
68
+ height=self.height,
69
+ src=pix.tobytes(),
70
+ fit=self.fitImage
71
+ ),
72
+ scale_enabled=self._enable_zoom,
73
+ trackpad_scroll_causes_scale=self._trackpad_scroll_causes_scale,
74
+ max_scale=self._max_zoom,
75
+ min_scale=self._min_zoom
76
+ )
77
+ )
78
+
79
+ self.update()
80
+ gc.collect()
81
+ del pix
82
+ del pdf_page
83
+ await asyncio.sleep(0.3)
84
+ else:
85
+ break
86
+ except :
87
+ self.start_function.cancel()
88
+ finally:
89
+ # تنظيف الذاكرة في كل الأحوال
90
+ if 'pdf_pages' in locals():
91
+ pdf_pages.close()
92
+ def did_mount(self):
93
+ if self._src:
94
+ self.start_function = asyncio.create_task(self.__start_converte(self._src, self._dpi))
95
+ def will_unmount(self):
96
+ if self.start_function:
97
+ self.start_function.cancel()
70
98
  @property
71
99
  def src(self):
72
100
  return self._src
73
101
  @src.setter
74
102
  def src(self,new_src):
75
103
  self._src=new_src
76
- asyncio.create_task(self.__start_converte(new_src,))
104
+ self.start_function = asyncio.create_task(self.__start_converte(new_src,))
77
105
  @property
78
106
  def fitImage(self):
79
107
  return self._fitImage
80
108
  @fitImage.setter
81
109
  def fitImage(self,new_fitImage):
82
110
  self._fitImage=new_fitImage
83
- for image in self.controls:
84
- if isinstance(image,Image):
85
- image.fit=new_fitImage
111
+ for parent_image in self.controls:
112
+ if isinstance(parent_image,InteractiveViewer):
113
+ image = parent_image.content
114
+ if isinstance(image,Image):
115
+ image.fit=new_fitImage
86
116
  @property
87
117
  def dpi(self):
88
118
  return self._dpi
89
119
  @dpi.setter
90
120
  def dpi(self,new_dpi):
91
121
  self._dpi=new_dpi
92
- asyncio.create_task(self.__start_converte(self.src,))
122
+ self.start_function = asyncio.create_task(self.__start_converte(self.src,))
123
+ @property
124
+ def enable_zoom(self):
125
+ return self._enable_zoom
126
+ @enable_zoom.setter
127
+ def enable_zoom(self, value: bool):
128
+ self._enable_zoom = value
129
+ for viewer in self.controls:
130
+ if isinstance(viewer, InteractiveViewer):
131
+ viewer.scale_enabled = value
132
+ self.update()
133
+ @property
134
+ def trackpad_scroll_causes_scale(self):
135
+ return self._trackpad_scroll_causes_scale
136
+ @trackpad_scroll_causes_scale.setter
137
+ def trackpad_scroll_causes_scale(self, value: bool):
138
+ for viewer in self.controls:
139
+ if isinstance(viewer, InteractiveViewer):
140
+ viewer.trackpad_scroll_causes_scale = value
141
+ @property
142
+ def max_zoom(self):
143
+ return self._max_zoom
144
+ @max_zoom.setter
145
+ def max_zoom(self, value: float):
146
+ for viewer in self.controls:
147
+ if isinstance(viewer, InteractiveViewer):
148
+ viewer.max_scale = value
149
+ @property
150
+ def min_zoom(self):
151
+ return self._min_zoom
152
+ @min_zoom.setter
153
+ def min_zoom(self, value: float):
154
+ for viewer in self.controls:
155
+ if isinstance(viewer, InteractiveViewer):
156
+ viewer.min_scale = value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet_pdfview
3
- Version: 0.1.2
3
+ Version: 0.2.1
4
4
  Summary: Flet pdf view for all platforms
5
5
  Author: Mostafa Kessassi
6
6
  Author-email: mustaphakessassi76@gmail.com
@@ -28,6 +28,7 @@ Dynamic: summary
28
28
  ### ✨ Features
29
29
 
30
30
  * 🧩 **Native PDF rendering** inside Flet layouts.
31
+ * 🔍 **Interactive Zoom**: Support for zooming in and out with configurable limits.
31
32
  * 📐 **High-resolution** rendering with custom DPI.
32
33
  * 🖼️ **Flexible image fitting** using `BoxFit`.
33
34
  * 📱 **Fully responsive** (via `expand=True`).
@@ -54,18 +55,33 @@ def main(page: Page):
54
55
  src="path/to/your/file.pdf",
55
56
  expand=True,
56
57
  dpi=300,
57
- fitImage=BoxFit.FILL
58
+ fitImage=BoxFit.FILL,
59
+ enable_zoom=True
58
60
  )
59
61
  )
60
62
 
61
63
  run(main)
62
64
  ```
63
- ### ⚠️ Important Behavior
65
+ ### 🔍 Zoom Control
66
+ You can now fully control the viewing experience with the following properties:
64
67
 
65
- `PdfColumn` will not render anything if:
68
+ min_zoom: Sets the minimum scale allowed (Default : 0.8).
66
69
 
67
- 1. The provided **path does not exist**.
68
- 2. The file path **does not end with `.pdf`**.
70
+ max_zoom: Sets the maximum scale allowed to ensure quality and performance (Default : 2.5).
71
+ ### ⚠️ Important Behavior & Performance
72
+ **1. Silent Failure**
73
+
74
+ PdfColumn will not render anything if the provided path does not exist or does not end with .pdf.
75
+
76
+ No exceptions ❌
77
+
78
+ No error dialogs ❌
79
+
80
+ No UI interruption ❌
81
+
82
+ **2. Technical Performance Warning**
83
+
84
+ [!WARNING] Resource Management: Be cautious when performing intensive property updates on the PdfColumn object after its initial call. If changes involve high values or frequent updates, it may cause a brief delay when closing the application as the component finishes processing tasks to ensure a stable exit.
69
85
 
70
86
  > [!IMPORTANT]
71
87
  > **This behavior is intentional:**
@@ -0,0 +1,6 @@
1
+ flet_pdfview/__init__.py,sha256=uxLtdoexxWnULjF0YXDF3bTUuoizSUearqHxcs-n-dY,27
2
+ flet_pdfview/main.py,sha256=tsgwmdw8TvZ9Ou8XO0ker0G8JrBz9ye9UpSyLb38wXQ,6035
3
+ flet_pdfview-0.2.1.dist-info/METADATA,sha256=x8OTXCanJpsa_ozHVsrZWXNozTU7qgDQZe1aJTzZX6w,3115
4
+ flet_pdfview-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ flet_pdfview-0.2.1.dist-info/top_level.txt,sha256=e-e9EU2FfrodvbFGo3DJapANzBRZgjcvCeG4d-jdnGM,13
6
+ flet_pdfview-0.2.1.dist-info/RECORD,,
@@ -1,6 +0,0 @@
1
- flet_pdfview/__init__.py,sha256=uxLtdoexxWnULjF0YXDF3bTUuoizSUearqHxcs-n-dY,27
2
- flet_pdfview/main.py,sha256=LscccGNDfx0-t6lnumqKthuxPT5Ki19V7ftlOKSiw_A,3040
3
- flet_pdfview-0.1.2.dist-info/METADATA,sha256=Qh_mA-seEwXK0k9dtACldjpzbBYxeF7--rPG8-lnCBY,2310
4
- flet_pdfview-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- flet_pdfview-0.1.2.dist-info/top_level.txt,sha256=e-e9EU2FfrodvbFGo3DJapANzBRZgjcvCeG4d-jdnGM,13
6
- flet_pdfview-0.1.2.dist-info/RECORD,,