diff --git a/pyproject.toml b/pyproject.toml
index 65bf401..9333919 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -29,7 +29,7 @@ dependencies = [
"numpy",
"openpyxl",
"pandas",
- "pydantic>2",
+ "pydantic<2.9",
"pydantic-settings",
"pydantic-extra-types",
"PyYAML",
diff --git a/src/ipyautoui/constants.py b/src/ipyautoui/constants.py
index 5c638f0..5cb3287 100644
--- a/src/ipyautoui/constants.py
+++ b/src/ipyautoui/constants.py
@@ -140,6 +140,13 @@
layout={"width": BUTTON_WIDTH_MIN, "height": BUTTON_HEIGHT_MIN},
disabled=True,
)
+HELP_BUTTON_KWARGS = frozenmap(
+ icon="question",
+ style={},
+ # button_style="primary",
+ tooltip="help",
+ layout={"width": BUTTON_WIDTH_MIN}, # , "height": BUTTON_HEIGHT_MIN
+)
DOWNARROW_BUTTON_KWARGS = frozenmap(
icon="arrow-down",
diff --git a/src/ipyautoui/custom/buttonbars.py b/src/ipyautoui/custom/buttonbars.py
index 2b15f09..aba7e8b 100644
--- a/src/ipyautoui/custom/buttonbars.py
+++ b/src/ipyautoui/custom/buttonbars.py
@@ -6,7 +6,7 @@
# extension: .py
# format_name: light
# format_version: '1.5'
-# jupytext_version: 1.15.2
+# jupytext_version: 1.16.1
# kernelspec:
# display_name: Python 3 (ipykernel)
# language: python
@@ -14,9 +14,6 @@
# ---
# +
-# %run ../_dev_maplocal_params.py
-
-
import ipywidgets as w
import traitlets as tr
import typing as ty
@@ -28,9 +25,9 @@
COPY_BUTTON_KWARGS,
DELETE_BUTTON_KWARGS,
RELOAD_BUTTON_KWARGS,
+ HELP_BUTTON_KWARGS,
)
-
-from IPython.display import display
+from IPython.display import display, clear_output
from datetime import datetime
import logging
from enum import Enum
@@ -272,40 +269,85 @@ class CrudView(ty.TypedDict):
edit: CrudOptions
copy: CrudOptions
delete: CrudOptions
+ reload: CrudOptions
DEFAULT_BUTTONBAR_CONFIG = CrudView(
add=CrudOptions(
- tooltip="Add item",
- tooltip_clicked="Go back to table",
- button_style="success",
- message="➕ Adding Value",
+ **dict(ADD_BUTTON_KWARGS)
+ | dict(
+ tooltip="Add item",
+ tooltip_clicked="Go back to table",
+ button_style="success",
+ message="➕ Adding Value",
+ )
),
edit=CrudOptions(
- tooltip="Edit item",
- tooltip_clicked="Go back to table",
- button_style="warning",
- message="✏️ Editing Value",
+ **dict(EDIT_BUTTON_KWARGS)
+ | dict(
+ tooltip="Edit item",
+ tooltip_clicked="Go back to table",
+ button_style="warning",
+ message="✏️ Editing Value",
+ )
),
copy=CrudOptions(
- tooltip="Copy item",
- tooltip_clicked="Go back to table",
- button_style="primary",
- message="📝 Copying Value",
+ **dict(COPY_BUTTON_KWARGS)
+ | dict(
+ tooltip="Copy item",
+ tooltip_clicked="Go back to table",
+ button_style="primary",
+ message="📝 Copying Value",
+ )
),
delete=CrudOptions(
- tooltip="Delete item",
- tooltip_clicked="Go back to table",
- button_style="danger",
- message="🗑️ Deleting Value",
+ **dict(DELETE_BUTTON_KWARGS)
+ | dict(
+ tooltip="Delete item",
+ tooltip_clicked="Go back to table",
+ button_style="danger",
+ message="🗑️ Deleting Value",
+ )
+ ),
+ reload=CrudOptions(
+ **dict(RELOAD_BUTTON_KWARGS)
+ | dict(
+ tooltip="reload data",
+ tooltip_clicked="",
+ button_style="info",
+ message="♻ reloading data|",
+ )
+ ),
+ support=CrudOptions(
+ **dict(HELP_BUTTON_KWARGS)
+ | dict(layout=dict(display="None"))
+ | dict(
+ tooltip="help - click to show description of all buttons in the toolbar",
+ tooltip_clicked="hide help dialogue",
+ message="❔ Help Selected",
+ )
),
)
-# -
+# +
+def display_ui_tooltips(uiobj: w.DOMWidget) -> w.VBox:
+ """Pass a UI object and display all widgets within it with their tooltips."""
+ li = []
+ for _, v in uiobj.__dict__.items():
+ try:
+ if "tooltip" in v.__dict__["_trait_values"]:
+ if v.tooltip is not None:
+ li.append(v)
+ except Exception as err:
+ logging.warning(err)
+ replace_newlines = lambda x: x.replace("\n", "
")
+ return w.VBox(
+ [w.HBox([l, w.HTML(f"{replace_newlines(l.tooltip)}")]) for l in li]
+ )
-class CrudButtonBar(w.HBox):
+class CrudButtonBar(w.VBox):
active = tr.Unicode(default_value=None, allow_none=True)
crud_view = tr.Dict(default_value=DEFAULT_BUTTONBAR_CONFIG)
fn_add = tr.Callable(default_value=lambda: print("add"))
@@ -313,7 +355,16 @@ class CrudButtonBar(w.HBox):
fn_copy = tr.Callable(default_value=lambda: print("copy"))
fn_delete = tr.Callable(default_value=lambda: print("delete"))
fn_backward = tr.Callable(default_value=lambda: print("backward"))
+ fn_support = tr.Callable(default_value=lambda: print("support"))
fn_reload = tr.Callable(default_value=None, allow_none=True)
+ show_support = tr.Bool(default_value=False)
+
+ @tr.observe("show_support")
+ def _observe_show_support(self, change):
+ if change["new"]:
+ self.support.layout.display = ""
+ else:
+ self.support.layout.display = "None"
@tr.observe("fn_reload")
def _observe_fn_reload(self, change):
@@ -333,31 +384,41 @@ def active_index(self):
else:
return list(self.crud_view.keys()).index(self.active)
+ def _fn_support(self):
+ with self.out:
+ clear_output()
+ display(display_ui_tooltips(self))
+
def __init__(
self,
**kwargs,
):
self._init_form()
super().__init__(**kwargs) # main container
+ self.fn_support = self._fn_support
self.out = w.Output()
- self.children = [
- self.add,
- self.edit,
- self.copy,
- self.delete,
- self.reload,
- self.message,
- ]
+ self.hbx_bbar = w.HBox(
+ [
+ self.add,
+ self.edit,
+ self.copy,
+ self.delete,
+ self.reload,
+ self.support,
+ self.message,
+ ]
+ )
+ self.children = [self.hbx_bbar, self.out]
self._init_controls()
def _init_form(self):
- # self.transpose w.ToggleButton(icon="arrow-right")
- self.add = w.ToggleButton(**ADD_BUTTON_KWARGS)
- self.edit = w.ToggleButton(**EDIT_BUTTON_KWARGS)
- self.copy = w.ToggleButton(**COPY_BUTTON_KWARGS)
- self.delete = w.ToggleButton(**DELETE_BUTTON_KWARGS)
- self.reload = w.Button(**RELOAD_BUTTON_KWARGS)
- self.reload.layout.display = "None"
+ self.add = w.ToggleButton()
+ self.edit = w.ToggleButton()
+ self.copy = w.ToggleButton()
+ self.delete = w.ToggleButton()
+ self.reload = w.Button()
+ self.support = w.ToggleButton()
+ # ^ KWARGS for the buttons are set by CrudView
self.message = w.HTML()
self._set_crud_view_options()
@@ -366,24 +427,27 @@ def _init_controls(self):
self.edit.observe(self._edit, "value")
self.copy.observe(self._copy, "value")
self.delete.observe(self._delete, "value")
+ self.support.observe(self._support, "value")
self.reload.on_click(self._reload)
def _onclick(self, button_name):
- w = getattr(self, button_name)
+ wi = getattr(self, button_name)
fn = getattr(self, ("fn_" + button_name))
- if w.value:
+ if wi.value:
self.reset_toggles_except(button_name)
self.active = button_name
- w.tooltip = self.crud_view[button_name]["tooltip_clicked"]
- w.layout.border = TOGGLEBUTTON_ONCLICK_BORDER_LAYOUT
+ wi.tooltip = self.crud_view[button_name]["tooltip_clicked"]
+ wi.layout.border = TOGGLEBUTTON_ONCLICK_BORDER_LAYOUT
self.message.value = self.crud_view[button_name]["message"]
fn()
else:
self.active = None
- w.tooltip = self.crud_view[button_name]["tooltip"]
- w.layout.border = None
+ wi.tooltip = self.crud_view[button_name]["tooltip"]
+ wi.layout.border = None
self.message.value = ""
self.fn_backward()
+ with self.out:
+ clear_output()
def _add(self, onchange):
self._onclick("add")
@@ -397,6 +461,13 @@ def _copy(self, onchange):
def _delete(self, onchange):
self._onclick("delete")
+ def _support(self, onchange):
+ self._onclick("support")
+
+ def _reload(self, on_click):
+ logger.info("Reloading all data")
+ self.fn_reload()
+
def _set_crud_view_options(self):
for button_name in self.crud_view.keys():
w = getattr(self, button_name)
@@ -414,10 +485,8 @@ def reset_toggles_except(self, name=None):
for n in names:
setattr(getattr(self, n), "value", False)
- def _reload(self, on_click):
- logger.info("Reloading all data")
- self.fn_reload()
+# -
if __name__ == "__main__":
@@ -444,5 +513,4 @@ def backward():
fn_backward=backward,
fn_reload=lambda: print("fn_reload"),
)
-
display(buttonbar)
diff --git a/src/ipyautoui/custom/editgrid.py b/src/ipyautoui/custom/editgrid.py
index 8bfd88b..96b21fd 100644
--- a/src/ipyautoui/custom/editgrid.py
+++ b/src/ipyautoui/custom/editgrid.py
@@ -480,6 +480,8 @@ def _grid_changed(self, onchange):
def _setview(self, onchange):
if self.buttonbar_grid.active is None:
self.stk_crud.selected_index = None
+ elif self.buttonbar_grid.active == "support":
+ self.stk_crud.selected_index = None
else:
self.stk_crud.selected_index = self.buttonbar_grid.active_index