Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

[SOLVED]GUI.Button that only work with Left mouse button?

Discussion in 'Immediate Mode GUI (IMGUI)' started by AzulValium, Sep 28, 2009.

  1. AzulValium

    AzulValium

    Joined:
    Sep 14, 2009
    Posts:
    103
    Hello, I noticed that buttons respond to any mouse button. Is there anyway to avoid this? just want that respond only with the left button.

    I was thinking...maybe a box with a button style and checkin with (Event.current.type == EventType.mouseDown ) (Event.current.button == 0) will work.

    Sorry for my S***ty english !
     
  2. cosmin25

    cosmin25

    Joined:
    Jul 27, 2009
    Posts:
    23
    if (GUI.Button(new Rect(5, 5, 55, 55), "Button")&Event.current.button==0)
    {
    DoSomething();
    }
     
  3. AzulValium

    AzulValium

    Joined:
    Sep 14, 2009
    Posts:
    103
    yes but if a press another mouse button, the GUIStyleState changes to "Active" and that's what I don't want. Just want the active state if I press the left button.

    Something like this, but not sure if this is the best solution.

    Code (csharp):
    1.  
    2.         style = GUI.skin.button;
    3.         Rect buttonRect = new Rect(45, 0, 40, 40);
    4.  
    5.         if (buttonRect.Contains(Event.current.mousePosition)) {
    6.             //print("mouse over button");
    7.             if (Event.current.type == EventType.mouseDown ) {
    8.                 if (Event.current.button == 0) {
    9.                     print("left button");
    10.                     style.active.textColor = Color.cyan;
    11.                 } else if (Event.current.button == 1 || Event.current.button == 2) {
    12.                     print("another button");
    13.                     style.active = style.hover;
    14.                 }
    15.             }
    16.            
    17.         }
    18.  
    19.         if (GUI.Button(buttonRect, "Co")  Event.current.button == 0) {
    20.             print("Combine Button");
    21.  
    22.         }
    23.  
     
  4. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    There doesn't seem to be a way to filter the clicks except by writing code that blocks them as they come in - your code is probably as good a way as any to handle this.
     
  5. AzulValium

    AzulValium

    Joined:
    Sep 14, 2009
    Posts:
    103
    yes I've made few changes and is working great, thanks anyway :)
     
  6. Siccity

    Siccity

    Joined:
    Dec 7, 2013
    Posts:
    255
    For future googlers: I made a pretty solid Implementation. It uses GUI.Label to display the button, and implements the button functionality manually. It is used just like a regular button.

    Code (CSharp):
    1. /// <summary> A button that only responds to left click </summary>
    2. private bool LeftClickButton(GUIContent content, GUIStyle style, params GUILayoutOption[] options) {
    3.     Rect rect = GUILayoutUtility.GetRect(content, style, options);
    4.     return LeftClickButton(rect, content, style);
    5. }
    6.  
    7. /// <summary> A button that only responds to left click </summary>
    8. private bool LeftClickButton(Rect rect, GUIContent content, GUIStyle style) {
    9.     Event e = Event.current;
    10.     int btnID = EditorGUIUtility.GetControlID(FocusType.Passive);
    11.  
    12.     // If this button is held down and hovered, modify the style
    13.     if (EditorGUIUtility.hotControl == btnID && rect.Contains(e.mousePosition)) {
    14.         // Create a copy of the style so we can modify it
    15.         style = new GUIStyle(style);
    16.         style.normal = style.active;
    17.     }
    18.     // Draw the 'button'
    19.     GUI.Label(rect, content, style);
    20.  
    21.     // If this button has mousedown 0, set it as hotControl
    22.     if (e.type == EventType.MouseDown && e.button == 0 && rect.Contains(e.mousePosition)) {
    23.         EditorGUIUtility.hotControl = btnID;
    24.         Repaint();
    25.     }
    26.     // If this button has mouseup 0, reset hotControl
    27.     else if (e.type == EventType.MouseUp && e.button == 0 && EditorGUIUtility.hotControl == btnID) {
    28.         EditorGUIUtility.hotControl = 0;
    29.         // Only return true if mouse is released inside button area
    30.         if (rect.Contains(e.mousePosition)) {
    31.             Repaint();
    32.             return true;
    33.         }
    34.     }
    35.     // Repaint when mouse is dragged. This increases responsiveness
    36.     else if (e.type == EventType.MouseDrag && e.button == 0 && EditorGUIUtility.hotControl == btnID) {
    37.         Repaint();
    38.     }
    39.     return false;
    40. }
     
  7. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,314
    Nice job! There are some ways that this can be improved upon, however.

    It's not ideal to be creating a new GUIStyle every time you want to show the active style. Best practice is to draw the field using
    GUIStyle.Draw
    . Additionally, the window is automatically tagged to be repainted if you Use the mouse events, which is a more portable option as Repaint wouldn't be available if you were to put this in a static utility class. Not to mention that properly Using events helps prevent unwanted overlapping behaviour.

    Here's an implementation that duplicates the internal behaviour of unity's editor buttons:

    Code (CSharp):
    1. private bool LeftClickButton( GUIContent content, GUIStyle style = null, params GUILayoutOption[] options ) {
    2.     Rect rect = GUILayoutUtility.GetRect( content, style, options );
    3.     return LeftClickButton( rect, content, style );
    4. }
    5. private bool LeftClickButton( Rect rect, GUIContent content, GUIStyle style = null ) {
    6.     if( style == null ) style = GUI.skin != null ? GUI.skin.button : "Button";
    7.  
    8.     Event evt = Event.current;
    9.     int controlId = EditorGUIUtility.GetControlID( FocusType.Passive );
    10.  
    11.     switch( evt.type ) {
    12.         case EventType.MouseDown: {
    13.             if( GUIUtility.hotControl == 0 && rect.Contains( evt.mousePosition ) && evt.button == 0 ) {
    14.                 GUIUtility.hotControl = controlId;
    15.                 evt.Use();
    16.             }
    17.             break;
    18.         }
    19.         case EventType.MouseDrag: {
    20.             if( GUIUtility.hotControl == controlId ) {
    21.                 evt.Use();
    22.             }
    23.             break;
    24.         }
    25.         case EventType.MouseUp: {
    26.             if( GUIUtility.hotControl == controlId && rect.Contains( evt.mousePosition ) && evt.button == 0 ) {
    27.                 GUIUtility.hotControl = 0;
    28.                 evt.Use();
    29.                 return true;
    30.             }
    31.             break;
    32.         }
    33.         case EventType.Repaint: {
    34.             style.Draw( rect, content, controlId );
    35.             break;
    36.         }
    37.     }
    38.  
    39.     return false;
    40. }
     
    Siccity likes this.