diff --git a/tree_display.py b/tree_display.py deleted file mode 100644 index 2d9a4af..0000000 --- a/tree_display.py +++ /dev/null @@ -1,295 +0,0 @@ -# Element supply of some sort -# Dict-/map-like -# Tree structure -# ↓ -# List of already formatted elements -# Each with a line height, indentation, ... -# List structure -# ↓ -# Messages and UI elements rendered to lines -# with meta-information, links/ids -# List structure, but on lines, not individual messages - -class Element: - pass - -class ElementSupply: - pass - -class TreeDisplay: - """ - Message line coordinates: - - n - Highest message - ... - 1 - Higher message - 0 - Lowest message - - Screen/line coordinates: - - h-1 - First line - h-2 - Second line - ... - 1 - Second to last line - 0 - Last line - - Terms: - - - | ... - | ... (above) - | ... - | - | | ... - | | | ... | - | ... - | ... (below) - | ... - - or - - - | ... - | ... (above) - | ... - | - | ... - | ... (below) - | ... - - The stem is a child of the base. The anchor is a direct or indirect child - of the stem, or it is the stem itself. - - The base id may also be None (the implicit parent of all top-level - messages in a room) - """ - - def __init__(self, window: Any) -> None: - self.window = window - - self._anchor_id = None - # Position of the formatted anchor's uppermost line on the screen - self._anchor_screen_pos = 0 - - - def render(self) -> None: - """ - Intermediate structures: - - Upwards and downwards list of elements + focused element - - Upwards and downwards list of rendered elements + focused element - - List of visible lines (saved and used for mouse clicks etc.) - - Steps of rendering: - 1. Load all necessary elements - 2. Render all messages with indentation - 3. Compile lines - - Steps of advanced rendering: - 1. Load focused element + render - 2. Load tree of focused element + render - 3. Load trees above and below + render, as many as necessary - 4. While loading and rendering trees, auto-collapse - 5. Move focus if focused element was hidden in an auto-collapse - ...? - """ - - # Step 1: Find and render the tree the anchor is in. - - stem_id = self._supply.find_stem_id(self._anchor_id, - base=self._base_id) - - tree = self._supply.get_tree(stem_id) - # The render might modify self._anchor_id, if the original anchor can't - # be displayed. - self._render_tree(tree) - - above, anchor, below = self._split_at_anchor(tree) - - # Step 2: Add more trees above and below, until the screen can be - # filled or there aren't any elements left in the store. - - # h_win = 7 - # 6 | <- h_above = 3 - # 5 | - # 4 | - # 3 | <- anchor, self._anchor_screen_pos = 3, anchor.height = 2 - # 2 | - # 1 | <- h_below = 2 - # 0 | - # - # 7 - 3 - 1 = 3 -- correct - # 3 - 2 + 1 = 2 -- correct - - height_window = None # TODO - - # All values are converted to zero indexed values in the calculations - height_above = (height_window - 1) - self._anchor_screen_pos - height_below = self._anchor_screen_pos - (anchor.height - 1) - - self._extend(above, height_above, base=self._base_id) - self._extend(below, height_below, base=self._base_id) - - self._lines = self._render_to_lines(above, anchor, below) - self._update_window(self._lines) - -# TreeDisplay plan(s): -# -# [ ] 1. Render a basic tree thing from an ElementSupply -# [ ] 1.1. Take/own a curses window -# [ ] 1.2. Keep track of the text internally -# [ ] 1.3. Retrieve elements from an ElementSupply -# [ ] 1.4. Render elements to text depending on width of curses window -# [ ] 1.5. Do indentation -# [ ] 1.6. Use "..." where a thing can't be rendered -# [ ] 2. Scroll and anchor to messages -# [ ] 2.1. Listen to key presses -# [ ] 2.2. Scroll up/down single lines -# [ ] 2.3. Render starting from the anchor -# [ ] 2.4. Some sort of culling, but preserve CONSISTENCY! -# [ ] 3. Focus on single message -# [ ] 3.1. Keep track of focused message -# [ ] 3.2. Move focused message -# [ ] 3.3. Keep message visible on screen -# [ ] 3.4. Set anchor to focus when focus is visible -# [ ] 3.5. Find anchor solution for when focus is offscreen -# [ ] 4. Collapse element threads -# [ ] 4.1. Collapse thread at any element -# [ ] 4.2. Auto-collapse threads when they can't be displayed -# [ ] 4.3. Focus collapsed messages -# [ ] 4.4. Move focus when a hidden message would have focus -# [ ] 5. Interaction with elements -# [ ] 5.1. Forward key presses -# [ ] 5.2. Mouse clicks + message attributes -# [ ] 5.3. Element visibility -# [ ] 5.4. Request more elements when the top of the element supply is hit -# [ ] 5.5. ... and various other things - -# STRUCTURE -# -# No async! -# -# The TreeView "owns" and completely fills one curses window. -# -# When rendering things, the TreeDisplay takes elements from the ElementSupply -# as needed. This should be a fast operation. -# -# When receiving key presses, the ones that are not interpreted by the TreeView -# are passed onto the currently focused element (if any). -# -# When receiving mouse clicks, the clicked-on element is focused and then the -# click and attributes of the clicked character are passed onto the focused -# element. -# -# (TODO: Notify focused elements? Make "viewed/new" state for elements -# possible?) -# -# -# -# DESIGN PRINCIPLES -# -# Layout: See below -# -# Color support: Definitely. -# No-color-mode: Not planned. -# => Colors required. - -# The tree display can display a tree-like structure of elements. -# -# Each element consists of: -# 1. a way to display the element -# 2. a way to forward key presses to the element -# 3. element-specific attributes (Attributes), including: -# 3.1 "id", the element's hashable id -# 3.2 optionally "parent_id", the element's parent's hashable id -# -# (TODO: A way to notify the element that it is visible?) -# -# (TODO: Jump to unread messages, mark messages as read, up/down arrows like -# instant, message jump tags?) -# -# (TODO: Curses + threading/interaction etc.?) -# -# -# -# LAYOUT -# -# A tree display's basic structure is something like this: -# -# -# | -# | | -# | | -# | -# | -# | | -# | | | -# | -# -# | -# -# It has an indentation string ("| " in the above example) that is prepended to -# each line according to its indentation. (TODO: Possibly add different types -# of indentation strings?) -# -# In general, "..." is inserted any time a message or other placeholder can't -# be displayed. (TODO: If "..." can't be displayed, it is shortened until it -# can be displayed?) -# -# Elements can be collapsed. Collapsed elements are displayed as "+ ()" -# where is the number of elements in the hidden subtree. -# -# If an element is so far right that it can't be displayed, the tree display -# first tries to collapse the tree. If the collapsed message can't be displayed -# either, it uses "..." as mentioned above. -# -# -# | -# | | -# | | -# | -# | + (3) -# | -# -# | -# | | -# | | | -# | | | | ... -# -# -# -# NAVIGATION -# -# For navigation, the following movements/keys are used (all other key presses -# are forwarded to the currently selected element, if there is one): -# -# LEFT (left arrow, h): move to the selected element's parent -# -# RIGHT (right arrow, l): move to the selected element's first child -# -# UP (up arrow, k): move to the element visually below the selected element -# -# DOWN (down arrow, j): move to the element visually above the selected element -# -# Mod + LEFT: move to the selected element's previous sibling, if one exists -# -# Mod + RIGHT: move to the selected element's next sibling, if one exists -# -# Mod + UP: scroll up by scroll step -# -# Mod + DOWN: scroll down by scroll step -# -# -# CURSES -# -# Main thread: -# - async -# - yaboli -# - curses: non-blocking input -# - curses: update visuals -# - run editor in async variant of subprocess or separate thread -# -# -# -# STRUCTURE -# -# ???