forked from mbk-lab/rui_orig
Added PopupButtonType
This commit is contained in:
parent
904859ff6e
commit
ab421b4c32
|
@ -73,7 +73,7 @@ func getStartPage(buffer *strings.Builder, params AppParams, addScripts string)
|
|||
buffer.WriteString(addScripts)
|
||||
buffer.WriteString(`</script>
|
||||
</head>
|
||||
<body>
|
||||
<body id="body" onkeydown="keyDownEvent(this, event)">
|
||||
<div class="ruiRoot" id="ruiRootView"></div>
|
||||
<div class="ruiPopupLayer" id="ruiPopupLayer" style="visibility: hidden; isolation: isolate;"></div>
|
||||
<div class="ruiTooltipLayer" id="ruiTooltipLayer" style="visibility: hidden; opacity: 0;">
|
||||
|
|
|
@ -110,6 +110,26 @@ theme {
|
|||
ruiButton:active {
|
||||
background-color = @ruiButtonActiveColor
|
||||
},
|
||||
ruiDefaultButton {
|
||||
align = center,
|
||||
padding = "@ruiButtonVerticalPadding, @ruiButtonHorizontalPadding, @ruiButtonVerticalPadding, @ruiButtonHorizontalPadding",
|
||||
margin = @ruiButtonMargin,
|
||||
radius = @ruiButtonRadius,
|
||||
background-color = @ruiButtonColor,
|
||||
text-color = @ruiButtonTextColor,
|
||||
text-weight = bold,
|
||||
border = _{width = 1px, style = solid, color = @ruiButtonTextColor}
|
||||
},
|
||||
ruiDefaultButton:hover {
|
||||
text-color = @ruiTextColor,
|
||||
background-color = @ruiBackgroundColor,
|
||||
},
|
||||
ruiDefaultButton:focus {
|
||||
shadow = _{spread-radius = @ruiButtonHighlightDilation, blur = @ruiButtonHighlightBlur, color = @ruiHighlightColor },
|
||||
},
|
||||
ruiDefaultButton:active {
|
||||
background-color = @ruiButtonActiveColor
|
||||
},
|
||||
ruiCheckbox {
|
||||
radius = 2px,
|
||||
padding = 1px,
|
||||
|
|
120
keyEvents.go
120
keyEvents.go
|
@ -18,6 +18,117 @@ const (
|
|||
// The additional listener formats:
|
||||
// func(KeyEvent), func(View), and func().
|
||||
KeyUpEvent = "key-up-event"
|
||||
|
||||
// AltKey is the mask of the "alt" key
|
||||
AltKey = 1
|
||||
// CtrlKey is the mask of the "ctrl" key
|
||||
CtrlKey = 2
|
||||
// ShiftKey is the mask of the "shift" key
|
||||
ShiftKey = 4
|
||||
// MetaKey is the mask of the "meta" key
|
||||
MetaKey = 8
|
||||
|
||||
KeyA = "KeyA"
|
||||
KeyB = "KeyB"
|
||||
KeyC = "KeyC"
|
||||
KeyD = "KeyD"
|
||||
KeyE = "KeyE"
|
||||
KeyF = "KeyF"
|
||||
KeyG = "KeyG"
|
||||
KeyH = "KeyH"
|
||||
KeyI = "KeyI"
|
||||
KeyJ = "KeyJ"
|
||||
KeyK = "KeyK"
|
||||
KeyL = "KeyL"
|
||||
KeyM = "KeyM"
|
||||
KeyN = "KeyN"
|
||||
KeyO = "KeyO"
|
||||
KeyP = "KeyP"
|
||||
KeyQ = "KeyQ"
|
||||
KeyR = "KeyR"
|
||||
KeyS = "KeyS"
|
||||
KeyT = "KeyT"
|
||||
KeyU = "KeyU"
|
||||
KeyV = "KeyV"
|
||||
KeyW = "KeyW"
|
||||
KeyX = "KeyX"
|
||||
KeyY = "KeyY"
|
||||
KeyZ = "KeyZ"
|
||||
Digit0Key = "Digit0"
|
||||
Digit1Key = "Digit1"
|
||||
Digit2Key = "Digit2"
|
||||
Digit3Key = "Digit3"
|
||||
Digit4Key = "Digit4"
|
||||
Digit5Key = "Digit5"
|
||||
Digit6Key = "Digit6"
|
||||
Digit7Key = "Digit7"
|
||||
Digit8Key = "Digit8"
|
||||
Digit9Key = "Digit9"
|
||||
SpaceKey = "Space"
|
||||
MinusKey = "Minus"
|
||||
EqualKey = "Equal"
|
||||
IntlBackslashKey = "IntlBackslash"
|
||||
BracketLeftKey = "BracketLeft"
|
||||
BracketRightKey = "BracketRight"
|
||||
SemicolonKey = "Semicolon"
|
||||
CommaKey = "Comma"
|
||||
PeriodKey = "Period"
|
||||
QuoteKey = "Quote"
|
||||
BackquoteKey = "Backquote"
|
||||
SlashKey = "Slash"
|
||||
EscapeKey = "Escape"
|
||||
EnterKey = "Enter"
|
||||
TabKey = "Tab"
|
||||
CapsLockKey = "CapsLock"
|
||||
DeleteKey = "Delete"
|
||||
HelpKey = "Help"
|
||||
BackspaceKey = "Backspace"
|
||||
ArrowLeftKey = "ArrowLeft"
|
||||
ArrowRightKey = "ArrowRight"
|
||||
ArrowUpKey = "ArrowUp"
|
||||
ArrowDownKey = "ArrowDown"
|
||||
HomeKey = "Home"
|
||||
EndKey = "End"
|
||||
PageUpKey = "PageUp"
|
||||
PageDownKey = "PageDown"
|
||||
F1Key = "F1"
|
||||
F2Key = "F2"
|
||||
F3Key = "F3"
|
||||
F4Key = "F4"
|
||||
F5Key = "F5"
|
||||
F6Key = "F6"
|
||||
F7Key = "F7"
|
||||
F8Key = "F8"
|
||||
F9Key = "F9"
|
||||
F10Key = "F10"
|
||||
F11Key = "F11"
|
||||
F12Key = "F12"
|
||||
F13Key = "F13"
|
||||
NumLockKey = "NumLock"
|
||||
NumpadKey0 = "Numpad0"
|
||||
NumpadKey1 = "Numpad1"
|
||||
NumpadKey2 = "Numpad2"
|
||||
NumpadKey3 = "Numpad3"
|
||||
NumpadKey4 = "Numpad4"
|
||||
NumpadKey5 = "Numpad5"
|
||||
NumpadKey6 = "Numpad6"
|
||||
NumpadKey7 = "Numpad7"
|
||||
NumpadKey8 = "Numpad8"
|
||||
NumpadKey9 = "Numpad9"
|
||||
NumpadDecimalKey = "NumpadDecimal"
|
||||
NumpadEnterKey = "NumpadEnter"
|
||||
NumpadAddKey = "NumpadAdd"
|
||||
NumpadSubtractKey = "NumpadSubtract"
|
||||
NumpadMultiplyKey = "NumpadMultiply"
|
||||
NumpadDivideKey = "NumpadDivide"
|
||||
ShiftLeftKey = "ShiftLeft"
|
||||
ShiftRightKey = "ShiftRight"
|
||||
ControlLeftKey = "ControlLeft"
|
||||
ControlRightKey = "ControlRight"
|
||||
AltLeftKey = "AltLeft"
|
||||
AltRightKey = "AltRight"
|
||||
MetaLeftKey = "MetaLeft"
|
||||
MetaRightKey = "MetaRight"
|
||||
)
|
||||
|
||||
type KeyEvent struct {
|
||||
|
@ -372,12 +483,6 @@ func valueToEventWithOldListeners[V View, E any](value any) ([]func(V, E, E), bo
|
|||
return nil, false
|
||||
}
|
||||
|
||||
/*
|
||||
var keyEvents = map[string]struct{ jsEvent, jsFunc string }{
|
||||
KeyDownEvent: {jsEvent: "onkeydown", jsFunc: "keyDownEvent"},
|
||||
KeyUpEvent: {jsEvent: "onkeyup", jsFunc: "keyUpEvent"},
|
||||
}
|
||||
*/
|
||||
func (view *viewData) setKeyListener(tag string, value any) bool {
|
||||
listeners, ok := valueToEventListeners[View, KeyEvent](value)
|
||||
if !ok {
|
||||
|
@ -390,11 +495,13 @@ func (view *viewData) setKeyListener(tag string, value any) bool {
|
|||
} else {
|
||||
switch tag {
|
||||
case KeyDownEvent:
|
||||
view.properties[tag] = listeners
|
||||
if view.created {
|
||||
view.session.updateProperty(view.htmlID(), "onkeydown", "keyDownEvent(this, event)")
|
||||
}
|
||||
|
||||
case KeyUpEvent:
|
||||
view.properties[tag] = listeners
|
||||
if view.created {
|
||||
view.session.updateProperty(view.htmlID(), "onkeyup", "keyUpEvent(this, event)")
|
||||
}
|
||||
|
@ -435,6 +542,7 @@ func getEventWithOldListeners[V View, E any](view View, subviewID []string, tag
|
|||
}
|
||||
return []func(V, E, E){}
|
||||
}
|
||||
|
||||
func getEventListeners[V View, E any](view View, subviewID []string, tag string) []func(V, E) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
|
|
98
popup.go
98
popup.go
|
@ -78,11 +78,21 @@ const (
|
|||
// LeftArrow is value of the popup "arrow" property:
|
||||
// Arrow on the left side of the pop-up window
|
||||
LeftArrow = 4
|
||||
|
||||
// NormalButton is the constant of the popup button type: the normal button
|
||||
NormalButton PopupButtonType = 0
|
||||
// DefaultButton is the constant of the popup button type: button that fires when the "Enter" key is pressed
|
||||
DefaultButton PopupButtonType = 1
|
||||
// CancelButton is the constant of the popup button type: button that fires when the "Escape" key is pressed
|
||||
CancelButton PopupButtonType = 2
|
||||
)
|
||||
|
||||
type PopupButtonType int
|
||||
|
||||
// PopupButton describes a button that will be placed at the bottom of the window.
|
||||
type PopupButton struct {
|
||||
Title string
|
||||
Type PopupButtonType
|
||||
OnClick func(Popup)
|
||||
}
|
||||
|
||||
|
@ -95,11 +105,14 @@ type Popup interface {
|
|||
onDismiss()
|
||||
html(buffer *strings.Builder)
|
||||
viewByHTMLID(id string) View
|
||||
keyEvent(event KeyEvent) bool
|
||||
}
|
||||
|
||||
type popupData struct {
|
||||
layerView View
|
||||
view View
|
||||
buttons []PopupButton
|
||||
cancelable bool
|
||||
dismissListener []func(Popup)
|
||||
}
|
||||
|
||||
|
@ -273,6 +286,7 @@ func (arrow *popupArrow) createView(popupView View) View {
|
|||
|
||||
func (popup *popupData) init(view View, popupParams Params) {
|
||||
popup.view = view
|
||||
popup.cancelable = false
|
||||
session := view.Session()
|
||||
|
||||
columnCount := 3
|
||||
|
@ -392,13 +406,15 @@ func (popup *popupData) init(view View, popupParams Params) {
|
|||
TextSize: Px(20),
|
||||
Content: "✕",
|
||||
NotTranslate: true,
|
||||
ClickEvent: func(View) {
|
||||
popup.Dismiss()
|
||||
},
|
||||
ClickEvent: popup.cancel,
|
||||
})
|
||||
popup.cancelable = true
|
||||
|
||||
case OutsideClose:
|
||||
outsideClose, _ = boolProperty(popupParams, OutsideClose, session)
|
||||
if outsideClose {
|
||||
popup.cancelable = true
|
||||
}
|
||||
|
||||
case Buttons:
|
||||
switch value := value.(type) {
|
||||
|
@ -494,6 +510,7 @@ func (popup *popupData) init(view View, popupParams Params) {
|
|||
view.Set(Row, viewRow)
|
||||
popupView.Append(view)
|
||||
|
||||
popup.buttons = buttons
|
||||
if buttonCount := len(buttons); buttonCount > 0 {
|
||||
buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign)
|
||||
popupCellHeight = append(popupCellHeight, AutoSize())
|
||||
|
@ -511,21 +528,31 @@ func (popup *popupData) init(view View, popupParams Params) {
|
|||
buttonsPanel.Set(Margin, gap)
|
||||
}
|
||||
|
||||
createButton := func(n int, button PopupButton) Button {
|
||||
return NewButton(session, Params{
|
||||
Column: n,
|
||||
Content: button.Title,
|
||||
ClickEvent: func() {
|
||||
if button.OnClick != nil {
|
||||
button.OnClick(popup)
|
||||
} else {
|
||||
popup.Dismiss()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
for i, button := range buttons {
|
||||
buttonsPanel.Append(createButton(i, button))
|
||||
title := button.Title
|
||||
if title == "" && button.Type == CancelButton {
|
||||
title = "Cancel"
|
||||
}
|
||||
|
||||
buttonView := NewButton(session, Params{
|
||||
Column: i,
|
||||
Content: title,
|
||||
})
|
||||
|
||||
if button.OnClick != nil {
|
||||
fn := button.OnClick
|
||||
buttonView.Set(ClickEvent, func() {
|
||||
fn(popup)
|
||||
})
|
||||
} else if button.Type == CancelButton {
|
||||
buttonView.Set(ClickEvent, popup.cancel)
|
||||
}
|
||||
|
||||
if button.Type == DefaultButton {
|
||||
buttonView.Set(Style, "ruiDefaultButton")
|
||||
}
|
||||
|
||||
buttonsPanel.Append(buttonView)
|
||||
}
|
||||
|
||||
popupView.Append(NewGridLayout(session, Params{
|
||||
|
@ -544,11 +571,8 @@ func (popup *popupData) init(view View, popupParams Params) {
|
|||
}
|
||||
|
||||
popup.layerView = NewGridLayout(session, layerParams)
|
||||
|
||||
if outsideClose {
|
||||
popup.layerView.Set(ClickEvent, func(View) {
|
||||
popup.Dismiss()
|
||||
})
|
||||
popup.layerView.Set(ClickEvent, popup.cancel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,12 +584,21 @@ func (popup *popupData) Session() Session {
|
|||
return popup.view.Session()
|
||||
}
|
||||
|
||||
func (popup *popupData) cancel() {
|
||||
for _, button := range popup.buttons {
|
||||
if button.Type == CancelButton && button.OnClick != nil {
|
||||
button.OnClick(popup)
|
||||
return
|
||||
}
|
||||
}
|
||||
popup.Dismiss()
|
||||
}
|
||||
|
||||
func (popup *popupData) Dismiss() {
|
||||
popup.Session().popupManager().dismissPopup(popup)
|
||||
for _, listener := range popup.dismissListener {
|
||||
listener(popup)
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (popup *popupData) Show() {
|
||||
|
@ -587,6 +620,27 @@ func (popup *popupData) onDismiss() {
|
|||
}
|
||||
}
|
||||
|
||||
func (popup *popupData) keyEvent(event KeyEvent) bool {
|
||||
if !event.AltKey && !event.CtrlKey && !event.ShiftKey && !event.MetaKey {
|
||||
switch strings.ToLower(event.Code) {
|
||||
case "enter":
|
||||
for _, button := range popup.buttons {
|
||||
if button.Type == DefaultButton && button.OnClick != nil {
|
||||
button.OnClick(popup)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
case "escape":
|
||||
if popup.cancelable {
|
||||
popup.Dismiss()
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NewPopup creates a new Popup
|
||||
func NewPopup(view View, param Params) Popup {
|
||||
if view == nil {
|
||||
|
|
17
session.go
17
session.go
|
@ -649,15 +649,32 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
|||
|
||||
default:
|
||||
if viewID, ok := data.PropertyValue("id"); ok {
|
||||
if viewID != "body" {
|
||||
if view := session.viewByHTMLID(viewID); view != nil {
|
||||
view.handleCommand(view, command, data)
|
||||
}
|
||||
}
|
||||
if command == KeyDownEvent {
|
||||
var event KeyEvent
|
||||
event.init(data)
|
||||
session.hotKey(event)
|
||||
}
|
||||
} else {
|
||||
ErrorLog(`"id" property not found. Event: ` + command)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) hotKey(event KeyEvent) {
|
||||
popups := session.popupManager().popups
|
||||
if count := len(popups); count > 0 {
|
||||
if popups[count-1].keyEvent(event) {
|
||||
return
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
func (session *sessionData) SetTitle(title string) {
|
||||
title, _ = session.GetString(title)
|
||||
session.callFunc("setTitle", title)
|
||||
|
|
Loading…
Reference in New Issue