CTkScrollableDropdownPP 2.0.3__tar.gz → 2.0.4__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,7 @@ 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, **button_kwargs):
13
+ groups=None, font=("Segoe UI", 12), **button_kwargs):
14
14
  super().__init__(master=attach.winfo_toplevel(), takefocus=1)
15
15
 
16
16
  self.group_patterns = None
@@ -37,18 +37,20 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
37
37
  self.current_page = 0
38
38
  self.filtered_values = None
39
39
  self.current_group = 0
40
+ self.font = font
40
41
  self.groups = []
42
+
41
43
  if groups is not None:
42
44
  for g in groups:
43
45
  if isinstance(g, (list, tuple)) and len(g) >= 2:
44
46
  self.groups.append({"name": g[0], "pattern": g[1]})
45
47
  else:
46
48
  raise ValueError(f"groups must be a list of [name, pattern], got {g!r}")
47
-
49
+
48
50
  self.group_names = [g["name"] for g in self.groups]
49
51
  self.group_patterns = []
50
52
  included_values = set()
51
-
53
+
52
54
  for g in self.groups:
53
55
  pattern = g["pattern"]
54
56
  if pattern == "__OTHERS__":
@@ -58,14 +60,14 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
58
60
  self.group_patterns.append(compiled)
59
61
  matched = [v for v in self.all_values if compiled.search(v)]
60
62
  included_values.update(matched)
61
-
63
+
62
64
  self.grouped_values = {}
63
65
  for i, pat in enumerate(self.group_patterns):
64
66
  if pat == "__OTHERS__":
65
67
  self.grouped_values[i] = [v for v in self.all_values if v not in included_values]
66
68
  else:
67
69
  self.grouped_values[i] = [v for v in self.all_values if pat.search(v)]
68
-
70
+
69
71
  if sys.platform.startswith("win"):
70
72
  self.after(100, lambda: self.overrideredirect(True))
71
73
  self.transparent_color = self._apply_appearance_mode(self._fg_color) if hasattr(self, '_fg_color') else "#FFFFFF"
@@ -101,15 +103,16 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
101
103
  self.search_var = customtkinter.StringVar()
102
104
  self.search_var.trace_add('write', lambda *args: self.live_update(self.search_var.get()))
103
105
  self.search_entry = customtkinter.CTkEntry(self, textvariable=self.search_var)
104
- self.search_entry.pack(fill="x")
106
+ self.search_entry.pack(fill="x", pady=(0, 5))
105
107
  if self.groups:
106
- self.group_frame = customtkinter.CTkFrame(self, fg_color=self.fg_color)
107
- self.group_frame.pack(fill="x", padx=5)
108
+ self.group_frame = customtkinter.CTkFrame(self, fg_color=self.fg_color, bg_color=self.transparent_color)
109
+ self.group_frame.pack(fill="x", padx=5, pady=(0, 5))
108
110
  self.group_buttons = []
109
111
  for idx, name in enumerate(self.group_names):
110
112
  btn = customtkinter.CTkButton(
111
113
  self.group_frame,
112
114
  text=name,
115
+ font=self.font,
113
116
  height=button_height,
114
117
  fg_color=self.button_color,
115
118
  text_color=self.text_color,
@@ -130,7 +133,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
130
133
  border_color=self.frame_border_color
131
134
  )
132
135
  self.frame._scrollbar.grid_configure(padx=3)
133
- self.frame.pack(expand=True, fill="both")
136
+ self.frame.pack(expand=True, fill="both", pady=(3, 0))
134
137
  if self.pagination:
135
138
  self.button_container = customtkinter.CTkFrame(self.frame, fg_color=self.fg_color)
136
139
  self.button_container.pack(expand=True, fill="both")
@@ -187,19 +190,36 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
187
190
  self._init_buttons()
188
191
 
189
192
  def _on_group_frame_configure(self, event):
193
+ if not self.group_buttons:
194
+ return
195
+
190
196
  min_btn_width = 100
