AllenDang / giu

Cross platform rapid GUI framework for golang based on Dear ImGui.
MIT License
2.28k stars 132 forks source link

`giu.PopupModal()` does not work properly in some cases [bug] #552

Closed Locter9001 closed 1 year ago

Locter9001 commented 2 years ago

What happend?

I'm using giu to make a simple widget, but I found that in table mode, PopupModal doesn't work properly, I use the right mouse button to pop up the menu and select the action to do inside the menu, but when I click the button Post "PopupModal" not working!

Code example

package main

import (
    "github.com/AllenDang/giu"
    "wifi/giu/controller"
)

func loop() {
    giu.SingleWindow().Layout(
        giu.Column(
            giu.Row(
                giu.Table().Columns(
                    giu.TableColumn("name"),
                    giu.TableColumn("balance"),
                ).Rows(
                    giu.TableRow(
                        giu.Selectable("locter"),
                        giu.ContextMenu().Layout(
                            giu.Button("about his").OnClick(func() {
                                giu.CloseCurrentPopup()
                                controller.ShowPopupModal()
                            }),
                        ),
                        giu.Selectable("$99.73"),
                        giu.ContextMenu().Layout(
                            giu.Button("refund").OnClick(func() {
                                giu.CloseCurrentPopup()
                                controller.ShowPopupModal()
                            }),
                        ),
                    ),
                ),
            ),
        ),
        giu.PopupModal("#PopupWindow").Layout(*controller.Layouts...),
    )
}

func main() {
    w := giu.NewMasterWindow("test", 400, 400, 0)
    w.Run(loop)
}
package controller

import (
    "github.com/AllenDang/giu"
    "time"
)

var Layouts = &giu.Layout{
    giu.Align(giu.AlignCenter).To(
        giu.Dummy(100, 1),
        giu.Labelf("time now: %v", time.Now().Format("2006-01-02")),
        giu.Button("clicked").OnClick(func() {
            giu.CloseCurrentPopup()
        }),
    ),
}

func ShowPopupModal() {
    Layouts = &giu.Layout{
        giu.Align(giu.AlignCenter).To(
            giu.Dummy(100, 1),
            giu.Label("show~"),
            giu.Dummy(100, 8),
            giu.Button("return").OnClick(func() {
                giu.CloseCurrentPopup()
            }),
        ),
    }

    giu.OpenPopup("#PopupWindow")
}

To Reproduce

  1. Run my demo
  2. will see that the popup is not working

Version

master

OS

Windows 11

AllenDang commented 2 years ago

@Locter9001 To open a popup by it's id, you need to make sure the popup is defined at the same level of button which triggers it. To avoid this, you could use a bool value to control the open/close state of a popup. Try giu.PopupModel(...).IsOpen(&shouldOpen).

Locter9001 commented 2 years ago

@Locter9001 To open a popup by it's id, you need to make sure the popup is defined at the same level of button which triggers it. To avoid this, you could use a bool value to control the open/close state of a popup. Try giu.PopupModel(...).IsOpen(&shouldOpen).

Thanks, I'll try it

Locter9001 commented 2 years ago

@Locter9001 To open a popup by it's id, you need to make sure the popup is defined at the same level of button which triggers it. To avoid this, you could use a bool value to control the open/close state of a popup. Try giu.PopupModel(...).IsOpen(&shouldOpen).

I tried many times, put the table row, put the outer layer, use 'IsOpen', all failed

Locter9001 commented 2 years ago

@Locter9001 To open a popup by it's id, you need to make sure the popup is defined at the same level of button which triggers it. To avoid this, you could use a bool value to control the open/close state of a popup. Try giu.PopupModel(...).IsOpen(&shouldOpen).

package main

import (
    "fmt"
    "github.com/AllenDang/giu"
    "time"
    "wifi/giu/controller"
)

func loop() {
    giu.SingleWindow().Layout(
        giu.Column(
            giu.Row(
                giu.Table().Columns(
                    giu.TableColumn("name"),
                    giu.TableColumn("balance"),
                ).Rows(
                    giu.TableRow(
                        giu.Selectable("locter"),
                        giu.ContextMenu().Layout(
                            giu.Button("about his").OnClick(func() {
                                giu.CloseCurrentPopup()
                                controller.ShowPopupModal()
                            }),
                        ),
                        //giu.PopupModal("##PopupWindow").Layout(*controller.Layouts...).IsOpen(&controller.IsOpen),
                        giu.Align(giu.AlignRight).To(
                            giu.Selectable("$99.73"),
                            giu.ContextMenu().Layout(
                                giu.Button("refund").OnClick(func() {
                                    giu.CloseCurrentPopup()
                                    controller.ShowPopupModal()
                                }),
                            ),
                        ),
                    ),
                ).Size(382, 200),
            ),
            giu.PopupModal("##PopupWindow").Layout(*controller.Layouts...).IsOpen(&controller.IsOpen),
        ),
        giu.Row(
            giu.Label("open the popup window! "),
            giu.Button("open now !!").OnClick(func() {
                controller.ShowPopupModal()
            }),
        ),
    )
}

