bootstack 0.4.2__py3-none-any.whl → 0.4.4__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.
@@ -3,8 +3,6 @@
3
3
  A single platform-neutral menu *model* (`MenuModel` / `MenuGroup` / `MenuItem`)
4
4
  is the source of truth; platform renderers consume it — a themed in-window strip
5
5
  on Windows/Linux and the native global menu bar on macOS.
6
-
7
- See `docs/_dev/menu-redesign.md` for the design.
8
6
  """
9
7
  from __future__ import annotations
10
8
 
@@ -5,7 +5,6 @@ from typing import Any, Literal
5
5
 
6
6
  from typing_extensions import Unpack
7
7
 
8
- from bootstack.events import ChangeEvent
9
8
  from bootstack.widgets._impl.primitives.button import Button
10
9
  from bootstack.widgets._impl.composites.field import Field, FieldOptions
11
10
  from bootstack.widgets._impl.mixins import configure_delegate
@@ -62,7 +61,6 @@ class PathEntry(Field):
62
61
  self._default_extension = default_extension
63
62
  self._default_filename = default_filename
64
63
  self._dialog_result = None
65
- self._prev_value: str | None = value
66
64
 
67
65
  super().__init__(master=master, label=label, message=message, value=value, **kwargs)
68
66
 
@@ -154,15 +152,5 @@ class PathEntry(Field):
154
152
  display_text = result
155
153
 
156
154
  if result:
157
- prev_value = self._prev_value
158
- self._prev_value = display_text
159
155
  self.value = display_text
160
- self.event_generate(
161
- '<<Change>>',
162
- data=ChangeEvent(
163
- value=display_text,
164
- prev_value=prev_value,
165
- text=display_text,
166
- ),
167
- when="tail"
168
- )
156
+ self._entry._check_if_changed()
@@ -1,6 +1,6 @@
1
1
  """Internal composites for the clean-slate application shell.
2
2
 
3
- Layered per `docs/_dev/appshell-navigation-spec.md`:
3
+ Layered as:
4
4
 
5
5
  - `layout.ShellLayout` — Layer 1, the dumb region/slot band layout.
6
6
  - `nav_panel.NavPanel` — the static single-select nav list (sidebar).
@@ -23,14 +23,14 @@ only the body row knows whether the rail/sidebar/dock exist. That invariant lets
23
23
  "sidebar + chrome", "chrome only", and "sidebar only" be the same layout with
24
24
  slots toggled rather than separate code paths.
25
25
 
