mirror of https://github.com/rivo/tview.git
Finished Image implementation.
This commit is contained in:
parent
10a525d206
commit
c5b1a7d818
|
@ -9,12 +9,13 @@ This Go package provides commonly used components for terminal based user interf
|
||||||
|
|
||||||
Among these components are:
|
Among these components are:
|
||||||
|
|
||||||
- __Input forms__ (include __input/password fields__, __drop-down selections__, __checkboxes__, and __buttons__)
|
- __Input forms__ (including __text input__, __selections__, __checkboxes__, and __buttons__)
|
||||||
- Navigable multi-color __text views__
|
- Navigable multi-color __text views__
|
||||||
- Editable multi-line __text areas__
|
- Editable multi-line __text areas__
|
||||||
- Sophisticated navigable __table views__
|
- Sophisticated navigable __table views__
|
||||||
- Flexible __tree views__
|
- Flexible __tree views__
|
||||||
- Selectable __lists__
|
- Selectable __lists__
|
||||||
|
- __Images__
|
||||||
- __Grid__, __Flexbox__ and __page layouts__
|
- __Grid__, __Flexbox__ and __page layouts__
|
||||||
- Modal __message windows__
|
- Modal __message windows__
|
||||||
- An __application__ wrapper
|
- An __application__ wrapper
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
![Screenshot](screenshot.jpg)
|
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
File diff suppressed because one or more lines are too long
19
form.go
19
form.go
|
@ -1,6 +1,8 @@
|
||||||
package tview
|
package tview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,7 +112,7 @@ func NewForm() *Form {
|
||||||
fieldTextColor: Styles.PrimaryTextColor,
|
fieldTextColor: Styles.PrimaryTextColor,
|
||||||
buttonStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor),
|
buttonStyle: tcell.StyleDefault.Background(Styles.ContrastBackgroundColor).Foreground(Styles.PrimaryTextColor),
|
||||||
buttonActivatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.ContrastBackgroundColor),
|
buttonActivatedStyle: tcell.StyleDefault.Background(Styles.PrimaryTextColor).Foreground(Styles.ContrastBackgroundColor),
|
||||||
lastFinishedKey: -1,
|
lastFinishedKey: tcell.KeyTab, // To skip over inactive elements at the beginning of the form.
|
||||||
}
|
}
|
||||||
|
|
||||||
return f
|
return f
|
||||||
|
@ -307,6 +309,21 @@ func (f *Form) AddCheckbox(label string, checked bool, changed func(checked bool
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddImage adds an image to the form. It has a label and the image will fit in
|
||||||
|
// the specified width and height (its aspect ratio is preserved). See
|
||||||
|
// [Image.SetColors] for a description of the "colors" parameter. Images are not
|
||||||
|
// interactive and are skipped over in a form. The "width" value may be 0
|
||||||
|
// (adjust dynamically) but "height" should generally be a positive value.
|
||||||
|
func (f *Form) AddImage(label string, image image.Image, width, height, colors int) *Form {
|
||||||
|
f.items = append(f.items, NewImage().
|
||||||
|
SetLabel(label).
|
||||||
|
SetImage(image).
|
||||||
|
SetSize(height, width).
|
||||||
|
SetAlign(AlignTop, AlignLeft).
|
||||||
|
SetColors(colors))
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
// AddButton adds a new button to the form. The "selected" function is called
|
// AddButton adds a new button to the form. The "selected" function is called
|
||||||
// when the user selects this button. It may be nil.
|
// when the user selects this button. It may be nil.
|
||||||
func (f *Form) AddButton(label string, selected func()) *Form {
|
func (f *Form) AddButton(label string, selected func()) *Form {
|
||||||
|
|
67
image.go
67
image.go
|
@ -79,9 +79,6 @@ type Image struct {
|
||||||
// "ImageDithering".
|
// "ImageDithering".
|
||||||
dithering int
|
dithering int
|
||||||
|
|
||||||
// The background color to use (RGB) for transparent pixels.
|
|
||||||
backgroundColor [3]int8
|
|
||||||
|
|
||||||
// The width of a terminal's cell divided by its height.
|
// The width of a terminal's cell divided by its height.
|
||||||
aspectRatio float64
|
aspectRatio float64
|
||||||
|
|
||||||
|
@ -104,6 +101,10 @@ type Image struct {
|
||||||
// The actual image (in cells) when it was drawn the last time. The size of
|
// The actual image (in cells) when it was drawn the last time. The size of
|
||||||
// this slice is lastWidth * lastHeight, indexed by y*lastWidth + x.
|
// this slice is lastWidth * lastHeight, indexed by y*lastWidth + x.
|
||||||
pixels []pixel
|
pixels []pixel
|
||||||
|
|
||||||
|
// A callback function set by the Form class and called when the user leaves
|
||||||
|
// this form item.
|
||||||
|
finished func(tcell.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImage returns a new image widget with an empty image (use [SetImage] to
|
// NewImage returns a new image widget with an empty image (use [SetImage] to
|
||||||
|
@ -173,21 +174,13 @@ func (i *Image) GetColors() int {
|
||||||
|
|
||||||
// SetDithering sets the dithering algorithm to use, one of the constants
|
// SetDithering sets the dithering algorithm to use, one of the constants
|
||||||
// starting with "Dithering", for example [DitheringFloydSteinberg] (the
|
// starting with "Dithering", for example [DitheringFloydSteinberg] (the
|
||||||
// default).
|
// default). Dithering is not applied when rendering in true-color.
|
||||||
func (i *Image) SetDithering(dithering int) *Image {
|
func (i *Image) SetDithering(dithering int) *Image {
|
||||||
i.dithering = dithering
|
i.dithering = dithering
|
||||||
i.lastWidth, i.lastHeight = 0, 0
|
i.lastWidth, i.lastHeight = 0, 0
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBackgroundColor sets the background color to use (RGB) for transparent
|
|
||||||
// pixels in the original image. The default is black (0, 0, 0).
|
|
||||||
func (i *Image) SetBackgroundColor(r, g, b int8) *Image {
|
|
||||||
i.backgroundColor = [3]int8{r, g, b}
|
|
||||||
i.lastWidth, i.lastHeight = 0, 0
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAspectRatio sets the width of a terminal's cell divided by its height.
|
// SetAspectRatio sets the width of a terminal's cell divided by its height.
|
||||||
// You may change the default of 0.5 if your terminal uses a different aspect
|
// You may change the default of 0.5 if your terminal uses a different aspect
|
||||||
// ratio. This is used to calculate the size of the image if one of the sizes
|
// ratio. This is used to calculate the size of the image if one of the sizes
|
||||||
|
@ -229,6 +222,40 @@ func (i *Image) SetLabelWidth(width int) *Image {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFieldWidth returns this primitive's field width. This is the image's width
|
||||||
|
// or, if the width is 0 or less, the proportional width of the image based on
|
||||||
|
// its height as returned by [Image.GetFieldHeight]. If there is no image, 0 is
|
||||||
|
// returned.
|
||||||
|
func (i *Image) GetFieldWidth() int {
|
||||||
|
if i.width <= 0 {
|
||||||
|
if i.image == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
bounds := i.image.Bounds()
|
||||||
|
height := i.GetFieldHeight()
|
||||||
|
return bounds.Dx() * height / bounds.Dy()
|
||||||
|
}
|
||||||
|
return i.width
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFieldHeight returns this primitive's field height. This is the image's
|
||||||
|
// height or 8 if the height is 0 or less.
|
||||||
|
func (i *Image) GetFieldHeight() int {
|
||||||
|
if i.height <= 0 {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
|
return i.height
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFormAttributes sets attributes shared by all form items.
|
||||||
|
func (i *Image) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
||||||
|
i.labelWidth = labelWidth
|
||||||
|
i.backgroundColor = bgColor
|
||||||
|
i.SetLabelStyle(tcell.StyleDefault.Foreground(labelColor).Background(bgColor))
|
||||||
|
i.lastWidth, i.lastHeight = 0, 0
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
// SetLabelStyle sets the style of the label.
|
// SetLabelStyle sets the style of the label.
|
||||||
func (i *Image) SetLabelStyle(style tcell.Style) *Image {
|
func (i *Image) SetLabelStyle(style tcell.Style) *Image {
|
||||||
i.labelStyle = style
|
i.labelStyle = style
|
||||||
|
@ -240,6 +267,22 @@ func (i *Image) GetLabelStyle() tcell.Style {
|
||||||
return i.labelStyle
|
return i.labelStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
|
||||||
|
func (i *Image) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
||||||
|
i.finished = handler
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focus is called when this primitive receives focus.
|
||||||
|
func (i *Image) Focus(delegate func(p Primitive)) {
|
||||||
|
// If we're part of a form, there's nothing the user can do here so we're
|
||||||
|
// finished.
|
||||||
|
if i.finished != nil {
|
||||||
|
i.finished(-1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// render re-populates the [Image.pixels] slice besed on the current settings,
|
// render re-populates the [Image.pixels] slice besed on the current settings,
|
||||||
// if [Image.lastWidth] and [Image.lastHeight] don't match the current image's
|
// if [Image.lastWidth] and [Image.lastHeight] don't match the current image's
|
||||||
// size. It also sets the new image size in these two variables.
|
// size. It also sets the new image size in these two variables.
|
||||||
|
|
2
list.go
2
list.go
|
@ -76,7 +76,7 @@ type List struct {
|
||||||
done func()
|
done func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewList returns a new form.
|
// NewList returns a new list.
|
||||||
func NewList() *List {
|
func NewList() *List {
|
||||||
return &List{
|
return &List{
|
||||||
Box: NewBox(),
|
Box: NewBox(),
|
||||||
|
|
Loading…
Reference in New Issue