Files
bj_power/bj_power_wms_client/internal/ui/numkeypad.go
T

173 lines
4.2 KiB
Go
Raw Normal View History

package ui
import (
"strconv"
"strings"
"github.com/ying32/govcl/vcl"
"github.com/ying32/govcl/vcl/types"
)
const (
keyBtnSize int32 = 96
keyFontSize int32 = 24
dispFontSize int32 = 32
gap int32 = 10
margin int32 = 16
)
// showNumKeyPad 弹出触屏数字键盘,返回(输入字符串, 是否确认)。
// initial 为初始显示值;owner 通常为主窗体。
// 布局:顶部显示框 + 左侧 4×3 数字网格 + 右侧纵向整列(退格/清空) + 底部整行(取消/确认)。
func showNumKeyPad(owner vcl.IComponent, initial string) (string, bool) {
form := vcl.NewForm(owner)
form.SetCaption("输入数值")
form.SetPosition(types.PoScreenCenter)
form.SetBorderStyle(types.BsDialog)
form.SetOnClose(func(sender vcl.IObject, action *types.TCloseAction) {
*action = types.CaFree
})
// 显示框高度随字号。
dispH := dispFontSize + 24
// 左侧 4 列 x 3 行数字网格。
gridCols := int32(4)
gridRows := int32(3)
gridW := gridCols*keyBtnSize + (gridCols-1)*gap
gridH := gridRows*keyBtnSize + (gridRows-1)*gap
// 右侧功能键列宽与数字键同宽,纵向整列高度与网格同高,两个按钮均分。
sideW := keyBtnSize
sideH := gridH
// 底部整行按钮高度与数字键同高。
bottomH := keyBtnSize
formW := margin*2 + gridW + gap + sideW
formH := margin + dispH + gap + gridH + gap + bottomH + margin
form.SetWidth(formW)
form.SetHeight(formH)
// 显示框:横跨整个宽度。
display := vcl.NewEdit(form)
display.SetParent(form)
display.SetLeft(margin)
display.SetTop(margin)
display.SetWidth(formW - margin*2)
display.SetHeight(dispH)
display.Font().SetSize(dispFontSize)
display.SetText(initial)
display.SetReadOnly(true)
display.SetAlignment(types.TaRightJustify)
var (
result string
confirmed bool
)
curText := func() string {
var s string
display.GetTextBuf(&s, 64)
return s
}
setText := func(s string) { display.SetText(s) }
makeBtn := func(caption string, l, t, w, h int32) *vcl.TButton {
b := vcl.NewButton(form)
b.SetParent(form)
b.SetLeft(l)
b.SetTop(t)
b.SetWidth(w)
b.SetHeight(h)
b.SetCaption(caption)
b.Font().SetSize(keyFontSize)
return b
}
gridTop := margin + dispH + gap
gridLeft := margin
// 数字键 4 列 x 3 行:
// [7][8][9][.]
// [4][5][6][0]
// [1][2][3][+/-]
layout := []string{"7", "8", "9", ".", "4", "5", "6", "0", "1", "2", "3", "+/-"}
for i, cap := range layout {
col := int32(i % int(gridCols))
row := int32(i / int(gridCols))
btn := makeBtn(cap,
gridLeft+col*(keyBtnSize+gap),
gridTop+row*(keyBtnSize+gap),
keyBtnSize, keyBtnSize)
btn.SetOnClick(func(sender vcl.IObject) {
c := vcl.AsButton(sender).Caption()
s := curText()
switch c {
case "+/-":
if strings.HasPrefix(s, "-") {
s = s[1:]
} else if s != "" {
s = "-" + s
}
case ".":
if !strings.Contains(s, ".") {
if s == "" || s == "-" {
s += "0."
} else {
s += "."
}
}
default:
s += c
}
setText(s)
})
}
// 右侧纵向整列:退格 / 清空,均分高度。
sideLeft := margin + gridW + gap
sideBtnH := (sideH - gap) / 2 // 两按钮间留一个 gap
sideBtns := []struct {
cap string
fn func()
}{
{"退格", func() {
s := curText()
if len(s) > 0 {
s = s[:len(s)-1]
}
setText(s)
}},
{"清空", func() { setText("") }},
}
for i, b := range sideBtns {
btn := makeBtn(b.cap, sideLeft, gridTop+int32(i)*(sideBtnH+gap), sideW, sideBtnH)
btn.SetOnClick(func(sender vcl.IObject) { b.fn() })
}
// 底部整行:取消 / 确认,均分宽度。
bottomTop := gridTop + gridH + gap
bottomW := (formW - margin*2 - gap) / 2 // 两按钮间留一个 gap
cancel := makeBtn("取消", margin, bottomTop, bottomW, bottomH)
cancel.SetOnClick(func(sender vcl.IObject) {
confirmed = false
form.Close()
})
ok := makeBtn("确认", margin+bottomW+gap, bottomTop, bottomW, bottomH)
ok.Font().SetSize(keyFontSize + 4)
ok.SetOnClick(func(sender vcl.IObject) {
s := curText()
if s == "" || s == "-" {
confirmed = false
} else if _, err := strconv.ParseFloat(s, 64); err != nil {
vcl.ShowMessage("请输入合法数值")
return
} else {
result = s
confirmed = true
}
form.Close()
})
form.ShowModal()
return result, confirmed
}