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(addScripts)
|
||||||
buffer.WriteString(`</script>
|
buffer.WriteString(`</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="body" onkeydown="keyDownEvent(this, event)">
|
||||||
<div class="ruiRoot" id="ruiRootView"></div>
|
<div class="ruiRoot" id="ruiRootView"></div>
|
||||||
<div class="ruiPopupLayer" id="ruiPopupLayer" style="visibility: hidden; isolation: isolate;"></div>
|
<div class="ruiPopupLayer" id="ruiPopupLayer" style="visibility: hidden; isolation: isolate;"></div>
|
||||||
<div class="ruiTooltipLayer" id="ruiTooltipLayer" style="visibility: hidden; opacity: 0;">
|
<div class="ruiTooltipLayer" id="ruiTooltipLayer" style="visibility: hidden; opacity: 0;">
|
||||||
|
|
|
@ -110,6 +110,26 @@ theme {
|
||||||
ruiButton:active {
|
ruiButton:active {
|
||||||
background-color = @ruiButtonActiveColor
|
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 {
|
ruiCheckbox {
|
||||||
radius = 2px,
|
radius = 2px,
|
||||||
padding = 1px,
|
padding = 1px,
|
||||||
|
|
120
keyEvents.go
120
keyEvents.go
|
@ -18,6 +18,117 @@ const (
|
||||||
// The additional listener formats:
|
// The additional listener formats:
|
||||||
// func(KeyEvent), func(View), and func().
|
// func(KeyEvent), func(View), and func().
|
||||||
KeyUpEvent = "key-up-event"
|
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 {
|
type KeyEvent struct {
|
||||||
|
@ -372,12 +483,6 @@ func valueToEventWithOldListeners[V View, E any](value any) ([]func(V, E, E), bo
|
||||||
return nil, false
|
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 {
|
func (view *viewData) setKeyListener(tag string, value any) bool {
|
||||||
listeners, ok := valueToEventListeners[View, KeyEvent](value)
|
listeners, ok := valueToEventListeners[View, KeyEvent](value)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -390,11 +495,13 @@ func (view *viewData) setKeyListener(tag string, value any) bool {
|
||||||
} else {
|
} else {
|
||||||
switch tag {
|
switch tag {
|
||||||
case KeyDownEvent:
|
case KeyDownEvent:
|
||||||
|
view.properties[tag] = listeners
|
||||||
if view.created {
|
if view.created {
|
||||||
view.session.updateProperty(view.htmlID(), "onkeydown", "keyDownEvent(this, event)")
|
view.session.updateProperty(view.htmlID(), "onkeydown", "keyDownEvent(this, event)")
|
||||||
}
|
}
|
||||||
|
|
||||||
case KeyUpEvent:
|
case KeyUpEvent:
|
||||||
|
view.properties[tag] = listeners
|
||||||
if view.created {
|
if view.created {
|
||||||
view.session.updateProperty(view.htmlID(), "onkeyup", "keyUpEvent(this, event)")
|
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){}
|
return []func(V, E, E){}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEventListeners[V View, E any](view View, subviewID []string, tag string) []func(V, E) {
|
func getEventListeners[V View, E any](view View, subviewID []string, tag string) []func(V, E) {
|
||||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||||
view = ViewByID(view, 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:
|
// LeftArrow is value of the popup "arrow" property:
|
||||||
// Arrow on the left side of the pop-up window
|
// Arrow on the left side of the pop-up window
|
||||||
LeftArrow = 4
|
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.
|
// PopupButton describes a button that will be placed at the bottom of the window.
|
||||||
type PopupButton struct {
|
type PopupButton struct {
|
||||||
Title string
|
Title string
|
||||||
|
Type PopupButtonType
|
||||||
OnClick func(Popup)
|
OnClick func(Popup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +105,14 @@ type Popup interface {
|
||||||
onDismiss()
|
onDismiss()
|
||||||
html(buffer *strings.Builder)
|
html(buffer *strings.Builder)
|
||||||
viewByHTMLID(id string) View
|
viewByHTMLID(id string) View
|
||||||
|
keyEvent(event KeyEvent) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type popupData struct {
|
type popupData struct {
|
||||||
layerView View
|
layerView View
|
||||||
view View
|
view View
|
||||||
|
buttons []PopupButton
|
||||||
|
cancelable bool
|
||||||
dismissListener []func(Popup)
|
dismissListener []func(Popup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +286,7 @@ func (arrow *popupArrow) createView(popupView View) View {
|
||||||
|
|
||||||
func (popup *popupData) init(view View, popupParams Params) {
|
func (popup *popupData) init(view View, popupParams Params) {
|
||||||
popup.view = view
|
popup.view = view
|
||||||
|
popup.cancelable = false
|
||||||
session := view.Session()
|
session := view.Session()
|
||||||
|
|
||||||
columnCount := 3
|
columnCount := 3
|
||||||
|
@ -392,13 +406,15 @@ func (popup *popupData) init(view View, popupParams Params) {
|
||||||
TextSize: Px(20),
|
TextSize: Px(20),
|
||||||
Content: "✕",
|
Content: "✕",
|
||||||
NotTranslate: true,
|
NotTranslate: true,
|
||||||
ClickEvent: func(View) {
|
ClickEvent: popup.cancel,
|
||||||
popup.Dismiss()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
popup.cancelable = true
|
||||||
|
|
||||||
case OutsideClose:
|
case OutsideClose:
|
||||||
outsideClose, _ = boolProperty(popupParams, OutsideClose, session)
|
outsideClose, _ = boolProperty(popupParams, OutsideClose, session)
|
||||||
|
if outsideClose {
|
||||||
|
popup.cancelable = true
|
||||||
|
}
|
||||||
|
|
||||||
case Buttons:
|
case Buttons:
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
|
@ -494,6 +510,7 @@ func (popup *popupData) init(view View, popupParams Params) {
|
||||||
view.Set(Row, viewRow)
|
view.Set(Row, viewRow)
|
||||||
popupView.Append(view)
|
popupView.Append(view)
|
||||||
|
|
||||||
|
popup.buttons = buttons
|
||||||
if buttonCount := len(buttons); buttonCount > 0 {
|
if buttonCount := len(buttons); buttonCount > 0 {
|
||||||
buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign)
|
buttonsAlign, _ := enumProperty(params, ButtonsAlign, session, RightAlign)
|
||||||
popupCellHeight = append(popupCellHeight, AutoSize())
|
popupCellHeight = append(popupCellHeight, AutoSize())
|
||||||
|
@ -511,21 +528,31 @@ func (popup *popupData) init(view View, popupParams Params) {
|
||||||
buttonsPanel.Set(Margin, gap)
|
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 {
|
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{
|
popupView.Append(NewGridLayout(session, Params{
|
||||||
|
@ -544,11 +571,8 @@ func (popup *popupData) init(view View, popupParams Params) {
|
||||||
}
|
}
|
||||||
|
|
||||||
popup.layerView = NewGridLayout(session, layerParams)
|
popup.layerView = NewGridLayout(session, layerParams)
|
||||||
|
|
||||||
if outsideClose {
|
if outsideClose {
|
||||||
popup.layerView.Set(ClickEvent, func(View) {
|
popup.layerView.Set(ClickEvent, popup.cancel)
|
||||||
popup.Dismiss()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,12 +584,21 @@ func (popup *popupData) Session() Session {
|
||||||
return popup.view.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() {
|
func (popup *popupData) Dismiss() {
|
||||||
popup.Session().popupManager().dismissPopup(popup)
|
popup.Session().popupManager().dismissPopup(popup)
|
||||||
for _, listener := range popup.dismissListener {
|
for _, listener := range popup.dismissListener {
|
||||||
listener(popup)
|
listener(popup)
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (popup *popupData) Show() {
|
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
|
// NewPopup creates a new Popup
|
||||||
func NewPopup(view View, param Params) Popup {
|
func NewPopup(view View, param Params) Popup {
|
||||||
if view == nil {
|
if view == nil {
|
||||||
|
|
21
session.go
21
session.go
|
@ -649,8 +649,15 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if viewID, ok := data.PropertyValue("id"); ok {
|
if viewID, ok := data.PropertyValue("id"); ok {
|
||||||
if view := session.viewByHTMLID(viewID); view != nil {
|
if viewID != "body" {
|
||||||
view.handleCommand(view, command, data)
|
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 {
|
} else {
|
||||||
ErrorLog(`"id" property not found. Event: ` + command)
|
ErrorLog(`"id" property not found. Event: ` + command)
|
||||||
|
@ -658,6 +665,16 @@ func (session *sessionData) handleEvent(command string, data DataObject) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
func (session *sessionData) SetTitle(title string) {
|
||||||
title, _ = session.GetString(title)
|
title, _ = session.GetString(title)
|
||||||
session.callFunc("setTitle", title)
|
session.callFunc("setTitle", title)
|
||||||
|
|
Loading…
Reference in New Issue