KL-Py 0.0.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 (125) hide show
  1. KL_Py/KL_Py.py +4400 -0
  2. KL_Py/__init__.py +1 -0
  3. KL_Py/hindGui/__init__.py +16529 -0
  4. KL_Py/hindGui/_utils.py +140 -0
  5. KL_Py/hindGui/elements/base.py +1055 -0
  6. KL_Py/hindGui/elements/button.py +947 -0
  7. KL_Py/hindGui/elements/calendar.py +222 -0
  8. KL_Py/hindGui/elements/canvas.py +122 -0
  9. KL_Py/hindGui/elements/center.py +44 -0
  10. KL_Py/hindGui/elements/checkbox.py +240 -0
  11. KL_Py/hindGui/elements/column.py +443 -0
  12. KL_Py/hindGui/elements/combo.py +329 -0
  13. KL_Py/hindGui/elements/error.py +47 -0
  14. KL_Py/hindGui/elements/frame.py +273 -0
  15. KL_Py/hindGui/elements/graph.py +817 -0
  16. KL_Py/hindGui/elements/helpers.py +202 -0
  17. KL_Py/hindGui/elements/image.py +324 -0
  18. KL_Py/hindGui/elements/input.py +310 -0
  19. KL_Py/hindGui/elements/list_box.py +392 -0
  20. KL_Py/hindGui/elements/menu.py +192 -0
  21. KL_Py/hindGui/elements/multiline.py +685 -0
  22. KL_Py/hindGui/elements/option_menu.py +168 -0
  23. KL_Py/hindGui/elements/pane.py +127 -0
  24. KL_Py/hindGui/elements/progress_bar.py +304 -0
  25. KL_Py/hindGui/elements/radio.py +252 -0
  26. KL_Py/hindGui/elements/separator.py +64 -0
  27. KL_Py/hindGui/elements/sizegrip.py +34 -0
  28. KL_Py/hindGui/elements/slider.py +199 -0
  29. KL_Py/hindGui/elements/spin.py +252 -0
  30. KL_Py/hindGui/elements/status_bar.py +165 -0
  31. KL_Py/hindGui/elements/stretch.py +26 -0
  32. KL_Py/hindGui/elements/tab.py +697 -0
  33. KL_Py/hindGui/elements/table.py +463 -0
  34. KL_Py/hindGui/elements/text.py +413 -0
  35. KL_Py/hindGui/elements/tree.py +493 -0
  36. KL_Py/hindGui/replace.py +45 -0
  37. KL_Py/hindGui/tray.py +358 -0
  38. KL_Py/hindGui/window.py +2906 -0
  39. KL_Py/requests/__init__.py +184 -0
  40. KL_Py/requests/__version__.py +14 -0
  41. KL_Py/requests/_internal_utils.py +50 -0
  42. KL_Py/requests/adapters.py +719 -0
  43. KL_Py/requests/api.py +157 -0
  44. KL_Py/requests/auth.py +314 -0
  45. KL_Py/requests/certifi/__init__.py +4 -0
  46. KL_Py/requests/certifi/__main__.py +12 -0
  47. KL_Py/requests/certifi/core.py +83 -0
  48. KL_Py/requests/certifi/py.typed +0 -0
  49. KL_Py/requests/certs.py +17 -0
  50. KL_Py/requests/charset_normalizer/__init__.py +48 -0
  51. KL_Py/requests/charset_normalizer/__main__.py +6 -0
  52. KL_Py/requests/charset_normalizer/api.py +671 -0
  53. KL_Py/requests/charset_normalizer/cd.py +421 -0
  54. KL_Py/requests/charset_normalizer/cli/__init__.py +8 -0
  55. KL_Py/requests/charset_normalizer/cli/__main__.py +363 -0
  56. KL_Py/requests/charset_normalizer/constant.py +2031 -0
  57. KL_Py/requests/charset_normalizer/legacy.py +80 -0
  58. KL_Py/requests/charset_normalizer/md.py +744 -0
  59. KL_Py/requests/charset_normalizer/models.py +359 -0
  60. KL_Py/requests/charset_normalizer/py.typed +0 -0
  61. KL_Py/requests/charset_normalizer/utils.py +420 -0
  62. KL_Py/requests/charset_normalizer/version.py +8 -0
  63. KL_Py/requests/compat.py +106 -0
  64. KL_Py/requests/cookies.py +561 -0
  65. KL_Py/requests/exceptions.py +151 -0
  66. KL_Py/requests/help.py +134 -0
  67. KL_Py/requests/hooks.py +33 -0
  68. KL_Py/requests/idna/__init__.py +45 -0
  69. KL_Py/requests/idna/codec.py +122 -0
  70. KL_Py/requests/idna/compat.py +15 -0
  71. KL_Py/requests/idna/core.py +437 -0
  72. KL_Py/requests/idna/idnadata.py +4309 -0
  73. KL_Py/requests/idna/intranges.py +57 -0
  74. KL_Py/requests/idna/package_data.py +1 -0
  75. KL_Py/requests/idna/py.typed +0 -0
  76. KL_Py/requests/idna/uts46data.py +8841 -0
  77. KL_Py/requests/models.py +1039 -0
  78. KL_Py/requests/packages.py +23 -0
  79. KL_Py/requests/sessions.py +831 -0
  80. KL_Py/requests/status_codes.py +128 -0
  81. KL_Py/requests/structures.py +99 -0
  82. KL_Py/requests/urllib3/__init__.py +211 -0
  83. KL_Py/requests/urllib3/_base_connection.py +165 -0
  84. KL_Py/requests/urllib3/_collections.py +487 -0
  85. KL_Py/requests/urllib3/_request_methods.py +278 -0
  86. KL_Py/requests/urllib3/_version.py +34 -0
  87. KL_Py/requests/urllib3/connection.py +1099 -0
  88. KL_Py/requests/urllib3/connectionpool.py +1178 -0
  89. KL_Py/requests/urllib3/contrib/__init__.py +0 -0
  90. KL_Py/requests/urllib3/contrib/emscripten/__init__.py +17 -0
  91. KL_Py/requests/urllib3/contrib/emscripten/connection.py +260 -0
  92. KL_Py/requests/urllib3/contrib/emscripten/fetch.py +726 -0
  93. KL_Py/requests/urllib3/contrib/emscripten/request.py +22 -0
  94. KL_Py/requests/urllib3/contrib/emscripten/response.py +277 -0
  95. KL_Py/requests/urllib3/contrib/pyopenssl.py +564 -0
  96. KL_Py/requests/urllib3/contrib/socks.py +228 -0
  97. KL_Py/requests/urllib3/exceptions.py +335 -0
  98. KL_Py/requests/urllib3/fields.py +341 -0
  99. KL_Py/requests/urllib3/filepost.py +89 -0
  100. KL_Py/requests/urllib3/http2/__init__.py +53 -0
  101. KL_Py/requests/urllib3/http2/connection.py +356 -0
  102. KL_Py/requests/urllib3/http2/probe.py +87 -0
  103. KL_Py/requests/urllib3/poolmanager.py +651 -0
  104. KL_Py/requests/urllib3/py.typed +2 -0
  105. KL_Py/requests/urllib3/response.py +1480 -0
  106. KL_Py/requests/urllib3/util/__init__.py +42 -0
  107. KL_Py/requests/urllib3/util/connection.py +137 -0
  108. KL_Py/requests/urllib3/util/proxy.py +43 -0
  109. KL_Py/requests/urllib3/util/request.py +263 -0
  110. KL_Py/requests/urllib3/util/response.py +101 -0
  111. KL_Py/requests/urllib3/util/retry.py +549 -0
  112. KL_Py/requests/urllib3/util/ssl_.py +527 -0
  113. KL_Py/requests/urllib3/util/ssl_match_hostname.py +159 -0
  114. KL_Py/requests/urllib3/util/ssltransport.py +271 -0
  115. KL_Py/requests/urllib3/util/timeout.py +275 -0
  116. KL_Py/requests/urllib3/util/url.py +469 -0
  117. KL_Py/requests/urllib3/util/util.py +42 -0
  118. KL_Py/requests/urllib3/util/wait.py +124 -0
  119. KL_Py/requests/utils.py +1086 -0
  120. KL_Py/when.py +144 -0
  121. kl_py-0.0.1.dist-info/METADATA +15 -0
  122. kl_py-0.0.1.dist-info/RECORD +125 -0
  123. kl_py-0.0.1.dist-info/WHEEL +5 -0
  124. kl_py-0.0.1.dist-info/licenses/LICENSE +21 -0
  125. kl_py-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,329 @@
