xref: /aosp_15_r20/external/pigweed/pw_console/py/pw_console/log_pane_toolbars.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2021 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""LogPane Info Toolbar classes."""
15
16from __future__ import annotations
17import functools
18from typing import TYPE_CHECKING
19
20from prompt_toolkit.filters import Condition
21from prompt_toolkit.layout import (
22    ConditionalContainer,
23    FormattedTextControl,
24    VSplit,
25    Window,
26    WindowAlign,
27    HorizontalAlign,
28)
29
30from pw_console.style import get_toolbar_style
31
32if TYPE_CHECKING:
33    from pw_console.log_pane import LogPane
34
35
36class LineInfoBar(ConditionalContainer):
37    """One line bar for showing current and total log lines."""
38
39    def get_tokens(self):
40        """Return formatted text tokens for display."""
41        tokens = ' {} / {} '.format(
42            self.log_pane.log_view.get_current_line() + 1,
43            self.log_pane.log_view.get_total_count(),
44        )
45        return [('', tokens)]
46
47    def __init__(self, log_pane: LogPane):
48        self.log_pane = log_pane
49        info_bar_control = FormattedTextControl(self.get_tokens)
50        info_bar_window = Window(
51            content=info_bar_control,
52            align=WindowAlign.RIGHT,
53            dont_extend_width=True,
54        )
55
56        super().__init__(
57            VSplit(
58                [info_bar_window],
59                height=1,
60                style=functools.partial(
61                    get_toolbar_style, self.log_pane, dim=True
62                ),
63                align=HorizontalAlign.RIGHT,
64            ),
65            # Only show current/total line info if not auto-following
66            # logs. Similar to tmux behavior.
67            filter=Condition(lambda: not self.log_pane.log_view.follow),
68        )
69
70
71class TableToolbar(ConditionalContainer):
72    """One line toolbar for showing table headers."""
73
74    TOOLBAR_HEIGHT = 1
75
76    def __init__(self, log_pane: LogPane):
77        # FormattedText of the table column headers.
78        table_header_bar_control = FormattedTextControl(
79            log_pane.log_view.render_table_header
80        )
81        # Left justify the header content.
82        table_header_bar_window = Window(
83            content=table_header_bar_control,
84            align=WindowAlign.LEFT,
85            dont_extend_width=False,
86        )
87        super().__init__(
88            VSplit(
89                [table_header_bar_window],
90                height=1,
91                style=functools.partial(get_toolbar_style, log_pane, dim=True),
92                align=HorizontalAlign.LEFT,
93            ),
94            filter=Condition(
95                lambda: log_pane.table_view
96                and log_pane.log_view.get_total_count() > 0
97            ),
98        )
99