Skip to content

Commit

Permalink
Merge pull request #341 from maxfordham/340-add-generic-buttonbar-hel…
Browse files Browse the repository at this point in the history
…p-to-crud-buttonbar

✨ Add support button to `CrudButtonBar`
  • Loading branch information
ollyhensby authored Sep 11, 2024
2 parents 40d6918 + 239a171 commit aedbeb9
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 50 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ dependencies = [
"numpy",
"openpyxl",
"pandas",
"pydantic>2",
"pydantic<2.9",
"pydantic-settings",
"pydantic-extra-types",
"PyYAML",
Expand Down
7 changes: 7 additions & 0 deletions src/ipyautoui/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
166 changes: 117 additions & 49 deletions src/ipyautoui/custom/buttonbars.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
# 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
# name: python3
# ---

# +
# %run ../_dev_maplocal_params.py


import ipywidgets as w
import traitlets as tr
import typing as ty
Expand All @@ -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
Expand Down Expand Up @@ -272,48 +269,102 @@ 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="➕ <i>Adding Value</i>",
**dict(ADD_BUTTON_KWARGS)
| dict(
tooltip="Add item",
tooltip_clicked="Go back to table",
button_style="success",
message="➕ <i>Adding Value</i>",
)
),
edit=CrudOptions(
tooltip="Edit item",
tooltip_clicked="Go back to table",
button_style="warning",
message="✏️ <i>Editing Value</i>",
**dict(EDIT_BUTTON_KWARGS)
| dict(
tooltip="Edit item",
tooltip_clicked="Go back to table",
button_style="warning",
message="✏️ <i>Editing Value</i>",
)
),
copy=CrudOptions(
tooltip="Copy item",
tooltip_clicked="Go back to table",
button_style="primary",
message="📝 <i>Copying Value</i>",
**dict(COPY_BUTTON_KWARGS)
| dict(
tooltip="Copy item",
tooltip_clicked="Go back to table",
button_style="primary",
message="📝 <i>Copying Value</i>",
)
),
delete=CrudOptions(
tooltip="Delete item",
tooltip_clicked="Go back to table",
button_style="danger",
message="🗑️ <i>Deleting Value</i>",
**dict(DELETE_BUTTON_KWARGS)
| dict(
tooltip="Delete item",
tooltip_clicked="Go back to table",
button_style="danger",
message="🗑️ <i>Deleting Value</i>",
)
),
reload=CrudOptions(
**dict(RELOAD_BUTTON_KWARGS)
| dict(
tooltip="reload data",
tooltip_clicked="",
button_style="info",
message="♻ <i>reloading data|</i>",
)
),
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="❔ <i>Help Selected</i>",
)
),
)


# -
# +
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", "<br>")
return w.VBox(
[w.HBox([l, w.HTML(f"<i>{replace_newlines(l.tooltip)}</i>")]) 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"))
fn_edit = tr.Callable(default_value=lambda: print("edit"))
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):
Expand All @@ -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()

Expand All @@ -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")
Expand All @@ -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)
Expand All @@ -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__":

Expand All @@ -444,5 +513,4 @@ def backward():
fn_backward=backward,
fn_reload=lambda: print("fn_reload"),
)

display(buttonbar)
2 changes: 2 additions & 0 deletions src/ipyautoui/custom/editgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit aedbeb9

Please sign in to comment.