- Home /
Clickable GUI.Window
Alright so what i'm trying to do is make GUI.Window components that do something when clicked, but i have no idea how to make it work.
Here's what i got so far:
GUI.WindowFunction winFunction;
Rect r = new Rect(30, 30, 300, 300);
void Start(){
winFunction = windowFunction;
}
void OnGUI(){
GUI.Window(0, r, winFunction, "test");
}
void windowFunction(int windowID){
//One of the things i've tried, doesn't work for some reason.
if(Input.GetMouseButtonDown(0) && r.Contains(Input.mousePosition))
{
print("doesnt work");
}
}
Any ideas how to make it work? besides perhaps using reflection.
btw, is there a reason why you use an explicit delegate variable? Usually you just pass the callback directly to the Window function.
No reason, i just threw this together and well it's kind of a habit that stuck with me over the years.
Answer by Bunny83 · Jul 15, 2012 at 04:18 PM
The input class is ment for gameinput and shouldn't be used in OnGUI. Use the Event class in OnGUI:
void windowFunction(int windowID)
{
Event e = Event.current;
if(e.type = EventType.MouseDown && e.button == 0 && r.Contains(e.mousePosition))
{
print("should work");
}
}
OnGUI is called for many different events. The GUI functions like Button or Label handle the event internally. When you do anything "manually" in OnGUI, keep in mind to pick the right event or you would execute your code for all events.
edit
Keep in mind that all events processed inside a window callback have mouse coordinates relative to the window origin.
No, it doesn't.
Working on Unity 4.2.0f4, more than a year later :), apologies for necro. I tried what you both suggested above:
$$anonymous$$entioned option 1) Insert the EventType... condition inside window specific function when window is created (wrapped in OnGUI()).
Not mentioned option 2) Insert the EventType... condition inside OnGUI() function but outside window creation function and read them for mouseDown/up and for buttons.
Well neither of them works. Clicking inside any created windows and debugging Events shows the only types of Events are "used", "repaint" and "layout" and those are known. "Contains()" works in all cases fine and mouse buttons register correctly (0,1,2,3,..), but what they DO (so down or up) does not register. However if I click outside created windows, the types register correctly for all mouse clicks.
So if there's a way to get mouseDown/up/click or other eventtypes(keyboard?) while inside a window, please help.
Sry for spam, unsure whether I should create new comment or edit last one. I'm sure some1 will tell me :)
Anyway, I just noticed that in the above code, when checking Event.current.type from inside window creation function and starting mouse drag from outside window and finishing inside window, you get $$anonymous$$ouseDrag Events and $$anonymous$$ouseUp events correctly. However, just to repeat the problem, when starting inside the window, these events don't register correctly.
An event is only valid until a control uses it. If a control (like a button) handles a $$anonymous$$ouseDown and the event happened in the area of the button, the Button will call Event.current.Use() which will "eat" the event by overriding it with the "used" event.
The GUI is an immediate mode GUI system. The first control in OnGUI is the first who has the change to process the event.
Windows are handled a little bit differently. The layout events are passed in the usual order (which will happen before any other event) but $$anonymous$$ouse and keyboard events are sent to the active window first, even before the OnGUI function that created the window.
Once an event has been eaten it can't be processed again. All data in the Event will be "erased".
From your comment we can't deter$$anonymous$$e what you actually want to do. I suggest you post your own question since your problem is clearly not related to this question. You either have "active" gui elements in your window or you do something else wrong. Without seeing your code this is a dead-end.
As i said if an even is processed and eated by a control the event will be set to "used". You have a GUI.DragWindow without Drag area so it will use the whole window area. DragWindow will eat the $$anonymous$$ouseDown event since it will process it (it starts dragging the window). Same for $$anonymous$$ouseDrag events.
If you want your print statement to show something useful, swap the two lines:
print(Event.current.type.ToString());
GUI.DragWindow();