func main() {
    go func1()
    w := giu.NewMasterWindow("test", 400, 400, 0)
    w.Run(loop)
}

func func1() {
    for {
        time.Sleep(time.Millisecond * 300)
        fmt.Println(controller.IsOpen)
    }
}

controller.go

package controller

import (
    "fmt"
    "github.com/AllenDang/giu"
    "time"
)

var IsOpen bool = true

var Layouts = &giu.Layout{
    giu.Align(giu.AlignCenter).To(
        giu.Dummy(100, 1),
        giu.Labelf("time now: %v", time.Now().Format("2006-01-02")),
        giu.Button("clicked").OnClick(func() {
            giu.CloseCurrentPopup()
        }),
    ),
}

func ShowPopupModal() {
    Layouts = &giu.Layout{
        giu.Align(giu.AlignCenter).To(
            giu.Dummy(100, 1),
            giu.Label("fuck you"),
            giu.Button("return").OnClick(func() {
                giu.CloseCurrentPopup()
                IsOpen = false
            }),
        ),
    }
    IsOpen = true
    fmt.Println("clicked show button")
    giu.OpenPopup("##PopupWindow")
}
gucio321 commented 2 years ago

You can check in exqmples/widgets. Iirc there was an pop-up modal impl I'll review your code and write some demo for you later since in in bus at the moment and can't write any code 😊

Locter9001 commented 2 years ago

You can check in exqmples/widgets. Iirc there was an pop-up modal impl I'll review your code and write some demo for you later since in in bus at the moment and can't write any code 😊

ok i try

Locter9001 commented 2 years ago

You can check in exqmples/widgets. Iirc there was an pop-up modal impl I'll review your code and write some demo for you later since in in bus at the moment and can't write any code 😊

I have seen this, it is useless, this is the simplest example, what I do is a bit more complicated, I want him to right-click in the table to pop up a menu, and click a menu button to pop up a window

Locter9001 commented 2 years ago

@AllenDang @gucio321 my problem is with #467 somewhat similar

gucio321 commented 2 years ago

bruh, it is crazy! I'm trying to generate minimal reproducable example and now, I can say that it isn't fault of context menu; gonna try table now

gucio321 commented 2 years ago

Well, I found that the popup needs to be placed in the same layout level as its trigger (Like Allen said) here is my current code

package main

import "github.com/AllenDang/giu"

func main() {
    wnd := giu.NewMasterWindow("Popup Modal crash [issue 552]", 640, 480, 0)
    wnd.Run(loop)
}

func loop() {
    giu.SingleWindow().Layout(
        giu.Table().Rows(
            giu.TableRow(
                giu.Selectable("Right-click me!"),
                giu.ContextMenu().Layout(
                    giu.Button("OpenPopup").OnClick(func() {
                        giu.OpenPopup("popup")
                    }),
                    giu.PopupModal("popup").Layout(
                        giu.Button("Close me!").OnClick(func() {
                            giu.CloseCurrentPopup()
                        }),
                    ),
                ),
            ),
        ),
    )
}
Locter9001 commented 2 years ago

Well, maybe it will be changed later, it's too bad for the table

gucio321 commented 2 years ago

so, what is going on here?....

gucio321 commented 2 years ago

Well, maybe it will be changed later, it's too bad for the table

I don't think that it's table's fault tbh...

Locter9001 commented 2 years ago

Unable to pop up window,because all my table rows are automatically generated

Locter9001 commented 2 years ago

Wait, let me show you an example

gucio321 commented 2 years ago

wait I got it probably!

gucio321 commented 2 years ago

you cannot call giu.CloseCurrentPopup - it prevents the next command dto proceed; why - idk

Locter9001 commented 2 years ago

I tried it and it didn't work

gucio321 commented 2 years ago

It works, whats more, you need to put the popup command just under your button in context menu here is working main.go file:

package main

import (
    "example.com/controller"
    "github.com/AllenDang/giu"
)

