giu icon indicating copy to clipboard operation
giu copied to clipboard

Changing windows resolution scale messes up positioning?

Open ItsVoltz opened this issue 4 years ago • 31 comments

With normal scaling iuh4sVX

With 125% scaling: E0ikIsC

However its the button positioning with the hardcoded buttonWidth for the two buttons together, is there a better way to dynamically align two buttons to center next to eachother?

			g.Custom(func() { // centered buttons
				width, _ := g.GetAvailableRegion()
				buttonWidth := float32(295)

				g.Row(
					g.Dummy(width/2-buttonWidth/2, 0),

					g.Button("Login").Size(136, 25).OnClick(cl.login),
					g.Button("Exit").Size(136, 25).OnClick(cl.exit),
				).Build()
			}),

ItsVoltz avatar Sep 20 '21 07:09 ItsVoltz

@ItsVoltz Maybe giu.Align(...) is the thing you are looking for?

AllenDang avatar Sep 20 '21 07:09 AllenDang

@ItsVoltz Maybe giu.Align(...) is the thing you are looking for?

I use align however is there a way to align two buttons in a row perfectly? when I try it just aligns the first one to the center then the second is off of the correctly centered button

Here is how it looks when I try to align it: onM1u7B

Code:

			g.Align(g.AlignCenter).To(
				g.Row(
					g.Button("Login").Size(136, 25).OnClick(cl.login),
					g.Button("Exit").Size(136, 25).OnClick(cl.exit),
					),
				),

ItsVoltz avatar Sep 20 '21 08:09 ItsVoltz

@gucio321 We may need to calcuate the row width here?

AllenDang avatar Sep 20 '21 08:09 AllenDang

@ItsVoltz For now, you need to use giu.Dummy and calculate it's width based on the width of the two buttons.

AllenDang avatar Sep 20 '21 08:09 AllenDang

image

yep, @AllenDang It's a kind of bug in AlignmentSetter I'll take a look

@ItsVoltz maybe try the following for now:

			g.Custom(func() { // centered buttons
				width, _ := g.GetAvailableRegion()
                                spacing := GetItemSpacing()
                                buttonW := (width - spacing)/2

				g.Row(
					g.Button("Login").Size(buttonW, 25).OnClick(cl.login),
					g.Button("Exit").Size(buttonW, 25).OnClick(cl.exit),
				).Build()
			}),

gucio321 avatar Sep 20 '21 14:09 gucio321

image

yep, @AllenDang It's a kind of bug in AlignmentSetter I'll take a look

@ItsVoltz maybe try the following for now:

			g.Custom(func() { // centered buttons
				width, _ := g.GetAvailableRegion()
                                spacing := GetItemSpacing()
                                buttonW := (width - spacing)/2

				g.Row(
					g.Button("Login").Size(buttonW, 25).OnClick(cl.login),
					g.Button("Exit").Size(buttonW, 25).OnClick(cl.exit),
				).Build()
			}),

See it works however not how I want as I don;t have the inputs span across the entire width: image

ItsVoltz avatar Sep 20 '21 17:09 ItsVoltz

@ItsVoltz it should be fixed in #343 (align setter will work)

gucio321 avatar Sep 20 '21 17:09 gucio321

@ItsVoltz it should be fixed in #343 (align setter will work)

Does not work:

			g.Align(g.AlignCenter).To(
				g.Row(
					g.Button("Login").Size(136, 25).OnClick(cl.login),
					g.Button("Exit").Size(136, 25).OnClick(cl.exit)),
				),

ItsVoltz avatar Sep 25 '21 04:09 ItsVoltz

@ItsVoltz The PR is just merged, can you make sure you are running the newest code from master branch?

AllenDang avatar Sep 25 '21 04:09 AllenDang

@ItsVoltz The PR is just merged, can you make sure you are running the newest code from master branch?

I am

ItsVoltz avatar Sep 25 '21 04:09 ItsVoltz

@gucio321 Seems this issue still there.

AllenDang avatar Sep 25 '21 04:09 AllenDang

