CTkScrollableDropdownPP 2.1.3__tar.gz → 2.3__tar.gz

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.
@@ -10,7 +10,8 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
10
10
  command=None, image_values=[], alpha: float = 0.95, frame_corner_radius=20, double_click=False,
11
11
  frame_border_color=None, text_color=None, autocomplete=False,
12
12
  hover_color=None, pagination: bool = True, items_per_page: int = 50,
13
- groups=None, font=("Segoe UI", 12), fade_in_duration: bool = True, fps: int = 60, **button_kwargs):
13
+ groups=None, font=("Segoe UI", 12), fade_in_duration: bool = True, fps: int = 60,
14
+ multiple: bool = False, **button_kwargs):
14
15
  super().__init__(master=attach.winfo_toplevel(), takefocus=1)
15
16
 
16
17
  self.group_patterns = None
@@ -43,6 +44,8 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
43
44
  self.fps = max(1, int(fps))
44
45
  self.fade_animation_duration = 0.25
45
46
  self.animating = False
47
+ self.multiple = multiple
48
+ self.selected_values = []
46
49
 
47
50
  if groups is not None:
48
51
  for g in groups:
@@ -141,8 +144,9 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
141
144
  if self.pagination:
142
145
  self.button_container = customtkinter.CTkFrame(self.frame, fg_color=self.fg_color)
143
146
  self.button_container.pack(expand=True, fill="both")
144
- self.pagination_frame = customtkinter.CTkFrame(self.frame, fg_color=self.fg_color)
145
- self.pagination_frame.pack(fill="x", side="bottom")
147
+
148
+ self.pagination_frame = customtkinter.CTkFrame(self, fg_color=self.fg_color)
149
+ self.pagination_frame.pack(fill="x", pady=(3, 0))
146
150
  else:
147
151
  self.button_container = self.frame
148
152
  self.dummy_entry = customtkinter.CTkEntry(self.frame, fg_color="transparent", border_width=0, height=1, width=1)
@@ -245,11 +249,18 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
245
249
  self.current_page = 0
246
250
  self._init_buttons()
247
251
 
252
+ def _update_button_appearance(self, btn, value):
253
+ if self.multiple and value in self.selected_values:
254
+ btn.configure(fg_color=self.hover_color)
255
+ else:
256
+ btn.configure(fg_color=self.button_color)
257
+
248
258
  def update_buttons(self, values_list):
249
259
  for i, value in enumerate(values_list):
250
260
  if i in self.widgets:
251
261
  btn, _ = self.widgets[i]
252
262
  btn.configure(text=value, command=lambda v=value: self._attach_key_press(v), image=self.value_to_image.get(value))
263
+ self._update_button_appearance(btn, value)
253
264
  btn.pack(fill="x", pady=2, padx=(self.padding, 0))
254
265
  self.widgets[i][1] = True
255
266
  else:
@@ -265,6 +276,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
265
276
  hover_color=self.hover_color,
266
277
  image=self.value_to_image.get(value)
267
278
  )
279
+ self._update_button_appearance(btn, value)
268
280
  btn.pack(fill="x", pady=2, padx=(self.padding, 0))
269
281
  self.widgets[i] = [btn, True]
270
282
  i = len(values_list)
@@ -325,9 +337,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
325
337
  total_pages = (len(values_list) + self.items_per_page - 1) // self.items_per_page
326
338
  button_width = 30
327
339
  button_padding = 4
