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/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.grid(row=1, column=0, columnspan=2, pady=5, padx=5, sticky='ew')
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
- # Initialize attributes for time and operation
383
- self.operation_type = None
384
- self.time_image = None
385
- self.time_batch = None
386
- self.time_left = None
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
- canvas = tk.Canvas(self, bg=bg, width=width)
410
- scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
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
- canvas.configure(yscrollcommand=scrollbar.set)
536
+ if scrollbar:
537
+ canvas.configure(yscrollcommand=scrollbar_widget.set)
419
538
 
420
539
  canvas.grid(row=0, column=0, sticky="nsew")
421
- scrollbar.grid(row=0, column=1, sticky="ns")
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
- self.grid_columnconfigure(1, weight=0)
545
+ if scrollbar:
546
+ self.grid_columnconfigure(1, weight=0)
426
547
 
427
- style = ttk.Style()
428
- _ = set_dark_style(style, containers=[self], widgets=[canvas, scrollbar, self.scrollable_frame])
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
- screen_height = self.winfo_screenheight()
438
- label_height = screen_height // 50
439
- label_width = label_height * 10
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):