spacr 0.2.41__py3-none-any.whl → 0.2.46__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.
- spacr/core.py +46 -66
- spacr/gui.py +20 -38
- spacr/gui_core.py +327 -625
- spacr/gui_elements.py +175 -24
- spacr/gui_utils.py +324 -62
- spacr/io.py +43 -46
- spacr/plot.py +106 -0
- spacr/resources/icons/logo.pdf +2786 -6
- spacr/resources/icons/logo_spacr.png +0 -0
- spacr/resources/icons/logo_spacr_1.png +0 -0
- spacr/settings.py +0 -2
- spacr/utils.py +4 -24
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/METADATA +1 -1
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/RECORD +18 -16
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/LICENSE +0 -0
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/WHEEL +0 -0
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/entry_points.txt +0 -0
- {spacr-0.2.41.dist-info → spacr-0.2.46.dist-info}/top_level.txt +0 -0
spacr/gui_elements.py
CHANGED
@@ -287,6 +287,73 @@ class spacrDropdownMenu(tk.OptionMenu):
|
|
287
287
|
# Create custom button
|
288
288
|
self.create_custom_button()
|
289
289
|
|
290
|
+
def create_custom_button(self):
|
291
|
+
self.canvas_width = self.winfo_reqwidth() + 20 # Adjust width based on required size
|
292
|
+
self.canvas_height = 40 # Adjust the height as needed
|
293
|
+
self.canvas = tk.Canvas(self, width=self.canvas_width, height=self.canvas_height, bd=0, highlightthickness=0, relief='ridge', bg='#2B2B2B')
|
294
|
+
self.canvas.pack()
|
295
|
+
self.label = tk.Label(self.canvas, text="Settings Category", bg='#2B2B2B', fg='#ffffff', font=('Arial', 12))
|
296
|
+
self.label.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
|
297
|
+
self.draw_rounded_rectangle('#2B2B2B')
|
298
|
+
|
299
|
+
# Bind the click event to open the dropdown menu
|
300
|
+
self.canvas.bind("<Button-1>", self.on_click)
|
301
|
+
self.label.bind("<Button-1>", self.on_click)
|
302
|
+
|
303
|
+
def draw_rounded_rectangle(self, color):
|
304
|
+
radius = 15
|
305
|
+
x0, y0 = 10, 5
|
306
|
+
x1, y1 = self.canvas_width - 10, self.canvas_height - 5 # Adjust based on canvas size
|
307
|
+
|
308
|
+
self.canvas.delete("all")
|
309
|
+
|
310
|
+
# Create the rounded rectangle
|
311
|
+
self.canvas.create_arc(x0, y0, x0 + 2 * radius, y0 + 2 * radius, start=90, extent=90, fill=color, outline=color)
|
312
|
+
self.canvas.create_arc(x1 - 2 * radius, y0, x1, y0 + 2 * radius, start=0, extent=90, fill=color, outline=color)
|
313
|
+
self.canvas.create_arc(x0, y1 - 2 * radius, x0 + 2 * radius, y1, start=180, extent=90, fill=color, outline=color)
|
314
|
+
self.canvas.create_arc(x1 - 2 * radius, y1 - 2 * radius, x1, y1, start=270, extent=90, fill=color, outline=color)
|
315
|
+
|
316
|
+
self.canvas.create_rectangle(x0 + radius, y0, x1 - radius, y1, fill=color, outline=color)
|
317
|
+
self.canvas.create_rectangle(x0, y0 + radius, x1, y1 - radius, fill=color, outline=color)
|
318
|
+
|
319
|
+
self.label.config(bg=color) # Update label background to match rectangle color
|
320
|
+
|
321
|
+
def on_click(self, event):
|
322
|
+
self.post_menu()
|
323
|
+
|
324
|
+
def post_menu(self):
|
325
|
+
x, y, width, height = self.winfo_rootx(), self.winfo_rooty(), self.winfo_width(), self.winfo_height()
|
326
|
+
self.menu.post(x, y + height)
|
327
|
+
|
328
|
+
def update_styles(self, active_categories=None):
|
329
|
+
style = ttk.Style()
|
330
|
+
style_out = set_dark_style(style, widgets=[self])
|
331
|
+
self.menu = self['menu']
|
332
|
+
style_out = set_dark_style(style, widgets=[self.menu])
|
333
|
+
|
334
|
+
if active_categories is not None:
|
335
|
+
for idx in range(self.menu.index("end") + 1):
|
336
|
+
option = self.menu.entrycget(idx, "label")
|
337
|
+
if option in active_categories:
|
338
|
+
self.menu.entryconfig(idx, background=style_out['active_color'], foreground=style_out['fg_color'])
|
339
|
+
else:
|
340
|
+
self.menu.entryconfig(idx, background=style_out['bg_color'], foreground=style_out['fg_color'])
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
class spacrDropdownMenu_v1(tk.OptionMenu):
|
345
|
+
def __init__(self, parent, variable, options, command=None, **kwargs):
|
346
|
+
self.variable = variable
|
347
|
+
self.variable.set("Settings Category")
|
348
|
+
super().__init__(parent, self.variable, *options, command=command, **kwargs)
|
349
|
+
self.update_styles()
|
350
|
+
|
351
|
+
# Hide the original button
|
352
|
+
self.configure(highlightthickness=0, relief='flat', bg='#2B2B2B', fg='#2B2B2B')
|
353
|
+
|
354
|
+
# Create custom button
|
355
|
+
self.create_custom_button()
|
356
|
+
|
290
357
|
def create_custom_button(self):
|
291
358
|
self.canvas_width = self.winfo_reqwidth() # Use the required width of the widget
|
292
359
|
self.canvas_height = 40 # Adjust the height as needed
|
@@ -374,19 +441,26 @@ class spacrProgressBar(ttk.Progressbar):
|
|
374
441
|
# Track whether to show the progress label
|
375
442
|
self.label = label
|
376
443
|
|
444
|
+
# Create the progress label (defer placement)
|
377
445
|
if self.label:
|
378
|
-
# Create the progress label
|
379
446
|
self.progress_label = tk.Label(parent, text="Processing: 0/0", anchor='w', justify='left', bg=self.inactive_color, fg=self.fg_color)
|
380
|
-
self.progress_label.
|
447
|
+
self.progress_label.grid_forget() # Temporarily hide it
|
448
|
+
|
449
|
+
# Initialize attributes for time and operation
|
450
|
+
self.operation_type = None
|
451
|
+
self.time_image = None
|
452
|
+
self.time_batch = None
|
453
|
+
self.time_left = None
|
381
454
|
|
382
|
-
|
383
|
-
|
384
|
-
self.
|
385
|
-
self.
|
386
|
-
self.
|
455
|
+
def set_label_position(self):
|
456
|
+
if self.label and self.progress_label:
|
457
|
+
row_info = self.grid_info().get('row', 0)
|
458
|
+
col_info = self.grid_info().get('column', 0)
|
459
|
+
col_span = self.grid_info().get('columnspan', 1)
|
460
|
+
self.progress_label.grid(row=row_info + 1, column=col_info, columnspan=col_span, pady=5, padx=5, sticky='ew')
|
387
461
|
|
388
462
|
def update_label(self):
|
389
|
-
if self.label:
|
463
|
+
if self.label and self.progress_label:
|
390
464
|
# Update the progress label with current progress and additional info
|
391
465
|
label_text = f"Processing: {self['value']}/{self['maximum']}"
|
392
466
|
if self.operation_type:
|
@@ -399,44 +473,120 @@ class spacrProgressBar(ttk.Progressbar):
|
|
399
473
|
label_text += f", Time_left: {self.time_left:.3f} min"
|
400
474
|
self.progress_label.config(text=label_text)
|
401
475
|
|
476
|
+
def spacrScrollbarStyle(style, inactive_color, active_color):
|
477
|
+
# Check if custom elements already exist to avoid duplication
|
478
|
+
if not style.element_names().count('custom.Vertical.Scrollbar.trough'):
|
479
|
+
style.element_create('custom.Vertical.Scrollbar.trough', 'from', 'clam')
|
480
|
+
if not style.element_names().count('custom.Vertical.Scrollbar.thumb'):
|
481
|
+
style.element_create('custom.Vertical.Scrollbar.thumb', 'from', 'clam')
|
482
|
+
|
483
|
+
style.layout('Custom.Vertical.TScrollbar',
|
484
|
+
[('Vertical.Scrollbar.trough', {'children': [('Vertical.Scrollbar.thumb', {'expand': '1', 'sticky': 'nswe'})], 'sticky': 'ns'})])
|
485
|
+
|
486
|
+
style.configure('Custom.Vertical.TScrollbar',
|
487
|
+
background=inactive_color,
|
488
|
+
troughcolor=inactive_color,
|
489
|
+
bordercolor=inactive_color,
|
490
|
+
lightcolor=inactive_color,
|
491
|
+
darkcolor=inactive_color)
|
492
|
+
|
493
|
+
style.map('Custom.Vertical.TScrollbar',
|
494
|
+
background=[('!active', inactive_color), ('active', active_color)],
|
495
|
+
troughcolor=[('!active', inactive_color), ('active', inactive_color)],
|
496
|
+
bordercolor=[('!active', inactive_color), ('active', inactive_color)],
|
497
|
+
lightcolor=[('!active', inactive_color), ('active', active_color)],
|
498
|
+
darkcolor=[('!active', inactive_color), ('active', active_color)])
|
499
|
+
|
402
500
|
class spacrFrame(ttk.Frame):
|
403
|
-
def __init__(self, container, width=None, *args, bg='black', **kwargs):
|
501
|
+
def __init__(self, container, width=None, *args, bg='black', radius=20, scrollbar=True, textbox=False, **kwargs):
|
404
502
|
super().__init__(container, *args, **kwargs)
|
405
503
|
self.configure(style='TFrame')
|
406
504
|
if width is None:
|
407
505
|
screen_width = self.winfo_screenwidth()
|
408
506
|
width = screen_width // 4
|
409
|
-
|
410
|
-
|
507
|
+
|
508
|
+
# Create the canvas
|
509
|
+
canvas = tk.Canvas(self, bg=bg, width=width, highlightthickness=0)
|
510
|
+
self.rounded_rectangle(canvas, 0, 0, width, self.winfo_screenheight(), radius, fill=bg)
|
511
|
+
|
512
|
+
# Define scrollbar styles
|
513
|
+
style_out = set_dark_style(ttk.Style())
|
514
|
+
self.inactive_color = style_out['inactive_color']
|
515
|
+
self.active_color = style_out['active_color']
|
516
|
+
self.fg_color = style_out['fg_color'] # Foreground color for text
|
517
|
+
|
518
|
+
# Set custom scrollbar style
|
519
|
+
style = ttk.Style()
|
520
|
+
spacrScrollbarStyle(style, self.inactive_color, self.active_color)
|
521
|
+
|
522
|
+
# Create scrollbar with custom style if scrollbar option is True
|
523
|
+
if scrollbar:
|
524
|
+
scrollbar_widget = ttk.Scrollbar(self, orient="vertical", command=canvas.yview, style='Custom.Vertical.TScrollbar')
|
525
|
+
|
526
|
+
if textbox:
|
527
|
+
self.scrollable_frame = tk.Text(canvas, bg=bg, fg=self.fg_color, wrap=tk.WORD)
|
528
|
+
else:
|
529
|
+
self.scrollable_frame = ttk.Frame(canvas, style='TFrame')
|
411
530
|
|
412
|
-
self.scrollable_frame = ttk.Frame(canvas, style='TFrame')
|
413
531
|
self.scrollable_frame.bind(
|
414
532
|
"<Configure>",
|
415
533
|
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
416
534
|
)
|
417
535
|
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
|
418
|
-
|
536
|
+
if scrollbar:
|
537
|
+
canvas.configure(yscrollcommand=scrollbar_widget.set)
|
419
538
|
|
420
539
|
canvas.grid(row=0, column=0, sticky="nsew")
|
421
|
-
scrollbar
|
540
|
+
if scrollbar:
|
541
|
+
scrollbar_widget.grid(row=0, column=1, sticky="ns")
|
422
542
|
|
423
543
|
self.grid_rowconfigure(0, weight=1)
|
424
544
|
self.grid_columnconfigure(0, weight=1)
|
425
|
-
|
545
|
+
if scrollbar:
|
546
|
+
self.grid_columnconfigure(1, weight=0)
|
426
547
|
|
427
|
-
style =
|
428
|
-
|
548
|
+
_ = set_dark_style(style, containers=[self], widgets=[canvas, self.scrollable_frame])
|
549
|
+
if scrollbar:
|
550
|
+
_ = set_dark_style(style, widgets=[scrollbar_widget])
|
551
|
+
|
552
|
+
def rounded_rectangle(self, canvas, x1, y1, x2, y2, radius=20, **kwargs):
|
553
|
+
points = [
|
554
|
+
x1 + radius, y1,
|
555
|
+
x2 - radius, y1,
|
556
|
+
x2 - radius, y1,
|
557
|
+
x2, y1,
|
558
|
+
x2, y1 + radius,
|
559
|
+
x2, y2 - radius,
|
560
|
+
x2, y2 - radius,
|
561
|
+
x2, y2,
|
562
|
+
x2 - radius, y2,
|
563
|
+
x1 + radius, y2,
|
564
|
+
x1 + radius, y2,
|
565
|
+
x1, y2,
|
566
|
+
x1, y2 - radius,
|
567
|
+
x1, y2 - radius,
|
568
|
+
x1, y1 + radius,
|
569
|
+
x1, y1 + radius,
|
570
|
+
x1, y1
|
571
|
+
]
|
572
|
+
return canvas.create_polygon(points, **kwargs, smooth=True)
|
429
573
|
|
430
574
|
class spacrLabel(tk.Frame):
|
431
|
-
def __init__(self, parent, text="", font=None, style=None, align="right", **kwargs):
|
575
|
+
def __init__(self, parent, text="", font=None, style=None, align="right", height=None, **kwargs):
|
432
576
|
valid_kwargs = {k: v for k, v in kwargs.items() if k not in ['foreground', 'background', 'font', 'anchor', 'justify', 'wraplength']}
|
433
577
|
super().__init__(parent, **valid_kwargs)
|
434
578
|
|
435
579
|
self.text = text
|
436
580
|
self.align = align
|
437
|
-
|
438
|
-
|
439
|
-
|
581
|
+
|
582
|
+
if height is None:
|
583
|
+
screen_height = self.winfo_screenheight()
|
584
|
+
label_height = screen_height // 50
|
585
|
+
label_width = label_height * 10
|
586
|
+
else:
|
587
|
+
label_height = height
|
588
|
+
label_width = label_height * 10
|
589
|
+
|
440
590
|
style_out = set_dark_style(ttk.Style())
|
441
591
|
|
442
592
|
self.canvas = tk.Canvas(self, width=label_width, height=label_height, highlightthickness=0, bg=style_out['bg_color'])
|
@@ -471,7 +621,7 @@ class spacrLabel(tk.Frame):
|
|
471
621
|
self.canvas.itemconfig(self.label_text, text=text)
|
472
622
|
|
473
623
|
class spacrButton(tk.Frame):
|
474
|
-
def __init__(self, parent, text="", command=None, font=None, icon_name=None, size=50, show_text=True, outline=False, *args, **kwargs):
|
624
|
+
def __init__(self, parent, text="", command=None, font=None, icon_name=None, size=50, show_text=True, outline=False, animation=True, *args, **kwargs):
|
475
625
|
super().__init__(parent, *args, **kwargs)
|
476
626
|
|
477
627
|
self.text = text.capitalize() # Capitalize only the first letter of the text
|
@@ -480,6 +630,7 @@ class spacrButton(tk.Frame):
|
|
480
630
|
self.size = size
|
481
631
|
self.show_text = show_text
|
482
632
|
self.outline = outline
|
633
|
+
self.animation = animation # Add animation attribute
|
483
634
|
|
484
635
|
style_out = set_dark_style(ttk.Style())
|
485
636
|
|
@@ -546,13 +697,13 @@ class spacrButton(tk.Frame):
|
|
546
697
|
def on_enter(self, event=None):
|
547
698
|
self.canvas.itemconfig(self.button_bg, fill=self.active_color)
|
548
699
|
self.update_description(event)
|
549
|
-
if not self.is_zoomed_in:
|
700
|
+
if self.animation and not self.is_zoomed_in:
|
550
701
|
self.animate_zoom(0.85) # Zoom in the icon to 85% of button size
|
551
702
|
|
552
703
|
def on_leave(self, event=None):
|
553
704
|
self.canvas.itemconfig(self.button_bg, fill=self.inactive_color)
|
554
705
|
self.clear_description(event)
|
555
|
-
if self.is_zoomed_in:
|
706
|
+
if self.animation and self.is_zoomed_in:
|
556
707
|
self.animate_zoom(0.65) # Reset the icon size to 65% of button size
|
557
708
|
|
558
709
|
def on_click(self, event=None):
|