sxplore: implement preview buffer following cursor
This commit is contained in:
parent
a4e35c95ee
commit
6a82b84af8
47
sx/plore.py
47
sx/plore.py
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue