sxplore: implement preview buffer following cursor

This commit is contained in:
Shiz 2021-07-05 04:49:04 +02:00
parent a4e35c95ee
commit 6a82b84af8
1 changed files with 32 additions and 15 deletions

View File

@ -36,10 +36,11 @@ def align_up_to(n, align):
class StreamCursor:
def __init__(self, length=0, style = None) -> None:
def __init__(self, length=0, style = None, leading=False) -> None:
self.offset = 0
self.length = length
self.style = style or Style(color='white', bgcolor='grey37', bold=True)
self.leading = leading
class StreamWindow:
def __init__(self, stream: Stream, pos: O[Pos] = 0, length=256, context=32, line=16):
@ -58,11 +59,12 @@ class StreamWindow:
def update(self, new_pos, force=False):
if self.pos == new_pos and not force:
return
self.buf_pos = max(0, align_down_to(int(self.pos) - self.context, self.line))
self.buf_end = align_up_to(int(self.pos) + self.length + self.context, self.line)
self.pos = align_down_to(int(new_pos), self.line)
self.buf_pos = max(0, self.pos - self.context)
self.buf_end = align_up_to(int(new_pos) + self.length, self.line) + self.context
self.stream.seek(self.buf_pos)
self.buf = self.stream.read(self.buf_end - self.buf_pos)
self.buf = self.stream.root.read(self.buf_end - self.buf_pos)
self.buf_end = self.buf_pos + len(self.buf)
@property
@ -71,16 +73,25 @@ class StreamWindow:
@property
def data_end(self):
return min(self.data_start + self.length, self.buf_end)
return min(self.data_start + self.length, self.end)
@property
def end(self):
return self.buf_end - self.buf_pos
def cursor_start(self, cursor):
return min(self.data_start + cursor.offset, self.data_end)
return min(cursor.offset - self.buf_pos, self.data_end)
def cursor_end(self, cursor):
return min(self.data_end, self.cursor_start(cursor) + cursor.length)
def adjust_cursor(self, cursor, adjust):
cursor.offset = max(0, min(cursor.offset + adjust, self.data_end - cursor.length - self.data_start))
if not cursor.leading:
cursor.offset = max(0, min(cursor.offset + adjust, self.data_end - cursor.length - self.data_start))
else:
cursor.offset = max(0, cursor.offset + adjust)
if not (self.pos <= cursor.offset < self.pos + self.length):
self.update(cursor.offset)
class StreamView(Widget):
@ -98,7 +109,6 @@ class StreamView(Widget):
def render(self) -> RenderableType:
sw = self.stream_window
sw.update(0)
parts = []
cursors = sorted(sw.cursors, key=lambda c: (c.offset, c.length))
@ -111,7 +121,7 @@ class StreamView(Widget):
parts.extend(self.format(cs, ce - cs, style=(self.style_addr_active, c.style)))
s = ce
parts.extend(self.format(s, sw.data_end - s, style=(self.style_addr_active, self.style_data_active)))
parts.extend(self.format(sw.data_end, sw.buf_end - sw.data_end, style=(self.style_addr_inactive, self.style_data_inactive)))
parts.extend(self.format(sw.data_end, sw.end - sw.data_end, style=(self.style_addr_inactive, self.style_data_inactive)))
return Text.assemble(*parts, style=self.style_data_inactive)
class StreamHexView(StreamView):
@ -241,7 +251,10 @@ class TreeNode:
i = self.parent.children.index(self)
if i == 0:
return self.parent
return self.parent.children[i - 1]
c = self.parent.children[i - 1]
while recursive and c.children:
c = c.children[-1]
return c
def toggle(self) -> None:
self.hidden = not self.hidden
@ -322,7 +335,7 @@ class SXplore(App):
self.cursor_hl = StreamCursor(length=4)
self.cursor_hl.offset = 192
self.cursor_node = StreamCursor(style=Style(color='black', bgcolor='white'))
self.cursor_node = StreamCursor(style=Style(color='black', bgcolor='white'), leading=True)
self.window = StreamWindow(stream)
self.window.cursors.append(self.cursor_hl)
self.window.cursors.append(self.cursor_node)
@ -473,11 +486,13 @@ class SXplore(App):
s.deselect()
p.select()
self.tree.selected_node = p
self.cursor_node.offset = p.extra.get('pos', 0)
if p.hidden:
self.cursor_node.length = 0
else:
self.cursor_node.length = p.extra.get('end', 0) - self.cursor_node.offset
s = p.extra.get('pos', 0)
e = p.extra.get('end', 0)
self.cursor_node.length = e - s
self.window.adjust_cursor(self.cursor_node, s - self.cursor_node.offset)
await self.tree.refresh()
await self.stream_hex.refresh()
await self.stream_txt.refresh()
@ -490,11 +505,13 @@ class SXplore(App):
s.deselect()
n.select()
self.tree.selected_node = n
self.cursor_node.offset = n.extra.get('pos', 0)
if n.hidden:
self.cursor_node.length = 0
else:
self.cursor_node.length = n.extra.get('end', 0) - self.cursor_node.offset
s = n.extra.get('pos', 0)
e = n.extra.get('end', 0)
self.cursor_node.length = e - s
self.window.adjust_cursor(self.cursor_node, s - self.cursor_node.offset)
await self.tree.refresh()
await self.stream_hex.refresh()
await self.stream_txt.refresh()