process.go 5.15 KB
Newer Older
1
2
3
4
package tui

import (
	"fmt"
5
	"get-container/cmd/hytop/backend"
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	"maps"
	"strings"

	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

type ModelProcessInfo struct {
	Title            string
	DoubleMiddleLine string
	MiddleLine       string
	BottomLine       string
	NoProceseLine    string // 没有进程时显示的行
	Cache            map[int][]backend.DCUProcessInfo
	width            int
	style            lipgloss.Style
22
	modMsg           *ModelMsg
liming6's avatar
liming6 committed
23
	actionMsg        *ActionMsg
24
25
26
27
}

const (
	Processes             = " Processes:"
28
	ModelProcessInfoTitle = " DCU     PID     USER  DCU-MEM SDMA  %CPU  %MEM      TIME Docker               Command"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
	ModelProcessInfoNoPro = "  No running processes found"
)

func NewModelProcessInfo(width int) *ModelProcessInfo {
	result := ModelProcessInfo{width: width, Cache: make(map[int][]backend.DCUProcessInfo), style: lipgloss.NewStyle()}
	return &result
}

func (m *ModelProcessInfo) Init() tea.Cmd {
	sb := strings.Builder{}
	sb.WriteString(myBorder.Left)
	sb.WriteString(Processes)

	uah := fmt.Sprintf("%s@%s ", m.style.Foreground(lipgloss.Color("#edff2cff")).SetString(backend.User).String(),
		m.style.Foreground(lipgloss.Color("#a3ff2bff")).SetString(backend.HostName).String())
	space := strings.Repeat(" ", m.width-lipgloss.Width(Processes)-lipgloss.Width(uah)-2)

	sb.WriteString(space)
	sb.WriteString(uah)
	sb.WriteString(myBorder.Right)
	sb.WriteByte('\n')
	sb.WriteString(myBorder.Left)
	sb.WriteString(ModelProcessInfoTitle)
	sb.WriteString(strings.Repeat(" ", m.width-2-lipgloss.Width(ModelProcessInfoTitle)))
	sb.WriteString(myBorder.Right)
	sb.WriteByte('\n')
	m.Title = sb.String()
	m.DoubleMiddleLine = "╞" + strings.Repeat("═", m.width-2) + "╡\n"
	m.MiddleLine = myBorder.MiddleLeft + strings.Repeat("─", m.width-2) + myBorder.MiddleRight + "\n"
	m.BottomLine = myBorder.BottomLeft + strings.Repeat("═", m.width-2) + myBorder.BottomRight
	m.NoProceseLine = myBorder.Left + ModelProcessInfoNoPro + strings.Repeat(" ", m.width-2-lipgloss.Width(ModelProcessInfoNoPro)) + myBorder.Right + "\n"
	return nil
}

func (m *ModelProcessInfo) View() string {
	haveProcess := false
liming6's avatar
liming6 committed
65
66
67
68
	var heightLightPid int32 = 0
	if m.actionMsg != nil && m.actionMsg.PointPid != nil {
		heightLightPid = *m.actionMsg.PointPid
	}
69
70
	lines := make([]string, 0)
	sb := strings.Builder{}
liming6's avatar
liming6 committed
71
	sbInner := strings.Builder{}
72
73
74
75
76
77
78
79
	for index := range 64 {
		processes, have := m.Cache[index]
		if !have {
			continue
		}
		for _, process := range processes {
			haveProcess = true
			sb.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

			sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.DCU), 4, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.Info.Pid), 7, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(process.Info.User, 8, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(process.DCUMem, 8, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(fmt.Sprintf("%d", process.SDMA), 4, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.CPU), 5, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(fmt.Sprintf("%.1f", process.Info.Mem), 5, lipgloss.Right))
			sbInner.WriteByte(' ')
			sbInner.WriteString(FormatStr(process.Info.Time, 9, lipgloss.Right))
			sbInner.WriteByte(' ')
97
			if process.Info.ContInfo != nil {
liming6's avatar
liming6 committed
98
				sbInner.WriteString(FormatStr(process.Info.ContInfo.Name, 20, lipgloss.Left))
99
			} else {
liming6's avatar
liming6 committed
100
				sbInner.WriteString(FormatStr("  -  ", 20, lipgloss.Right))
101
			}
liming6's avatar
liming6 committed
102
103
			sbInner.WriteByte(' ')
			w := m.width - lipgloss.Width(sbInner.String()) - 3
104
105
			tw := lipgloss.Width(process.Info.Cmd)
			if w >= tw {
liming6's avatar
liming6 committed
106
107
				sbInner.WriteString(process.Info.Cmd)
				sbInner.WriteString(strings.Repeat(" ", w-tw))
108
			} else {
liming6's avatar
liming6 committed
109
110
				sbInner.WriteString(FormatStr(process.Info.Cmd, w-1, lipgloss.Left))
				sbInner.WriteString("..")
111
			}
liming6's avatar
liming6 committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
			sbInner.WriteByte(' ')
			selected := false
			if m.actionMsg != nil && m.actionMsg.SelectPids != nil {
				b, have := m.actionMsg.SelectPids[process.Info.Pid]
				if have && b {
					selected = true
				}
			}
			if heightLightPid == process.Info.Pid {
				if selected {
					sb.WriteString(HeightSelectedStyle.Render(sbInner.String()))
				} else {
					sb.WriteString(HeightLightStyle.Render(sbInner.String()))
				}
			} else {
				if selected {
					sb.WriteString(SelectedStyle.Render(sbInner.String()))
				} else {
					sb.WriteString(sbInner.String())
				}
			}

			sbInner.Reset()
135
136
137
138
139
140
141
			sb.WriteString(myBorder.Right)
			sb.WriteByte('\n')
			lines = append(lines, sb.String())
			sb.Reset()
		}
		lines = append(lines, m.MiddleLine)
	}
142

143
144
	sb.WriteString(m.Title)
	sb.WriteString(m.DoubleMiddleLine)
145
146
147
148
149
150
	if !haveProcess {
		sb.WriteString(m.NoProceseLine)
	} else {
		for _, v := range lines[:len(lines)-1] {
			sb.WriteString(v)
		}
151
152
153
154
155
156
157
158
159
160
	}
	sb.WriteString(m.BottomLine)
	return sb.String()
}

func (m *ModelProcessInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := inputMsg.(type) {
	case *ModelMsg:
		clear(m.Cache)
		maps.Copy(m.Cache, msg.DCUPidInfo)
161
162
		m.modMsg = msg
		return m, nil
liming6's avatar
liming6 committed
163
164
165
	case *ActionMsg:
		m.actionMsg = msg
		return m, nil
166
167
168
	}
	return m, nil
}