mirror of https://github.com/rivo/tview.git
Forms will attempt to keep focused form items within available area. Fixes #79
This commit is contained in:
parent
370ee01609
commit
258c9d1f8e
90
form.go
90
form.go
|
@ -259,6 +259,7 @@ func (f *Form) Draw(screen tcell.Screen) {
|
||||||
|
|
||||||
// Determine the dimensions.
|
// Determine the dimensions.
|
||||||
x, y, width, height := f.GetInnerRect()
|
x, y, width, height := f.GetInnerRect()
|
||||||
|
topLimit := y
|
||||||
bottomLimit := y + height
|
bottomLimit := y + height
|
||||||
rightLimit := x + width
|
rightLimit := x + width
|
||||||
startX := x
|
startX := x
|
||||||
|
@ -274,13 +275,10 @@ func (f *Form) Draw(screen tcell.Screen) {
|
||||||
}
|
}
|
||||||
maxLabelWidth++ // Add one space.
|
maxLabelWidth++ // Add one space.
|
||||||
|
|
||||||
// Set up and draw the input fields.
|
// Calculate positions of form items.
|
||||||
for _, item := range f.items {
|
positions := make([]struct{ x, y, width, height int }, len(f.items)+len(f.buttons))
|
||||||
// Stop if there is no more space.
|
var focusedPosition struct{ x, y, width, height int }
|
||||||
if y >= bottomLimit {
|
for index, item := range f.items {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the space needed.
|
// Calculate the space needed.
|
||||||
label := strings.TrimSpace(item.GetLabel())
|
label := strings.TrimSpace(item.GetLabel())
|
||||||
labelWidth := StringWidth(label)
|
labelWidth := StringWidth(label)
|
||||||
|
@ -315,13 +313,15 @@ func (f *Form) Draw(screen tcell.Screen) {
|
||||||
f.backgroundColor,
|
f.backgroundColor,
|
||||||
f.fieldTextColor,
|
f.fieldTextColor,
|
||||||
f.fieldBackgroundColor,
|
f.fieldBackgroundColor,
|
||||||
).SetRect(x, y, itemWidth, 1)
|
)
|
||||||
|
|
||||||
// Draw items with focus last (in case of overlaps).
|
// Save position.
|
||||||
|
positions[index].x = x
|
||||||
|
positions[index].y = y
|
||||||
|
positions[index].width = itemWidth
|
||||||
|
positions[index].height = 1
|
||||||
if item.GetFocusable().HasFocus() {
|
if item.GetFocusable().HasFocus() {
|
||||||
defer item.Draw(screen)
|
focusedPosition = positions[index]
|
||||||
} else {
|
|
||||||
item.Draw(screen)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advance to next item.
|
// Advance to next item.
|
||||||
|
@ -356,12 +356,8 @@ func (f *Form) Draw(screen tcell.Screen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw them.
|
// Calculate positions of buttons.
|
||||||
for index, button := range f.buttons {
|
for index, button := range f.buttons {
|
||||||
if y >= bottomLimit {
|
|
||||||
return // Stop here.
|
|
||||||
}
|
|
||||||
|
|
||||||
space := rightLimit - x
|
space := rightLimit - x
|
||||||
buttonWidth := buttonWidths[index]
|
buttonWidth := buttonWidths[index]
|
||||||
if f.horizontal {
|
if f.horizontal {
|
||||||
|
@ -381,12 +377,66 @@ func (f *Form) Draw(screen tcell.Screen) {
|
||||||
button.SetLabelColor(f.buttonTextColor).
|
button.SetLabelColor(f.buttonTextColor).
|
||||||
SetLabelColorActivated(f.buttonBackgroundColor).
|
SetLabelColorActivated(f.buttonBackgroundColor).
|
||||||
SetBackgroundColorActivated(f.buttonTextColor).
|
SetBackgroundColorActivated(f.buttonTextColor).
|
||||||
SetBackgroundColor(f.buttonBackgroundColor).
|
SetBackgroundColor(f.buttonBackgroundColor)
|
||||||
SetRect(x, y, buttonWidth, 1)
|
|
||||||
button.Draw(screen)
|
buttonIndex := index + len(f.items)
|
||||||
|
positions[buttonIndex].x = x
|
||||||
|
positions[buttonIndex].y = y
|
||||||
|
positions[buttonIndex].width = buttonWidth
|
||||||
|
positions[buttonIndex].height = 1
|
||||||
|
|
||||||
|
if button.HasFocus() {
|
||||||
|
focusedPosition = positions[buttonIndex]
|
||||||
|
}
|
||||||
|
|
||||||
x += buttonWidth + 1
|
x += buttonWidth + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine vertical offset based on the position of the focused item.
|
||||||
|
var offset int
|
||||||
|
if focusedPosition.y+focusedPosition.height > bottomLimit {
|
||||||
|
offset = focusedPosition.y + focusedPosition.height - bottomLimit
|
||||||
|
if focusedPosition.y-offset < topLimit {
|
||||||
|
offset = focusedPosition.y - topLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw items.
|
||||||
|
for index, item := range f.items {
|
||||||
|
// Set position.
|
||||||
|
y := positions[index].y - offset
|
||||||
|
height := positions[index].height
|
||||||
|
item.SetRect(positions[index].x, y, positions[index].width, height)
|
||||||
|
|
||||||
|
// Is this item visible?
|
||||||
|
if y+height <= topLimit || y >= bottomLimit {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw items with focus last (in case of overlaps).
|
||||||
|
if item.GetFocusable().HasFocus() {
|
||||||
|
defer item.Draw(screen)
|
||||||
|
} else {
|
||||||
|
item.Draw(screen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw buttons.
|
||||||
|
for index, button := range f.buttons {
|
||||||
|
// Set position.
|
||||||
|
buttonIndex := index + len(f.items)
|
||||||
|
y := positions[buttonIndex].y - offset
|
||||||
|
height := positions[buttonIndex].height
|
||||||
|
button.SetRect(positions[buttonIndex].x, y, positions[buttonIndex].width, height)
|
||||||
|
|
||||||
|
// Is this button visible?
|
||||||
|
if y+height <= topLimit || y >= bottomLimit {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw button.
|
||||||
|
button.Draw(screen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Focus is called by the application when the primitive receives focus.
|
// Focus is called by the application when the primitive receives focus.
|
||||||
|
|
Loading…
Reference in New Issue