func loop() {
    giu.SingleWindow().Layout(
        giu.Column(
            giu.Row(
                giu.Table().Columns(
                    giu.TableColumn("name"),
                    giu.TableColumn("balance"),
                ).Rows(
                    giu.TableRow(
                        giu.Selectable("locter"),
                        giu.ContextMenu().Layout(
                            giu.Button("about his").OnClick(func() {
                                controller.ShowPopupModal()
                            }),
                            giu.PopupModal("#PopupWindow").Layout(*controller.Layouts...),
                        ),
                        giu.Selectable("$99.73"),
                        giu.ContextMenu().Layout(
                            giu.Button("refund").OnClick(func() {
                                controller.ShowPopupModal()
                            }),
                            giu.PopupModal("#PopupWindow").Layout(*controller.Layouts...),
                        ),
                    ),
                ),
            ),
        ),
    )
}

func main() {
    w := giu.NewMasterWindow("test", 400, 400, 0)
    w.Run(loop)
}

PS: you need to fix imports since I was using diffrent go.mod file

Locter9001 commented 2 years ago
func InsertToMastersLayout(master model.Master, i int) {
    var isBool bool
    if i == -1 {
        i = len(model.MasterData) - 1
        isBool = true
    }

    widget := createTableRow(master, i)

    if isBool {
        model.MastersLayout = append(model.MastersLayout, widget)
    } else {
        model.MastersLayout[i] = widget
        g.Update()
    }
}

func createTableRow(master model.Master, i int) *g.TableRowWidget {
    //  right click context
    clickFunc := createClickLayout(i)
    str := fmt.Sprintf("%v", i)
    return g.TableRow(
        // name
        g.Checkbox(master.GroupName, &model.MasterData[i].IsSelect).OnChange(func() {
            ChangeCheckBoxForUsers(i)
        }),
        // ID
        g.Selectable(master.GroupID),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // mastername
        g.Selectable(master.MasterName),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // master id
        g.Selectable(master.MasterID),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // agent
        g.Selectable(master.Agent),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // odds
        g.Selectable(master.Odds),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // agencyfee
        g.Selectable(master.AgencyFee),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // goods sum
        g.Selectablef("%v", master.GoodsSum),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        // open game
        g.Selectable(master.OpenGems),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        //
        g.Selectable(strconv.Itoa(master.GoodLuck)),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        //
        g.Selectablef("%v", master.Data),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        //
        g.Selectable(master.Attribution),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
        //
        g.Selectablef("%v", master.ReciveInstructions),
        g.ContextMenuChange(str).Layout(
            clickFunc...,
        ),
    )
}

func createClickLayout(i int) g.Layout {
    return g.Layout{
        g.Button("open").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            OpenTreasure(i)
        }),
        g.Button("make imags").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            Drawings(i)
        }),
        g.Button("sum iamges").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            ClosingChart(i)
        }),
        g.Button("all imags").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            AllClosingChart(i)

        }),
        g.Button("send all images").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            ALlClosingChartPrivateMessage(i)

        }),
        g.Button("add agent").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            AddAgent(i)

        }),
        g.Button("add same levle").Size(100, 30).OnClick(func() {
            g.CloseCurrentPopup()
            AddSameLevel(i)

        }),
    }
}
Locter9001 commented 2 years ago

okay I'll try again

Locter9001 commented 2 years ago

this is a project I'm working on that will generate table rows in bulk without me having to write the GUI code manually

gucio321 commented 2 years ago

It works, whats more, you need to put the popup command just under your button in context menu here is working main.go file:

package main

import (
  "example.com/controller"
  "github.com/AllenDang/giu"
)

func loop() {
  giu.SingleWindow().Layout(
      giu.Column(
          giu.Row(
              giu.Table().Columns(
                  giu.TableColumn("name"),
                  giu.TableColumn("balance"),
              ).Rows(
                  giu.TableRow(
                      giu.Selectable("locter"),
                      giu.ContextMenu().Layout(
                          giu.Button("about his").OnClick(func() {
                              controller.ShowPopupModal()
                          }),
                          giu.PopupModal("#PopupWindow").Layout(*controller.Layouts...),
                      ),
                      giu.Selectable("$99.73"),
                      giu.ContextMenu().Layout(
                          giu.Button("refund").OnClick(func() {
                              controller.ShowPopupModal()
                          }),
                          giu.PopupModal("#PopupWindow").Layout(*controller.Layouts...),
                      ),
                  ),
              ),
          ),
      ),
  )
}

func main() {
  w := giu.NewMasterWindow("test", 400, 400, 0)
  w.Run(loop)
}

PS: you need to fix imports since I was using diffrent go.mod file

did it owrked?

Locter9001 commented 2 years ago

He works in another test project I built, not yet in another big project, I'm troubleshooting the problem

gucio321 commented 2 years ago

ok, let me know if you have any issues

Locter9001 commented 2 years ago

ok, let me know if you have any issues okay, I just tested it and he worked correctly, thank you very much for your help