From fd424f56c1e67b84643361dcc1a4716f62a96d7d Mon Sep 17 00:00:00 2001 From: Alexei Anoshenko <2277098+anoshenko@users.noreply.github.com> Date: Mon, 25 May 2026 15:31:45 +0300 Subject: [PATCH] Added SetHotKey method to Popup interface --- CHANGELOG.md | 2 +- LICENSE | 2 +- popup.go | 76 +++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 993dc8d..4e38bfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * Added GoogleFonts field to AppParams * Added functions: GetWhiteSpace, GetWordBreak, ScrollIntoViewIfNeeded * Added PopupShowAnimation and SetPopupShowAnimation methods to Session interface -* Added DismissWithoutAnimation methos to Popup interface +* Added DismissWithoutAnimation add SetHotKey methods to Popup interface * Added ToBoundsProperty method to Bounds struct # v0.20.0 diff --git a/LICENSE b/LICENSE index 86aba24..2e75c0a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021-2022 Alexei Anoshenko +Copyright (c) 2021-2026 Alexei Anoshenko Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/popup.go b/popup.go index 570a345..668e9ca 100644 --- a/popup.go +++ b/popup.go @@ -299,6 +299,10 @@ type Popup interface { // DismissWithoutAnimation closes a popup without animation DismissWithoutAnimation() + // SetHotKey sets the function that will be called when the given hotkey is pressed. + // Invoke SetHotKey(..., ..., nil) for remove hotkey function. + SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Popup)) + onDismiss() html(buffer *strings.Builder) viewByHTMLID(id string) View @@ -332,6 +336,7 @@ type popupData struct { popupView GridLayout contentContainer ColumnLayout contentView View + hotkeys map[string]func(Popup) } type popupManager struct { @@ -935,6 +940,16 @@ func (popup *popupData) cancel() { popup.Dismiss() } +func (popup *popupData) SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Popup)) { + hotkey := hotkeyCode(keyCode, controlKeys) + if fn == nil { + delete(popup.hotkeys, hotkey) + } else { + popup.hotkeys[hotkey] = fn + } + +} + func (popup *popupData) Dismiss() { popup.Session().popupManager().dismissPopup(popup, true) } @@ -1032,7 +1047,22 @@ func (popup *popupData) onDismiss() { } func (popup *popupData) keyEvent(event KeyEvent) bool { - if !event.AltKey && !event.CtrlKey && !event.ShiftKey && !event.MetaKey { + + var controlKeys ControlKeyMask = 0 + if event.AltKey { + controlKeys |= AltKey + } + if event.CtrlKey { + controlKeys |= CtrlKey + } + if event.MetaKey { + controlKeys |= MetaKey + } + if event.ShiftKey { + controlKeys |= ShiftKey + } + + if controlKeys == 0 { switch event.Code { case EnterKey: for _, button := range popup.buttons() { @@ -1043,28 +1073,36 @@ func (popup *popupData) keyEvent(event KeyEvent) bool { } case EscapeKey: - cancelable := func() bool { - if closeButton, _ := boolProperty(popup, CloseButton, popup.session); closeButton { - return true - } - if outsideClose, _ := boolProperty(popup, OutsideClose, popup.session); outsideClose { - return true - } - - for _, button := range popup.buttons() { - if button.buttonType == CancelButton { - return true - } - } - return false - } - - if cancelable() { + if popup.isCancelable() { popup.cancel() return true } } } + + key := hotkeyCode(KeyCode(event.Code), controlKeys) + if fn, ok := popup.hotkeys[key]; ok && fn != nil { + fn(popup) + return true + } + + return false +} + +func (popup *popupData) isCancelable() bool { + if closeButton, _ := boolProperty(popup, CloseButton, popup.session); closeButton { + return true + } + + if outsideClose, _ := boolProperty(popup, OutsideClose, popup.session); outsideClose { + return true + } + + for _, button := range popup.buttons() { + if button.buttonType == CancelButton { + return true + } + } return false } @@ -1327,6 +1365,7 @@ func NewPopup(view View, param Params) Popup { popup.session = view.Session() popup.contentView = view popup.properties = map[PropertyName]any{} + popup.hotkeys = map[string]func(Popup){} defaultTransform, defaultOpacity, duration, timing := popup.session.PopupShowAnimation() @@ -1390,6 +1429,7 @@ func CreatePopupFromObject(session Session, object DataObject, binding any) Popu popup := new(popupData) popup.session = session popup.properties = map[PropertyName]any{} + popup.hotkeys = map[string]func(Popup){} for key, value := range object.ToParams() { popup.Set(key, value)