How to get screen size (width, height) in a Go application using tview?

199 views Asked by At

"I'm currently working on a Go application using the tview library for building terminal-based user interfaces. I need to retrieve the screen size (width and height) to properly configure my application layout. However, I couldn't find a direct function in the tview library to get the screen size.

Can anyone provide guidance on how to obtain the screen size when using tview? If there's no direct function in tview, is there a recommended way to achieve this using the underlying tcell package or any other approach?"

I attempted to find a direct function within the tview library to retrieve the screen size, but I couldn't locate one. Following that, I explored the tcell package, which is the underlying terminal handling library used by tview, but I encountered difficulties in obtaining the screen size using tcell.Screen.Size().

My expectation was to find a straightforward way to retrieve the screen width and height, either through tview or tcell, to properly configure the layout of my Go application. However, I'm currently uncertain about the correct approach and would appreciate guidance on how to achieve this.

1

There are 1 answers

2
Jadefox10200 On

Assuming you are using a linux based system:

package main

import (
    "github.com/gdamore/tcell"
    "os"
    "fmt"
)
    
func main() {
    
    p := GetPrinter()

    var st tcell.Style

    sty := st.Foreground(tcell.ColorRed).Dim(true)      
    p.Println("Hello", sty)
    a, b := p.Screen.Size()
    p.Println(fmt.Sprintf("%v %v", a ,b ), sty)
    
    p.Return()  

    return
}

type Printer struct {
    Screen  tcell.Screen
    Cursor  Coords
    DefaultStyle    tcell.Style
    Size
}

//keep track of our last known screen size
type Size struct {
    X   int
    Y   int
}

//x = vertical
//y = horizontal
type Coords struct {
    X   int
    Y   int
}

func (p *Printer) Clear() {
    p.Screen.Clear()
    p.Screen.Show() 
}

func (p *Printer) Return() {
    p.Cursor.X = 0
    p.Cursor.Y++
}

func (p *Printer) CurosorRight() {  
    p.Cursor.X++
    if p.Cursor.X >= p.Size.X {p.Return()}
}

func (p *Printer) CurosorLeft() {
    if p.Cursor.X < 1 {return}
    p.Cursor.X--
}

func (p *Printer) UpdateSize() {
    p.Size.X, p.Size.Y = p.Screen.Size()
}

func (p *Printer) Print(str string, sty tcell.Style) {

    //whenever we print, we should update our screen size in case the user has changed it.
    p.UpdateSize()

    for _, v := range []rune(str) {
        p.Screen.SetContent(p.Cursor.X, p.Cursor.Y, v, nil, sty)
        p.CurosorRight()
    }

    p.Screen.Show()

    return

}

func (p *Printer) Println(str string, sty tcell.Style) {

    //whenever we print, we should update our screen size in case the user has changed it.
    p.UpdateSize()

    for _, v := range []rune(str) {
        p.Screen.SetContent(p.Cursor.X, p.Cursor.Y, v, nil, sty)
        p.CurosorRight()        
    }
    p.Return()

    p.Screen.Show()

    return
}

func GetPrinter() Printer {

    s, err := tcell.NewScreen()
    if err != nil {fmt.Println(err.Error()); os.Exit(1) }

    s.Init()

    sty := tcell.StyleDefault.Foreground(tcell.ColorLightGrey).Background(tcell.ColorBlack)

    s.SetStyle(sty)

    c := Coords{
        X: 0,
        Y: 0,
    }

    var p = Printer{
        Screen: s,
        DefaultStyle: sty,
        Cursor: c,
    }

    return p

}

That does work and if you resize the window you will get different results. I tried this on a windows system and seems to also work but I can't resize my window to verify that.