• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _module-pw_console-plugins:
2
3============
4Plugin Guide
5============
6Pigweed Console supports extending the user interface with custom widgets. For
7example: Toolbars that display device information and provide buttons for
8interacting with the device.
9
10---------------
11Writing Plugins
12---------------
13Creating new plugins has a few high level steps:
14
151. Create a new Python class inheriting from either `WindowPane`_ or
16   `WindowPaneToolbar`_.
17
18   - Optionally inherit from The ``PluginMixin`` class as well for running
19     background tasks.
20
212. Enable the plugin before pw_console startup by calling ``add_window_plugin``,
22   ``add_top_toolbar`` or ``add_bottom_toolbar``. See the
23   :ref:`module-pw_console-embedding-plugins` section of the
24   :ref:`module-pw_console-embedding` for an example.
25
263. Run the console and enjoy!
27
28   - Debugging Plugin behavior can be done by logging to a dedicated Python
29     logger and viewing in-app. See `Debugging Plugin Behavior`_ below.
30
31Background Tasks
32================
33Plugins may need to have long running background tasks which could block or slow
34down the Pigweed Console user interface. For those situations use the
35``PluginMixin`` class. Plugins can inherit from this and setup the callback that
36should be executed in the background.
37
38.. autoclass:: pw_console.plugin_mixin.PluginMixin
39    :members:
40    :show-inheritance:
41
42Debugging Plugin Behavior
43=========================
44If your plugin uses background threads for updating it can be difficult to see
45errors. Often, nothing will appear to be happening and exceptions may not be
46visible. When using ``PluginMixin`` you can specify a name for a Python logger
47to use with the ``plugin_logger_name`` keyword argument.
48
49.. code-block:: python
50
51   class AwesomeToolbar(WindowPaneToolbar, PluginMixin):
52
53       def __init__(self, *args, **kwargs):
54           super().__init__(*args, **kwargs)
55           self.update_count = 0
56
57           self.plugin_init(
58               plugin_callback=self._background_task,
59               plugin_callback_frequency=1.0,
60               plugin_logger_name='my_awesome_plugin',
61           )
62
63       def _background_task(self) -> bool:
64           self.update_count += 1
65           self.plugin_logger.debug('background_task_update_count: %s',
66                                    self.update_count)
67           return True
68
69This will let you open up a new log window while the console is running to see
70what the plugin is doing. Open up the logger name provided above by clicking in
71the main menu: :guilabel:`File > Open Logger > my_awesome_plugin`.
72
73--------------
74Sample Plugins
75--------------
76Pigweed Console will provide a few sample plugins to serve as templates for
77creating your own plugins. These are a work in progress at the moment and not
78available at this time.
79
80Calculator
81==========
82This plugin is similar to the full-screen `calculator.py example`_ provided in
83prompt_toolkit. It's a full window that can be moved around the user interface
84like other Pigweed Console window panes. An input prompt is displayed on the
85bottom of the window where the user can type in some math equation. When the
86enter key is pressed the input is processed and the result shown in the top half
87of the window.
88
89Both input and output fields are prompt_toolkit `TextArea`_ objects which can
90have their own options like syntax highlighting.
91
92.. figure:: images/calculator_plugin.png
93  :alt: Screenshot of the CalcPane plugin showing some math calculations.
94
95  Screenshot of the ``CalcPane`` plugin showing some math calculations.
96
97The code is heavily commented and describes what each line is doing. See
98the :ref:`calc_pane_code` for the full source.
99
100Clock
101=====
102The ClockPane is another WindowPane based plugin that displays a clock and some
103formatted text examples. It inherits from both WindowPane and PluginMixin.
104
105.. figure:: images/clock_plugin1.png
106  :alt: ClockPane plugin screenshot showing the clock text.
107
108  ``ClockPane`` plugin screenshot showing the clock text.
109
110This plugin makes use of PluginMixin to run a task a background thread that
111triggers UI re-draws. There are also two toolbar buttons to toggle view mode
112(between the clock and some sample text) and line wrapping. pressing the
113:kbd:`v` key or mouse clicking on the :guilabel:`View Mode` button will toggle
114the view to show some formatted text samples:
115
116.. figure:: images/clock_plugin2.png
117  :alt: ClockPane plugin screenshot showing formatted text examples.
118
119  ``ClockPane`` plugin screenshot showing formatted text examples.
120
121Like the CalcPane example the code is heavily commented to guide plugin authors
122through developmenp. See the :ref:`clock_pane_code` below for the full source.
123
124--------
125Appendix
126--------
127.. _calc_pane_code:
128
129Code Listing: ``calc_pane.py``
130==============================
131.. literalinclude:: ./py/pw_console/plugins/calc_pane.py
132   :language: python
133   :linenos:
134
135.. _clock_pane_code:
136
137Code Listing: ``clock_pane.py``
138===============================
139.. literalinclude:: ./py/pw_console/plugins/clock_pane.py
140   :language: python
141   :linenos:
142
143.. _WindowPane: https://cs.opensource.google/pigweed/pigweed/+/main:pw_console/py/pw_console/widgets/window_pane.py
144.. _WindowPaneToolbar: https://cs.opensource.google/pigweed/pigweed/+/main:pw_console/py/pw_console/widgets/window_pane_toolbar.py
145.. _calculator.py example: https://github.com/prompt-toolkit/python-prompt-toolkit/blob/3.0.23/examples/full-screen/calculator.py
146.. _TextArea: https://python-prompt-toolkit.readthedocs.io/en/latest/pages/reference.html#prompt_toolkit.widgets.TextArea
147