26
- Note: the resizable sidebar/content sash (a `PanedWindow`) is deferred to the
27
- collapse step — for now the body uses fixed-width pack slots. See the build order
28
- in `docs/_dev/appshell-navigation-spec.md`.
26
+ Note: the body uses fixed-width pack slots; a resizable sidebar/content sash
27
+ (a `PanedWindow`) is not built.
29
28
  """
30
29
 
31
30
  from __future__ import annotations
32
31
 
33
32
  import sys
33
+ from tkinter import TclError
34
34
  from typing import Any
35
35
 
36
36
  from bootstack._runtime.app import App
@@ -128,6 +128,7 @@ class ShellLayout(App):
128
128
  self._show_rail = False
129
129
  self._show_sidebar = True
130
130
  self._show_dock = False
131
+ self._recolor_pending = False
131
132
 
132
133
  self._build_regions()
133
134
  self._relayout_window()
@@ -206,6 +207,7 @@ class ShellLayout(App):
206
207
  self._status_sep.pack(side="bottom", fill="x")
207
208
  # Body fills whatever the bands leave; packed last so it claims the middle.
208
209
  self._body.pack(side="top", fill="both", expand=True)
210
+ self._recolor_show_slots()
209
211
 
210
212
  def _relayout_body(self) -> None:
211
213
  """Re-pack the rail / sidebar / content / dock slots left-to-right."""
@@ -221,6 +223,35 @@ class ShellLayout(App):
221
223
  self._content.pack(side="left", fill="both", expand=True)
222
224
  if self._show_dock:
223
225
  self._dock.pack(side="right", fill="y")
226
+ self._recolor_show_slots()
227
+
228
+ def _recolor_show_slots(self):
229
+ """Repaint slots that just became visible after a theme change"""
230
+ if self._recolor_pending:
231
+ return
232
+ self._recolor_pending = True
233
+
234
+ def _recolor():
235
+ self._recolor_pending = False
236
+ from bootstack.style.style import get_style
237
+ style = get_style()
238
+ shown = [self._content]
239
+ if self._show_rail:
240
+ shown.append(self._rail)
241
+ if self._show_sidebar:
242
+ shown.append(self._sidebar)
243
+ if self._show_statusbar:
244
+ shown.append(self._statusbar)
245
+ for slot in shown:
246
+ try:
247
+ style.apply_theme_walk(slot, only_stale=True)
248
+ except TclError:
249
+ pass # destroyed between relayout and the idle callback
250
+
251
+ try:
252
+ self.after_idle(_recolor)
253
+ except (TclError, AttributeError):
254
+ pass
224
255
 
225
256
  # ----- Region sizing -----
226
257
 
@@ -716,27 +716,29 @@ class RangeSlider(ConfigureDelegationMixin, tk.Frame):
716
716
  self._sync()
717
717
  lo = self._lo_var.get()
718
718
  hi = self._hi_var.get()
719
- self.event_generate("<<Change>>", data=RangeSliderEvent(
720
- low_value=lo,
721
- high_value=hi,
722
- prev_low_value=self._prev_lovalue,
723
- prev_high_value=self._prev_hivalue,
724
- ))
725
- self._prev_lovalue = lo
726
- self._prev_hivalue = hi
719
+ if hi != self._prev_hivalue or lo != self._prev_lovalue:
720
+ self.event_generate("<<Change>>", data=RangeSliderEvent(
721
+ low_value=lo,
722
+ high_value=hi,
723
+ prev_low_value=self._prev_lovalue,
724
+ prev_high_value=self._prev_hivalue,
725
+ ))
726
+ self._prev_lovalue = lo
727
+ self._prev_hivalue = hi
727
728
 
728
729
  def _on_hi_write(self, *_: Any) -> None:
729
730
  self._sync()
730
731
  lo = self._lo_var.get()
731
732
  hi = self._hi_var.get()
732
- self.event_generate("<<Change>>", data=RangeSliderEvent(
733
- low_value=lo,
734
- high_value=hi,
735
- prev_low_value=self._prev_lovalue,
736
- prev_high_value=self._prev_hivalue,
737
- ))
738
- self._prev_lovalue = lo
739
- self._prev_hivalue = hi
733
+ if lo != self._prev_lovalue or hi != self._prev_hivalue:
734
+ self.event_generate("<<Change>>", data=RangeSliderEvent(
735
+ low_value=lo,
736
+ high_value=hi,
737
+ prev_low_value=self._prev_lovalue,
738
+ prev_high_value=self._prev_hivalue,
739
+ ))
740
+ self._prev_lovalue = lo
741
+ self._prev_hivalue = hi
740
742
 
741
743
  def _on_map(self) -> None:
742
744
  if getattr(self, '_theme_update_pending', False):
@@ -579,8 +579,9 @@ class Slider(ConfigureDelegationMixin, tk.Frame):
579
579
  def _on_var_write(self, *_: Any) -> None:
580
580
  self._sync()
581
581
  val = self._var.get()
582
- self.event_generate("<<Change>>", data=SliderEvent(value=val, prev_value=self._prev_value))
583
- self._prev_value = val
582
+ if val != self._prev_value:
583
+ self.event_generate("<<Change>>", data=SliderEvent(value=val, prev_value=self._prev_value))
584
+ self._prev_value = val
584
585
 
585
586
  def _mouse_focus_set(self, _event: tk.Event) -> None:
586
587
  self._mouse_pressed = True
@@ -114,6 +114,9 @@ class TextArea(GridFrame):
114
114
  self._valid_signal: Signal = Signal(True)
115
115
  self._error_signal: Signal = Signal("")
116
116
 
117
+ self._prev_changed_value = value
118
+ self._prev_input_text = value
119
+
117
120
  # ── label (row 0) ─────────────────────────────────────────────────
118
121
  if label:
119
122
  _lbl_text = f"{label} *" if required else label
@@ -192,6 +195,7 @@ class TextArea(GridFrame):
192
195
  self._core._signal_text_sink = lambda text: setattr(self, "value", text)
193
196
  if textsignal is not None:
194
197
  self._core.bind_signal(textsignal)
198
+ self._prev_input_text = self.value
195
199
 
196
200
  # ── placeholder ───────────────────────────────────────────────────
197
201
  self._default_fg = self._core.text.cget("foreground")
@@ -223,6 +227,7 @@ class TextArea(GridFrame):
223
227
  # Fire <<Input>> on every edit, <<Changed>> + validation on blur.
224
228
  self._core.text.bind("<<Change>>", self._on_core_change, add="+")
225
229
  self._core.text.bind("<FocusOut>", self._on_focus_out, add="+")
230
+ self._core.text.bind("<FocusIn>", self._on_focus_in, add="+")
226
231
 
227
232
  # ── constructor callbacks ─────────────────────────────────────────
228
233
  if on_input is not None:
@@ -348,24 +353,35 @@ class TextArea(GridFrame):
348
353
 
349
354
  def _on_core_change(self, _event: tk.Event) -> None:
350
355
  if not self._showing_placeholder:
356
+ text = self.value
357
+ if text == self._prev_input_text:
358
+ return
359
+ self._prev_input_text = text
351
360
  self.event_generate(
352
361
  "<<Input>>",
353
- data=InputEvent(text=self.value),
362
+ data=InputEvent(text=text),
354
363
  when="tail",
355
364
  )
356
365
 
357
366
  def _on_focus_out(self, _event: tk.Event) -> None:
358
367
  if self._placeholder_text and not self._core.value:
359
368
  self._show_placeholder()
360
- if not self._showing_placeholder:
369
+ if not self._showing_placeholder and self.value != self._prev_changed_value:
361
370
  self.event_generate(
362
371
  "<<Changed>>",
363
- data=ChangeEvent(value=self.value, text=self.value),
372
+ data=ChangeEvent(
373
+ value=self.value,
374
+ text=self.value,
375
+ prev_value=self._prev_changed_value),
364
376
  when="tail",
365
377
  )
378
+ self._prev_changed_value = self.value
366
379
  if self._rules:
367
380
  self._run_validation(trigger="blur")
368
381
 
382
+ def _on_focus_in(self, _event: tk.Event) -> None:
383
+ self._prev_changed_value = self.value
384
+
369
385
  # ── public value API ──────────────────────────────────────────────────
370
386
 
371
387
  @property
@@ -102,9 +102,11 @@ class OptionMenu(MenuButton):
102
102
  # Store the textvariable if provided, or create a new one. This variable
103
103
  # holds the raw VALUE-KEY text (untranslated): it drives the radio
104
104
  # highlight, the public value/selection, and <<Change>> in value-space.
105
+ _initial_text = self._resolve_initial_text(value)
106
+ self._prev_value = self._value_by_text.get(_initial_text, _initial_text) if _initial_text else None
105
107
  self._textvariable = kwargs.pop('textvariable', None)
106
108
  if self._textvariable is None:
107
- self._textvariable = StringVar(value=self._resolve_initial_text(value))
109
+ self._textvariable = StringVar(value=_initial_text)
108
110
 
109
111
  # A separate variable backs the visible button face, holding the
110
112
  # (optionally translated) DISPLAY text — decoupled from the value key so
@@ -208,14 +210,17 @@ class OptionMenu(MenuButton):
208
210
 
209
211
  def _on_change(text: str) -> None:
210
212
  self._sync_display()
213
+ value = self._value_by_text.get(text, text) if text else None
211
214
  self.event_generate(
212
215
  '<<Change>>',
213
- data=ChangeEvent(value=self._value_by_text.get(text, text) if text else None),
216
+ data=ChangeEvent(
217
+ value=value,
218
+ prev_value=self._prev_value,
219
+ text=self._display_text(text)
220
+ )
214
221
  )
222
+ self._prev_value = value
215
223
 
216
- # Store it here, not at the call site (#476). A caller that discards the
217
- # return leaves an untracked subscription the guard above can never
218
- # cancel, and every one of them emits its own <<Change>>.
219
224
  self._bind_id = self.textsignal.subscribe(_on_change)
220
225
  return self._bind_id
221
226
 
@@ -140,21 +140,34 @@ class CodeEditor(PublicWidgetBase):
140
140
  internal_kwargs["extensions"] = extensions
141
141
 
142
142
  self._internal = _InternalCodeEditor(tk_master, **internal_kwargs)
143
+ self._prev_value = self._internal.value
144
+ self._prev_input_text = self._internal.value
143
145
 
144
146
  # Generate <<CursorMove>> so on_cursor_move() subscribers always work.
145
147
  t = self._internal.core.text
146
148
  t.bind("<KeyRelease>", lambda e: t.event_generate("<<CursorMove>>"), add="+")
147
149
  t.bind("<ButtonRelease-1>", lambda e: t.event_generate("<<CursorMove>>"), add="+")
148
150
 
149
- # Re-emit the core's raw <<Change>> (which carries a low-level
150
- # {"op", "index"} dict) as typed payloads on the public widget, so
151
- # on_change()/on_input() deliver the editor text — like TextArea.
152
151
  def _emit_typed_change(_e: Any = None) -> None:
153
152
  text = self._internal.value
154
- self._internal.event_generate("<<BsChange>>", data=ChangeEvent(value=text, text=text))
153
+ if text == self._prev_input_text:
154
+ return
155
+ self._prev_input_text = text
155
156
  self._internal.event_generate("<<BsInput>>", data=InputEvent(text=text))
156
157
  t.bind("<<Change>>", _emit_typed_change, add="+")
157
158
 
159
+ def _emit_typed_blur(_e: Any = None) -> None:
160
+ text = self._internal.value
161
+ if text != self._prev_value:
162
+ self._internal.event_generate("<<BsChange>>",
163
+ data=ChangeEvent(value=text, text=text, prev_value=self._prev_value))
164
+ self._prev_value = text
165
+ t.bind("<FocusOut>", _emit_typed_blur, add="+")
166
+
167
+ def _on_focus_in(_e: Any = None) -> None:
168
+ self._prev_value = self._internal.value
169
+ t.bind("<FocusIn>", _on_focus_in, add="+")
170
+
158
171
  self._attach_to_parent(layout_kw)
159
172
 
160
173
  # ----- Event routing -----
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bootstack
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Build desktop GUI apps in pure Python and ship them as a standalone executable — built on Tk, no Tkinter boilerplate.
5
5
  Author-email: Israel Dryer <israel.dryer@gmail.com>
6
6
  License-Expression: MIT
@@ -260,7 +260,7 @@ bootstack/widgets/calendar.py,sha256=zkSCufG-s429qDr2ncb1qFe-MwYb2wLWgrlfvqdwaMQ
260
260
  bootstack/widgets/card.py,sha256=wRrF64HurkT6QRUoqcX6Ath7IUlYXBLVRn1zCcZScAg,7071
261
261
  bootstack/widgets/carousel.py,sha256=Y_G1s-aavbV8bMgdEW_5ups4I5i4EF7WJg-7jvK9p8U,9453
262
262
  bootstack/widgets/chart.py,sha256=lo-faUePR2SQvUyhXJ_ZALh5vmIY4GwfXtYmDkxbijE,14195
263
- bootstack/widgets/codeeditor.py,sha256=8gjUCZnIjPzMKmgWp2FXLCQ4D1IR-9mK8cCCwh0Wuyc,26354
263
+ bootstack/widgets/codeeditor.py,sha256=oMkUMzRTxNLap_8yeEFzFDxq09FOvN2sPrg6oCUxPrg,26817
264
264
  bootstack/widgets/contextmenu.py,sha256=EnAGQQzEbOSbb9M-CK7lAzKFj81veOeR995an6kz7zk,13720
265
265
  bootstack/widgets/datatable.py,sha256=KeUo35cSjWNAdNeBtrWuuNO-dvZ7T8Ja810AENMI7E0,29828
266
266
  bootstack/widgets/datefield.py,sha256=8avae2cFfjCskNKGiO10NwzUV9PhYTrKWplMk5qQmP8,15292
@@ -351,7 +351,7 @@ bootstack/widgets/_impl/composites/meter.py,sha256=EvgUUjqkxmQLsq6VDJ6rI2VrDPfDo
351
351
  bootstack/widgets/_impl/composites/numericentry.py,sha256=krjud6vUKrcMvZViG1WGwwvcrYrVbmY7BHjIbTYfH_4,8651
352
352
  bootstack/widgets/_impl/composites/pagestack.py,sha256=SQu-6qVoje9_cBOINJuI0YJXi2fnna5lhstyIhmpbaY,15776
353
353
  bootstack/widgets/_impl/composites/passwordentry.py,sha256=qOIGDkl5MFfXwJpJEL143z18M0Zfkoca44cRHSWaAqU,6352
354
- bootstack/widgets/_impl/composites/pathentry.py,sha256=Cnd0US82sxqP8VXlOvrZRQcbxssP2yFsF2AUwwXNn2s,6270
354
+ bootstack/widgets/_impl/composites/pathentry.py,sha256=uDVQFYbQonhI7YoFLk0ycHEat6aoHSJRpVVWfhu5uLI,5852
355
355
  bootstack/widgets/_impl/composites/picture.py,sha256=vzKWvuTPXpFkmlcZrxsGFQLyf2QtLIuIZO4uKgpXl_Q,10962
356
356
  bootstack/widgets/_impl/composites/radiogroup.py,sha256=CEYhCfBgH19Y7x-63nqKdycbawm_JBFp0tQRNE7B70Q,18986
357
357
  bootstack/widgets/_impl/composites/scrolledtext.py,sha256=Dkp2ATIe-UADhvVDl6W6xEEwe-3AWkv2mESC5wP9Xik,15000
@@ -369,13 +369,13 @@ bootstack/widgets/_impl/composites/tooltip.py,sha256=FN6OKJJc24l2CKWqUDxqbNgCH8r
369
369
  bootstack/widgets/_impl/composites/list/__init__.py,sha256=J-F-Fjj5IcX8EyCwSSNyZ8BN2SMrJIDBYsYSiuNt1C4,365
370
370
  bootstack/widgets/_impl/composites/list/listitem.py,sha256=wqzanMAUSxgbW7GLXgKMZlYFRgbzc_Qmi5Z_DG7Adf0,32484
371
371
  bootstack/widgets/_impl/composites/list/listview.py,sha256=LN_4bCR4XLLQsE01vyFq8G0kwdXyDnxHMDN6cskjczE,55276
372
- bootstack/widgets/_impl/composites/menu/__init__.py,sha256=EMFcYSFwUJCj-e81KZjy8k_iwG7M4WTBQ0xRXMpcGiM,546
372
+ bootstack/widgets/_impl/composites/menu/__init__.py,sha256=1flA1uz2hZE6FJTdfWXWmr1d8OhJdvTeA0ufgshL5so,494
373
373
  bootstack/widgets/_impl/composites/menu/model.py,sha256=bn3B-QqXPRE8cVNhtSWWKC2L_F4I2nQ2NpceHDLAPXU,12742
374
374
  bootstack/widgets/_impl/composites/menu/render_native.py,sha256=VwDLtnWWIlXx8ZKLpJKLK6BEhHz-IVAF1xk_pXOlaDU,4629
375
375
  bootstack/widgets/_impl/composites/menu/render_themed.py,sha256=35CY2wkr2zUtwM69eUhr-Mnr3nh6CxVzWHHp462Mfio,4808
376
- bootstack/widgets/_impl/composites/shell/__init__.py,sha256=6PE1ZskVFbKLjKOXSvV39Ht9YsUeSdZVjA2Hiqf1yn8,1412
376
+ bootstack/widgets/_impl/composites/shell/__init__.py,sha256=IGP4RcKBmz8eoJvE2p86CDPGNxCgRSIro9vMEXKAOH0,1371
377
377
  bootstack/widgets/_impl/composites/shell/content_host.py,sha256=09ebue5Q7i9JEbwlu_A8YLLp2ucuJb3K2HguV_-SFog,2122
378
- bootstack/widgets/_impl/composites/shell/layout.py,sha256=srHQaFGflacTGaotM53StXilEUcFS4D6RD--KijvaYM,14751
378
+ bootstack/widgets/_impl/composites/shell/layout.py,sha256=Uidmwrren6ZAHpuXH8SlCjRiLGkNtaOO_o8MYOimZe0,15787
379
379
  bootstack/widgets/_impl/composites/shell/nav_panel.py,sha256=6am5VuGqtYw-PI88T8B90d7vxSAqTLBZbUEvDIoaK_A,16262
380
380
  bootstack/widgets/_impl/composites/shell/providers.py,sha256=tvy9rXtcf3KnNISlwRzh_ugYzgkOJRjd-niqM4kp0ps,20178
381
381
  bootstack/widgets/_impl/composites/shell/rail.py,sha256=Z9Emy4AlXnivwqDDEtUoqOs1-a0C_l6vC8PW60YCw9Q,4927
@@ -386,8 +386,8 @@ bootstack/widgets/_impl/composites/sidenav/header.py,sha256=4aAmqY98l4fx5M2URIGH
386
386
  bootstack/widgets/_impl/composites/sidenav/separator.py,sha256=QEDZjXSmYD65-soOpDmx3RQ-UBF5Jb3P_lmTZyy9jDM,1376
387
387
  bootstack/widgets/_impl/composites/slider/__init__.py,sha256=G4LcfzXCxD78j24D7iOXg72BPQM5FSh7l89tI2dckAA,190
388
388
  bootstack/widgets/_impl/composites/slider/_shared.py,sha256=xbwghVe-mKno5gDJsQNXqK8M13rPZrY4qh3kAz7SRvM,7615
389
- bootstack/widgets/_impl/composites/slider/rangeslider.py,sha256=xhzv68hhSx2iImtPdXBzuk9p41tdOJxzdl8APnGAnhY,43770
390
- bootstack/widgets/_impl/composites/slider/slider.py,sha256=OWdhzahCDsXP1xNtDoHb82iQMbtYyzR895CePBbEQP0,38996
389
+ bootstack/widgets/_impl/composites/slider/rangeslider.py,sha256=KLWKGyo7khUXrkfz-tYuiGZuJIKUiNQBISXL-6Dbzpk,43966
390
+ bootstack/widgets/_impl/composites/slider/slider.py,sha256=Ertqs1qrucPv46lugXXwNcQb607phCqiJPBgr49i1BY,39041
391
391
  bootstack/widgets/_impl/composites/tableview/__init__.py,sha256=ccQKtGH53tGj7K1ezfsbY2iEyIH1wRgd1qEQ0Glqra4,127
392
392
  bootstack/widgets/_impl/composites/tableview/tableview.py,sha256=QuhguaAvMCi9k3tiyyha8WkFlEgtQUPjj3Gk4rc5HDc,151228
393
393
  bootstack/widgets/_impl/composites/tableview/types.py,sha256=oDmJco19M42Zv_lUEpsfeM7kjjuHHsNBMVZoWRe-QDs,4906
@@ -406,7 +406,7 @@ bootstack/widgets/_impl/composites/textarea/redirector.py,sha256=vAL8Y3HuevC8Fab
406
406
  bootstack/widgets/_impl/composites/textarea/search_overlay.py,sha256=humVYBFN-EbfbIFC6IavtsNEFGHJtuYZCZ5W7SmZUeU,18669
407
407
  bootstack/widgets/_impl/composites/textarea/sidebar.py,sha256=X3LcIv-OMvymL3xTcNMEhP5ddzh53gxreDWmeMItXg8,3151
408
408
  bootstack/widgets/_impl/composites/textarea/style_registry.py,sha256=NOgBOGLJzYvw-Mf6O0YV7kwIoUc_yvOOWlqZDDzC6Qc,7678
409
- bootstack/widgets/_impl/composites/textarea/textarea.py,sha256=Dk3LGmJUH8Nc5dv5-0x77-X7t8S_IT8RNhJ5dpMgEgo,25586
409
+ bootstack/widgets/_impl/composites/textarea/textarea.py,sha256=PZpKe0rxNoHNOvU-4Fs_7h29jrJdK8QbV7qVvp9ayiw,26221
410
410
  bootstack/widgets/_impl/composites/textarea/undo.py,sha256=gTkQ0UEh9F5BivjdbN96AfBqLxK348S2rCvri6sb0Pk,8622
411
411
  bootstack/widgets/_impl/composites/textarea/extensions/__init__.py,sha256=jQRM97jFIw-9rdnkHuY8tXMijeZiuYmqBVhX8TLG1pg,48
412
412
  bootstack/widgets/_impl/composites/textarea/extensions/bracket_matcher.py,sha256=70lGUz6AWTKnBcsGmhJ1PZghzSq-aYdtITQGZjITJPY,5054
@@ -441,7 +441,7 @@ bootstack/widgets/_impl/primitives/frame.py,sha256=Q2FWhgGkBU74YgYnKr9TFlkbrf_qX
441
441
  bootstack/widgets/_impl/primitives/gridframe.py,sha256=hr74jDwX9pdw0LquQNANHFkpyubw7vmyX8vUhXI7VfY,21629
442
442
  bootstack/widgets/_impl/primitives/label.py,sha256=2XxnObg6xmbLIkefCMYkb9hwyZIuU8FJclvcMpnszW0,3495
443
443
  bootstack/widgets/_impl/primitives/labelframe.py,sha256=IB5fqGgwG44vDrszFRBLEqrJGW5IXX1veK5AhetPGOE,2013
444
- bootstack/widgets/_impl/primitives/optionmenu.py,sha256=9fPutiWHs9kmn-FKmbXCCMkfG7yAdYEfQSsbi218INU,16543
444
+ bootstack/widgets/_impl/primitives/optionmenu.py,sha256=cH15ls1msZx74FzWIj3mZdBwBCJ3uYf0iwVbA3mesfQ,16671
445
445
  bootstack/widgets/_impl/primitives/packframe.py,sha256=maUgSNlnJFoLr6ErpRMoO4922uJMPrxkfzTkc2jc-tg,8754
446
446
  bootstack/widgets/_impl/primitives/panedwindow.py,sha256=kSuXphwDDwITTenmHVMLwevBg5czbeJjJzRHUO504KM,1697
447
447
  bootstack/widgets/_impl/primitives/progressbar.py,sha256=Mmj-AUmfQEB671OzDvWxezowcBliZdQkuwWaCHBedmU,3129
@@ -453,10 +453,10 @@ bootstack/widgets/_impl/primitives/sizegrip.py,sha256=uwQRzOEHjNPXtUURhT6k2TNYdy
453
453
  bootstack/widgets/_impl/primitives/spinbox.py,sha256=5m0tZrqCw745nvIiBrJWnZ0q8fZ7bNEvopjROMbQolc,4526
454
454
  bootstack/widgets/_impl/primitives/switch.py,sha256=7dt43uE2P_WdkxZZsGtCFRAQ20nI2jx5VUqGSrWwEmA,2543
455
455
  bootstack/widgets/_impl/primitives/treeview.py,sha256=vnSowgzmtNEWst_i9ZgcacHjdvuheF9xmeTvTWE1bLg,2709
456
- bootstack-0.4.2.dist-info/licenses/LICENSE,sha256=CUeTPUOM8Qc0yuqneJUwuUmDBooET5UfsHjMrkdBeCg,1097
457
- bootstack-0.4.2.dist-info/licenses/NOTICE,sha256=c62TcygUKbXx1V3FEgziroDDry_NwmycqKEg_CRnYBU,1503
458
- bootstack-0.4.2.dist-info/METADATA,sha256=rjQd8aCKIj2jphR1hvz0tYgnjVgE4HgBzyra8_rSArE,16107
459
- bootstack-0.4.2.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
460
- bootstack-0.4.2.dist-info/entry_points.txt,sha256=phOlfRy3Th86IYlNhQiUrTLLLzxie1IG-kMas_5iMdA,49
461
- bootstack-0.4.2.dist-info/top_level.txt,sha256=IsKBAac2vRCegvRFSCzwcBr7TpHp4bLnLFgA75LOkXs,10
462
- bootstack-0.4.2.dist-info/RECORD,,
456
+ bootstack-0.4.4.dist-info/licenses/LICENSE,sha256=CUeTPUOM8Qc0yuqneJUwuUmDBooET5UfsHjMrkdBeCg,1097
457
+ bootstack-0.4.4.dist-info/licenses/NOTICE,sha256=c62TcygUKbXx1V3FEgziroDDry_NwmycqKEg_CRnYBU,1503
458
+ bootstack-0.4.4.dist-info/METADATA,sha256=wvAP1pUf9a0zQWHNnUr2OFMu4P0E2YBkV-ry5FIOssU,16107
459
+ bootstack-0.4.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
460
+ bootstack-0.4.4.dist-info/entry_points.txt,sha256=phOlfRy3Th86IYlNhQiUrTLLLzxie1IG-kMas_5iMdA,49
461
+ bootstack-0.4.4.dist-info/top_level.txt,sha256=IsKBAac2vRCegvRFSCzwcBr7TpHp4bLnLFgA75LOkXs,10
462
+ bootstack-0.4.4.dist-info/RECORD,,