328
- available_width = self.pagination_frame.winfo_width() if self.pagination_frame.winfo_ismapped() else self.width_new
329
- if available_width < 1:
330
- available_width = self.attach.winfo_width() if self.width is None else self.width
340
+ available_width = self.pagination_frame.winfo_width() or self.width_new or self.attach.winfo_width() or 200
331
341
  max_buttons_per_row = max(1, available_width // (button_width + button_padding))
332
342
  total_rows = (total_pages + max_buttons_per_row - 1) // max_buttons_per_row
333
343
  for row in range(total_rows):
@@ -352,20 +362,18 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
352
362
 
353
363
  def _change_page(self, page_index):
354
364
  self.current_page = page_index
355
- if self.filtered_values is not None:
356
- values_to_show = self.filtered_values[self.current_page * self.items_per_page:
357
- (self.current_page + 1) * self.items_per_page]
358
- else:
365
+ if self.filtered_values is None:
359
366
  values_to_show = self.values[self.current_page * self.items_per_page:
360
367
  (self.current_page + 1) * self.items_per_page]
361
368
  self.update_buttons(values_to_show)
362
369
  self._update_pagination_buttons(filtered=bool(self.filtered_values))
363
370
  self.frame.update_idletasks()
364
- self.frame._parent_canvas.yview_moveto(len(values_to_show) / self.items_per_page)
371
+ ratio = len(values_to_show) / self.items_per_page
372
+ self.frame._parent_canvas.yview_moveto(0 if ratio < 0.5 else ratio)
365
373
 
366
374
  def destroy_popup(self):
367
- self.destroy()
368
- self.disable = True
375
+ self.destroy()
376
+ self.disable = True
369
377
 
370
378
  def place_dropdown(self):
371
379
  if not self.winfo_exists():
@@ -423,17 +431,30 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
423
431
  self.search_var.set("")
424
432
  self.event_generate("<<Selected>>")
425
433
  self.fade = True
426
- if self.command:
427
- self.command(k)
434
+ if self.multiple:
435
+ if k in self.selected_values:
436
+ self.selected_values.remove(k)
437
+ else:
438
+ self.selected_values.append(k)
439
+ for i, (btn, visible) in self.widgets.items():
440
+ if visible:
441
+ value = btn.cget("text")
442
+ self._update_button_appearance(btn, value)
443
+ if self.command:
444
+ self.command(self.selected_values)
445
+ else:
446
+ if self.command:
447
+ self.command(k)
428
448
  if hasattr(self, "search_var") and self.search_var.get().strip() != "":
429
449
  self.filtered_values = None
430
450
  self.current_page = 0
431
451
  self._init_buttons()
432
452
  if self.pagination:
433
- self.pagination_frame.pack(fill="x", side="bottom")
453
+ self.pagination_frame.pack(fill="x", pady=(3, 0))
434
454
  self.fade = False
435
- self._animated_withdraw()
436
- self.hide_flag = True
455
+ if not self.multiple:
456
+ self._animated_withdraw()
457
+ self.hide_flag = True
437
458
 
438
459
  def live_update(self, string=None):
439
460
  if self.disable or self.fade or self.animating:
@@ -453,11 +474,11 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
453
474
  values_to_show = filtered
454
475
  self.update_buttons(values_to_show)
455
476
  if self.pagination:
456
- self.pagination_frame.pack(fill="x", side="bottom")
477
+ self.pagination_frame.pack(fill="x", pady=(3, 0))
457
478
  self.place_dropdown()
458
479
  else:
459
480
  if self.pagination:
460
- self.pagination_frame.pack(fill="x", side="bottom")
481
+ self.pagination_frame.pack(fill="x", pady=(3, 0))
461
482
  self.filtered_values = None
462
483
  self.current_page = 0
463
484
  self._init_buttons()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CTkScrollableDropdownPP
3
- Version: 2.1.3
3
+ Version: 2.3
4
4
  Summary: Enhanced CTkScrollableDropdown with pagination, search and groups support
5
5
  Author: PLauncher-Team, Akash Bora
6
6
  License: MIT
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.8
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: customtkinter>=5.2.0
15
+ Requires-Dist: customtkinter
16
16
  Requires-Dist: pillow
17
17
  Dynamic: license-file
18
18
 
@@ -20,7 +20,7 @@ Dynamic: license-file
20
20
 
21
21
  [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
22
22
 
23
- **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
23
+ **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, grouping support, and multiple selection.
24
24
 
25
25
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
26
26
 
@@ -30,6 +30,7 @@ Dynamic: license-file
30
30
  * Real-time filtering
31
31
  * Grouped items (using regex or labels)
32
32
  * Autocomplete on typing
33
+ * Multiple selection support
33
34
  * Fully customizable appearance
34
35
 
35
36
  ## Installation
@@ -115,7 +116,7 @@ groups = [
115
116
  dropdown = CTkScrollableDropdown(attach=combobox, button_color="#2b2b2b", height=200, width=300, fg_color="#333333",
116
117
  values=all_values, command=lambda value: print(f"Selected: {value}"),
117
118
  image_values=all_images, text_color="#ffffff", hover_color="#3a3a3a",
118
- font=("Arial", 12), groups=groups, items_per_page=10)
119
+ font=("Arial", 12), groups=groups, items_per_page=10, multiple=True)
119
120
 
120
121
  root.mainloop()
121
122
  ```
@@ -0,0 +1,2 @@
1
+ customtkinter
2
+ pillow
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CTkScrollableDropdownPP
3
- Version: 2.1.3
3
+ Version: 2.3
4
4
  Summary: Enhanced CTkScrollableDropdown with pagination, search and groups support
5
5
  Author: PLauncher-Team, Akash Bora
6
6
  License: MIT
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.8
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: customtkinter>=5.2.0
15
+ Requires-Dist: customtkinter
16
16
  Requires-Dist: pillow
17
17
  Dynamic: license-file
18
18
 
@@ -20,7 +20,7 @@ Dynamic: license-file
20
20
 
21
21
  [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
22
22
 
23
- **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
23
+ **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, grouping support, and multiple selection.
24
24
 
25
25
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
26
26
 
@@ -30,6 +30,7 @@ Dynamic: license-file
30
30
  * Real-time filtering
31
31
  * Grouped items (using regex or labels)
32
32
  * Autocomplete on typing
33
+ * Multiple selection support
33
34
  * Fully customizable appearance
34
35
 
35
36
  ## Installation
@@ -115,7 +116,7 @@ groups = [
115
116
  dropdown = CTkScrollableDropdown(attach=combobox, button_color="#2b2b2b", height=200, width=300, fg_color="#333333",
116
117
  values=all_values, command=lambda value: print(f"Selected: {value}"),
117
118
  image_values=all_images, text_color="#ffffff", hover_color="#3a3a3a",
118
- font=("Arial", 12), groups=groups, items_per_page=10)
119
+ font=("Arial", 12), groups=groups, items_per_page=10, multiple=True)
119
120
 
120
121
  root.mainloop()
121
122
  ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
4
4
 
5
- **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
5
+ **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, grouping support, and multiple selection.
6
6
 
7
7
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
8
8
 
@@ -12,6 +12,7 @@
12
12
  * Real-time filtering
13
13
  * Grouped items (using regex or labels)
14
14
  * Autocomplete on typing
15
+ * Multiple selection support
15
16
  * Fully customizable appearance
16
17
 
17
18
  ## Installation
@@ -97,7 +98,7 @@ groups = [
97
98
  dropdown = CTkScrollableDropdown(attach=combobox, button_color="#2b2b2b", height=200, width=300, fg_color="#333333",
98
99
  values=all_values, command=lambda value: print(f"Selected: {value}"),
99
100
  image_values=all_images, text_color="#ffffff", hover_color="#3a3a3a",
100
- font=("Arial", 12), groups=groups, items_per_page=10)
101
+ font=("Arial", 12), groups=groups, items_per_page=10, multiple=True)
101
102
 
102
103
  root.mainloop()
103
104
  ```
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools>=61"]
2
+ requires = ["setuptools"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "CTkScrollableDropdownPP"
7
- version = "2.1.3"
7
+ version = "2.3"
8
8
  description = "Enhanced CTkScrollableDropdown with pagination, search and groups support"
9
9
  authors = [
10
10
  {name = "PLauncher-Team"},
@@ -19,7 +19,7 @@ classifiers = [
19
19
  ]
20
20
  keywords = ["customtkinter", "dropdown", "pagination", "search", "groups"]
21
21
  dependencies = [
22
- "customtkinter>=5.2.0",
22
+ "customtkinter",
23
23
  "pillow"
24
24
  ]
25
25
 
@@ -1,2 +0,0 @@
1
- customtkinter>=5.2.0
2
- pillow