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() }