npyscreen - get NPSAppManaged screen width?

58 Views Asked by At

I try to center a widget and so getting the screen width from the form

class myForm(npyscreen.Form):
   def create(self):
      # Center the form horizontally
      self.show_atx = 0
      center = self.width / 2
      center = self.parentApp.COLS /2
      ...

I also tried to use onResize() but it has no w/h parameters to rely on

how can I get the screen size ?

thanks for your help but there is nothing like width or similar in that class

1

There are 1 best solutions below

2
Alan On

TL;DR:

  1. You're not supposed to
  2. ScreenSize.py and TESTING-TinyForm.py in the github repo
  3. Use Textual instead

(1) Widget Positioning

The widget positioning system is based on a relative x,y coordinate system. The layout engine tries to place widgets in the left-most columns by default - see add_widget and create_widgets_from_list.

(2) Layout

ScreenSize.py gives us self.F = npyscreen.Form(name = "Welcome to Npyscreen") and self.F._max_physical()

npyscreendoesn't have a Form class. Checking __init__.py, this has a relative import: from .fmForm import Form, which has a relative import to proto_fm_screen_area. This has a ScreenArea class providing three useful functions:

_max_physical(self) -> raw size test
useable_space(self, rely=0, relx=0) -> safer size check
widget_useable_space(self, rely=0, relx=0) -> probably should use this

The return from these provides (rows, columns). Potentially these can be used to calculate the positioning for a centre widget.

Going back to fmForm.py and class _FormBase(proto_fm_screen_area.ScreenArea, the function add_widget(rely=None, relx=None) can be called where rely is the centre column to place the widget.

If F is the form, my_widget is widget, and the 3rd column is the centre, self.add_widget(widgetClass = my_widget, relx=3) should put the widget at the centre-top of the form.

TESTING-TinyForm.py demonstrates a method to create a fixed size screen TinyForm(lines=1, columns=0) which might be easier if planning to force a centre widget. Using a pre-planned number of lines and columns would avoid the need to calculate the position. If I understand the code correctly, when the form is too big for the terminal then managed apps will automatically supply a scrollbar.

(3) Textual

npyscreen was (is?) a nice curses library. It's very old now and really could use a big cleanup.

Textual is a modern codebase from Will Mcgugan, who is also the author of Rich.

This can use CSS layouts, or direct widget layouts, including a Grid-style layout.

An example of what you want can be inferred from the "5x5" code example:

class GameCell(Button):
    def __init__(self, row: int, col: int) -> None:

With a fixed "5x5" grid to place the widgets on, it is trivial to place a centre widget.