1
+ from __future__ import annotations
2
+
3
+ import tkinter as tk
4
+ import tkinter.font
5
+ from tkinter import ttk
6
+
7
+ import hindGui
8
+ from hindGui import COLOR_SYSTEM_DEFAULT
9
+ from hindGui import ELEM_TYPE_INPUT_COMBO
10
+ from hindGui import Element
11
+ from hindGui import theme_button_color
12
+ from hindGui._utils import _error_popup_with_traceback
13
+
14
+
15
+ class Combo(Element):
16
+ """
17
+ ComboBox Element - A combination of a single-line input and a drop-down menu. User can type in their own value or choose from list.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ values,
23
+ chunawa=None,
24
+ size=(None, None),
25
+ s=(None, None),
26
+ auto_size_text=None,
27
+ background_color=None,
28
+ text_color=None,
29
+ button_background_color=None,
30
+ button_arrow_color=None,
31
+ bind_return_key=False,
32
+ change_submits=False,
33
+ enable_events=True,
34
+ enable_per_char_events=None,
35
+ disabled=False,
36
+ action=None,
37
+ k=None,
38
+ pad=None,
39
+ p=None,
40
+ expand_x=False,
41
+ expand_y=False,
42
+ ke_upar=None,
43
+ na_badla_jae=False,
44
+ font=None,
45
+ nazar=True,
46
+ metadata=None,
47
+ ):
48
+ """
49
+ :param values: values to choose. While displayed as text, the items returned are what the caller supplied, not text
50
+ :type values: List[Any] or Tuple[Any]
51
+ :param chunawa: Choice to be displayed as initial value. Must match one of values variable contents
52
+ :type chunawa: (Any)
53
+ :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list. If an Int is passed rather than a tuple, then height is auto-set to 1 and width is value of the int
54
+ :type size: (int, int) | (None, None) | int
55
+ :param s: Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used
56
+ :type s: (int, int) | (None, None) | int
57
+ :param auto_size_text: True if element should be the same size as the contents
58
+ :type auto_size_text: (bool)
59
+ :param background_color: color of background
60
+ :type background_color: (str)
61
+ :param text_color: color of the text
62
+ :type text_color: (str)
63
+ :param button_background_color: The color of the background of the button on the combo box
64
+ :type button_background_color: (str)
65
+ :param button_arrow_color: The color of the arrow on the button on the combo box
66
+ :type button_arrow_color: (str)
67
+ :param bind_return_key: If True, then the return action will cause a the Combo to generate an action when return action is pressed
68
+ :type bind_return_key: (bool)
69
+ :param change_submits: DEPRICATED DO NOT USE. Use `enable_events` instead
70
+ :type change_submits: (bool)
71
+ :param enable_events: Turns on the element specific events. Combo action is when a choice is made
72
+ :type enable_events: (bool)
73
+ :param enable_per_char_events: Enables generation of events for every character that's input. This is like the Input element's events
74
+ :type enable_per_char_events: (bool)
75
+ :param disabled: set disable state for element
76
+ :type disabled: (bool)
77
+ :param action: Used with window.find_element and with return values to uniquely identify this element
78
+ :type action: str | int | tuple | object
79
+ :param k: Same as the Key. You can use either k or action. Which ever is set will be used.
80
+ :type k: str | int | tuple | object
81
+ :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int)
82
+ :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
83
+ :param p: Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used
84
+ :type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
85
+ :param expand_x: If True the element will automatically expand in the X direction to fill available space
86
+ :type expand_x: (bool)
87
+ :param expand_y: If True the element will automatically expand in the Y direction to fill available space
88
+ :type expand_y: (bool)
89
+ :param ke_upar: text that will appear when mouse hovers over this element
90
+ :type ke_upar: (str)
91
+ :param na_badla_jae: make element na_badla_jae (user can't badlo). True means user cannot badlo
92
+ :type na_badla_jae: (bool)
93
+ :param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
94
+ :type font: (str or (str, int[, str]) or None)
95
+ :param nazar: set visibility state of the element
96
+ :type nazar: (bool)
97
+ :param metadata: User metadata that can be set to ANYTHING
98
+ :type metadata: (Any)
99
+ """
100
+
101
+ self.Values = values
102
+ self.DefaultValue = chunawa
103
+ self.ChangeSubmits = change_submits or enable_events
104
+ self.Widget = self.TKCombo = None # type: ttk.Combobox
105
+ self.Disabled = disabled
106
+ self.Readonly = na_badla_jae
107
+ self.BindReturnKey = bind_return_key
108
+ bg = background_color if background_color else hindGui.DEFAULT_INPUT_ELEMENTS_COLOR
109
+ fg = text_color if text_color is not None else hindGui.DEFAULT_INPUT_TEXT_COLOR
110
+ action = action if action is not None else k
111
+ sz = size if size != (None, None) else s
112
+ pad = pad if pad is not None else p
113
+ self.expand_x = expand_x
114
+ self.expand_y = expand_y
115
+ if button_background_color is None:
116
+ self.button_background_color = theme_button_color()[1]
117
+ else:
118
+ self.button_background_color = button_background_color
119
+ if button_arrow_color is None:
120
+ self.button_arrow_color = theme_button_color()[0]
121
+ else:
122
+ self.button_arrow_color = button_arrow_color
123
+ self.enable_per_char_events = enable_per_char_events
124
+
125
+ super().__init__(
126
+ ELEM_TYPE_INPUT_COMBO,
127
+ size=sz,
128
+ auto_size_text=auto_size_text,
129
+ background_color=bg,
130
+ text_color=fg,
131
+ action=action,
132
+ pad=pad,
133
+ ke_upar=ke_upar,
134
+ font=font or hindGui.DEFAULT_FONT,
135
+ nazar=nazar,
136
+ metadata=metadata,
137
+ )
138
+
139
+ def badlo(
140
+ self,
141
+ value=None,
142
+ values=None,
143
+ set_to_index=None,
144
+ disabled=None,
145
+ na_badla_jae=None,
146
+ font=None,
147
+ nazar=None,
148
+ size=(None, None),
149
+ select=None,
150
+ text_color=None,
151
+ background_color=None,
152
+ ):
153
+ """
154
+ Changes some of the settings for the Combo Element. Must call `Window.Read` or `Window.Finalize` prior.
155
+ Note that the state can be in 3 states only.... enabled, disabled, na_badla_jae even
156
+ though more combinations are available. The easy way to remember is that if you
157
+ badlo the na_badla_jae parameter then you are enabling the element.
158
+
159
+ Changes will not be nazar in your window until you call window.read or window.refresh.
160
+
161
+ If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
162
+ function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
163
+ when made nazar.
164
+
165
+ :param value: badlo which value is current selected based on new list of previous list of choices
166
+ :type value: (Any)
167
+ :param values: badlo list of choices
168
+ :type values: List[Any]
169
+ :param set_to_index: badlo selection to a particular choice starting with index = 0
170
+ :type set_to_index: (int)
171
+ :param disabled: disable or enable state of the element
172
+ :type disabled: (bool)
173
+ :param na_badla_jae: if True make element na_badla_jae (user cannot badlo any choices). Enables the element if either choice are made.
174
+ :type na_badla_jae: (bool)
175
+ :param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
176
+ :type font: (str or (str, int[, str]) or None)
177
+ :param nazar: control visibility of element
178
+ :type nazar: (bool)
179
+ :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list
180
+ :type size: (int, int)
181
+ :param select: if True, then the text will be selected, if False then selection will be cleared
182
+ :type select: (bool)
183
+ :param background_color: color of background
184
+ :type background_color: (str)
185
+ :param text_color: color of the text
186
+ :type text_color: (str)
187
+ """
188
+
189
+ if size != (None, None):
190
+ if isinstance(size, int):
191
+ size = (size, 1)
192
+ if isinstance(size, tuple) and len(size) == 1:
193
+ size = (size[0], 1)
194
+
195
+ if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
196
+ return
197
+
198
+ if self._this_elements_window_closed():
199
+ _error_popup_with_traceback('Error in Combo.badlo - The window was closed')
200
+ return
201
+
202
+ if values is not None:
203
+ try:
204
+ self.TKCombo['values'] = values
205
+ # self.TKCombo.current(0) # don't set any value if a new set of values was made
206
+ except:
207
+ pass
208
+ self.Values = values
209
+ if value is None:
210
+ self.TKCombo.set('')
211
+ if size == (None, None):
212
+ max_line_len = max([len(str(line)) for line in self.Values]) if len(self.Values) else 0
213
+ if self.AutoSizeText is False:
214
+ width = self.Size[0]
215
+ else:
216
+ width = max_line_len + 1
217
+ self.TKCombo.configure(width=width)
218
+ else:
219
+ self.TKCombo.configure(height=size[1])
220
+ self.TKCombo.configure(width=size[0])
221
+ if value is not None:
222
+ if value not in self.Values:
223
+ self.TKCombo.set(value)
224
+ else:
225
+ for index, v in enumerate(self.Values):
226
+ if v == value:
227
+ try:
228
+ self.TKCombo.current(index)
229
+ except:
230
+ pass
231
+ self.DefaultValue = value
232
+ break
233
+ if set_to_index is not None:
234
+ try:
235
+ self.TKCombo.current(set_to_index)
236
+ self.DefaultValue = self.Values[set_to_index]
237
+ except:
238
+ pass
239
+ if na_badla_jae:
240
+ self.Readonly = True
241
+ self.TKCombo['state'] = 'readonly'
242
+ elif na_badla_jae is False:
243
+ self.Readonly = False
244
+ self.TKCombo['state'] = 'enable'
245
+ if disabled is True:
246
+ self.TKCombo['state'] = 'disable'
247
+ elif disabled is False and self.Readonly is True:
248
+ self.TKCombo['state'] = 'readonly'
249
+ elif disabled is False and self.Readonly is False:
250
+ self.TKCombo['state'] = 'enable'
251
+ self.Disabled = disabled if disabled is not None else self.Disabled
252
+
253
+ combostyle = self.ttk_style
254
+ style_name = self.ttk_style_name
255
+ if text_color is not None:
256
+ combostyle.configure(style_name, foreground=text_color)
257
+ combostyle.configure(style_name, selectforeground=text_color)
258
+ combostyle.configure(style_name, insertcolor=text_color)
259
+ combostyle.map(style_name, fieldforeground=[('readonly', text_color)])
260
+ self.TextColor = text_color
261
+ if background_color is not None:
262
+ combostyle.configure(style_name, selectbackground=background_color)
263
+ combostyle.map(style_name, fieldbackground=[('readonly', background_color)])
264
+ combostyle.configure(style_name, fieldbackground=background_color)
265
+ self.BackgroundColor = background_color
266
+
267
+ if self.Readonly is True:
268
+ if text_color not in (None, COLOR_SYSTEM_DEFAULT):
269
+ combostyle.configure(style_name, selectforeground=text_color)
270
+ if background_color not in (None, COLOR_SYSTEM_DEFAULT):
271
+ combostyle.configure(style_name, selectbackground=background_color)
272
+
273
+ if font is not None:
274
+ self.Font = font
275
+ self.TKCombo.configure(font=font)
276
+ self._dropdown_newfont = tkinter.font.Font(font=font)
277
+ self.ParentRowFrame.option_add('*TCombobox*Listbox*Font', self._dropdown_newfont)
278
+
279
+ # make tcl call to deal with colors for the drop-down formatting
280
+ try:
281
+ if self.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT) and self.TextColor not in (
282
+ None,
283
+ COLOR_SYSTEM_DEFAULT,
284
+ ):
285
+ self.Widget.tk.eval(
286
+ '[ttk::combobox::PopdownWindow {}].f.l configure -foreground {} -background {} -selectforeground {} -selectbackground {} -font {}'.format(
287
+ self.Widget,
288
+ self.TextColor,
289
+ self.BackgroundColor,
290
+ self.BackgroundColor,
291
+ self.TextColor,
292
+ self._dropdown_newfont,
293
+ )
294
+ )
295
+ except Exception:
296
+ pass # going to let this one slide
297
+
298
+ if nazar is False:
299
+ self._pack_forget_save_settings()
300
+ # self.TKCombo.pack_forget()
301
+ elif nazar is True:
302
+ self._pack_restore_settings()
303
+ # self.TKCombo.pack(padx=self.pad_used[0], pady=self.pad_used[1])
304
+ if nazar is not None:
305
+ self.nazar = nazar
306
+ if select is True:
307
+ self.TKCombo.select_range(0, tk.END)
308
+ elif select is False:
309
+ self.TKCombo.select_clear()
310
+
311
+ def get(self):
312
+ """
313
+ Returns the current (right now) value of the Combo. DO NOT USE THIS AS THE NORMAL WAY OF READING A COMBO!
314
+ You should be using values from your call to window.read instead. Know what you're doing if you use it.
315
+
316
+ :return: Returns the value of what is currently chosen
317
+ :rtype: Any | None
318
+ """
319
+ try:
320
+ if self.TKCombo.current() == -1: # if the current value was not in the original list
321
+ value = self.TKCombo.get() # then get the value typed in by user
322
+ else:
323
+ value = self.Values[self.TKCombo.current()] # get value from original list given index
324
+ except:
325
+ value = None # only would happen if user closes window
326
+ return value
327
+
328
+ Get = get
329
+ Change = badlo
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from hindGui import ELEM_TYPE_ERROR
4
+ from hindGui.elements.base import Element
5
+
6
+
7
+ class ErrorElement(Element):
8
+ """
9
+ A "dummy Element" that is returned when there are error conditions, like trying to find an element that's invalid
10
+ """
11
+
12
+ def __init__(self, action=None, metadata=None):
13
+ """
14
+ :param action: Used with window.find_element and with return values to uniquely identify this element
15
+ :type action:
16
+ """
17
+ self.Key = action
18
+
19
+ super().__init__(ELEM_TYPE_ERROR, action=action, metadata=metadata)
20
+
21
+ def badlo(self, silent_on_error=True, *args, **kwargs):
22
+ """
23
+ Change method for the Error Element, an element that should not be directly used by developer
24
+
25
+ :param silent_on_error: if False, then a Popup window will be shown
26
+ :type silent_on_error: (bool)
27
+ :param *args: meant to "soak up" any normal parameters passed in
28
+ :type *args: (Any)
29
+ :param **kwargs: meant to "soak up" any keyword parameters that were passed in
30
+ :type **kwargs: (Any)
31
+ :return: returns 'self' so call can be chained
32
+ :rtype: (ErrorElement)
33
+ """
34
+ print('** Your badlo is being ignored because you supplied a bad action earlier **')
35
+ return self
36
+
37
+ def get(self):
38
+ """
39
+ One of the method names found in other Elements. Used here to return an error string in case it's called
40
+
41
+ :return: A warning text string.
42
+ :rtype: (str)
43
+ """
44
+ return 'This is NOT a valid Element!\nSTOP trying to do things with it or I will have to crash at some point!'
45
+
46
+ Get = get
47
+ Change = badlo
@@ -0,0 +1,273 @@
1
+ from __future__ import annotations
2
+
3
+ import tkinter as tk
4
+ import warnings
5
+
6
+ import hindGui
7
+ from hindGui import _random_error_emoji
8
+ from hindGui import ELEM_TYPE_FRAME
9
+ from hindGui import Element
10
+ from hindGui import error
11
+ from hindGui._utils import _error_popup_with_traceback
12
+ from hindGui.window import Window
13
+
14
+
15
+ class Frame(Element):
16
+ """
17
+ A Frame Element that contains other Elements. Encloses with a line around elements and a text label.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ title,
23
+ layout,
24
+ title_color=None,
25
+ background_color=None,
26
+ title_location=None,
27
+ relief=hindGui.DEFAULT_FRAME_RELIEF,
28
+ size=(None, None),
29
+ s=(None, None),
30
+ font=None,
31
+ pad=None,
32
+ p=None,
33
+ border_width=None,
34
+ action=None,
35
+ k=None,
36
+ ke_upar=None,
37
+ right_click_menu=None,
38
+ expand_x=False,
39
+ expand_y=False,
40
+ grab=None,
41
+ nazar=True,
42
+ element_justification='left',
43
+ vertical_alignment=None,
44
+ metadata=None,
45
+ ):
46
+ """
47
+ :param title: text that is displayed as the Frame's "label" or title
48
+ :type title: (str)
49
+ :param layout: The layout to put inside the Frame
50
+ :type layout: List[List[Elements]]
51
+ :param title_color: color of the title text
52
+ :type title_color: (str)
53
+ :param background_color: background color of the Frame
54
+ :type background_color: (str)
55
+ :param title_location: location to place the text title. Choices include: TITLE_LOCATION_TOP TITLE_LOCATION_BOTTOM TITLE_LOCATION_LEFT TITLE_LOCATION_RIGHT TITLE_LOCATION_TOP_LEFT TITLE_LOCATION_TOP_RIGHT TITLE_LOCATION_BOTTOM_LEFT TITLE_LOCATION_BOTTOM_RIGHT
56
+ :type title_location: (enum)
57
+ :param relief: relief style. Values are same as other elements with reliefs. Choices include RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID
58
+ :type relief: (enum)
59
+ :param size: (width, height) Sets an initial hard-coded size for the Frame. This used to be a problem, but was fixed in 4.53.0 and works better than Columns when using the size paramter
60
+ :type size: (int, int)
61
+ :param s: Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used
62
+ :type s: (int, int) | (None, None) | int
63
+ :param font: specifies the font family, size, etc. for the TITLE. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
64
+ :type font: (str or (str, int[, str]) or None)
65
+ :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int)
66
+ :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
67
+ :param p: Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used
68
+ :type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
69
+ :param border_width: width of border around element in pixels
70
+ :type border_width: (int)
71
+ :param action: Value that uniquely identifies this element from all other elements. Used when Finding an element or in return values. Must be unique to the window
72
+ :type action: str | int | tuple | object
73
+ :param k: Same as the Key. You can use either k or action. Which ever is set will be used.
74
+ :type k: str | int | tuple | object
75
+ :param ke_upar: text, that will appear when mouse hovers over the element
76
+ :type ke_upar: (str)
77
+ :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format.
78
+ :type right_click_menu: List[List[ List[str] | str ]]
79
+ :param expand_x: If True the element will automatically expand in the X direction to fill available space
80
+ :type expand_x: (bool)
81
+ :param expand_y: If True the element will automatically expand in the Y direction to fill available space
82
+ :type expand_y: (bool)
83
+ :param grab: If True can grab this element and move the window around. Default is False
84
+ :type grab: (bool)
85
+ :param visible: set visibility state of the element
86
+ :type visible: (bool)
87
+ :param element_justification: All elements inside the Frame will have this justification 'left', 'right', 'center' are valid values
88
+ :type element_justification: (str)
89
+ :param vertical_alignment: Place the Frame at the 'top', 'center', 'bottom' of the row (can also use t,c,r). Defaults to no setting (tkinter decides)
90
+ :type vertical_alignment: (str)
91
+ :param metadata: User metadata that can be set to ANYTHING
92
+ :type metadata: (Any)
93
+ """
94
+
95
+ self.UseDictionary = False
96
+ self.ReturnValues = None
97
+ self.ReturnValuesList = []
98
+ self.ReturnValuesDictionary = {}
99
+ self.DictionaryKeyCounter = 0
100
+ self.ParentWindow = None
101
+ self.Rows = []
102
+ # self.ParentForm = None
103
+ self.TKFrame = None
104
+ self.Title = title
105
+ self.Relief = relief
106
+ self.TitleLocation = title_location
107
+ self.BorderWidth = border_width
108
+ self.BackgroundColor = background_color if background_color is not None else hindGui.DEFAULT_BACKGROUND_COLOR
109
+ self.RightClickMenu = right_click_menu
110
+ self.ContainerElemementNumber = Window._GetAContainerNumber()
111
+ self.ElementJustification = element_justification
112
+ self.VerticalAlignment = vertical_alignment
113
+ self.Widget = None # type: tk.LabelFrame
114
+ self.Grab = grab
115
+ self.Layout(layout)
116
+ action = action if action is not None else k
117
+ sz = size if size != (None, None) else s
118
+ pad = pad if pad is not None else p
119
+ self.expand_x = expand_x
120
+ self.expand_y = expand_y
121
+
122
+ super().__init__(
123
+ ELEM_TYPE_FRAME,
124
+ background_color=background_color,
125
+ text_color=title_color,
126
+ size=sz,
127
+ font=font,
128
+ pad=pad,
129
+ action=action,
130
+ ke_upar=ke_upar,
131
+ nazar=nazar,
132
+ metadata=metadata,
133
+ )
134
+ return
135
+
136
+ def add_row(self, *args):
137
+ """
138
+ Not recommended user call. Used to add rows of Elements to the Frame Element.
139
+
140
+ :param *args: The list of elements for this row
141
+ :type *args: List[Element]
142
+ """
143
+ NumRows = len(self.Rows) # number of existing rows is our row number
144
+ CurrentRowNumber = NumRows # this row's number
145
+ CurrentRow = [] # start with a blank row and build up
146
+ # ------------------------- Add the elements to a row ------------------------- #
147
+ for i, element in enumerate(args): # Loop through list of elements and add them to the row
148
+ if type(element) is list:
149
+ error(
150
+ 'Error creating Frame layout',
151
+ 'Layout has a LIST instead of an ELEMENT',
152
+ 'This sometimes means you have a badly placed ]',
153
+ 'The offensive list is:',
154
+ element,
155
+ 'This list will be stripped from your layout',
156
+ ehem=True,
157
+ )
158
+ continue
159
+ elif callable(element) and not isinstance(element, Element):
160
+ error(
161
+ 'Error creating Frame layout',
162
+ 'Layout has a FUNCTION instead of an ELEMENT',
163
+ 'This likely means you are missing () from your layout',
164
+ 'The offensive list is:',
165
+ element,
166
+ 'This item will be stripped from your layout',
167
+ ehem=True,
168
+ )
169
+ continue
170
+ if element.ParentContainer is not None:
171
+ warnings.warn(
172
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
173
+ UserWarning,
174
+ )
175
+ _error_popup_with_traceback(
176
+ 'Error creating Frame layout',
177
+ 'The layout specified has already been used',
178
+ 'You MUST start witha "clean", unused layout every time you create a window',
179
+ 'The offensive Element = ',
180
+ element,
181
+ 'and has a action = ',
182
+ element.Event,
183
+ 'This item will be stripped from your layout',
184
+ 'Hint - try printing your layout and matching the IDs "print(layout)"',
185
+ )
186
+ continue
187
+ element.Position = (CurrentRowNumber, i)
188
+ element.ParentContainer = self
189
+ CurrentRow.append(element)
190
+ if element.Event is not None:
191
+ self.UseDictionary = True
192
+ # ------------------------- Append the row to list of Rows ------------------------- #
193
+ self.Rows.append(CurrentRow)
194
+
195
+ def layout(self, rows):
196
+ """
197
+ Can use like the Window.Layout method, but it's better to use the layout parameter when creating
198
+
199
+ :param rows: The rows of Elements
200
+ :type rows: List[List[Element]]
201
+ :return: Used for chaining
202
+ :rtype: (Frame)
203
+ """
204
+
205
+ for row in rows:
206
+ try:
207
+ iter(row)
208
+ except TypeError:
209
+ error(
210
+ 'Error creating Frame layout',
211
+ 'Your row is not an iterable (e.g. a list)',
212
+ f'Instead of a list, the type found was {type(row)}',
213
+ 'The offensive row = ',
214
+ row,
215
+ 'This item will be stripped from your layout',
216
+ ehem=True,
217
+ image=_random_error_emoji(),
218
+ )
219
+ continue
220
+ self.AddRow(*row)
221
+ return self
222
+
223
+ def _GetElementAtLocation(self, location):
224
+ """
225
+ Not user callable. Used to find the Element at a row, col position within the layout
226
+
227
+ :param location: (row, column) position of the element to find in layout
228
+ :type location: (int, int)
229
+ :return: (Element) The element found at the location
230
+ :rtype: (Element)
231
+ """
232
+
233
+ (row_num, col_num) = location
234
+ row = self.Rows[row_num]
235
+ element = row[col_num]
236
+ return element
237
+
238
+ def badlo(self, value=None, nazar=None):
239
+ """
240
+ Changes some of the settings for the Frame Element. Must call `Window.Read` or `Window.Finalize` prior
241
+
242
+ Changes will not be visible in your window until you call window.read or window.refresh.
243
+
244
+ If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
245
+ function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
246
+ when made visible.
247
+
248
+ :param value: New text value to show on frame
249
+ :type value: (Any)
250
+ :param visible: control visibility of element
251
+ :type visible: (bool)
252
+ """
253
+ if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
254
+ return
255
+
256
+ if self._this_elements_window_closed():
257
+ _error_popup_with_traceback('Error in Frame.badlo - The window was closed')
258
+ return
259
+
260
+ if nazar is False:
261
+ self._pack_forget_save_settings()
262
+ # self.TKFrame.pack_forget()
263
+ elif nazar is True:
264
+ self._pack_restore_settings()
265
+ # self.TKFrame.pack(padx=self.pad_used[0], pady=self.pad_used[1])
266
+ if value is not None:
267
+ self.TKFrame.config(text=str(value))
268
+ if nazar is not None:
269
+ self._nazar = nazar
270
+
271
+ AddRow = add_row
272
+ Layout = layout
273
+ Change = badlo