public void StartFadeOnIcon(ConstellationMenuIcon icon, IconState newState) { bool hoverChanged = false; if (newState == IconState.Hovering) { if (hoverIcon != null) { hoverIcon.FadeIfNeeded(IconState.Hovering, IconState.Shown); } hoverIcon = icon; hoverChanged = true; } if (icon == hoverIcon && newState == IconState.Closed) { hoverIcon = null; hoverChanged = true; } if (hoverChanged) { dummyParent.OnHoverChange(GetHoverIcon()); } }
private bool IsPointingAwayFromIcon(Vector3 cameraCenter, Vector3 laserEndToCameraNormalized, ConstellationMenuIcon icon) { if (icon == null) { return(true); } return(icon.GetClosestAngle(cameraCenter, laserEndToCameraNormalized) > closeAngle); }
public bool IsDescendentOf(ConstellationMenuIcon parent) { ConstellationMenuIcon child = this; while (child != null) { if (child == parent) { return(true); } child = child.parentMenu; } return(false); }
/// Returns IconRelationship. /// AncestorOfRhs if this class is a descendant of relative (or they are the same) /// DescendantOfRhs if the opposite is true (or rhsIcon is null) /// or UnkownRelationship if neither is true. public IconRelationship GetRelationship(ConstellationMenuIcon rhsIcon) { if (rhsIcon == null || IsDescendentOf(rhsIcon)) { return(IconRelationship.DescendantOfRhs); } else if (rhsIcon.IsDescendentOf(this)) { return(IconRelationship.AncestorOfRhs); } else { return(IconRelationship.UnkownRelationship); } }
/// Helper function to create a top level icon. /// The root icon does not have any interaction or icon /// ShowRootIcon() initializes the root icon and opens the next level of icons. private ConstellationMenuIcon ShowRootIcon() { ConstellationMenuIcon rootIcon = (ConstellationMenuIcon)Instantiate(menuIconPrefab, transform); rootIcon.transform.position = menuCenter; rootIcon.transform.rotation = menuOrientation; rootIcon.Initialize(this, menuTree.tree.Root, MENU_SCALE); ConstellationMenuIcon.ShowMenu(this, menuTree.tree.Root, rootIcon, menuOrientation, MENU_SCALE); rootIcon.SetDummy(); if (OnMenuOpened != null) { OnMenuOpened.Invoke(); } return(rootIcon); }
/// Recursive call to find the child at the deepest MenuLayer public ConstellationMenuIcon GetDeepestIcon() { ConstellationMenuIcon returnValue = this; foreach (var child in childMenus) { if (child.state == IconState.Closed) { continue; } ConstellationMenuIcon otherIcon = child.GetDeepestIcon(); if (otherIcon.MenuLayer > returnValue.MenuLayer) { returnValue = otherIcon; } } return(returnValue); }
private bool StartFade(IconState nextState) { if (state == nextState) { return(false); } if (nextState == IconState.Closed && childMenus.Count > 0) { FadeChildren(IconState.Closed); } state = nextState; fadeInProgress = true; if (nextState == IconState.Closed) { menuRoot.MarkGraphDirty(); } fadeParameters = new FadeParameters(nextState); buttonActive = fadeParameters.buttonActive; SetColliderSize(Mathf.Min(boxCollider.size.x, fadeParameters.colliderSize)); menuRoot.StartFadeOnIcon(this, nextState); ConstellationMenuIcon hoverIcon = (menuRoot == null) ? null : menuRoot.GetHoverIcon(); // Change the background based on the relationship between this icon and the hoverIcon var relationship = GetRelationship(hoverIcon); tooltipAlpha.FadeTo(GetTooltipAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); iconBgAlpha.FadeTo(GetBackgroundAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); decorationLabelAlpha.FadeTo(GetDecorationLabelAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); iconScale.FadeTo(SHOWN_ICON_SCALE, ANIMATION_DURATION_SECONDS, Time.time); iconAlpha.FadeTo(fadeParameters.alpha, ANIMATION_DURATION_SECONDS, Time.time); return(true); }
/// Fades out and closes all ConstellationMenuIcon's icons except those between the root and /// this node. Ignores children nodes. public void HideAllExceptParentsAndChildren() { ConstellationMenuIcon menu = this; ConstellationMenuIcon parent = menu.parentMenu; while (parent != null) { foreach (var sibling in parent.childMenus) { if (sibling != menu) { sibling.FadeChildren(IconState.Closed); sibling.StartFade(IconState.Hidden); } } menu = parent; parent = parent.parentMenu; } }
public float MenuDepth() { if (dummyParent == null) { return(0); } float hoverDepth = 0; if (hoverIcon != null) { // hovering on leaf node moves the menu deeper as if it had children. // This is so hovering has the same results across siblings. hoverDepth = (hoverIcon.MenuLayer + 1); } if (graphDirty) { deepestIcon = dummyParent.GetDeepestIcon(); graphDirty = false; } return(Mathf.Max(hoverDepth, deepestIcon.MenuLayer)); }
/// Called recursively when any icon starts to hover. public void OnHoverChange(ConstellationMenuIcon hoverIcon) { foreach (var child in childMenus) { child.OnHoverChange(hoverIcon); } var relationship = GetRelationship(hoverIcon); decorationLabelAlpha.FadeTo(GetDecorationLabelAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); // Change the background based on the relationship between this icon and the hoverIcon iconBgAlpha.FadeTo(GetBackgroundAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); // Change the tooltip based on the relationship between this icon and the hoverIcon tooltipAlpha.FadeTo(GetTooltipAlpha(relationship), ANIMATION_DURATION_SECONDS, Time.time); // Set how easy/difficult it is to hover based on this relationship hoverDelaySeconds = GetHoverDelay(relationship); }
void Update() { // Update the menu state if it needs to suddenly open or close if (!dummyParent && IsButtonClicked()) { SetMenuLocation(); if (IsMenuInFOV()) { reticleDistance = laserPointer.defaultReticleDistance; laserPointer.defaultReticleDistance = menuDistance * POINTER_DISTANCE_SCALE; dummyParent = ShowRootIcon(); } } else if ((GvrControllerInput.ClickButtonDown && !selected) || IsPointingAway()) { CloseAll(); } else if (dummyParent && GvrControllerInput.AppButtonUp) { CloseAll(); } }
/// Creates and shows a layer of icons below this one. /// Returns true if a fade needs to occur. public static bool ShowMenu(ConstellationMenuRoot root, AssetTree.Node treeNode, ConstellationMenuIcon parent, Quaternion orientation, float scale, IconState initialState = IconState.Shown) { // Determine how many children are in the sub-menu List <AssetTree.Node> childItems = treeNode.children; // If this is the end of a menu, invoke the action and return early if (childItems.Count == 0) { root.MakeSelection(parent.menuItem); root.CloseAll(); return(false); } if (parent.childMenus.Count == childItems.Count) { // children already exist. just fade them in. bool stateChanged = false; foreach (ConstellationMenuIcon child in parent.childMenus) { if (child.StartFade(initialState)) { stateChanged = true; } // Close any children. child.FadeChildren(IconState.Closed); } return(stateChanged); } List <Vector3> childPositions; float radius; if (parent.parentMenu != null) { radius = (parent.menuCenter - parent.startPosition).magnitude + ITEM_SPACING; childPositions = ArrangeInCircle(childItems.Count, radius, parent.angleToRoot - Mathf.PI * .5f, parent.angleToRoot + Mathf.PI * .5f, ITEM_SPACING); } else { // Radius needs to expand when there are more icons radius = ITEM_SPACING * Mathf.Max(childItems.Count, MIN_ITEM_SPACE) / (2.0f * Mathf.PI); // add one unused position to item positions childPositions = ArrangeInCircle(childItems.Count + 1, radius); } for (int i = 0; i < childItems.Count; ++i) { Vector3 posOffset = childPositions[i]; ConstellationMenuIcon childMenu = (ConstellationMenuIcon)Instantiate(root.menuIconPrefab, root.transform); childMenu.transform.position = parent.menuCenter + (orientation * posOffset); childMenu.transform.rotation = orientation; childMenu.transform.localScale = Vector3.one * scale; childMenu.Initialize(root, parent, childItems[i], parent.menuCenter, scale, initialState); childMenu.angleToRoot = Mathf.Atan2(posOffset[1], posOffset[0]); } return(true); }
/// Called to make this icon visible and interactable public void Initialize(ConstellationMenuRoot root, ConstellationMenuIcon _parentMenu, AssetTree.Node node, Vector3 _menuCenter, float scale, IconState initialState) { parentMenu = _parentMenu; startPosition = transform.position; startScale = transform.localScale; menuRoot = root; menuNode = node; menuCenter = _menuCenter; savedCameraPosition = _parentMenu.savedCameraPosition; savedCameraRotation = _parentMenu.savedCameraRotation; menuOrientation = transform.rotation; // Icons are oriented up in world space. Vector3 iconToCamera = savedCameraPosition - transform.position; Quaternion rotationToCamera = Quaternion.FromToRotation(-transform.forward, iconToCamera.normalized); transform.localRotation = rotationToCamera * transform.localRotation; menuScale = scale; background = null; state = IconState.Closed; if (node != null) { // Set foreground icon menuItem = (ConstellationMenuItem)node.value; spriteRenderer.sprite = menuItem.icon; gameObject.name = menuItem.name; // Set background icon background = new GameObject(name + " Item Background"); background.transform.parent = transform.parent; background.transform.localPosition = transform.localPosition + transform.forward * BACKGROUND_ICON_ZOFFSET; background.transform.localRotation = transform.localRotation; background.transform.localScale = transform.localScale; backgroundSpriteRenderer = background.AddComponent <SpriteRenderer>(); backgroundSpriteRenderer.sprite = menuRoot.iconBackground; if (menuNode.children.Count != 0 && decorationLabelPrefab != null && menuRoot.expandableIconDecoration) { decorationLabel = Instantiate(decorationLabelPrefab, background.transform); decorationLabelRenderer = decorationLabel.GetComponent <SpriteRenderer>(); decorationLabelRenderer.sprite = menuRoot.expandableIconDecoration; decorationLabel.SetActive(false); } menuRoot.MarkGraphDirty(); float tooltipOffset; if (menuItem.tooltipSprite) { tooltip = new GameObject(name + " Tooltip Sprite"); SpriteRenderer tooltipSpriteRenderer = tooltip.AddComponent <SpriteRenderer>(); tooltipSpriteRenderer.sprite = menuItem.tooltipSprite; tooltipRenderer = tooltipSpriteRenderer; tooltip.transform.localScale *= TOOLTIP_SPRITE_SCALE; tooltipOffset = TOOLTIP_SPRITE_OFFSET; } else { tooltip = Instantiate(tooltipPrefab); tooltip.name = name + " Tooltip Text"; tooltip.GetComponent <TextMesh>().text = menuItem.toolTip.Replace('\\', '\n'); tooltipRenderer = tooltip.GetComponent <MeshRenderer>(); tooltip.transform.localScale = Vector3.one * TOOLTIP_TEXT_SCALE; tooltipOffset = TOOLTIP_TEXT_OFFSET; } tooltip.transform.SetParent(transform, false); tooltip.transform.localPosition = Vector3.up * tooltipOffset; tooltip.transform.rotation = transform.rotation; SetRendererAlpha(tooltipRenderer, DEFAULT_TOOLTIP_ALPHA); } parentMenu.childMenus.Add(this); lineToParent = GetComponent <LineRenderer>(); lineToParent.startColor = Color.clear; lineToParent.endColor = Color.clear; UpdateLines(); SetDecorationLabelAlpha(decorationLabelAlpha.ValueAtTime(Time.time)); SetBackgroundTransparency(iconBgAlpha.ValueAtTime(Time.time)); SetRendererAlpha(spriteRenderer, iconAlpha.ValueAtTime(Time.time)); StartFade(initialState); SetColliderSize(0.0f); }