{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "import param\n",
    "\n",
    "pn.extension()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example demonstrates how to order and hide widgets by means of the ``precedence`` and  ``display_threshold`` attributes.\n",
    "\n",
    "Each ``Parameter`` object has a ``precedence`` attribute that is defined as follows  in the documentation of ``param``:\n",
    "\n",
    "> ``precedence`` is a value, usually in the range 0.0 to 1.0, that allows the order of Parameters in a class to be defined (for e.g. in GUI menus).  \n",
    "> A negative precedence indicates a parameter that should be hidden in e.g. GUI menus.\n",
    "\n",
    "A `Param` pane has a ``display_threshold`` attribute defaulting to 0 and defined as follows:\n",
    "\n",
    "> Parameters with precedence below this value are not displayed.\n",
    "\n",
    "The interactive example below helps to understand how the interplay between these two attributes affects the display of widgets.\n",
    "\n",
    "The ``PrecedenceTutorial`` class emulates a dummy app whose display we want to control and that consists of three input parameters, ``x``, ``y`` and ``z``. These parameters will be displayed by `panel` with their associated default widgets. Additionally, the class declares the four parameters that will control the dummy app display: ``x_precedence``, ``y_precedence`` and ``z_precedence`` and ``dummy_app_display_threshold``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Precedence(param.Parameterized):\n",
    "\n",
    "    # Parameters of the dummy app.\n",
    "    x = param.Number(precedence=-1)\n",
    "    y = param.Boolean(precedence=3)\n",
    "    z = param.String(precedence=2)\n",
    "\n",
    "    # Parameters of the control app.\n",
    "    x_precedence = param.Number(default=x.precedence, bounds=(-10, 10), step=1)\n",
    "    y_precedence = param.Number(default=y.precedence, bounds=(-10, 10), step=1)\n",
    "    z_precedence = param.Number(default=z.precedence, bounds=(-10, 10), step=1)\n",
    "    dummy_app_display_threshold = param.Number(default=1, bounds=(-10, 10), step=1)\n",
    "    \n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        # Building the dummy app as a Param pane in here so that its ``display_threshold``\n",
    "        # parameter can be accessed and linked via @param.depends(...).\n",
    "        self.dummy_app = pn.Param(\n",
    "            self.param,\n",
    "            parameters=[\"x\", \"y\", \"z\"],\n",
    "            widgets={\n",
    "                \"x\": {\"background\": \"#fac400\"},\n",
    "                \"y\": {\"background\": \"#07d900\"},\n",
    "                \"z\": {\"background\": \"#00c0d9\"},\n",
    "            },\n",
    "            show_name=False\n",
    "        )\n",
    "\n",
    "    # Linking the two apps here.\n",
    "    @param.depends(\"dummy_app_display_threshold\", \"x_precedence\", \"y_precedence\", \"z_precedence\", watch=True)\n",
    "    def update_precedences_and_threshold(self):\n",
    "        self.param.x.precedence = self.x_precedence\n",
    "        self.param.y.precedence = self.y_precedence        \n",
    "        self.param.z.precedence = self.z_precedence     \n",
    "        self.dummy_app.display_threshold = self.dummy_app_display_threshold\n",
    "\n",
    "precedence_model = Precedence()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Bulding the control app as a Param pane too.\n",
    "control_app = pn.Param(\n",
    "    precedence_model.param,\n",
    "    parameters=[\"x_precedence\", \"y_precedence\", \"z_precedence\", \"dummy_app_display_threshold\"],\n",
    "    widgets={\n",
    "        \"x_precedence\": {\"background\": \"#fac400\"},\n",
    "        \"y_precedence\": {\"background\": \"#07d900\"},\n",
    "        \"z_precedence\": {\"background\": \"#00c0d9\"},\n",
    "    },\n",
    "    show_name=False\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Building the complete interactive example.\n",
    "interactive_precedence_app = pn.Column(\n",
    "    \"## Precedence Example\",\n",
    "    \"Moving the sliders of the control app should update the display of the dummy app.\",\n",
    "    pn.Row(\n",
    "        pn.Column(\"**Control app**\", control_app),\n",
    "        pn.Column(\"**Dummy app**\", precedence_model.dummy_app)\n",
    "    )\n",
    ")\n",
    "interactive_precedence_app"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.template.FastListTemplate(site=\"Panel\", title=\"Parameter Precedence\", main_max_width=\"700px\",\n",
    "                             main=[\n",
    "                                 pn.pane.Markdown(\"This example demonstrates how to order and hide widgets by means of the **``precedence`` and  ``display_threshold``** parameter attributes.\", sizing_mode=\"stretch_width\"),\n",
    "                                 interactive_precedence_app,\n",
    "                             ]).servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
