Search Unity

How can I change the guilayout.button text color when clicking on , and how to use also scrollbar ?

Discussion in 'Immediate Mode GUI (IMGUI)' started by haimmoshe, Aug 9, 2018.

  1. haimmoshe

    haimmoshe

    Joined:
    Jun 3, 2017
    Posts:
    237
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Diagnostics;
    5. using System.Linq;
    6. using UnityEditor;
    7. using UnityEngine;
    8. using System.IO;
    9.  
    10. public class ScriptsManager : EditorWindow
    11. {
    12.    Vector2 scrollPos;
    13.    List<GUIStyle> styles = new List<GUIStyle>();
    14.  
    15.    [MenuItem("Tools/Scripts")]
    16.    static void Scripts()
    17.    {
    18.        EditorWindow.GetWindow<ScriptsManager>();
    19.        GetWindow<ScriptsManager>().minSize = new Vector2(900,500);
    20.        GetWindow<ScriptsManager>().maxSize = new Vector2(900, 500);
    21.        GetWindow<ScriptsManager>().maximized = false;
    22.    }
    23.    
    24.    private void OnGUI()
    25.    {
    26.        string[] assetPaths = AssetDatabase.GetAllAssetPaths();
    27.  
    28.        if (styles.Count() < assetPaths.Length)
    29.        {
    30.            for (int y = 0; y < assetPaths.Length; y++)
    31.            {
    32.                styles.Add(new GUIStyle(GUI.skin.button));
    33.                styles[y].normal.textColor = Color.red;
    34.                styles[y].fontSize = 18;
    35.            }
    36.        }
    37.  
    38.        EditorGUILayout.BeginVertical();
    39.        scrollPos =
    40.            EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(900), GUILayout.Height(500));
    41.  
    42.        for (int i = 0; i < assetPaths.Length; i++)
    43.        {
    44.            if (assetPaths[i].Contains(".cs"))
    45.            {
    46.                var x = assetPaths[i].LastIndexOf("/");
    47.                var t = assetPaths[i].Substring(x + 1);
    48.  
    49.                GUILayout.Button(t, styles[i], GUILayout.Width(1000), GUILayout.Height(50));
    50.               if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
    51.                {
    52.                        OnMouseOver(i, assetPaths[i]);
    53.                }
    54.            }
    55.        }
    56.  
    57.        EditorGUILayout.EndScrollView();
    58.        EditorGUILayout.EndVertical();
    59.    }
    60.  
    61.    private void OnMouseOver(int buttinIndex, string file)
    62.    {
    63.        styles[buttinIndex].normal.textColor = Color.green;
    64.    }
    65. }
    66.  
    The problem is that I want to make a scrollbar and also to make that when I click on a specific button to change the button text color to green.

    This is the part that change the color when clicking on a button:

    Code (csharp):
    1.  
    2. GUILayout.Button(t, styles[i], GUILayout.Width(1000), GUILayout.Height(50));
    3.               if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
    4.                {
    5.                        OnMouseOver(i, assetPaths[i]);
    6.                }
    7.  
    This is working good but the problem is when I move the scrollbar up down it seems like the scrollbar is render the buttons and color them in green even if I don't click on the buttons.
    Not sure if render is the right word here but when I move the scrollbar up down it's coloring the buttons in green.

    So I tried to change the line:

    Code (csharp):
    1.  
    2. GUILayout.Button(t, styles[i], GUILayout.Width(1000), GUILayout.Height(50));
    3.  
    To:

    Code (csharp):
    1.  
    2. if(GUILayout.Button(t, styles[i], GUILayout.Width(1000), GUILayout.Height(50)))
    3.  
    So:

    Code (csharp):
    1.  
    2. if(GUILayout.Button(t, styles[i], GUILayout.Width(1000), GUILayout.Height(50)))
    3. {
    4.               if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
    5.                {
    6.                        OnMouseOver(i, assetPaths[i]);
    7.                }
    8. }
    9.  
    But then when I click on a button it will never pass the line:

    Code (csharp):
    1.  
    2.  if (Event.current.type == EventType.Repaint && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition))
    3.  
    And will never get to the line:

    Code (csharp):
    1.  
    2. OnMouseOver(i, assetPaths[i]);
    3.  
    So the problem is that I want to click on specific button and change it's color to green.
    But also using a scrollbar but that the scrollbar will not color the buttons text when scrolling up down.

    I'm stuck here.
     
  2. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    I'm assuming that you want the buttons to act as toggle switches, between red and green? That is way simpler than you'd think!

    First, use toggles instead of buttons. Those are built to keep their state. You can then store the toggle state of the buttons in a dictionary or list.

    Second, you can simply modify the style's different property states to style the button however you would like. In this case, since you're looking for toggle action, you can use the
    onNormal
    state to change the text color when the toggle is "on".

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Diagnostics;
    4. using System.Linq;
    5. using UnityEditor;
    6. using UnityEngine;
    7. using System.IO;
    8. public class ScriptsManager : EditorWindow
    9. {
    10.    Vector2 scrollPos;
    11.    List<GUIStyle> styles = new List<GUIStyle>();
    12.  
    13.    GUIStyle buttonStyle;
    14.  
    15.    Dictionary<string,bool> pathToggles = new Dictionary<string,bool>();
    16.    [MenuItem("Tools/Scripts")]
    17.    static void Scripts()
    18.    {
    19.        EditorWindow.GetWindow<ScriptsManager>();
    20.    }
    21.  
    22.    void OnEnable ()
    23.    {
    24.        buttonStyle = new GUIStyle( GUI.skin.button );
    25.        buttonStyle.normal.textColor = Color.red;
    26.        buttonStyle.fontSize = 18;
    27.        buttonStyle.onNormal.textColor = Color.green;
    28.  
    29.        minSize = new Vector2(900,500);
    30.        maxSize = new Vector2(900, 500);
    31.        maximized = false;
    32.    }
    33.  
    34.    private void OnGUI()
    35.    {
    36.        string[] assetPaths = AssetDatabase.GetAllAssetPaths();
    37.        EditorGUILayout.BeginVertical();
    38.        scrollPos =
    39.            EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(900), GUILayout.Height(500));
    40.        for (int i = 0; i < assetPaths.Length; i++)
    41.        {
    42.            var path = assetPaths[ i ];
    43.  
    44.            if (path.Contains(".cs"))
    45.            {
    46.                var toggled = false;
    47.                if( pathToggles.ContainsKey( path ) )
    48.                {
    49.                    toggled = pathToggles[ path ];
    50.                }
    51.  
    52.                var x = path.LastIndexOf("/");
    53.                var t = path.Substring(x + 1);
    54.  
    55.                if( GUILayout.Toggle( t,  ))
    56.                
    57.                EditorGUI.BeginChangeCheck();
    58.                toggled = GUILayout.Button(t, toggled, buttonStyle, GUILayout.Width(1000), GUILayout.Height(50));
    59.                if( EditorGUI.EndChangeCheck() ) {
    60.                    pathToggles[ path ] = toggled;
    61.                }
    62.            }
    63.        }
    64.        EditorGUILayout.EndScrollView();
    65.        EditorGUILayout.EndVertical();
    66.    }
    67. }
    68.  
     
    Last edited: Aug 13, 2018
  3. haimmoshe

    haimmoshe

    Joined:
    Jun 3, 2017
    Posts:
    237

    Some errors I can't fix yet in your code.

    First you declared toggled as bool and then delcared the same name variable as button:

    Code (csharp):
    1.  
    2. var toggled = false;
    3.  
    And then you did:

    Code (csharp):
    1.  
    2. var toggled = GUILayout.Button(t, toggled, buttonStyle, GUILayout.Width(1000), GUILayout.Height(50));
    3.  
    You can't declare the same variable name twice.
    Even if I change the second toggled to toggled1 it will not work and give errors.

    And another error on the line:

    Code (csharp):
    1.  
    2. if (pathToggles.Contains(path))
    3.  
    I'm using System.Linq already.

    On the pathToggles:

    Severity Code Description Project File Line Suppression State
    Error CS1929 'Dictionary<string, bool>' does not contain a definition for 'Contains' and the best extension method overload 'Queryable.Contains<string>(IQueryable<string>, string)' requires a receiver of type 'IQueryable<string>' Assembly-CSharp D:\New Unity Projects\Switch Prefabs\Assets\ScriptsManager.cs 48 Active
     
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Ah, that was a typo. I wrote this out without running it, so not super surprising there was a couple of errors.

    The second
    toggled
    var is meant to just be reusing the first. You can simply remove the var keyword.

    Similarly superficial error. Lists have a
    Contains
    method. Dictionaries don't, and instead have a
    ContainsKey
    method, which is what should be used there.

    I've updated my original post to contain these corrections.
     
    Last edited: Aug 13, 2018
    haimmoshe likes this.