I am trying to do a practice with a unity’s blog. It creates a custom GUI button which will flash red if I holding it down for longger than 2 seconds. But when I trying to follow the code in the article, I find when I hold the button down, the event.repaint would not be called, and the button would not flash red. Only when I move the mouse in and out the button area, the event.repaint will be called few times. Here is part of main code:
private void OnGUI()
{
bool clicked = FlashingButton(buttonRect, new GUIContent("FlashingButton"), EditorStyles.miniButton);
}
public bool FlashingButton(Rect rc, GUIContent content, GUIStyle style)
{
int controlID = GUIUtility.GetControlID(FocusType.Passive);
var state = (FlashingButtonInfo)GUIUtility.GetStateObject(typeof(FlashingButtonInfo), controlID);
switch (Event.current.GetTypeForControl(controlID))
{
case EventType.Repaint:
Debug.Log("repaint");
GUI.color = state.IsFlashing(controlID) ? Color.red : Color.white;
style.Draw(rc, content, controlID);
break;
case EventType.MouseDown:
Debug.Log("mouse down");
if(rc.Contains(Event.current.mousePosition)
&& Event.current.button == 0
&& GUIUtility.hotControl == 0)
{
GUIUtility.hotControl = controlID;
state.MouseDownNow();
}
break;
case EventType.MouseUp:
if(GUIUtility.hotControl == controlID)
{
GUIUtility.hotControl = 0;
}
break;
}
return GUIUtility.hotControl == controlID;
}
And the FlashingButtonInfo Class:
public class FlashingButtonInfo
{
private double mouseDownAt;
public void MouseDownNow()
{
mouseDownAt = EditorApplication.timeSinceStartup;
}
public bool IsFlashing(int controlID)
{
if (GUIUtility.hotControl != controlID)
return false;
double elapsedTime = EditorApplication.timeSinceStartup - mouseDownAt;
if (elapsedTime < 2.0f)
return false;
return (int)((elapsedTime - 2f) / 0.1f) % 2 == 0;
}
}