191
- cols = max(1, event.width // min_btn_width)
192
-
193
- for child in self.group_frame.grid_slaves():
194
- child.grid_forget()
195
-
197
+ n = len(self.group_buttons)
198
+ cols = max(1, min(n, event.width // min_btn_width))
199
+ rows = (n + cols - 1) // cols
200
+
201
+ frame_height = rows * self.button_height
202
+ if self.group_frame.winfo_height() != frame_height:
203
+ self.group_frame.configure(height=frame_height)
204
+
196
205
  for idx, btn in enumerate(self.group_buttons):
197
206
  row = idx // cols
198
- col = idx % cols
199
- btn.grid(row=row, column=col, sticky="ew", padx=2, pady=2)
200
-
201
- for c in range(cols):
202
- self.group_frame.grid_columnconfigure(c, weight=1)
207
+ col_in_row = idx % cols
208
+ row_start = row * cols
209
+ num_in_row = min(cols, n - row_start)
210
+
211
+ rel_width = 1.0 / num_in_row
212
+ rel_x = col_in_row * rel_width
213
+ rel_y = row / rows
214
+ rel_height = 1.0 / rows
215
+
216
+ btn.place(
217
+ in_=self.group_frame,
218
+ relx=rel_x,
219
+ rely=rel_y,
220
+ relwidth=rel_width,
221
+ relheight=rel_height
222
+ )
203
223
 
204
224
  def switch_group(self, idx):
205
225
  if idx == self.current_group:
@@ -216,7 +236,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
216
236
  self.filtered_values = None
217
237
  self.current_page = 0
218
238
  self._init_buttons()
219
-
239
+
220
240
  def update_buttons(self, values_list):
221
241
  for i, value in enumerate(values_list):
222
242
  if i in self.widgets:
@@ -228,7 +248,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
228
248
  btn = customtkinter.CTkButton(
229
249
  self.button_container,
230
250
  text=value,
231
- font=("Segoe UI", 12),
251
+ font=self.font,
232
252
  command=lambda v=value: self._attach_key_press(v),
233
253
  height=self.button_height,
234
254
  fg_color=self.button_color,
@@ -330,7 +350,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
330
350
  self._update_pagination_buttons(filtered=bool(self.filtered_values))
331
351
  self.frame.update_idletasks()
332
352
  self.frame._parent_canvas.yview_moveto(len(values_to_show) / self.items_per_page)
333
-
353
+
334
354
  def destroy_popup(self):
335
355
  self.destroy()
336
356
  self.disable = True
@@ -442,7 +462,7 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
442
462
  anchor=self.justify,
443
463
  command=lambda v=value: self._attach_key_press(v),
444
464
  width=0
445
- **kwargs)
465
+ **kwargs)
446
466
  btn.pack(fill="x", pady=2, padx=(self.padding, 0))
447
467
  self.widgets[index] = [btn, True]
448
468
  self.values.append(value)
@@ -511,11 +531,11 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
511
531
  self.groups.append({"name": g[0], "pattern": g[1]})
512
532
  else:
513
533
  raise ValueError(f"groups must be list of [name, pattern], got {g!r}")
514
-
534
+
515
535
  self.group_names = [g["name"] for g in self.groups]
516
536
  self.group_patterns = []
517
537
  included_values = set()
518
-
538
+
519
539
  for g in self.groups:
520
540
  pattern = g["pattern"]
521
541
  if pattern == "__OTHERS__":
@@ -525,14 +545,14 @@ class CTkScrollableDropdown(customtkinter.CTkToplevel):
525
545
  self.group_patterns.append(compiled)
526
546
  matched = [v for v in self.all_values if compiled.search(v)]
527
547
  included_values.update(matched)
528
-
548
+
529
549
  self.grouped_values = {}
530
550
  for i, pat in enumerate(self.group_patterns):
531
551
  if pat == "__OTHERS__":
532
552
  self.grouped_values[i] = [v for v in self.all_values if v not in included_values]
533
553
  else:
534
554
  self.grouped_values[i] = [v for v in self.all_values if pat.search(v)]
535
-
555
+
536
556
  self.current_group = 0
537
557
  self.switch_group(self.current_group)
538
558
  if "image_values" in kwargs:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CTkScrollableDropdownPP
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: Enhanced CTkScrollableDropdown with pagination, search and groups support
5
5
  Author: PLauncher-Team, Akash Bora
6
6
  License: MIT
@@ -17,6 +17,8 @@ Dynamic: license-file
17
17
 
18
18
  # CTkScrollableDropdownPP
19
19
 
20
+ [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
21
+
20
22
  **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
21
23
 
22
24
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: CTkScrollableDropdownPP
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: Enhanced CTkScrollableDropdown with pagination, search and groups support
5
5
  Author: PLauncher-Team, Akash Bora
6
6
  License: MIT
@@ -17,6 +17,8 @@ Dynamic: license-file
17
17
 
18
18
  # CTkScrollableDropdownPP
19
19
 
20
+ [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
21
+
20
22
  **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
21
23
 
22
24
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
@@ -1,5 +1,7 @@
1
1
  # CTkScrollableDropdownPP
2
2
 
3
+ [![PyPI Downloads](https://static.pepy.tech/badge/ctkscrollabledropdownpp)](https://pepy.tech/projects/ctkscrollabledropdownpp)
4
+
3
5
  **CTkScrollableDropdownPP** is an enhanced dropdown widget for CustomTkinter featuring pagination, live search, and grouping support.
4
6
 
5
7
  > Based on the original [CTkScrollableDropdown](https://github.com/Akascape/CTkScrollableDropdown) project.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "CTkScrollableDropdownPP"
7
- version = "2.0.3"
7
+ version = "2.0.4"
8
8
  description = "Enhanced CTkScrollableDropdown with pagination, search and groups support"
9
9
  authors = [
10
10
  {name = "PLauncher-Team"},