Skip to content

Commit

Permalink
Merge pull request #1788 from Textualize/datatable-select-headers
Browse files Browse the repository at this point in the history
DataTable - Message emitted when header selected
  • Loading branch information
willmcgugan authored Feb 14, 2023
2 parents 0204498 + c80299e commit df1edb0
Show file tree
Hide file tree
Showing 6 changed files with 323 additions and 245 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added `DataTable.get_row_at` to retrieve the values from a row by index https://github.com/Textualize/textual/pull/1786
- Added `DataTable.get_column` to retrieve the values from a column by key https://github.com/Textualize/textual/pull/1786
- Added `DataTable.get_column_at` to retrieve the values from a column by index https://github.com/Textualize/textual/pull/1786
- Added `DataTable.HeaderSelected` which is posted when header label clicked https://github.com/Textualize/textual/pull/1788
- Added `DOMNode.watch` and `DOMNode.is_attached` methods https://github.com/Textualize/textual/pull/1750
- Added `DOMNode.css_tree` which is a renderable that shows the DOM and CSS https://github.com/Textualize/textual/pull/1778
- Added `DOMNode.children_view` which is a view on to a nodes children list, use for querying https://github.com/Textualize/textual/pull/1778
Expand Down
2 changes: 2 additions & 0 deletions docs/widgets/data_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ The example below populates a table with CSV data.

### ::: textual.widgets.DataTable.ColumnSelected

### ::: textual.widgets.DataTable.HeaderSelected

## Bindings

The data table widget defines directly the following bindings:
Expand Down
1 change: 0 additions & 1 deletion src/textual/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

if TYPE_CHECKING:
from .message_pump import MessagePump
from .widget import Widget


@rich.repr.auto
Expand Down
52 changes: 43 additions & 9 deletions src/textual/widgets/_data_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,29 @@ def __rich_repr__(self) -> rich.repr.Result:
yield "cursor_column", self.cursor_column
yield "column_key", self.column_key

class HeaderSelected(Message, bubble=True):
"""Posted when a column header/label is clicked."""

def __init__(
self,
sender: DataTable,
column_key: ColumnKey,
column_index: int,
label: Text,
):
self.column_key = column_key
"""The key for the column."""
self.column_index = column_index
"""The index for the column."""
self.label = label
"""The text of the label."""
super().__init__(sender)

def __rich_repr__(self) -> rich.repr.Result:
yield "sender", self.sender
yield "column_key", self.column_key
yield "label", self.label.plain

def __init__(
self,
*,
Expand Down Expand Up @@ -1327,8 +1350,7 @@ def _render_cell(
column_key = self._column_locations.get_key(column_index)
cell_cache_key = (row_key, column_key, style, cursor, hover, self._update_count)
if cell_cache_key not in self._cell_render_cache:
if not is_header_row:
style += Style.from_meta({"row": row_index, "column": column_index})
style += Style.from_meta({"row": row_index, "column": column_index})
height = self.header_height if is_header_row else self.rows[row_key].height
cell = self._get_row_renderables(row_index)[column_index]
lines = self.app.console.render_lines(
Expand Down Expand Up @@ -1643,14 +1665,26 @@ def _set_hover_cursor(self, active: bool) -> None:

def on_click(self, event: events.Click) -> None:
self._set_hover_cursor(True)
if self.show_cursor and self.cursor_type != "none":
meta = self.get_style_at(event.x, event.y).meta
if not meta:
return

row_index = meta["row"]
column_index = meta["column"]
is_header_click = self.show_header and row_index == -1
if is_header_click:
# Header clicks work even if cursor is off, and doesn't move the cursor.
column = self.ordered_columns[column_index]
message = DataTable.HeaderSelected(
self, column.key, column_index, label=column.label
)
self.post_message_no_wait(message)
elif self.show_cursor and self.cursor_type != "none":
# Only post selection events if there is a visible row/col/cell cursor.
meta = self.get_style_at(event.x, event.y).meta
if meta:
self.cursor_coordinate = Coordinate(meta["row"], meta["column"])
self._post_selected_message()
self._scroll_cursor_into_view(animate=True)
event.stop()
self.cursor_coordinate = Coordinate(row_index, column_index)
self._post_selected_message()
self._scroll_cursor_into_view(animate=True)
event.stop()

def action_cursor_up(self) -> None:
self._set_hover_cursor(False)
Expand Down
Loading

0 comments on commit df1edb0

Please sign in to comment.