173 lines
4.2 KiB
Go
173 lines
4.2 KiB
Go
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
|
|
}
|