Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

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

Discussion in 'Extensions & OnGUI' 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:
    70
    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:
    273
    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.