ui calculator

This commit is contained in:
Ilia Denisov
2026-03-30 19:38:24 +02:00
committed by GitHub
parent 17f366cd6b
commit a7793f5416
37 changed files with 2046 additions and 270 deletions
+185 -10
View File
@@ -1,30 +1,82 @@
package numeric
import (
"galaxy/client/widget/validator"
"galaxy/util"
"strconv"
"strings"
"unicode/utf8"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver/mobile"
"fyne.io/fyne/v2/widget"
)
type numericalEntry struct {
type FloatEntry struct {
widget.Entry
origin float64
MaxValue float64
maxSize uint
validator fyne.StringValidator
Valid bool
}
func NewNumericalEntry() *numericalEntry {
entry := &numericalEntry{}
entry.ExtendBaseWidget(entry)
return entry
type IntEntry struct {
widget.Entry
origin uint
MaxValue uint
maxSize uint
validator fyne.StringValidator
Valid bool
}
func (e *numericalEntry) TypedRune(r rune) {
if (r >= '0' && r <= '9') || r == '.' || r == ',' {
e.Entry.TypedRune(r)
func NewFloatEntry(maxSize uint, onChanged func(string)) *FloatEntry {
e := &FloatEntry{maxSize: maxSize, validator: validator.FloatEntryValidator}
e.ExtendBaseWidget(e)
e.Entry.Scroll = fyne.ScrollNone
e.Entry.TextStyle = fyne.TextStyle{Monospace: true}
// e.Validator = validator.FloatEntryValidator
// e.AlwaysShowValidationError = true
e.Entry.ActionItem = nil
e.SetOrigin(0)
e.Validate()
e.Entry.OnChanged = onChanged
return e
}
func NewIntEntry(maxSize uint, onChanged func(string)) *IntEntry {
e := &IntEntry{maxSize: maxSize, validator: validator.IntEntryValidator}
e.ExtendBaseWidget(e)
e.Entry.Scroll = fyne.ScrollNone
e.Entry.TextStyle = fyne.TextStyle{Monospace: true}
// e.Validator = validator.IntEntryValidator
// e.AlwaysShowValidationError = true
e.Entry.ActionItem = nil
e.SetOrigin(0)
e.Validate()
e.Entry.OnChanged = onChanged
return e
}
func (e *FloatEntry) CreateRenderer() fyne.WidgetRenderer {
r := e.Entry.CreateRenderer()
return r
}
func (e *FloatEntry) TypedRune(r rune) {
if !((r >= '0' && r <= '9') || r == '.') {
return
}
if !lengthBelowLimit(e.Entry.Text, e.maxSize) && e.Entry.SelectedText() == "" {
return
}
if r == '.' && strings.Contains(e.Entry.Text, ".") {
return
}
e.Entry.TypedRune(r)
}
func (e *numericalEntry) TypedShortcut(shortcut fyne.Shortcut) {
func (e *FloatEntry) TypedShortcut(shortcut fyne.Shortcut) {
paste, ok := shortcut.(*fyne.ShortcutPaste)
if !ok {
e.Entry.TypedShortcut(shortcut)
@@ -37,6 +89,129 @@ func (e *numericalEntry) TypedShortcut(shortcut fyne.Shortcut) {
}
}
func (e *numericalEntry) Keyboard() mobile.KeyboardType {
func (e *FloatEntry) Keyboard() mobile.KeyboardType {
return mobile.NumberKeyboard
}
func (e *FloatEntry) SetOrigin(v float64) {
if v < 0 {
return
}
e.origin = v
e.Reset()
}
func (e *FloatEntry) Reset() {
e.SetValue(e.origin)
}
func (e *FloatEntry) Clear() {
onChanged := e.Entry.OnChanged
e.Entry.OnChanged = nil
e.Entry.SetText("")
e.Entry.OnChanged = onChanged
}
func (e *FloatEntry) SetValue(v float64) {
if v < 0 {
return
}
e.Entry.SetText(strconv.FormatFloat(util.Fixed3(v), 'f', -1, 64))
}
func (e *FloatEntry) Value() (float64, bool) {
if v, err := validator.ParseFloat(e.Entry.Text); err != nil {
return 0, false
} else {
return v, true
}
}
func (e *FloatEntry) Overriden() bool {
if v, ok := e.Value(); !ok {
return false
} else {
return util.Fixed3(v) != util.Fixed3(e.origin)
}
}
func (e *FloatEntry) Validate() {
if e.validator == nil {
return
}
err := e.validator(e.Entry.Text)
e.Valid = err == nil
}
func (e *IntEntry) TypedRune(r rune) {
if r >= '0' && r <= '9' {
if lengthBelowLimit(e.Entry.Text, e.maxSize) || e.Entry.SelectedText() != "" {
e.Entry.TypedRune(r)
}
}
}
func (e *IntEntry) TypedShortcut(shortcut fyne.Shortcut) {
paste, ok := shortcut.(*fyne.ShortcutPaste)
if !ok {
e.Entry.TypedShortcut(shortcut)
return
}
content := paste.Clipboard.Content()
if _, err := strconv.ParseInt(content, 10, 64); err == nil {
e.Entry.TypedShortcut(shortcut)
}
}
func (e *IntEntry) Keyboard() mobile.KeyboardType {
return mobile.NumberKeyboard
}
func (e *IntEntry) SetOrigin(v int) {
if v < 0 {
return
}
e.origin = uint(v)
e.Reset()
}
func (e *IntEntry) Reset() {
e.SetValue(int(e.origin))
}
func (e *IntEntry) SetValue(v int) {
if v < 0 {
return
}
e.Entry.SetText(strconv.Itoa(v))
}
func (e *IntEntry) Value() (int, bool) {
if v, err := validator.ParseInt(e.Entry.Text); err != nil {
return 0, false
} else {
return v, true
}
}
func (e *IntEntry) Overriden() bool {
if v, ok := e.Value(); !ok {
return false
} else {
return v != int(e.origin)
}
}
func (e *IntEntry) Validate() {
if e.validator == nil {
return
}
err := e.validator(e.Entry.Text)
e.Valid = err == nil
}
func lengthBelowLimit(s string, max uint) bool {
return utf8.RuneCountInString(s) < int(max)
}