Closed jonnieey closed 2 years ago
I think the "cleanest" way to achieve this would be by setting static_width
for each Button
. Sadly, as far as I can remember this won't actually do anything. Please let me know if I'm wrong though, I might have implemented it at some point.
If that doesn't work, what I personally would do is do some preprocessing on the lines of data you have. You can, for example, slice them to your target width - 3, and add ...
to the end to indicate "more". Something like the below should work:
max_width = ...
for line in data:
if len(line) <= max_width:
continue
line = line[:max_width - 3] + "..."
Technically, you can also do this slicing within a Button
subclass' get_lines
:
def get_lines(self) -> list[str]:
full = self.label
if len(full) > MAX_WIDTH:
self.label = self.label[:MAX_WIDTH - 3] + '...'
lines = super().get_lines()
self.label = original
return lines
I am writing this on my phone, so apologies if formatting of the code is weird/broken. The idea should be there.
Thanks for using the library, and feel free to ask about anything else that might be unclear!
static_width on buttons doesn't work :(
I had used the second suggestion by using ellipsis at the end the only problem is that the strings don't scale with window on resize. They are static and are displayed ontop of window.
Yeah, I guess I'll have to stick with the ellipsis for now as I maybe wait for horizontal scroll-ability. Is that something that you plan on adding?
the strings don't scale with window on resize
Actually, I think if you used the subclassing method that should no longer be the case!
Is that something that you plan on adding?
For sure, though the timeline is unclear at the moment. I'm currently hard at work on layouts and highlighters, next update is planned to be about colorschemes and general color related business, but I might be able to sneak a ScrollView
in, depending on the implementation difficulty.
One thing though: As far as I've tested, terminals don't send horizontal scroll events, only vertical ones. So you sadly won't be able to use the touchpad to scroll left or right, which will probably feel a bit clunky. There will be scrollbars for it though, so it should be alright.
Great. I'll try subclassing, thank you.
Hey there! Did it end up working?
import pytermgui as ptg
from pytermgui.window_manager.layouts import Layout
class MainWindow(ptg.Window):
title: "Title"
overflow = ptg.Overflow.SCROLL
def __init__(self, *widgets, **attrs):
super().__init__(*widgets, **attrs)
self.box = "DOUBLE"
class CustomButton(ptg.Button):
def __init__(self, label, max_width, **attrs):
self.max_width = max_width
super().__init__(label, **attrs)
def get_lines(self):
original = self.label
if len(original) > self.max_width:
self.label = self.label[:self.max_width] + '...'
lines = super().get_lines()
self.label = original
return lines
def client_container(clients: list = []):
scrollview = ptg.Container(overflow=ptg.Overflow.SCROLL, box="DOUBLE", height=10)
t = "The quick brown fox jumped over the lazy dog on a bike and did not return until the end of the line."
for i in clients:
scrollview.lazy_add(CustomButton(t, max_width=scrollview.width))
return scrollview
def app_layout():
layout = Layout()
layout.add_slot("Clients", height=30)
layout.add_slot("Jobs", height=30)
return layout
def main():
with ptg.WindowManager() as manager:
manager.layout = app_layout()
window = MainWindow(client_container([1, 2, 3]))
manager.add(window)
window2 = MainWindow(client_container([1, 3]))
manager.add(window2)
main()
So this is what I've come up with so far. Subclassing works but only upto the initial width of the container. I've been trying to figure out how to update the width of container as the window is resized.
One thing I could suggest is instead of passing the width value by name, maybe wrap it into a callable that can be called every time Button.get_lines
is called. That way it is always up to date, which should be what you are looking for.
Now the buttons don't show at all after that patch. eg sandbox/scrolling.py
Now the buttons don't show at all after that patch. eg sandbox/scrolling.py
Now that you say it, I'm pretty sure I forgot to give the buttons a default width. Will fix that tomorrow, but until then just setting some width to each button should fix it. Sorry!
Works great, thanks.
Great to hear! Is there anything else I can do related to this issue, or can we close it?
No, not right now. If I come across an issue I'll let you know. thanks.
Glad I could help then!
I have a list of lists of strings which contains data and I want them to be visible on a scrollable container as buttons. The only problem is that they have long data which wraps to the next line. Is there a way to truncate this view to the layout/slot width so that each button can be on one line?