scustomtkinter 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.
Files changed (101) hide show
  1. scustomtkinter/__init__.py +81 -0
  2. scustomtkinter/assets/images/error.png +0 -0
  3. scustomtkinter/assets/images/info.png +0 -0
  4. scustomtkinter/assets/images/warning.png +0 -0
  5. scustomtkinter/assets/sCTkThemes.json +1963 -0
  6. scustomtkinter/license_morecustomtkinterwidgets.txt +22 -0
  7. scustomtkinter/sctk_button_primary.py +366 -0
  8. scustomtkinter/sctk_button_secondary.py +354 -0
  9. scustomtkinter/sctk_button_tertiary.py +375 -0
  10. scustomtkinter/sctk_checkbox.py +270 -0
  11. scustomtkinter/sctk_combobox.py +155 -0
  12. scustomtkinter/sctk_core.py +15 -0
  13. scustomtkinter/sctk_dial.py +1472 -0
  14. scustomtkinter/sctk_dialog.py +701 -0
  15. scustomtkinter/sctk_dialog_toplevel.py +268 -0
  16. scustomtkinter/sctk_entry_primary.py +400 -0
  17. scustomtkinter/sctk_entry_secondary.py +342 -0
  18. scustomtkinter/sctk_file_explorer.py +879 -0
  19. scustomtkinter/sctk_frame.py +210 -0
  20. scustomtkinter/sctk_frame_labeled_primary.py +667 -0
  21. scustomtkinter/sctk_frame_labeled_secondary.py +598 -0
  22. scustomtkinter/sctk_frequency_display.py +636 -0
  23. scustomtkinter/sctk_label_primary.py +283 -0
  24. scustomtkinter/sctk_label_secondary.py +275 -0
  25. scustomtkinter/sctk_label_tertiary.py +278 -0
  26. scustomtkinter/sctk_messagebox.py +275 -0
  27. scustomtkinter/sctk_notebook.py +1103 -0
  28. scustomtkinter/sctk_optionmenu_border_mixin.py +203 -0
  29. scustomtkinter/sctk_optionmenu_primary.py +378 -0
  30. scustomtkinter/sctk_optionmenu_secondary.py +346 -0
  31. scustomtkinter/sctk_path_chooser.py +516 -0
  32. scustomtkinter/sctk_progress_bar.py +274 -0
  33. scustomtkinter/sctk_radiobutton.py +360 -0
  34. scustomtkinter/sctk_scroll_mixin.py +546 -0
  35. scustomtkinter/sctk_scrollable_frame.py +795 -0
  36. scustomtkinter/sctk_scrollbar.py +313 -0
  37. scustomtkinter/sctk_segmentedbutton.py +424 -0
  38. scustomtkinter/sctk_selector.py +581 -0
  39. scustomtkinter/sctk_separator.py +308 -0
  40. scustomtkinter/sctk_slider.py +264 -0
  41. scustomtkinter/sctk_smeter.py +405 -0
  42. scustomtkinter/sctk_smeter_bar.py +557 -0
  43. scustomtkinter/sctk_spinbox.py +664 -0
  44. scustomtkinter/sctk_switch.py +463 -0
  45. scustomtkinter/sctk_tableview.py +869 -0
  46. scustomtkinter/sctk_tabview.py +409 -0
  47. scustomtkinter/sctk_textbox_primary.py +291 -0
  48. scustomtkinter/sctk_textbox_secondary.py +225 -0
  49. scustomtkinter/sctk_toplevel.py +153 -0
  50. scustomtkinter/themeable_widget.py +938 -0
  51. scustomtkinter-0.2.1.dist-info/METADATA +336 -0
  52. scustomtkinter-0.2.1.dist-info/RECORD +101 -0
  53. scustomtkinter-0.2.1.dist-info/WHEEL +5 -0
  54. scustomtkinter-0.2.1.dist-info/entry_points.txt +2 -0
  55. scustomtkinter-0.2.1.dist-info/licenses/LICENSE +21 -0
  56. scustomtkinter-0.2.1.dist-info/licenses/scustomtkinter/license_morecustomtkinterwidgets.txt +22 -0
  57. scustomtkinter-0.2.1.dist-info/top_level.txt +2 -0
  58. scustomtkinter_pygubu/__init__.py +1 -0
  59. scustomtkinter_pygubu/designer/__init__.py +0 -0
  60. scustomtkinter_pygubu/designer/plugin.py +1854 -0
  61. scustomtkinter_pygubu/designer/properties.py +247 -0
  62. scustomtkinter_pygubu/sCTkButtonPrimarybo.py +46 -0
  63. scustomtkinter_pygubu/sCTkButtonSecondarybo.py +45 -0
  64. scustomtkinter_pygubu/sCTkButtonTertiarybo.py +44 -0
  65. scustomtkinter_pygubu/sCTkCheckBoxbo.py +45 -0
  66. scustomtkinter_pygubu/sCTkComboBoxbo.py +45 -0
  67. scustomtkinter_pygubu/sCTkCorebo.py +120 -0
  68. scustomtkinter_pygubu/sCTkDialbo.py +371 -0
  69. scustomtkinter_pygubu/sCTkDialogbo.py +397 -0
  70. scustomtkinter_pygubu/sCTkEntryPrimarybo.py +100 -0
  71. scustomtkinter_pygubu/sCTkEntrySecondarybo.py +98 -0
  72. scustomtkinter_pygubu/sCTkFileExplorerbo.py +189 -0
  73. scustomtkinter_pygubu/sCTkFrameLabeledPrimarybo.py +69 -0
  74. scustomtkinter_pygubu/sCTkFrameLabeledSecondarybo.py +71 -0
  75. scustomtkinter_pygubu/sCTkFramebo.py +46 -0
  76. scustomtkinter_pygubu/sCTkFrequencyDisplaybo.py +175 -0
  77. scustomtkinter_pygubu/sCTkLabelPrimarybo.py +45 -0
  78. scustomtkinter_pygubu/sCTkLabelSecondarybo.py +44 -0
  79. scustomtkinter_pygubu/sCTkLabelTertiarybo.py +45 -0
  80. scustomtkinter_pygubu/sCTkNotebookbo.py +392 -0
  81. scustomtkinter_pygubu/sCTkOptionMenuPrimarybo.py +45 -0
  82. scustomtkinter_pygubu/sCTkOptionMenuSecondarybo.py +39 -0
  83. scustomtkinter_pygubu/sCTkPathChooserbo.py +204 -0
  84. scustomtkinter_pygubu/sCTkProgressBarbo.py +45 -0
  85. scustomtkinter_pygubu/sCTkRadioButtonbo.py +45 -0
  86. scustomtkinter_pygubu/sCTkSMeterBarbo.py +153 -0
  87. scustomtkinter_pygubu/sCTkSMeterbo.py +101 -0
  88. scustomtkinter_pygubu/sCTkScrollableFramebo.py +66 -0
  89. scustomtkinter_pygubu/sCTkScrollbarbo.py +48 -0
  90. scustomtkinter_pygubu/sCTkSegmentedButtonbo.py +47 -0
  91. scustomtkinter_pygubu/sCTkSelectorbo.py +167 -0
  92. scustomtkinter_pygubu/sCTkSeparatorbo.py +141 -0
  93. scustomtkinter_pygubu/sCTkSliderbo.py +45 -0
  94. scustomtkinter_pygubu/sCTkSpinboxbo.py +200 -0
  95. scustomtkinter_pygubu/sCTkSwitchbo.py +45 -0
  96. scustomtkinter_pygubu/sCTkTableviewbo.py +188 -0
  97. scustomtkinter_pygubu/sCTkTabviewbo.py +226 -0
  98. scustomtkinter_pygubu/sCTkTextboxPrimarybo.py +45 -0
  99. scustomtkinter_pygubu/sCTkTextboxSecondarybo.py +45 -0
  100. scustomtkinter_pygubu/sCTkToplevelbo.py +55 -0
  101. scustomtkinter_pygubu/sCTkWidgetSetForPygubuDesigner.py +141 -0
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/python3
2
+ """
3
+ sCTkComboBox
4
+
5
+ A custom, theme-compliant parameter selection dropdown combobox widget.
6
+ Inherits cleanly and directly from ctk.CTkComboBox to preserve 100% of native
7
+ CustomTkinter features, theme tracking loops, and native input locks.
8
+ """
9
+ import customtkinter as ctk
10
+ from .themeable_widget import ThemeableWidget
11
+
12
+ class sCTkComboBox(ctk.CTkComboBox, ThemeableWidget):
13
+ def __init__(self, master=None, **kw):
14
+ # 1. PARAMETER POPPING: Capture combobox-specific tracking parameters early
15
+ values = kw.pop("values", [""])
16
+ command = kw.pop("command", None)
17
+ variable = kw.pop("variable", None)
18
+
19
+ # 2. Fire our shared theme logic first. It automatically finds "sCTkComboBox" in the JSON
20
+ ThemeableWidget.__init__(self, kw)
21
+
22
+ # 3. THE MUTATION SAFEGUARD DEEP COPY:
23
+ self._local_defaults = dict(self.final_kw)
24
+ self._custom_disabled_map = dict(self._widget_disabled_map)
25
+
26
+ # 4. Initialize CustomTkinter natively with the clean final kwargs array safely
27
+ super().__init__(master, **self.final_kw)
28
+
29
+ # 5. Build your inner custom properties using your popped parameters safely
30
+ if values:
31
+ super().configure(values=values)
32
+ if isinstance(values, list) and len(values) > 0 and values[0] != "":
33
+ self.set(values[0])
34
+
35
+ if command: super().configure(command=command)
36
+ if variable: super().configure(variable=variable)
37
+
38
+ self._custom_current_state = "normal"
39
+
40
+ # 6. REGISTER LIFECYCLE HANDSHAKE HOOK:
41
+ self._finalize_themeable_lifecycle()
42
+
43
+ def _set_appearance_mode(self, mode_string: str):
44
+ """
45
+ EXPERIMENTAL: no longer manually re-triggers _update_current_visual_state().
46
+ _update_current_visual_state() now passes raw (light, dark) tuples straight
47
+ through to configure() instead of pre-resolving to a single color, so CTk's
48
+ own appearance-mode tracking should repaint correctly on its own. If colors
49
+ stop following mode changes (especially while disabled), that's the signal
50
+ this doesn't hold and the manual re-trigger needs to come back.
51
+ """
52
+ if hasattr(super(), "_set_appearance_mode"):
53
+ try:
54
+ super()._set_appearance_mode(mode_string)
55
+ except Exception:
56
+ pass
57
+
58
+ def configure(self, *args, **kwargs):
59
+ """Handles Pygubu designer queries and manages composite state updates safely."""
60
+ if len(args) == 1:
61
+ if isinstance(args[0], dict):
62
+ kwargs = {**args[0], **kwargs}
63
+ else:
64
+ pname = args[0]
65
+ if pname == "state":
66
+ return ("state", "state", "state", "normal", str(self.state()))
67
+
68
+ if pname in ["fg_color", "border_color", "text_color", "hover_color"]:
69
+ current_state = str(self.state()).lower()
70
+ val = self._custom_disabled_map.get(pname) if current_state == "disabled" else self._local_defaults.get(pname)
71
+ return (pname, pname, pname, self._query_value(self._theme_default(pname)), self._query_value(val))
72
+
73
+ return self._configure_query(pname)
74
+
75
+ if "values" in kwargs: super().configure(values=kwargs.pop("values"))
76
+ if "command" in kwargs: super().configure(command=kwargs.pop("command"))
77
+ if "variable" in kwargs: super().configure(variable=kwargs.pop("variable"))
78
+
79
+ # Runtime overrides have to reach the map a repaint reads, or
80
+ # _update_current_visual_state() puts the theme value straight back --
81
+ # see ThemeableWidget._record_theme_overrides().
82
+ self._record_theme_overrides(kwargs)
83
+
84
+ if "state" in kwargs:
85
+ self.state(kwargs.pop("state"))
86
+
87
+ if kwargs:
88
+ self._drop_cleared(kwargs)
89
+ if kwargs:
90
+ return super().configure(**kwargs)
91
+ return None
92
+
93
+ config = configure
94
+
95
+ def get_state(self):
96
+ """Explicit getter synchronized with your standalone test harness script assertions."""
97
+ return self.state()
98
+
99
+ def state(self, mode: str = None):
100
+ """Dedicated combobox state controller."""
101
+ if mode is None:
102
+ return str(getattr(self, "_custom_current_state", "normal")).lower()
103
+
104
+ mode = mode.lower()
105
+ if mode in ("normal", "enabled", "active"):
106
+ self._custom_current_state = "normal"
107
+ self._update_current_visual_state()
108
+
109
+ elif mode == "disabled":
110
+ self._custom_current_state = "disabled"
111
+ self._update_current_visual_state()
112
+
113
+ # FIX: this returned nothing when SETTING a mode -- only the query
114
+ # branch above returned a value -- so `widget.state("disabled")` gave
115
+ # None. Every other themed widget returns the resulting state, and
116
+ # sCTkCheckBox had the identical gap fixed earlier in this audit.
117
+ return self._custom_current_state
118
+
119
+ def _update_current_visual_state(self):
120
+ """
121
+ EXPERIMENTAL: passes raw (light, dark) tuples straight through to configure()
122
+ instead of resolving to a single color first, so CTk's native tracking can
123
+ handle appearance-mode repaints without help from _set_appearance_mode.
124
+ """
125
+ is_disabled = getattr(self, "_custom_current_state", "normal") == "disabled"
126
+ target_map = self._custom_disabled_map if is_disabled else self._local_defaults
127
+
128
+ config_payload = {}
129
+ for key in ("fg_color", "border_color", "button_color", "button_hover_color",
130
+ "dropdown_fg_color", "dropdown_text_color", "dropdown_hover_color", "border_width", "font"):
131
+ val = target_map.get(key)
132
+ if val is not None:
133
+ config_payload[key] = val
134
+
135
+ # text_color is handled separately, because this widget sets CTk's own
136
+ # state="disabled" below -- and CTkComboBox's draw code then uses its
137
+ # native text_color_disabled option, overriding whatever text_color was
138
+ # set to. Swapping text_color out of disabled_map was therefore
139
+ # discarded at draw time and the theme key had no visible effect.
140
+ #
141
+ # Both options are set, so CTk chooses between them as designed.
142
+ normal_text = self._local_defaults.get("text_color")
143
+ if normal_text is not None:
144
+ config_payload["text_color"] = normal_text
145
+ disabled_text = self._custom_disabled_map.get("text_color")
146
+ if disabled_text is not None:
147
+ config_payload["text_color_disabled"] = disabled_text
148
+
149
+ if config_payload:
150
+ super().configure(**config_payload)
151
+
152
+ if is_disabled:
153
+ super().configure(state="disabled")
154
+ else:
155
+ super().configure(state="normal")
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/python3
2
+ """
3
+ sCTk
4
+
5
+ A clean, zero-overhead wrapper subclass of ctk.CTk.
6
+ Eliminitates the need for end-users to import customtkinter directly,
7
+ acting as the singular core application window root for the sCustomTkinter library.
8
+ """
9
+ import customtkinter as ctk
10
+
11
+ class sCTk(ctk.CTk):
12
+ def __init__(self, fg_color=None, **kwargs):
13
+ # 🔑 THE HOOK PASS: Explicitly scoop up and forward all positional/keyword arguments
14
+ # directly up to the native CustomTkinter top-level application root constructor safely.
15
+ super().__init__(fg_color=fg_color, **kwargs)