// Change the value and hide the dropdown. private void OnSelectItem(IMCToggle toggle) { if (!toggle.isOn) { toggle.isOn = true; } int selectedIndex = -1; Transform tr = toggle.transform; Transform parent = tr.parent; for (int i = 0; i < parent.childCount; i++) { if (parent.GetChild(i) == tr) { // Subtract one to account for template child. selectedIndex = i - 1; break; } } if (selectedIndex < 0) { return; } value = selectedIndex; Hide(); }
public void UnregisterToggle(IMCToggle toggle) { if (m_Toggles.Contains(toggle)) { m_Toggles.Remove(toggle); } }
public void RegisterToggle(IMCToggle toggle) { if (!m_Toggles.Contains(toggle)) { m_Toggles.Add(toggle); } }
private void ValidateToggleIsInGroup(IMCToggle toggle) { if (toggle == null || !m_Toggles.Contains(toggle)) { throw new ArgumentException(string.Format("Toggle {0} is not part of ToggleGroup {1}", new object[] { toggle, this })); } }
public static GameObject CreateToggle(Resources resources) { // Set up hierarchy GameObject toggleRoot = CreateUIElementRoot("IMC Toggle", s_ThinElementSize); GameObject background = CreateUIObject("Background", toggleRoot); GameObject checkmark = CreateUIObject("Checkmark", background); GameObject childLabel = CreateUIObject("Label", toggleRoot); // Set up components IMCToggle toggle = toggleRoot.AddComponent <IMCToggle>(); toggle.isOn = true; IMCImage bgImage = background.AddComponent <IMCImage>(); bgImage.sprite = resources.standard; bgImage.type = IMCImage.Type.Sliced; bgImage.color = s_DefaultSelectableColor; IMCImage checkmarkImage = checkmark.AddComponent <IMCImage>(); checkmarkImage.sprite = resources.checkmark; IMCText label = childLabel.AddComponent <IMCText>(); label.text = "Toggle"; label.raycast = false; SetDefaultTextValues(label); //toggle.backGround = bgImage; toggle.graphic = checkmarkImage; toggle.targetGraphic = bgImage; SetDefaultColorTransitionValues(toggle); RectTransform bgRect = background.GetComponent <RectTransform>(); bgRect.anchorMin = new Vector2(0f, 1f); bgRect.anchorMax = new Vector2(0f, 1f); bgRect.anchoredPosition = new Vector2(10f, -10f); bgRect.sizeDelta = new Vector2(kThinHeight, kThinHeight); RectTransform checkmarkRect = checkmark.GetComponent <RectTransform>(); checkmarkRect.anchorMin = new Vector2(0.5f, 0.5f); checkmarkRect.anchorMax = new Vector2(0.5f, 0.5f); checkmarkRect.anchoredPosition = Vector2.zero; checkmarkRect.sizeDelta = new Vector2(20f, 20f); RectTransform labelRect = childLabel.GetComponent <RectTransform>(); labelRect.anchorMin = new Vector2(0f, 0f); labelRect.anchorMax = new Vector2(1f, 1f); labelRect.offsetMin = new Vector2(23f, 1f); labelRect.offsetMax = new Vector2(-5f, -2f); return(toggleRoot); }
public void NotifyToggleOn(IMCToggle toggle) { ValidateToggleIsInGroup(toggle); // disable all toggles in the group for (var i = 0; i < m_Toggles.Count; i++) { if (m_Toggles[i] == toggle) { continue; } m_Toggles[i].isOn = false; } }
// Show the dropdown. // // Plan for dropdown scrolling to ensure dropdown is contained within screen. // // We assume the Canvas is the screen that the dropdown must be kept inside. // This is always valid for screen space canvas modes. // For world space canvases we don't know how it's used, but it could be e.g. for an in-game monitor. // We consider it a fair constraint that the canvas must be big enough to contains dropdowns. public void Show() { m_isShow = true; lastValue = m_Value; m_isOnHideChangedExecutionOnce = true; if (!IsActive() || !IsInteractable() || m_Dropdown != null) { return; } if (!validTemplate) { SetupTemplate(); if (!validTemplate) { return; } } // Get root Canvas. var list = ListPool <Canvas> .Get(); gameObject.GetComponentsInParent(false, list); if (list.Count == 0) { return; } Canvas rootCanvas = list[0]; ListPool <Canvas> .Release(list); m_Template.gameObject.SetActive(true); // Instantiate the drop-down template m_Dropdown = CreateDropdownList(m_Template.gameObject); m_Dropdown.name = "Dropdown List"; m_Dropdown.SetActive(true); // Make drop-down RectTransform have same values as original. RectTransform dropdownRectTransform = m_Dropdown.transform as RectTransform; dropdownRectTransform.SetParent(m_Template.transform.parent, false); // Instantiate the drop-down list items // Find the dropdown item and disable it. DropdownItem itemTemplate = m_Dropdown.GetComponentInChildren <DropdownItem>(); GameObject content = itemTemplate.rectTransform.parent.gameObject; RectTransform contentRectTransform = content.transform as RectTransform; itemTemplate.rectTransform.gameObject.SetActive(true); // Get the rects of the dropdown and item Rect dropdownContentRect = contentRectTransform.rect; Rect itemTemplateRect = itemTemplate.rectTransform.rect; // Calculate the visual offset between the item's edges and the background's edges Vector2 offsetMin = itemTemplateRect.min - dropdownContentRect.min + (Vector2)itemTemplate.rectTransform.localPosition; Vector2 offsetMax = itemTemplateRect.max - dropdownContentRect.max + (Vector2)itemTemplate.rectTransform.localPosition; Vector2 itemSize = itemTemplateRect.size; m_Items.Clear(); IMCToggle prev = null; for (int i = 0; i < options.Count; ++i) { OptionData data = options[i]; DropdownItem item = AddItem(data, value == i, itemTemplate, m_Items); if (item == null) { continue; } // Automatically set up a toggle state change listener item.toggle.isOn = value == i; item.toggle.onValueChanged.AddListener(x => OnSelectItem(item.toggle)); // Select current option if (item.toggle.isOn) { item.toggle.Select(); } // Automatically set up explicit navigation if (prev != null) { Navigation prevNav = prev.navigation; Navigation toggleNav = item.toggle.navigation; prevNav.mode = Navigation.Mode.Explicit; toggleNav.mode = Navigation.Mode.Explicit; prevNav.selectOnDown = item.toggle; prevNav.selectOnRight = item.toggle; toggleNav.selectOnLeft = prev; toggleNav.selectOnUp = prev; prev.navigation = prevNav; item.toggle.navigation = toggleNav; } prev = item.toggle; } if (ShowItemAction != null) { ShowItemAction(); } // Reposition all items now that all of them have been added Vector2 sizeDelta = contentRectTransform.sizeDelta; sizeDelta.y = itemSize.y * m_Items.Count /*+ offsetMin.y - offsetMax.y*/; contentRectTransform.sizeDelta = sizeDelta; float extraSpace = dropdownRectTransform.rect.height - contentRectTransform.rect.height; if (extraSpace > 0) { dropdownRectTransform.sizeDelta = new Vector2(dropdownRectTransform.sizeDelta.x, dropdownRectTransform.sizeDelta.y - extraSpace); } // Invert anchoring and position if dropdown is partially or fully outside of canvas rect. // Typically this will have the effect of placing the dropdown above the button instead of below, // but it works as inversion regardless of initial setup. Vector3[] corners = new Vector3[4]; dropdownRectTransform.GetWorldCorners(corners); bool outside = false; RectTransform rootCanvasRectTransform = rootCanvas.transform as RectTransform; for (int i = 0; i < 4; i++) { Vector3 corner = rootCanvasRectTransform.InverseTransformPoint(corners[i]); if (!rootCanvasRectTransform.rect.Contains(corner)) { outside = true; break; } } if (outside) { RectTransformUtility.FlipLayoutOnAxis(dropdownRectTransform, 0, false, false); RectTransformUtility.FlipLayoutOnAxis(dropdownRectTransform, 1, false, false); } for (int i = 0; i < m_Items.Count; i++) { RectTransform itemRect = m_Items[i].rectTransform; itemRect.anchorMin = new Vector2(itemRect.anchorMin.x, 0); itemRect.anchorMax = new Vector2(itemRect.anchorMax.x, 0); itemRect.anchoredPosition = new Vector2(itemRect.anchoredPosition.x, /* offsetMin.y*/ +itemSize.y * (m_Items.Count - 1 - i) + itemSize.y * itemRect.pivot.y); itemRect.sizeDelta = new Vector2(itemRect.sizeDelta.x, itemSize.y); } // Fade in the popup AlphaFadeList(0.15f, 0f, 1f); // Make drop-down template and item template inactive m_Template.gameObject.SetActive(false); itemTemplate.gameObject.SetActive(false); m_Blocker = CreateBlocker(rootCanvas); }
private void SetupTemplate() { validTemplate = false; if (!m_Template) { Debug.LogError("The dropdown template is not assigned. The template needs to be assigned and must have a child GameObject with a Toggle component serving as the item.", this); return; } GameObject templateGo = m_Template.gameObject; templateGo.SetActive(true); IMCToggle itemToggle = m_Template.GetComponentInChildren <IMCToggle>(); validTemplate = true; if (!itemToggle || itemToggle.transform == template) { validTemplate = false; Debug.LogError("The dropdown template is not valid. The template must have a child GameObject with a Toggle component serving as the item.", template); } else if (!(itemToggle.transform.parent is RectTransform)) { validTemplate = false; Debug.LogError("The dropdown template is not valid. The child GameObject with a Toggle component (the item) must have a RectTransform on its parent.", template); } else if (itemText != null && !itemText.transform.IsChildOf(itemToggle.transform)) { validTemplate = false; Debug.LogError("The dropdown template is not valid. The Item Text must be on the item GameObject or children of it.", template); } else if (itemImage != null && !itemImage.transform.IsChildOf(itemToggle.transform)) { validTemplate = false; Debug.LogError("The dropdown template is not valid. The Item Image must be on the item GameObject or children of it.", template); } if (!validTemplate) { templateGo.SetActive(false); return; } DropdownItem item = itemToggle.gameObject.AddComponent <DropdownItem>(); item.text = m_ItemText; item.image = m_ItemImage; item.toggle = itemToggle; item.rectTransform = (RectTransform)itemToggle.transform; Canvas popupCanvas = GetOrAddComponent <Canvas>(templateGo); popupCanvas.overrideSorting = true; popupCanvas.sortingOrder = 30000; GetOrAddComponent <IMCGraphicRaycaster>(templateGo); GetOrAddComponent <CanvasGroup>(templateGo); templateGo.SetActive(false); validTemplate = true; }
public static GameObject CreateTabView(Resources resources) { GameObject go = CreateUIElementRoot("IMC Tab View", s_ImageElementSize); go.AddComponent <CanvasGroup>(); IMCTabView tabView = go.AddComponent <IMCTabView>(); IMCImage image = go.AddComponent <IMCImage>(); image.sprite = resources.background; image.type = IMCImage.Type.Sliced; image.color = s_PanelColor; RectTransform tabViewRT = go.GetComponent <RectTransform>(); tabViewRT.sizeDelta = new Vector2(600, 250); tabViewRT.pivot = new Vector2(0.5f, 1); GameObject toggleContainer = CreateUIElementRoot("ToggleContainer", s_ImageElementSize); RectTransform toggleContainerRT = toggleContainer.GetComponent <RectTransform>(); toggleContainerRT.SetParent(tabViewRT); toggleContainerRT.anchorMin = new Vector2(0.5f, 1); toggleContainerRT.anchorMax = new Vector2(0.5f, 1); toggleContainerRT.pivot = new Vector2(0.5f, 0); toggleContainerRT.anchoredPosition = Vector2.zero; toggleContainerRT.sizeDelta = new Vector2(600, 50); ContentSizeFitter contentSizeFitter = toggleContainer.AddComponent <ContentSizeFitter>(); contentSizeFitter.horizontalFit = IMCUI.UI.ContentSizeFitter.FitMode.PreferredSize; toggleContainer.AddComponent <IMCHorizontalLayoutGroup>(); ToggleGroup toggleGroup = toggleContainer.AddComponent <ToggleGroup>(); for (int i = 0; i <= 2; i++) { GameObject toggle = CreateToggle(resources); toggle.transform.FindChild("Label").GetComponent <IMCText>().raycast = false;//if don't shut down IMCText is raycast attribute ,occur BUG. IMCTabViewToggle tabViewToggle = toggle.AddComponent <IMCTabViewToggle>(); tabViewToggle.tabView = tabViewRT.GetComponent <IMCTabView>(); tabViewRT.GetComponent <IMCTabView>().toggles.Add(tabViewToggle); // in editor script , add event invalidity. //tabViewToggle.toggle.onValueChanged.AddListener(tabViewToggle.parent.TabViewControlShowOrClose); IMCToggle toggleT = toggle.GetComponent <IMCToggle>(); toggleT.name = toggleT.name + i.ToString(); toggleT.transform.SetParent(toggleContainerRT); toggleT.group = toggleGroup; // because toggleContainer is ToggleGroup component,ToggleGroup is Execution order impact Toggle,so annotation this code . //if (i == 0) // toggleT.isOn = true; //else // toggleT.isOn = false; RectTransform backGround = toggle.transform.GetChild(0).GetComponent <RectTransform>(); backGround.anchorMin = Vector2.zero; backGround.anchorMax = Vector2.one; backGround.pivot = Vector2.zero; backGround.anchoredPosition = Vector2.zero; backGround.sizeDelta = Vector2.zero; RectTransform checkmark = backGround.GetChild(0).GetComponent <RectTransform>(); checkmark.anchorMin = Vector2.zero; checkmark.anchorMax = Vector2.one; checkmark.anchoredPosition = Vector2.zero; checkmark.sizeDelta = Vector2.zero; RectTransform labelRT = toggle.transform.GetChild(1).GetComponent <RectTransform>(); labelRT.anchoredPosition = Vector2.zero; labelRT.sizeDelta = Vector2.zero; labelRT.GetComponent <IMCText>().alignment = TextAnchor.MiddleCenter; LayoutElement layoutElement = toggle.AddComponent <LayoutElement>(); layoutElement.preferredWidth = 200; layoutElement.preferredHeight = 20; } GameObject contentContainer = CreateUIElementRoot("ContentContainer", s_ImageElementSize); RectTransform contentContainerRT = contentContainer.GetComponent <RectTransform>(); contentContainerRT.sizeDelta = tabViewRT.sizeDelta; contentContainerRT.SetParent(tabViewRT); contentContainerRT.anchoredPosition = Vector2.zero; for (int i = 0; i <= 2; i++) { GameObject toggleContent = CreateUIElementRoot("TabContent" + i.ToString(), s_ImageElementSize); IMCImage toggleContentImage = toggleContent.AddComponent <IMCImage>(); toggleContentImage.sprite = resources.background; toggleContentImage.type = IMCImage.Type.Sliced; toggleContentImage.color = s_PanelColor; tabViewRT.GetComponent <IMCTabView>().contents.Add(toggleContentImage); RectTransform toggleContentRT = toggleContent.GetComponent <RectTransform>(); toggleContentRT.sizeDelta = tabViewRT.sizeDelta; toggleContentRT.SetParent(contentContainerRT); toggleContentRT.anchoredPosition = Vector2.zero; } return(go); }
public static GameObject CreateDropdown(Resources resources) { GameObject root = CreateUIElementRoot("IMC Dropdown", s_ThickElementSize); GameObject label = CreateUIObject("Label", root); GameObject arrow = CreateUIObject("Arrow", root); GameObject template = CreateUIObject("Template", root); GameObject viewport = CreateUIObject("Viewport", template); GameObject content = CreateUIObject("Content", viewport); GameObject item = CreateUIObject("Item", content); GameObject itemBackground = CreateUIObject("Item Background", item); GameObject itemCheckmark = CreateUIObject("Item Checkmark", item); GameObject itemLabel = CreateUIObject("Item Label", item); // Sub controls. GameObject scrollbar = CreateScrollbar(resources); scrollbar.name = "Scrollbar"; SetParentAndAlign(scrollbar, template); IMCScrollbar scrollbarScrollbar = scrollbar.GetComponent <IMCScrollbar>(); scrollbarScrollbar.SetDirection(IMCScrollbar.Direction.BottomToTop, true); RectTransform vScrollbarRT = scrollbar.GetComponent <RectTransform>(); vScrollbarRT.anchorMin = Vector2.right; vScrollbarRT.anchorMax = Vector2.one; vScrollbarRT.pivot = Vector2.one; vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0); // Setup item UI components. IMCText itemLabelText = itemLabel.AddComponent <IMCText>(); itemLabelText.raycast = false; SetDefaultTextValues(itemLabelText); itemLabelText.alignment = TextAnchor.MiddleLeft; IMCImage itemBackgroundImage = itemBackground.AddComponent <IMCImage>(); itemBackgroundImage.color = new Color32(245, 245, 245, 255); IMCImage itemCheckmarkImage = itemCheckmark.AddComponent <IMCImage>(); itemCheckmarkImage.sprite = resources.checkmark; IMCToggle itemToggle = item.AddComponent <IMCToggle>(); itemToggle.targetGraphic = itemBackgroundImage; itemToggle.graphic = itemCheckmarkImage; itemToggle.isOn = true; // Setup template UI components. IMCImage templateImage = template.AddComponent <IMCImage>(); templateImage.sprite = resources.standard; templateImage.type = IMCImage.Type.Sliced; IMCScrollRect templateScrollRect = template.AddComponent <IMCScrollRect>(); templateScrollRect.content = (RectTransform)content.transform; templateScrollRect.viewport = (RectTransform)viewport.transform; templateScrollRect.horizontal = false; templateScrollRect.movementType = IMCScrollRect.MovementType.Clamped; templateScrollRect.verticalScrollbar = scrollbarScrollbar; templateScrollRect.verticalScrollbarVisibility = IMCScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport; templateScrollRect.verticalScrollbarSpacing = -3; Mask scrollRectMask = viewport.AddComponent <Mask>(); scrollRectMask.showMaskGraphic = false; IMCImage viewportImage = viewport.AddComponent <IMCImage>(); viewportImage.sprite = resources.mask; viewportImage.type = IMCImage.Type.Sliced; // Setup dropdown UI components. IMCText labelText = label.AddComponent <IMCText>(); SetDefaultTextValues(labelText); labelText.text = "Option A"; labelText.raycast = false; labelText.alignment = TextAnchor.MiddleLeft; IMCImage arrowImage = arrow.AddComponent <IMCImage>(); arrowImage.sprite = resources.dropdown; IMCImage backgroundImage = root.AddComponent <IMCImage>(); backgroundImage.sprite = resources.standard; backgroundImage.color = s_DefaultSelectableColor; backgroundImage.type = IMCImage.Type.Sliced; IMCDropdown dropdown = root.AddComponent <IMCDropdown>(); dropdown.targetGraphic = backgroundImage; SetDefaultColorTransitionValues(dropdown); dropdown.template = template.GetComponent <RectTransform>(); dropdown.captionText = labelText; dropdown.itemText = itemLabelText; // Setting default Item list. itemLabelText.text = "Option A"; dropdown.options.Add(new IMCDropdown.OptionData { text = "Option A" }); dropdown.options.Add(new IMCDropdown.OptionData { text = "Option B" }); dropdown.options.Add(new IMCDropdown.OptionData { text = "Option C" }); // Set up RectTransforms. RectTransform labelRT = label.GetComponent <RectTransform>(); labelRT.anchorMin = Vector2.zero; labelRT.anchorMax = Vector2.one; labelRT.offsetMin = new Vector2(10, 6); labelRT.offsetMax = new Vector2(-25, -7); RectTransform arrowRT = arrow.GetComponent <RectTransform>(); arrowRT.anchorMin = new Vector2(1, 0.5f); arrowRT.anchorMax = new Vector2(1, 0.5f); arrowRT.sizeDelta = new Vector2(20, 20); arrowRT.anchoredPosition = new Vector2(-15, 0); RectTransform templateRT = template.GetComponent <RectTransform>(); templateRT.anchorMin = new Vector2(0, 0); templateRT.anchorMax = new Vector2(1, 0); templateRT.pivot = new Vector2(0.5f, 1); templateRT.anchoredPosition = new Vector2(0, 2); templateRT.sizeDelta = new Vector2(0, 150); RectTransform viewportRT = viewport.GetComponent <RectTransform>(); viewportRT.anchorMin = new Vector2(0, 0); viewportRT.anchorMax = new Vector2(1, 1); viewportRT.sizeDelta = new Vector2(-18, 0); viewportRT.pivot = new Vector2(0, 1); RectTransform contentRT = content.GetComponent <RectTransform>(); contentRT.anchorMin = new Vector2(0f, 1); contentRT.anchorMax = new Vector2(1f, 1); contentRT.pivot = new Vector2(0.5f, 1); contentRT.anchoredPosition = new Vector2(0, 0); contentRT.sizeDelta = new Vector2(0, 28); RectTransform itemRT = item.GetComponent <RectTransform>(); itemRT.anchorMin = new Vector2(0, 0.5f); itemRT.anchorMax = new Vector2(1, 0.5f); itemRT.sizeDelta = new Vector2(0, 20); RectTransform itemBackgroundRT = itemBackground.GetComponent <RectTransform>(); itemBackgroundRT.anchorMin = Vector2.zero; itemBackgroundRT.anchorMax = Vector2.one; itemBackgroundRT.sizeDelta = Vector2.zero; RectTransform itemCheckmarkRT = itemCheckmark.GetComponent <RectTransform>(); itemCheckmarkRT.anchorMin = new Vector2(0, 0.5f); itemCheckmarkRT.anchorMax = new Vector2(0, 0.5f); itemCheckmarkRT.sizeDelta = new Vector2(20, 20); itemCheckmarkRT.anchoredPosition = new Vector2(10, 0); RectTransform itemLabelRT = itemLabel.GetComponent <RectTransform>(); itemLabelRT.anchorMin = Vector2.zero; itemLabelRT.anchorMax = Vector2.one; itemLabelRT.offsetMin = new Vector2(20, 1); itemLabelRT.offsetMax = new Vector2(-10, -2); template.SetActive(false); return(root); }