| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- package giu
- import "fmt"
- // DialogResult represents dialog result
- // dialog resullt is bool. if OK/Yes it is true, else (Cancel/No) - false.
- type DialogResult bool
- // dialog results.
- const (
- DialogResultOK DialogResult = true
- DialogResultCancel DialogResult = false
- DialogResultYes = DialogResultOK
- DialogResultNo = DialogResultCancel
- )
- // MsgboxButtons determines which buttons are in the dialog.
- type MsgboxButtons uint8
- // button sets.
- const (
- // Yes-No question.
- MsgboxButtonsYesNo MsgboxButtons = 1 << iota
- // Ok / Cancel dialog.
- MsgboxButtonsOkCancel
- // info.
- MsgboxButtonsOk
- )
- // DialogResultCallback is a callback for dialogs.
- type DialogResultCallback func(DialogResult)
- var _ Disposable = &msgboxState{}
- type msgboxState struct {
- title string
- content string
- resultCallback DialogResultCallback
- buttons MsgboxButtons
- open bool
- }
- // Dispose implements disposable interface.
- func (ms *msgboxState) Dispose() {
- // Nothing to do here.
- }
- func msgboxInvokeCallback(result DialogResult, callback DialogResultCallback) {
- CloseCurrentPopup()
- if callback != nil {
- callback(result)
- }
- }
- func buildMsgboxButtons(buttons MsgboxButtons, callback DialogResultCallback) Layout {
- switch buttons {
- case MsgboxButtonsOk:
- return Layout{
- Button(" Ok ").OnClick(func() {
- msgboxInvokeCallback(DialogResultOK, callback)
- }),
- }
- case MsgboxButtonsOkCancel:
- return Layout{
- Row(
- Button(" Ok ").OnClick(func() {
- msgboxInvokeCallback(DialogResultOK, callback)
- }),
- Button("Cancel").OnClick(func() {
- msgboxInvokeCallback(DialogResultCancel, callback)
- }),
- ),
- }
- case MsgboxButtonsYesNo:
- return Layout{
- Row(
- Button(" Yes ").OnClick(func() {
- msgboxInvokeCallback(DialogResultYes, callback)
- }),
- Button(" No ").OnClick(func() {
- msgboxInvokeCallback(DialogResultNo, callback)
- }),
- ),
- }
- default:
- return Layout{
- Button(" Ok ").OnClick(func() {
- msgboxInvokeCallback(DialogResultOK, callback)
- }),
- }
- }
- }
- const msgboxID string = "###Msgbox"
- // PrepareMsgbox should be invoked in function in the same layout level where you call g.Msgbox.
- // BUG: calling this more than 1 time per frame causes unexpected
- // merging msgboxes layouts (see https://github.com/AllenDang/giu/issues/290)
- func PrepareMsgbox() Layout {
- return Layout{
- Custom(func() {
- var state *msgboxState
- // Register state.
- stateRaw := Context.GetState(msgboxID)
- if stateRaw == nil {
- state = &msgboxState{title: "Info", content: "Content", buttons: MsgboxButtonsOk, resultCallback: nil, open: false}
- Context.SetState(msgboxID, state)
- } else {
- var isOk bool
- state, isOk = stateRaw.(*msgboxState)
- Assert(isOk, "MsgboxWidget", "PrepareMsgbox", "got state of unexpected type")
- }
- if state.open {
- OpenPopup(msgboxID)
- state.open = false
- }
- SetNextWindowSize(300, 0)
- PopupModal(fmt.Sprintf("%s%s", state.title, msgboxID)).Layout(
- Custom(func() {
- // Ensure the state is valid.
- Context.GetState(msgboxID)
- }),
- Label(state.content).Wrapped(true),
- buildMsgboxButtons(state.buttons, state.resultCallback),
- ).Build()
- }),
- }
- }
- // MsgboxWidget represents message dialog.
- type MsgboxWidget struct{}
- func (m *MsgboxWidget) getState() *msgboxState {
- stateRaw := Context.GetState(msgboxID)
- if stateRaw == nil {
- panic("Msgbox is not prepared. Invoke giu.PrepareMsgbox in the end of the layout.")
- }
- result, isOk := stateRaw.(*msgboxState)
- Assert(isOk, "MsgboxWidget", "getState", "unexpected type of widget's state recovered")
- return result
- }
- // Msgbox opens message box.
- // call it whenever you want to open popup with
- // question / info.
- func Msgbox(title, content string) *MsgboxWidget {
- result := &MsgboxWidget{}
- state := result.getState()
- state.title = title
- state.content = content
- state.buttons = MsgboxButtonsOk
- state.resultCallback = nil
- state.open = true
- return result
- }
- // Buttons sets which buttons should be possible.
- func (m *MsgboxWidget) Buttons(buttons MsgboxButtons) *MsgboxWidget {
- s := m.getState()
- s.buttons = buttons
- return m
- }
- // ResultCallback sets result callback.
- func (m *MsgboxWidget) ResultCallback(cb DialogResultCallback) *MsgboxWidget {
- s := m.getState()
- s.resultCallback = cb
- return m
- }
|