public void OnDrop(UIReceiver receiver) { if (DropEvent != null) { DropEvent(receiver); } }
void Start() { if (receiver == null) { receiver = GetComponent <UIReceiver>(); } }
/// <summary> /// Show or hide the tooltip. /// </summary> public void ShowTooltip(bool val) { mTooltipTime = 0f; // Notify(mTooltip, "OnTooltip", val); mTooltip.OnTooltip(val); if (!val) { mTooltip = null; } }
/// <summary> /// Returns whether the widget should be currently highlighted as far as the UICamera knows. /// </summary> static public bool IsHighlighted(UIReceiver go) { for (int i = mHighlighted.Count; i > 0;) { Highlighted hl = mHighlighted[--i]; if (hl.go == go) { return(true); } } return(false); }
/// <summary> /// Update the object under the mouse if we're not using touch-based input. /// </summary> void FixedUpdate() { if (useMouse && Application.isPlaying && handlesEvents) { hoveredObject = Raycast(Input.mousePosition, ref lastHit) ? lastHit.collider.gameObject.GetComponent <UIReceiver>() : fallThrough; if (hoveredObject == null) { hoveredObject = genericEventHandler; } for (int i = 0; i < 3; ++i) { mMouse[i].current = hoveredObject; } } }
void OnDisable() { receiver = GetComponent <UIReceiver>(); receiver.ClickEvent -= OnClick; receiver.DoubleClickEvent -= OnDoubleClick; receiver.PressEvent -= OnPress; receiver.HoverEvent -= OnHover; receiver.SelectEvent -= OnSelect; receiver.InputEvent -= OnInput; receiver.ScrollEvent -= OnScroll; receiver.DragEvent -= OnDrag; receiver.DropEvent -= OnDrop; receiver.TooltipEvent -= OnTooltip; receiver.KeyEvent -= OnKey; Disable(); }
/// <summary> /// Apply or remove highlighted (hovered) state from the specified object. /// </summary> static void Highlight(UIReceiver go, bool highlighted) { if (go != null) { for (int i = mHighlighted.Count; i > 0;) { Highlighted hl = mHighlighted[--i]; if (hl == null || hl.go == null) { mHighlighted.RemoveAt(i); } else if (hl.go == go) { if (highlighted) { ++hl.counter; } else if (--hl.counter < 1) { mHighlighted.Remove(hl); go.OnHover(false); // Notify(go, "OnHover", false); } return; } } if (highlighted) { Highlighted hl = new Highlighted(); hl.go = go; hl.counter = 1; mHighlighted.Add(hl); // Notify(go, "OnHover", true); go.OnHover(true); } } }
protected virtual void OnDrop(UIReceiver receiver) { }
/// <summary> /// Update mouse input. /// </summary> public void ProcessMouse() { bool updateRaycast = (useMouse && Time.timeScale < 0.9f); if (!updateRaycast) { for (int i = 0; i < 3; ++i) { if (Input.GetMouseButton(i) || Input.GetMouseButtonUp(i)) { updateRaycast = true; break; } } } // Update the position and delta mMouse[0].pos = Input.mousePosition; mMouse[0].delta = mMouse[0].pos - lastTouchPosition; bool posChanged = (mMouse[0].pos != lastTouchPosition); lastTouchPosition = mMouse[0].pos; // Update the object under the mouse if (updateRaycast) { hoveredObject = Raycast(Input.mousePosition, ref lastHit) ? lastHit.collider.gameObject.GetComponent <UIReceiver>() : fallThrough; if (hoveredObject == null) { hoveredObject = genericEventHandler; } mMouse[0].current = hoveredObject; } // Propagate the updates to the other mouse buttons for (int i = 1; i < 3; ++i) { mMouse[i].pos = mMouse[0].pos; mMouse[i].delta = mMouse[0].delta; mMouse[i].current = mMouse[0].current; } // Is any button currently pressed? bool isPressed = false; for (int i = 0; i < 3; ++i) { if (Input.GetMouseButton(i)) { isPressed = true; break; } } if (isPressed) { // A button was pressed -- cancel the tooltip mTooltipTime = 0f; } else if (useMouse && posChanged && (!stickyTooltip || mHover != mMouse[0].current)) { if (mTooltipTime != 0f) { // Delay the tooltip mTooltipTime = Time.realtimeSinceStartup + tooltipDelay; } else if (mTooltip != null) { // Hide the tooltip ShowTooltip(false); } } // The button was released over a different object -- remove the highlight from the previous if (useMouse && !isPressed && mHover != null && mHover != mMouse[0].current) { if (mTooltip != null) { ShowTooltip(false); } Highlight(mHover, false); mHover = null; } // Process all 3 mouse buttons as individual touches if (useMouse) { for (int i = 0; i < 3; ++i) { bool pressed = Input.GetMouseButtonDown(i); bool unpressed = Input.GetMouseButtonUp(i); currentTouch = mMouse[i]; currentTouchID = -1 - i; // We don't want to update the last camera while there is a touch happening if (pressed) { currentTouch.pressedCam = currentCamera; } else if (currentTouch.pressed != null) { currentCamera = currentTouch.pressedCam; } // Process the mouse events ProcessTouch(pressed, unpressed); } currentTouch = null; } // If nothing is pressed and there is an object under the touch, highlight it if (useMouse && !isPressed && mHover != mMouse[0].current) { mTooltipTime = Time.realtimeSinceStartup + tooltipDelay; mHover = mMouse[0].current; Highlight(mHover, true); } }
/// <summary> /// Check the input and send out appropriate events. /// </summary> void Update() { // Only the first UI layer should be processing events if (!Application.isPlaying || !handlesEvents) { return; } current = this; // Update mouse input if (useMouse || (useTouch && mIsEditor)) { ProcessMouse(); } // Process touch input if (useTouch) { ProcessTouches(); } // Custom input processing if (onCustomInput != null) { onCustomInput(); } // Clear the selection on the cancel key, but only if mouse input is allowed if (useMouse && mSel != null && ((cancelKey0 != KeyCode.None && Input.GetKeyDown(cancelKey0)) || (cancelKey1 != KeyCode.None && Input.GetKeyDown(cancelKey1)))) { selectedObject = null; } // Forward the input to the selected object if (mSel != null) { string input = Input.inputString; // Adding support for some macs only having the "Delete" key instead of "Backspace" if (useKeyboard && Input.GetKeyDown(KeyCode.Delete)) { input += "\b"; } if (input.Length > 0) { if (!stickyTooltip && mTooltip != null) { ShowTooltip(false); } // Notify(mSel, "OnInput", input); mSel.OnInput(input); } } else { inputHasFocus = false; } // Update the keyboard and joystick events if (mSel != null) { ProcessOthers(); } // If it's time to show a tooltip, inform the object we're hovering over if (useMouse && mHover != null) { float scroll = Input.GetAxis(scrollAxisName); if (scroll != 0f) { mHover.OnScroll(scroll); } // Notify(mHover, "OnScroll", scroll); if (showTooltips && mTooltipTime != 0f && (mTooltipTime < Time.realtimeSinceStartup || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))) { mTooltip = mHover; ShowTooltip(true); } } current = null; }
/// <summary> /// Process the events of the specified touch. /// </summary> public void ProcessTouch(bool pressed, bool unpressed) { // Whether we're using the mouse bool isMouse = (currentTouch == mMouse[0] || currentTouch == mMouse[1] || currentTouch == mMouse[2]); float drag = isMouse ? mouseDragThreshold : touchDragThreshold; float click = isMouse ? mouseClickThreshold : touchClickThreshold; // Send out the press message if (pressed) { if (mTooltip != null) { ShowTooltip(false); } currentTouch.pressStarted = true; // Notify(currentTouch.pressed, "OnPress", false); if (currentTouch.pressed != null) { currentTouch.pressed.OnPress(false); } currentTouch.pressed = currentTouch.current; currentTouch.dragged = currentTouch.current; currentTouch.clickNotification = isMouse ? ClickNotification.BasedOnDelta : ClickNotification.Always; currentTouch.totalDelta = Vector2.zero; currentTouch.dragStarted = false; // Notify(currentTouch.pressed, "OnPress", true); if (currentTouch.pressed != null) { currentTouch.pressed.OnPress(true); } // Clear the selection if (currentTouch.pressed != mSel) { if (mTooltip != null) { ShowTooltip(false); } selectedObject = null; } } else { // If the user is pressing down and has dragged the touch away from the original object, // unpress the original object and notify the new object that it is now being pressed on. if (!stickyPress && !unpressed && currentTouch.pressStarted && currentTouch.pressed != hoveredObject) { isDragging = true; // Notify(currentTouch.pressed, "OnPress", false); currentTouch.pressed.OnPress(false); currentTouch.pressed = hoveredObject; // Notify(currentTouch.pressed, "OnPress", true); currentTouch.pressed.OnPress(true); isDragging = false; } if (currentTouch.pressed != null) { float mag = currentTouch.delta.magnitude; if (mag != 0f) { // Keep track of the total movement currentTouch.totalDelta += currentTouch.delta; mag = currentTouch.totalDelta.magnitude; // If the drag event has not yet started, see if we've dragged the touch far enough to start it if (!currentTouch.dragStarted && drag < mag) { currentTouch.dragStarted = true; currentTouch.delta = currentTouch.totalDelta; } // If we're dragging the touch, send out drag events if (currentTouch.dragStarted) { if (mTooltip != null) { ShowTooltip(false); } isDragging = true; bool isDisabled = (currentTouch.clickNotification == ClickNotification.None); // Notify(currentTouch.dragged, "OnDrag", currentTouch.delta); currentTouch.dragged.OnDrag(currentTouch.delta); isDragging = false; if (isDisabled) { // If the notification status has already been disabled, keep it as such currentTouch.clickNotification = ClickNotification.None; } else if (currentTouch.clickNotification == ClickNotification.BasedOnDelta && click < mag) { // We've dragged far enough to cancel the click currentTouch.clickNotification = ClickNotification.None; } } } } } // Send out the unpress message if (unpressed) { currentTouch.pressStarted = false; if (mTooltip != null) { ShowTooltip(false); } if (currentTouch.pressed != null) { // Notify(currentTouch.pressed, "OnPress", false); currentTouch.pressed.OnPress(false); // Send a hover message to the object, but don't add it to the list of hovered items // as it's already present. This happens when the mouse is released over the same button // it was pressed on, and since it already had its 'OnHover' event, it never got // Highlight(false), so we simply re-notify it so it can update the visible state. if (useMouse && currentTouch.pressed == mHover) { // Notify(currentTouch.pressed, "OnHover", true); currentTouch.pressed.OnHover(true); } // If the button/touch was released on the same object, consider it a click and select it if (currentTouch.dragged == currentTouch.current || (currentTouch.clickNotification != ClickNotification.None && currentTouch.totalDelta.magnitude < drag)) { if (currentTouch.pressed != mSel) { mSel = currentTouch.pressed; // Notify(currentTouch.pressed, "OnSelect", true); currentTouch.pressed.OnSelect(true); } else { mSel = currentTouch.pressed; } // If the touch should consider clicks, send out an OnClick notification if (currentTouch.clickNotification != ClickNotification.None) { float time = Time.realtimeSinceStartup; // Notify(currentTouch.pressed, "OnClick", null); currentTouch.pressed.OnClick(); if (currentTouch.clickTime + 0.35f > time) { // Notify(currentTouch.pressed, "OnDoubleClick", null); currentTouch.pressed.OnDoubleClick(); } currentTouch.clickTime = time; } } else // The button/touch was released on a different object { // Send a drop notification (for drag & drop) // Notify(currentTouch.current, "OnDrop", currentTouch.dragged); if (currentTouch.current != null) { currentTouch.current.OnDrop(currentTouch.dragged); } } } currentTouch.dragStarted = false; currentTouch.pressed = null; currentTouch.dragged = null; } }
/// <summary> /// Update touch-based events. /// </summary> public void ProcessTouches() { for (int i = 0; i < Input.touchCount; ++i) { Touch input = Input.GetTouch(i); currentTouchID = allowMultiTouch ? input.fingerId : 1; currentTouch = GetTouch(currentTouchID); bool pressed = (input.phase == TouchPhase.Began) || currentTouch.touchBegan; bool unpressed = (input.phase == TouchPhase.Canceled) || (input.phase == TouchPhase.Ended); currentTouch.touchBegan = false; if (pressed) { currentTouch.delta = Vector2.zero; } else { // Although input.deltaPosition can be used, calculating it manually is safer (just in case) currentTouch.delta = input.position - currentTouch.pos; } currentTouch.pos = input.position; hoveredObject = Raycast(currentTouch.pos, ref lastHit) ? lastHit.collider.gameObject.GetComponent <UIReceiver>() : fallThrough; if (hoveredObject == null) { hoveredObject = genericEventHandler; } currentTouch.current = hoveredObject; lastTouchPosition = currentTouch.pos; // We don't want to update the last camera while there is a touch happening if (pressed) { currentTouch.pressedCam = currentCamera; } else if (currentTouch.pressed != null) { currentCamera = currentTouch.pressedCam; } // Double-tap support if (input.tapCount > 1) { currentTouch.clickTime = Time.realtimeSinceStartup; } // Process the events from this touch ProcessTouch(pressed, unpressed); // If the touch has ended, remove it from the list if (unpressed) { RemoveTouch(currentTouchID); } currentTouch = null; // Don't consider other touches if (!allowMultiTouch) { break; } } }