xref: /aosp_15_r20/external/pigweed/pw_console/plugins.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_console-plugins:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker============
4*61c4878aSAndroid Build Coastguard WorkerPlugin Guide
5*61c4878aSAndroid Build Coastguard Worker============
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module-subpage::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_console
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard WorkerPigweed Console supports extending the user interface with custom widgets. For
10*61c4878aSAndroid Build Coastguard Workerexample: Toolbars that display device information and provide buttons for
11*61c4878aSAndroid Build Coastguard Workerinteracting with the device.
12*61c4878aSAndroid Build Coastguard Worker
13*61c4878aSAndroid Build Coastguard Worker---------------
14*61c4878aSAndroid Build Coastguard WorkerWriting Plugins
15*61c4878aSAndroid Build Coastguard Worker---------------
16*61c4878aSAndroid Build Coastguard WorkerCreating new plugins has a few high level steps:
17*61c4878aSAndroid Build Coastguard Worker
18*61c4878aSAndroid Build Coastguard Worker1. Create a new Python class inheriting from either `WindowPane`_ or
19*61c4878aSAndroid Build Coastguard Worker   `WindowPaneToolbar`_.
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker   - Optionally inherit from The ``PluginMixin`` class as well for running
22*61c4878aSAndroid Build Coastguard Worker     background tasks.
23*61c4878aSAndroid Build Coastguard Worker
24*61c4878aSAndroid Build Coastguard Worker2. Enable the plugin before pw_console startup by calling ``add_window_plugin``,
25*61c4878aSAndroid Build Coastguard Worker   ``add_floating_window_plugin``, ``add_top_toolbar`` or
26*61c4878aSAndroid Build Coastguard Worker   ``add_bottom_toolbar``. See the
27*61c4878aSAndroid Build Coastguard Worker   :ref:`module-pw_console-embedding-plugins` section of the
28*61c4878aSAndroid Build Coastguard Worker   :ref:`module-pw_console-embedding` for an example.
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard Worker3. Run the console and enjoy!
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker   - Debugging Plugin behavior can be done by logging to a dedicated Python
33*61c4878aSAndroid Build Coastguard Worker     logger and viewing in-app. See `Debugging Plugin Behavior`_ below.
34*61c4878aSAndroid Build Coastguard Worker
35*61c4878aSAndroid Build Coastguard WorkerBackground Tasks
36*61c4878aSAndroid Build Coastguard Worker================
37*61c4878aSAndroid Build Coastguard WorkerPlugins may need to have long running background tasks which could block or slow
38*61c4878aSAndroid Build Coastguard Workerdown the Pigweed Console user interface. For those situations use the
39*61c4878aSAndroid Build Coastguard Worker``PluginMixin`` class. Plugins can inherit from this and setup the callback that
40*61c4878aSAndroid Build Coastguard Workershould be executed in the background.
41*61c4878aSAndroid Build Coastguard Worker
42*61c4878aSAndroid Build Coastguard Worker.. autoclass:: pw_console.plugin_mixin.PluginMixin
43*61c4878aSAndroid Build Coastguard Worker    :members:
44*61c4878aSAndroid Build Coastguard Worker    :show-inheritance:
45*61c4878aSAndroid Build Coastguard Worker
46*61c4878aSAndroid Build Coastguard WorkerDebugging Plugin Behavior
47*61c4878aSAndroid Build Coastguard Worker=========================
48*61c4878aSAndroid Build Coastguard WorkerIf your plugin uses background threads for updating it can be difficult to see
49*61c4878aSAndroid Build Coastguard Workererrors. Often, nothing will appear to be happening and exceptions may not be
50*61c4878aSAndroid Build Coastguard Workervisible. When using ``PluginMixin`` you can specify a name for a Python logger
51*61c4878aSAndroid Build Coastguard Workerto use with the ``plugin_logger_name`` keyword argument.
52*61c4878aSAndroid Build Coastguard Worker
53*61c4878aSAndroid Build Coastguard Worker.. code-block:: python
54*61c4878aSAndroid Build Coastguard Worker
55*61c4878aSAndroid Build Coastguard Worker   class AwesomeToolbar(WindowPaneToolbar, PluginMixin):
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker       def __init__(self, *args, **kwargs):
58*61c4878aSAndroid Build Coastguard Worker           super().__init__(*args, **kwargs)
59*61c4878aSAndroid Build Coastguard Worker           self.update_count = 0
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker           self.plugin_init(
62*61c4878aSAndroid Build Coastguard Worker               plugin_callback=self._background_task,
63*61c4878aSAndroid Build Coastguard Worker               plugin_callback_frequency=1.0,
64*61c4878aSAndroid Build Coastguard Worker               plugin_logger_name='my_awesome_plugin',
65*61c4878aSAndroid Build Coastguard Worker           )
66*61c4878aSAndroid Build Coastguard Worker
67*61c4878aSAndroid Build Coastguard Worker       def _background_task(self) -> bool:
68*61c4878aSAndroid Build Coastguard Worker           self.update_count += 1
69*61c4878aSAndroid Build Coastguard Worker           self.plugin_logger.debug('background_task_update_count: %s',
70*61c4878aSAndroid Build Coastguard Worker                                    self.update_count)
71*61c4878aSAndroid Build Coastguard Worker           return True
72*61c4878aSAndroid Build Coastguard Worker
73*61c4878aSAndroid Build Coastguard WorkerThis will let you open up a new log window while the console is running to see
74*61c4878aSAndroid Build Coastguard Workerwhat the plugin is doing. Open up the logger name provided above by clicking in
75*61c4878aSAndroid Build Coastguard Workerthe main menu: :guilabel:`File > Open Logger > my_awesome_plugin`.
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker--------------
78*61c4878aSAndroid Build Coastguard WorkerSample Plugins
79*61c4878aSAndroid Build Coastguard Worker--------------
80*61c4878aSAndroid Build Coastguard WorkerPigweed Console will provide a few sample plugins to serve as templates for
81*61c4878aSAndroid Build Coastguard Workercreating your own plugins. These are a work in progress at the moment and not
82*61c4878aSAndroid Build Coastguard Workeravailable at this time.
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard WorkerBandwidth Toolbar
85*61c4878aSAndroid Build Coastguard Worker=================
86*61c4878aSAndroid Build Coastguard WorkerTracks and logs the data sent and received over a serial transport like a socket
87*61c4878aSAndroid Build Coastguard Workeror PySerial device. To use in a custom transport interface instantiate the
88*61c4878aSAndroid Build Coastguard Worker``SerialBandwidthTracker`` and call ``track_read_data`` on incoming data bytes
89*61c4878aSAndroid Build Coastguard Workerand ``track_write_data`` on outoing data bytes.
90*61c4878aSAndroid Build Coastguard Worker
91*61c4878aSAndroid Build Coastguard WorkerCalculator
92*61c4878aSAndroid Build Coastguard Worker==========
93*61c4878aSAndroid Build Coastguard WorkerThis plugin is similar to the full-screen `calculator.py example`_ provided in
94*61c4878aSAndroid Build Coastguard Workerprompt_toolkit. It's a full window that can be moved around the user interface
95*61c4878aSAndroid Build Coastguard Workerlike other Pigweed Console window panes. An input prompt is displayed on the
96*61c4878aSAndroid Build Coastguard Workerbottom of the window where the user can type in some math equation. When the
97*61c4878aSAndroid Build Coastguard Workerenter key is pressed the input is processed and the result shown in the top half
98*61c4878aSAndroid Build Coastguard Workerof the window.
99*61c4878aSAndroid Build Coastguard Worker
100*61c4878aSAndroid Build Coastguard WorkerBoth input and output fields are prompt_toolkit `TextArea`_ objects which can
101*61c4878aSAndroid Build Coastguard Workerhave their own options like syntax highlighting.
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard Worker.. figure:: images/calculator_plugin.svg
104*61c4878aSAndroid Build Coastguard Worker  :alt: Screenshot of the CalcPane plugin showing some math calculations.
105*61c4878aSAndroid Build Coastguard Worker
106*61c4878aSAndroid Build Coastguard Worker  Screenshot of the ``CalcPane`` plugin showing some math calculations.
107*61c4878aSAndroid Build Coastguard Worker
108*61c4878aSAndroid Build Coastguard WorkerThe code is heavily commented and describes what each line is doing. See
109*61c4878aSAndroid Build Coastguard Workerthe :ref:`calc_pane_code` for the full source.
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard WorkerClock
112*61c4878aSAndroid Build Coastguard Worker=====
113*61c4878aSAndroid Build Coastguard WorkerThe ClockPane is another WindowPane based plugin that displays a clock and some
114*61c4878aSAndroid Build Coastguard Workerformatted text examples. It inherits from both WindowPane and PluginMixin.
115*61c4878aSAndroid Build Coastguard Worker
116*61c4878aSAndroid Build Coastguard Worker.. figure:: images/clock_plugin1.svg
117*61c4878aSAndroid Build Coastguard Worker  :alt: ClockPane plugin screenshot showing the clock text.
118*61c4878aSAndroid Build Coastguard Worker
119*61c4878aSAndroid Build Coastguard Worker  ``ClockPane`` plugin screenshot showing the clock text.
120*61c4878aSAndroid Build Coastguard Worker
121*61c4878aSAndroid Build Coastguard WorkerThis plugin makes use of PluginMixin to run a task a background thread that
122*61c4878aSAndroid Build Coastguard Workertriggers UI re-draws. There are also two toolbar buttons to toggle view mode
123*61c4878aSAndroid Build Coastguard Worker(between the clock and some sample text) and line wrapping. pressing the
124*61c4878aSAndroid Build Coastguard Worker:kbd:`v` key or mouse clicking on the :guilabel:`View Mode` button will toggle
125*61c4878aSAndroid Build Coastguard Workerthe view to show some formatted text samples:
126*61c4878aSAndroid Build Coastguard Worker
127*61c4878aSAndroid Build Coastguard Worker.. figure:: images/clock_plugin2.svg
128*61c4878aSAndroid Build Coastguard Worker  :alt: ClockPane plugin screenshot showing formatted text examples.
129*61c4878aSAndroid Build Coastguard Worker
130*61c4878aSAndroid Build Coastguard Worker  ``ClockPane`` plugin screenshot showing formatted text examples.
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard WorkerLike the CalcPane example the code is heavily commented to guide plugin authors
133*61c4878aSAndroid Build Coastguard Workerthrough developmenp. See the :ref:`clock_pane_code` below for the full source.
134*61c4878aSAndroid Build Coastguard Worker
135*61c4878aSAndroid Build Coastguard Worker2048 Game
136*61c4878aSAndroid Build Coastguard Worker=========
137*61c4878aSAndroid Build Coastguard WorkerThis is a plugin that demonstrates more complex user interaction by playing a
138*61c4878aSAndroid Build Coastguard Workergame of 2048.
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard WorkerSimilar to the ``ClockPane`` the ``Twenty48Pane`` class inherits from
141*61c4878aSAndroid Build Coastguard Worker``PluginMixin`` to manage background tasks. With a few differences:
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard Worker- Uses ``FloatingWindowPane`` to create a floating window instead of a
144*61c4878aSAndroid Build Coastguard Worker  standard tiled window.
145*61c4878aSAndroid Build Coastguard Worker- Implements the ``get_top_level_menus`` function to create a new ``[2048]``
146*61c4878aSAndroid Build Coastguard Worker  menu in Pigweed Console's own main menu bar.
147*61c4878aSAndroid Build Coastguard Worker- Adds custom game keybindings which are set within the ``Twenty48Control``
148*61c4878aSAndroid Build Coastguard Worker  class. That is the prompt_toolkit ``FormattedTextControl`` widget which
149*61c4878aSAndroid Build Coastguard Worker  receives keyboard input when the game is in focus.
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard WorkerThe ``Twenty48Game`` class is separate from the user interface and handles
152*61c4878aSAndroid Build Coastguard Workermanaging the game state as well as printing the game board. The
153*61c4878aSAndroid Build Coastguard Worker``Twenty48Game.__pt_formatted_text__()`` function is responsible for drawing the
154*61c4878aSAndroid Build Coastguard Workergame board using prompt_toolkit style and text tuples.
155*61c4878aSAndroid Build Coastguard Worker
156*61c4878aSAndroid Build Coastguard Worker.. figure:: images/2048_plugin1.svg
157*61c4878aSAndroid Build Coastguard Worker  :alt: Twenty48Pane plugin screenshot showing the game board.
158*61c4878aSAndroid Build Coastguard Worker
159*61c4878aSAndroid Build Coastguard Worker  ``Twenty48Pane`` plugin screenshot showing the game board.
160*61c4878aSAndroid Build Coastguard Worker
161*61c4878aSAndroid Build Coastguard Worker--------
162*61c4878aSAndroid Build Coastguard WorkerAppendix
163*61c4878aSAndroid Build Coastguard Worker--------
164*61c4878aSAndroid Build Coastguard Worker.. _calc_pane_code:
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard WorkerCode Listing: ``calc_pane.py``
167*61c4878aSAndroid Build Coastguard Worker==============================
168*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: ./py/pw_console/plugins/calc_pane.py
169*61c4878aSAndroid Build Coastguard Worker   :language: python
170*61c4878aSAndroid Build Coastguard Worker   :linenos:
171*61c4878aSAndroid Build Coastguard Worker
172*61c4878aSAndroid Build Coastguard Worker.. _clock_pane_code:
173*61c4878aSAndroid Build Coastguard Worker
174*61c4878aSAndroid Build Coastguard WorkerCode Listing: ``clock_pane.py``
175*61c4878aSAndroid Build Coastguard Worker===============================
176*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: ./py/pw_console/plugins/clock_pane.py
177*61c4878aSAndroid Build Coastguard Worker   :language: python
178*61c4878aSAndroid Build Coastguard Worker   :linenos:
179*61c4878aSAndroid Build Coastguard Worker
180*61c4878aSAndroid Build Coastguard Worker.. _twenty48_pane_code:
181*61c4878aSAndroid Build Coastguard Worker
182*61c4878aSAndroid Build Coastguard WorkerCode Listing: ``twenty48_pane.py``
183*61c4878aSAndroid Build Coastguard Worker==================================
184*61c4878aSAndroid Build Coastguard Worker.. literalinclude:: ./py/pw_console/plugins/twenty48_pane.py
185*61c4878aSAndroid Build Coastguard Worker   :language: python
186*61c4878aSAndroid Build Coastguard Worker   :linenos:
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker
189*61c4878aSAndroid Build Coastguard Worker.. _WindowPane: https://cs.pigweed.dev/pigweed/+/main:pw_console/py/pw_console/widgets/window_pane.py
190*61c4878aSAndroid Build Coastguard Worker.. _WindowPaneToolbar: https://cs.pigweed.dev/pigweed/+/main:pw_console/py/pw_console/widgets/window_pane_toolbar.py
191*61c4878aSAndroid Build Coastguard Worker.. _calculator.py example: https://github.com/prompt-toolkit/python-prompt-toolkit/blob/3.0.23/examples/full-screen/calculator.py
192*61c4878aSAndroid Build Coastguard Worker.. _TextArea: https://python-prompt-toolkit.readthedocs.io/en/latest/pages/reference.html#prompt_toolkit.widgets.TextArea
193