@ItsVoltz could you try go get -u github.com/AllenDang/giu@36465fb9879a6ec167166bf35b66408b34150ed7? (sometimes go get -u repo@master doesn't use the latest commit) I think that aligning a RowWidget should work: image

gucio321 avatar Sep 25 '21 09:09 gucio321

@ItsVoltz could you try go get -u github.com/AllenDang/giu@36465fb9879a6ec167166bf35b66408b34150ed7? (sometimes go get -u repo@master doesn't use the latest commit) I think that aligning a RowWidget should work: image

That worked thank you!, all though I have come across a bug with clicks registering on these row aligned buttons, the first button works fine however clicks on the second one seem to work sometimes,

ItsVoltz avatar Sep 25 '21 15:09 ItsVoltz

Also, another bug is if you are using align unless I actually use a g.Dummy(0, 0) in a row with the widget it doesn't correctly align it is off some pixels. EDIT: nvm it is still off some that was my solution before however it does not seem to work anymore

ItsVoltz avatar Sep 25 '21 15:09 ItsVoltz

That worked thank you!, all though I have come across a bug with clicks registering on these row aligned buttons, the first button works fine however clicks on the second one seem to work sometimes,

that's very strange, but right, I can reproduce. EDIT: seems like it happens only for buttons in row

gucio321 avatar Sep 25 '21 15:09 gucio321

@AllenDang I got an idea, but it it may be reallly experimanetal: to measure widget size:

  • get MasterWindowSize
  • render widgets OUT OF WINDOW BOUNDS (to avoid user interaction with them)
  • measure widgets size

what do you think about it? EDIT: ok, it will not work, because of the fact, that I'm building widgets inside of WindowWidget's layout so the size of the window will be automatically changed?... Does anyone has any idea how to render widgets and prevent user from interaction with them? I see only this: https://github.com/ocornut/imgui/issues/3714#issuecomment-759319966

gucio321 avatar Sep 25 '21 15:09 gucio321

hmm, in the other comment of discussion on upstream issue, I can see this:

  • using ImDrawListSplitter with two channels, select second channel, after drawing select to first channel but do not merge splitter back, also ImDrawList vertex pointer can be moved back to reuse vertices used by "invisible" widget.

I'll investigate if it can be used more evectively.

gucio321 avatar Sep 25 '21 17:09 gucio321

@AllenDang seems like ImDrawListSplitter isn't implemented in imgui-go yet. could you take a look on it (as I'm not a C guy, I can't sadly do it myself)

gucio321 avatar Sep 25 '21 18:09 gucio321

@gucio321 Sure, let me do it.

AllenDang avatar Sep 26 '21 03:09 AllenDang

@gucio321 Frankly, I think we should hold Align until upstream finish measure widget before it is actually being built. Otherwise, a large refinement will occur in future, which leads to a waste of time for now. I've been experienced this on DPI awareness, at that moment I spent a lot of time to implement it and for now the code are totally useless.

And another thing I'm waiting for is docking.

AllenDang avatar Sep 26 '21 03:09 AllenDang

That worked thank you!, all though I have come across a bug with clicks registering on these row aligned buttons, the first button works fine however clicks on the second one seem to work sometimes,

that's very strange, but right, I can reproduce. EDIT: seems like it happens only for buttons in row

Any idea on fix for the buttons in a row align

ItsVoltz avatar Sep 26 '21 05:09 ItsVoltz

Any idea on fix for the buttons in a row align

well, the problem is more complex, than I thought. This isn't a bug only in case of buttons in row. It is present for all clickable widgets. The reason is, that Align builts one widget two times (invisible to measure width an visible - aligned). The real issue is, that the user is able to interact with this invisible button so it causes clicking issue described above.

So, @ItsVoltz ofc there is a solution (something like I described in #340 ) - manually align your buttons. if you know them's width:

const button1W, button2W = 100, 80
// ...
giu.Custom(func() {
      availableW, _ := giu.GetAvailableRegion()
      spacingW, _ := giu.GetItemSpacing()
      giu.Dummy(availableW-(button1W+button2W+spacingW), 0).Build()
      giu.Row(
            giu.Button("my first button").Size(button1W, 20),
            giu.Button("my second button").Size(button2W, 20),
      ).Build()
}),

gucio321 avatar Sep 26 '21 08:09 gucio321

@gucio321 Frankly, I think we should hold Align until upstream finish measure widget before it is actually being built. Otherwise, a large refinement will occur in future, which leads to a waste of time for now. I've been experienced this on DPI awareness, at that moment I spent a lot of time to implement it and for now the code are totally useless.

And another thing I'm waiting for is docking.

@AllenDang as far as I understand measure widget before it is actually being built will mean

We are currently missing - and we will eventually implement - a "null" layout mode which will allow submitting items for size measurement.

Originally posted in https://github.com/ocornut/imgui/issues/3714#issuecomment-759319966

so It will not be so large refinement for giu - just minor edit for GetWidgetWidth method (and removal of tone comments :grinning:).

The other thing is that imgui-go currently misses ImDrawListSplitter and giu alignment setter is probably unable to work with current implementation of widget measurement (rendering with 0 alpha).

gucio321 avatar Sep 26 '21 09:09 gucio321

@gucio321 Ok, I got cold these days, may need some time to implement ImDrawListSplitter... Sorry to the delay.

AllenDang avatar Sep 27 '21 03:09 AllenDang

well, I hope, that this code:

        {

            ImGui::Begin("Hello, world!");                          // Create a window called "Hello, world!" and append into it.

            ImDrawList* list =  ImGui::GetWindowDrawList();

            struct foo {
                    bool btn() { return ImGui::Button("btn",ImVec2{200,20}); };
            } btn;

            ImVec2 start = ImGui::GetCursorPos();
            ImVec2 size;

            list->ChannelsSplit(2);

            list->ChannelsSetCurrent(0);
            //ImGui::PushID("someotherid");


            if (btn.btn() ) {
                    std::cout << "btn 1 (invisible) pressed\n";
            };

            size = ImGui::GetItemRectSize();
            ImVec2 available = ImGui::GetContentRegionMax();
            start.x = (available.x-size.x)/2;


            //ImGui::PopID();

            ImGui::SetCursorPos(start);

            list->ChannelsSetCurrent(1);
            if (ImGui::BeginChild("measure") ){
            if (btn.btn()){
                    std::cout << "btn 1 pressed\n";
            };
            }
            ImGui::EndChild();
            list->ChannelsMerge();

            ImGui::End();
        }

despite it doesn't work like I expected, in connection with PushDisabled will finally work and we'll have these bugs fixed (clicking bug from here and double-pasting from #340 )

gucio321 avatar Sep 27 '21 05:09 gucio321

wow, @AllenDang it seems to work without list splitter for now:

        {

            ImGui::Begin("Hello, world!");                          // Create a window called "Hello, world!" and append into it.

            //ImDrawList* list =  ImGui::GetWindowDrawList();

            struct button {
                    bool Build() { return ImGui::Button("btn",ImVec2{200,20}); };
            } mybutton;

            ImVec2 start = ImGui::GetCursorPos();
            ImVec2 size;

            //list->ChannelsSplit(2);

            //list->ChannelsSetCurrent(0);

            if (mybutton.Build() ) {
                    std::cout << "btn 1 (invisible) pressed\n";
            };

            size = ImGui::GetItemRectSize();
            ImVec2 available = ImGui::GetContentRegionMax();
            start.x = (available.x-size.x)/2;

            ImGui::SetCursorPos(start);

            //list->ChannelsSetCurrent(1);
            if (ImGui::BeginChild("measure") ){
                if (mybutton.Build()){
                    std::cout << "btn 1 pressed\n";
                };
            }
            ImGui::EndChild();
            //list->ChannelsMerge();

            ImGui::End();
        }

I'll try to implement to go and tell you if it works.

IMO the problem is with the rendering order. if we put our centered button in a child, it works. Is there any way to render invisible btn in background? I see GetForeground/BackgroundDrawList...

gucio321 avatar Sep 27 '21 05:09 gucio321

@gucio321 The best place to ask this question is raise an issue in imgui's issue list.

AllenDang avatar Sep 27 '21 06:09 AllenDang

@gucio321 After your implementation, it's not only Align but also a whole Flex-box like layout mechanism becomes possible. Keep going man! It's a huge step.

AllenDang avatar Sep 27 '21 06:09 AllenDang

I opened an issue in upstream: https://github.com/ocornut/imgui/issues/4588 If there will not be any better idea, I'll try with ChildWidget, but I'll need to investigate some child's parameters, because in C imgui, child doesn't have any style/bg color and is exactly the same size as widget inside of it. In giu child doesn't look so...

gucio321 avatar Sep 27 '21 16:09 gucio321

hmm, @AllenDang so it seems that there is no solution right now, So I'm going to try with ChildWidget until upstream issue gets fixed. But I cannot figure out, why imgui-go's implementation of child doesn't work like this in DearImGui... lets try this code:

// Here's some code anyone can copy and paste to reproduce your issue
        {
            ImGui::Begin("Hello, world!");

            struct foo {
                    bool btn() { return ImGui::Button("btn",ImVec2{200,20}); };
            } btn;

            ImVec2 start = ImGui::GetCursorPos();
            ImVec2 size;

            ImGui::PushID("someotherid");
            ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0);
            if (btn.btn() ) {
                    std::cout << "btn 1 (invisible) pressed\n";
            };
            ImGui::PopStyleVar();
            ImGui::PopID();

            size = ImGui::GetItemRectSize();
            ImVec2 available = ImGui::GetContentRegionMax();
            start.x = (available.x-size.x)/2;
            ImGui::SetCursorPos(start);

            if (ImGui::BeginChild("container")) {
                if (btn.btn()){
                    std::cout << "btn 1 pressed\n";
                }
            }
            ImGui::EndChild();

            ImGui::End();
        }

the child widget is here invisible at all in giu, ChildWIdget has a gray background and is always visible e.g.:

giu.Child().Layout(giu.Button("btn"))

wil be like: image

do you have any idea? PushStyle?...

gucio321 avatar Sep 30 '21 16:09 gucio321

@gucio321 I just back to work, let me do some digging, will feedback to you soon.

AllenDang avatar Oct 08 '21 09:10 AllenDang