{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# Widget" ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "import ipywidgets as ipw\n", "from IPython.display import SVG\n", "\n", "from pyabc2.abcjs.widget import ABCJSWidget, interactive" ] }, { "cell_type": "markdown", "id": "2", "metadata": {}, "source": [ "## The display widget\n", "\n", "Used to {ref}`display ` {class}`~pyabc2.Tune`s in the notebook environment.\n", "{class}`~pyabc2.abcjs.widget.ABCJSWidget` supports many of the [abcjs render options](https://docs.abcjs.net/visual/render-abc-options.html)." ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "# Nothing (or logo if abcjs hasn't been loaded yet)\n", "ABCJSWidget()" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": {}, "outputs": [], "source": [ "# Nothing\n", "ABCJSWidget()" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "# Really nothing\n", "ABCJSWidget(hide=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], "source": [ "# Just logo\n", "ABCJSWidget(logo=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "# Logo and a bit of music\n", "ABCJSWidget(abc=\"DEFG E2 CD- | D8 ||\", logo=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], "source": [ "# Slightly more complicated example\n", "ABCJSWidget(abc=\"K:G\\n\" + \" G,A,B,C DEFG | \" * 4, staff_width=500, foreground=\"teal\")" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "# Adding ABC and modifying parameters after init\n", "w = ABCJSWidget()\n", "w.abc = \"\"\"\\\n", "K: G\n", "G,A,B,C DEFG | ABcd efga | bc'd'e' f'g'a'b' |\n", "\"\"\"\n", "w.scale = 0.8\n", "w.staff_width = 550\n", "display(w)" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "# Dynamic update\n", "# Note both display instances are modified!\n", "w.abc += \"| c'\"\n", "w" ] }, { "cell_type": "markdown", "id": "11", "metadata": {}, "source": [ "## Save the SVG from the display widget\n", "\n", "It doesn't seem to be possible to do this with a single cell,\n", "but with two cells we can get to the SVGs\n", "(based on experiments in JupyterLab)." ] }, { "cell_type": "code", "execution_count": null, "id": "12", "metadata": {}, "outputs": [], "source": [ "w = ABCJSWidget(hide=True)\n", "w.abc = \"\"\"\\\n", "K: G\n", "G,A,B,C DEFG | ABcd efga | bc'd'e' f'g'a'\n", "\"\"\"\n", "display(w)\n", "print(w.svgs) # NOTE: Empty at this point" ] }, { "cell_type": "code", "execution_count": null, "id": "13", "metadata": {}, "outputs": [], "source": [ "# NOTE: must run this cell again for `.svgs` to be populated if using restart and run (to selected cell or full)\n", "print(len(w.svgs), \"SVG(s)\")\n", "for i, s in enumerate(w.svgs):\n", " display(SVG(s))" ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "## Editor\n", "\n", "```{note}\n", "The docs version doesn't currently provide full interactivity\n", "(a running Python kernel is needed, e.g. JupyterLab).\n", "```" ] }, { "cell_type": "code", "execution_count": null, "id": "15", "metadata": {}, "outputs": [], "source": [ "interactive()" ] }, { "cell_type": "markdown", "id": "16", "metadata": {}, "source": [ "## Editor example\n", "\n", "With a single widget instance, both display instances _should_ update when you change something.\n", "\n", "Here, we initialize the widget with some ABC and a few non-default settings." ] }, { "cell_type": "code", "execution_count": null, "id": "17", "metadata": {}, "outputs": [], "source": [ "abc = \"K: C\\nM: 4/4\\nT: The best scale\\n\" + '\"C\"' + \"CDEF GABc | \" * 4\n", "\n", "w = interactive(abc, foreground=\"#808080\", staff_width=600)\n", "w" ] }, { "cell_type": "code", "execution_count": null, "id": "18", "metadata": {}, "outputs": [], "source": [ "w" ] }, { "cell_type": "markdown", "id": "19", "metadata": {}, "source": [ "### Compare to ipywidgets behavior" ] }, { "cell_type": "code", "execution_count": null, "id": "20", "metadata": {}, "outputs": [], "source": [ "slider = ipw.FloatSlider(min=200, max=500, value=400)" ] }, { "cell_type": "code", "execution_count": null, "id": "21", "metadata": {}, "outputs": [], "source": [ "slider" ] }, { "cell_type": "code", "execution_count": null, "id": "22", "metadata": {}, "outputs": [], "source": [ "# We can do this and all display instances change and the slider still shows for this cell\n", "slider.value += 1\n", "slider" ] }, { "cell_type": "markdown", "id": "23", "metadata": {}, "source": [ "## Headless\n", "\n", "We can also use abcjs in the background via Node.js using {mod}`pyabc2.abcjs.headless`." ] }, { "cell_type": "code", "execution_count": null, "id": "24", "metadata": {}, "outputs": [], "source": [ "from IPython.display import SVG, Image\n", "\n", "from pyabc2.abcjs.headless import svg, svg_to" ] }, { "cell_type": "code", "execution_count": null, "id": "25", "metadata": {}, "outputs": [], "source": [ "s = svg(\"CDEF GABc |\")\n", "print(s[:100], \"...\")\n", "SVG(s)" ] }, { "cell_type": "markdown", "id": "26", "metadata": {}, "source": [ "{func}`~pyabc2.abcjs.headless.build` is automatically called if needed.\n", "The next time we call {func}`~pyabc2.abcjs.headless.svg`, it should be faster." ] }, { "cell_type": "code", "execution_count": null, "id": "27", "metadata": {}, "outputs": [], "source": [ "SVG(svg(\"A2 B2 C2 D2 |\"))" ] }, { "cell_type": "code", "execution_count": null, "id": "28", "metadata": {}, "outputs": [], "source": [ "try:\n", " display(Image(data=svg_to(s, \"png\")))\n", "except RuntimeError:\n", " print(\"failed to load cairo\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 5 }