pkg/selector/outputs/verboseView.go (68 lines of code) (raw):
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package outputs
import (
"fmt"
"math"
"strings"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
const (
// verbose view formatting.
outlinePadding = 8
// controls.
verboseControls = "Controls: ↑/↓ - up/down • esc - return to table • q - quit"
)
// verboseModel represents the current state of the verbose view.
type verboseModel struct {
// model for verbose output viewport
viewport viewport.Model
// the instance which the verbose output is focused on
focusedInstanceName ec2types.InstanceType
}
// styling for viewport.
var (
titleStyle = func() lipgloss.Style {
b := lipgloss.RoundedBorder()
b.Right = "├"
return lipgloss.NewStyle().BorderStyle(b).Padding(0, 1)
}()
infoStyle = func() lipgloss.Style {
b := lipgloss.RoundedBorder()
b.Left = "┤"
return titleStyle.BorderStyle(b)
}()
)
// initVerboseModel initializes and returns a new verboseModel based on the given
// instance type details.
func initVerboseModel() *verboseModel {
viewportModel := viewport.New(initialDimensionVal, initialDimensionVal)
viewportModel.MouseWheelEnabled = true
return &verboseModel{
viewport: viewportModel,
}
}
// resizeView will change the dimensions of the verbose viewport in order to accommodate
// the new window dimensions represented by the given tea.WindowSizeMsg.
func (m verboseModel) resizeView(msg tea.WindowSizeMsg) verboseModel {
// handle width changes
m.viewport.Width = msg.Width
// handle height changes
if outlinePadding >= msg.Height {
// height too short to fit viewport
m.viewport.Height = 0
} else {
newHeight := msg.Height - outlinePadding
m.viewport.Height = newHeight
}
return m
}
// update updates the state of the verboseModel.
func (m verboseModel) update(msg tea.Msg) (verboseModel, tea.Cmd) {
var cmd tea.Cmd
m.viewport, cmd = m.viewport.Update(msg)
return m, cmd
}
func (m verboseModel) view() string {
outputStr := strings.Builder{}
// format header for viewport
instanceName := titleStyle.Render(string(m.focusedInstanceName))
line := strings.Repeat("─", int(math.Max(0, float64(m.viewport.Width-lipgloss.Width(instanceName)))))
outputStr.WriteString(lipgloss.JoinHorizontal(lipgloss.Center, instanceName, line))
outputStr.WriteString("\n")
outputStr.WriteString(m.viewport.View())
outputStr.WriteString("\n")
// format footer for viewport
pagePercentage := infoStyle.Render(fmt.Sprintf("%3.f%%", m.viewport.ScrollPercent()*100))
line = strings.Repeat("─", int(math.Max(0, float64(m.viewport.Width-lipgloss.Width(pagePercentage)))))
outputStr.WriteString(lipgloss.JoinHorizontal(lipgloss.Center, line, pagePercentage))
outputStr.WriteString("\n")
// controls
outputStr.WriteString(controlsStyle.Render(verboseControls))
outputStr.WriteString("\n")
return outputStr.String()
}