private void LateUpdate() { //update the status object on lateupdate, to avoid moving it multiple times in on frame if (mRunBlockView != null) { RectTransform statusRect = mStatusObj.GetComponent <RectTransform>(); statusRect.SetParent(mRunBlockView.ViewTransform, false); statusRect.anchoredPosition = new Vector2(20, -25); mRunBlockView = null; } }
/// <summary> /// Build block views for the active category, child class should implement this for custom build /// </summary> protected virtual void BuildBlockViewsForActiveCategory() { Transform contentTrans = mRootList[mActiveCategory].transform; var blockTypes = mConfig.GetBlockCategory(mActiveCategory).BlockList; foreach (string blockType in blockTypes) { BlockView block = NewBlockView(blockType, contentTrans); SetBlockCount(block); } }
protected void PickBlockView(BlockView blockView) { if (!blockView.enabled) { return; } if (mPickedBlockView != null) { Debug.LogError("Toolbox-PickBlockView: Already picked a block view."); return; } // compute the local position of the block view in coding area Vector3 localPos = BlocklyUI.WorkspaceView.CodingArea.InverseTransformPoint(blockView.ViewTransform.position); // clone a new block view for coding area mPickedBlockView = BlocklyUI.WorkspaceView.CloneBlockView(blockView, new Vector2(localPos.x, localPos.y)); if (mPickedBlockView.InToolbox) { return; } mPickedBlockView.OnBeginDrag(null); mPickedBlockView.ActivateCountText(false); //if the max number of blocks have been used disable the block if (Block.blocksAvailable.ContainsKey(blockView.BlockType) && Block.blocksAvailable[blockView.BlockType] > 0) { Block.blocksAvailable[blockView.BlockType]--; if (Block.blocksAvailable[blockView.BlockType] <= 0) { blockView.ChangeBgColor(Color.grey); blockView.enabled = false; } } blockView.UpdateCount(); OnPickBlockView(); string id = GameManager.Instance.GetBlockId(mPickedBlockView.Block); XmlNode dom = Xml.BlockToDomWithXY(mPickedBlockView.Block, false); string text = UBlockly.Xml.DomToText(dom); text = GameManager.Instance.ChangeCodeIDs(text); TrackerAsset.Instance.setVar("block_type", mPickedBlockView.Block.Type); TrackerAsset.Instance.setVar("code", "\r\n" + text); TrackerAsset.Instance.setVar("action", "create"); TrackerAsset.Instance.setVar("level", GameManager.Instance.GetCurrentLevelName().ToLower()); TrackerAsset.Instance.GameObject.Interacted(id); }
public void UpdateStatus(InterpreterUpdateState args) { switch (args.Type) { case InterpreterUpdateState.RunBlock: { mRunningBlocks.Push(args.RunningBlock); mRunBlockView = BlocklyUI.WorkspaceView.GetBlockView(args.RunningBlock); break; } case InterpreterUpdateState.FinishBlock: { if (mRunningBlocks.Count > 0 && mRunningBlocks.Peek() == args.RunningBlock) { mRunningBlocks.Pop(); if (mRunningBlocks.Count > 0) { mRunBlockView = BlocklyUI.WorkspaceView.GetBlockView(mRunningBlocks.Peek()); } } break; } case InterpreterUpdateState.Stop: { enabled = false; mRunningBlocks.Clear(); mRunBlockView = null; break; } case InterpreterUpdateState.Error: { if (!string.IsNullOrEmpty(args.Msg)) { MsgDialog dialog = DialogFactory.CreateDialog("message") as MsgDialog; dialog.SetMsg(args.Msg); Action closeEvent = () => { MessageManager.Instance.SendMessage("", MSG_TYPE.CODE_END); }; dialog.AddCloseEvent(closeEvent); } enabled = false; mRunningBlocks.Clear(); mRunBlockView = null; break; } } }
/// <summary> /// Get the background color for block view /// </summary> public Color GetColorOfBlockView(BlockView view) { foreach (var category in mConfig.BlockCategoryList) { foreach (string type in category.BlockList) { if (string.Equals(view.BlockType, type)) { return(category.Color); } } } return(Color.white); }
public static LineGroupView BuildNewLineGroup(BlockView blockView) { GameObject groupObj = new GameObject("LineGroup"); RectTransform groupTrans = groupObj.AddComponent <RectTransform>(); groupTrans.SetParent(blockView.transform); UniformRectTransform(groupTrans); LineGroupView groupView = AddViewComponent <LineGroupView>(groupObj); blockView.AddChild(groupView); return(groupView); }
/// <summary> /// Get the category name for block view /// </summary> public string GetCategoryNameOfBlockView(BlockView view) { foreach (var category in mConfig.BlockCategoryList) { foreach (string type in category.BlockList) { if (string.Equals(view.BlockType, type)) { return(category.CategoryName); } } } return(null); }
protected void UpdatePickedBlockView() { if (mPickedBlockView == null) { return; } if (!UnityEngine.Input.anyKey) { mPickedBlockView.OnEndDrag(null); mPickedBlockView = null; return; } mPickedBlockView.OnDrag(null); }
/// <summary> /// Clone the block view, and all its child block views /// </summary> public BlockView CloneBlockView(BlockView blockView, Vector2 xyPos) { if (blockView.Block == null) { Debug.LogError("CloneBlockView: the block model is null"); return(null); } Block newBlock = blockView.Block.Clone(); newBlock.XY = xyPos; BlockView newView = BuildBlockView(newBlock); return(newView); }
protected void PickBlockView(BlockView blockView) { if (mPickedBlockView != null) { Debug.LogError("Toolbox-PickBlockView: Already picked a block view."); return; } // compute the local position of the block view in coding area Vector3 localPos = BlocklyUI.WorkspaceView.CodingArea.InverseTransformPoint(blockView.ViewTransform.position); // clone a new block view for coding area mPickedBlockView = BlocklyUI.WorkspaceView.CloneBlockView(blockView, new Vector2(localPos.x, localPos.y)); mPickedBlockView.OnBeginDrag(null); OnPickBlockView(); }
public void UpdateStatus(InterpreterUpdateState args) { switch (args.Type) { case InterpreterUpdateState.RunBlock: { mRunningBlocks.Push(args.RunningBlock); mRunBlockView = BlocklyUI.WorkspaceView.GetBlockView(args.RunningBlock); break; } case InterpreterUpdateState.FinishBlock: { if (mRunningBlocks.Count > 0 && mRunningBlocks.Peek() == args.RunningBlock) { mRunningBlocks.Pop(); if (mRunningBlocks.Count > 0) { mRunBlockView = BlocklyUI.WorkspaceView.GetBlockView(mRunningBlocks.Peek()); } } break; } case InterpreterUpdateState.Stop: { enabled = false; mRunningBlocks.Clear(); mRunBlockView = null; break; } case InterpreterUpdateState.Error: { if (!string.IsNullOrEmpty(args.Msg)) { MsgDialog dialog = DialogFactory.CreateDialog("message") as MsgDialog; dialog.SetMsg(args.Msg); } enabled = false; mRunningBlocks.Clear(); mRunBlockView = null; break; } } }
public override bool CheckBin(BlockView blockView) { if (blockView.InToolbox) { return(false); } RectTransform toggleTrans = m_BinArea.transform as RectTransform; if (RectTransformUtility.RectangleContainsScreenPoint(toggleTrans, UnityEngine.Input.mousePosition, BlocklyUI.UICanvas.worldCamera)) { m_BinArea.gameObject.SetActive(true); return(true); } m_BinArea.gameObject.SetActive(false); return(false); }
protected void UpdatePickedBlockView() { if (mPickedBlockView == null) { return; } #if UNITY_EDITOR if (!UnityEngine.Input.anyKey) #else if (UnityEngine.Input.touchCount == 0) #endif { mPickedBlockView.OnEndDrag(null); mPickedBlockView = null; return; } mPickedBlockView.OnDrag(null); }
public override bool CheckBin(BlockView blockView) { if (blockView.InToolbox || nActiveCategories == 0) { return(false); } m_BinArea.SetActive(true); RectTransform toggleTrans = m_BinArea.transform as RectTransform; if (RectTransformUtility.RectangleContainsScreenPoint(toggleTrans, UnityEngine.Input.mousePosition, BlocklyUI.UICanvas.worldCamera)) { m_BinArea.transform.GetChild(0).GetComponent <Image>().color = Color.white; return(true); } m_BinArea.transform.GetChild(0).GetComponent <Image>().color = Color.grey; return(false); }
protected void SetBlockCount(BlockView block) { //Deactivate the block if it's not in the active list bool active = false; string blockType = block.BlockType; if (activeCategories != null && mActiveCategory != null && activeCategories.ContainsKey(mActiveCategory.ToLower())) { CategoryBlocks info = activeCategories[mActiveCategory.ToLower()]; active = info.activate == (info.activeBlocks.ContainsKey(blockType)); int value = (Block.blocksAvailable.ContainsKey(blockType) ? Block.blocksAvailable[blockType] : Int16.MaxValue); if (value <= 0) { block.enabled = false; block.ChangeBgColor(Color.grey); } } block.gameObject.SetActive(allActive || active); block.UpdateCount(); }
/// <summary> /// INPUT_VALUE: mTargetBlockView /// NEXT_STATEMENT: the last block view of the target statement block views chain /// </summary> public BlockView GetChildLastBlockView() { if (ConnectionType == Define.EConnection.InputValue) { return(mTargetBlockView); } BlockView nextView = mTargetBlockView; while (nextView != null) { ConnectionView nextCon = nextView.GetConnectionView(Define.EConnection.NextStatement); if (nextCon == null) { break; } nextView = nextCon.TargetBlockView; } return(nextView); }
protected void CreateVariableGetterView(string varName) { if (mVariableGetterViews.ContainsKey(varName)) { return; } GameObject parentObj; if (!mRootList.TryGetValue(Define.VARIABLE_CATEGORY_NAME, out parentObj)) { return; } Block block = mWorkspace.NewBlock(Define.VARIABLE_GET_BLOCK_TYPE); block.SetFieldValue("VAR", varName); BlockView view = NewBlockView(block, parentObj.transform); mVariableGetterViews[varName] = view; }
public virtual void BindModel(Connection connection) { if (mConnection == connection) { return; } if (mConnection != null) { UnBindModel(); } if (connection.Type != m_ConnectionType) { throw new Exception("ConnectionView must be bound to connection with the same connection type"); } mConnection = connection; mSourceBlockView = BlocklyUI.WorkspaceView.GetBlockView(mConnection.SourceBlock); mObserver = new MemorySafeConnectionObserver(this); mConnection.AddObserver(mObserver); }
protected void CreateProcedureCallerView(Procedure procedureInfo, bool hasReturn) { if (mProcedureCallerViews.ContainsKey(procedureInfo.Name)) { return; } GameObject parentObj; if (!mRootList.TryGetValue(Define.PROCEDURE_CATEGORY_NAME, out parentObj)) { return; } string blockType = hasReturn ? Define.CALL_WITH_RETURN_BLOCK_TYPE : Define.CALL_NO_RETURN_BLOCK_TYPE; Block block = mWorkspace.NewBlock(blockType); block.SetFieldValue("NAME", procedureInfo.Name); BlockView view = NewBlockView(block, parentObj.transform); mProcedureCallerViews[procedureInfo.Name] = view; }
public override void FinishCheckBin(BlockView blockView) { if (CheckBin(blockView)) { blockView.Dispose(); //Update the blockCounter in the Toolbox foreach (GameObject gO in mRootList.Values) { foreach (BlockView bw in gO.transform.GetComponentsInChildren <BlockView>()) { if (Block.blocksAvailable.ContainsKey(bw.BlockType) && Block.blocksAvailable[bw.BlockType] > 0) { //If the block was disabled we reactivate it bw.enabled = true; bw.ChangeBgColor(GetColorOfBlockView(bw)); } bw.UpdateCount(); } } } m_BinArea.gameObject.SetActive(false); }
public void OnPointerClick(PointerEventData eventData) { //todo: background outline if (eventData.button == PointerEventData.InputButton.Right && !eventData.dragging && !InToolbox && CanBeCloned(null)) { BlockView newBlock = BlocklyUI.WorkspaceView.CloneBlockView(this, XY + BlockViewSettings.Get().BumpAwayOffset); newBlock.InitIDs(); TrackerAsset.Instance.setVar("block_type", Block.Type); TrackerAsset.Instance.setVar("action", "duplicate"); TrackerAsset.Instance.setVar("new_block_id", GameManager.Instance.GetBlockId(newBlock.Block)); TrackerAsset.Instance.GameObject.Interacted(GameManager.Instance.GetBlockId(Block)); TrackerAsset.Instance.setVar("block_type", Block.Type); TrackerAsset.Instance.setVar("action", "create_clone"); XmlNode dom = Xml.BlockToDomWithXY(newBlock.Block, false); string text = UBlockly.Xml.DomToText(dom); text = GameManager.Instance.ChangeCodeIDs(text); TrackerAsset.Instance.setVar("code", "\r\n" + text); TrackerAsset.Instance.GameObject.Interacted(GameManager.Instance.GetBlockId(newBlock.Block)); } }
protected void CreateVariableHelperViews() { GameObject parentObj; if (!mRootList.TryGetValue(Define.VARIABLE_CATEGORY_NAME, out parentObj)) { return; } string varName = mWorkspace.GetAllVariables()[0].Name; List <string> blockTypes = mConfig.GetBlockCategory(Define.VARIABLE_CATEGORY_NAME).BlockList; foreach (string blockType in blockTypes) { if (!blockType.Equals(Define.VARIABLE_GET_BLOCK_TYPE)) { Block block = mWorkspace.NewBlock(blockType); block.SetFieldValue("VAR", varName); BlockView view = NewBlockView(block, parentObj.transform); mVariableHelperViews.Add(view); } } }
/// <summary> /// Get the background color for block view /// </summary> public Color GetColorOfBlockView(BlockView view) { switch (view.BlockType) { case "blocky_move_forward": return(new Color(1.0f, 0.6f, 0.3f)); case "blocky_move_backward": return(new Color(1.0f, 0.6f, 0.3f)); case "blocky_turn_left": return(new Color(0.0f, 0.8f, 0.9f)); case "blocky_turn_right": return(new Color(0.0f, 0.8f, 0.9f)); case "blocky_jump_forward": return(new Color(0.2f, 0.8f, 0.2f)); case "blocky_jump_backward": return(new Color(0.2f, 0.8f, 0.2f)); case "blocky_move_left": return(new Color(0.4f, 0.6f, 0.4f)); case "blocky_move_right": return(new Color(0.4f, 0.6f, 0.4f)); case "blocky_open_door": return(new Color(0.5f, 0.5f, 0.8f)); default: break; } foreach (var category in mConfig.BlockCategoryList) { foreach (string type in category.BlockList) { if (string.Equals(view.BlockType, type)) { return(category.Color); } } } return(Color.white); }
protected override Vector2 CalculateSize() { switch (m_ConnectionInputViewType) { case ConnectionInputViewType.Value: { //width is not concerned Vector2 size = new Vector2(BlockViewSettings.Get().ValueConnectPointRect.width, 0); if (mTargetBlockView == null) { size.y = BlockViewSettings.Get().ContentHeight; } else { size.y = mTargetBlockView.Height; } return(size); } case ConnectionInputViewType.ValueSlot: { if (mTargetBlockView == null) { return(new Vector2(BlockViewSettings.Get().MinUnitWidth, BlockViewSettings.Get().ContentHeight)); } Vector2 size = new Vector2(BlockViewSettings.Get().ValueConnectPointRect.width + mTargetBlockView.Width, mTargetBlockView.Height); return(size); } case ConnectionInputViewType.Statement: { if (mTargetBlockView == null) { return(new Vector2(70, BlockViewSettings.Get().ContentHeight + BlockViewSettings.Get().ContentMargin.bottom)); } // calculate the height by adding all child statement blocks' height Vector2 size = new Vector2(70, 0); bool addConnectPointSpace = true; BlockView nextView = mTargetBlockView; while (nextView != null) { size.y += nextView.Height; ConnectionView nextCon = nextView.GetConnectionView(Define.EConnection.NextStatement); if (nextCon == null) { addConnectPointSpace = false; break; } nextView = nextCon.TargetBlockView; } if (addConnectPointSpace) { size.y += BlockViewSettings.Get().StatementConnectPointRect.height; } size.y += BlockViewSettings.Get().ContentMargin.bottom; return(size); } } return(Vector2.zero); }
public static GameObject BuildBlockView(Block block) { GameObject blockPrefab = BlockViewSettings.Get().PrefabRoot; if (block.OutputConnection != null) { blockPrefab = BlockViewSettings.Get().PrefabRootOutput; } else if (block.PreviousConnection != null && block.NextConnection != null) { blockPrefab = BlockViewSettings.Get().PrefabRootPrevNext; } else if (block.PreviousConnection != null) { blockPrefab = BlockViewSettings.Get().PrefabRootPrev; } GameObject blockObj = GameObject.Instantiate(blockPrefab); blockObj.name = "Block_" + block.Type; RectTransform blockTrans = blockObj.GetComponent <RectTransform>(); UniformRectTransform(blockTrans); //blockview script BlockView blockView = AddViewComponent <BlockView>(blockObj); //block view's background image blockView.AddBgImage(blockObj.GetComponent <Image>()); //block view's childs: connection, lineGroup Transform mutatorEntry = null; foreach (Transform child in blockTrans) { string childName = child.name.ToLower(); if (childName.StartsWith("connection")) { //connection node views ConnectionView conView = AddViewComponent <ConnectionView>(child.gameObject); blockView.AddChild(conView, 0); if (childName.EndsWith("output")) { conView.ConnectionType = Define.EConnection.OutputValue; } else if (childName.EndsWith("prev")) { conView.ConnectionType = Define.EConnection.PrevStatement; } else if (childName.EndsWith("next")) { conView.ConnectionType = Define.EConnection.NextStatement; } //connection node view background color Image image = child.GetComponent <Image>(); if (image != null) { blockView.AddBgImage(image); } } else if (childName.Equals("linegroup")) { UniformRectTransform(child as RectTransform); //lineGroup view LineGroupView groupView = AddViewComponent <LineGroupView>(child.gameObject); blockView.AddChild(groupView); } else if (childName.Equals("mutator_entry")) { mutatorEntry = child; } else if (childName.StartsWith("block_count")) { blockView.SetCountText(child.GetComponentInChildren <Text>()); } } //check if has mutator entry if (mutatorEntry == null) { throw new Exception("There should be a mutator_entry image under block view prefab"); } if (block.Mutator == null || !block.Mutator.NeedEditor) { GameObject.DestroyImmediate(mutatorEntry.gameObject); } else { blockView.GetLineGroup(0).ReservedStartX = ((RectTransform)mutatorEntry).rect.width + BlockViewSettings.Get().ContentSpace.x; } //block view's input views, including field's views BuildInputViews(block, blockView); //block view's layout, build from the very first field blockView.BuildLayout(); //default background color blockView.ChangeBgColor(Color.blue); return(blockObj); }
public static InputView BuildInputView(Input input, LineGroupView groupView, BlockView blockView) { GameObject inputPrefab; ConnectionInputViewType viewType; if (input.Type == Define.EConnection.NextStatement) { inputPrefab = BlockViewSettings.Get().PrefabInputStatement; viewType = ConnectionInputViewType.Statement; } else if (input.SourceBlock.InputList.Count > 1 && input.SourceBlock.GetInputsInline()) { inputPrefab = BlockViewSettings.Get().PrefabInputValueSlot; viewType = ConnectionInputViewType.ValueSlot; } else { inputPrefab = BlockViewSettings.Get().PrefabInputValue; viewType = ConnectionInputViewType.Value; } GameObject inputObj = GameObject.Instantiate(inputPrefab); inputObj.name = "Input_" + (!string.IsNullOrEmpty(input.Name) ? input.Name : ""); RectTransform inputTrans = inputObj.GetComponent <RectTransform>(); inputTrans.SetParent(groupView.transform, false); UniformRectTransform(inputTrans); Transform conInputTrans = inputTrans.GetChild(0); InputView inputView = AddViewComponent <InputView>(inputObj); inputView.AlignRight = input.Align == Define.EAlign.Right; // build child field views of this input view List <Field> fields = input.FieldRow; foreach (Field field in fields) { FieldView fieldView = BuildFieldView(field); inputView.AddChild(fieldView); RectTransform fieldTrans = fieldView.GetComponent <RectTransform>(); UniformRectTransform(fieldTrans); } if (input.Type == Define.EConnection.DummyInput) { //dummy input doesn't need to have a connection point GameObject.DestroyImmediate(conInputTrans.gameObject); } else { ConnectionInputView conInputView = AddViewComponent <ConnectionInputView>(conInputTrans.gameObject); conInputView.ConnectionType = input.Type; conInputView.ConnectionInputViewType = viewType; inputView.AddChild(conInputView); conInputView.BgImage.raycastTarget = false; if (viewType != ConnectionInputViewType.ValueSlot) { blockView.AddBgImage(conInputView.BgImage); } } return(inputView); }
/// <summary> /// Build Input views, including field views, and calucate block size /// including dispose old input views with disposed input models /// </summary> public static void BuildInputViews(Block block, BlockView blockView) { bool inputsInline = block.GetInputsInline(); LineGroupView groupView = blockView.GetLineGroup(0); //1. check dispose old inputviews List <InputView> oldInputViews = blockView.GetInputViews(); foreach (InputView view in oldInputViews) { if (!block.InputList.Contains(view.Input)) { view.UnBindModel(); GameObject.DestroyImmediate(view.gameObject); } } //2. build new inputviews for (int i = 0; i < block.InputList.Count; i++) { Input input = block.InputList[i]; // build new line group view bool newLine = i > 0 && (!inputsInline || input.Connection != null && input.Connection.Type == Define.EConnection.NextStatement); if (newLine) { groupView = blockView.GetLineGroup(i); if (groupView == null) { groupView = BuildNewLineGroup(blockView); } } // build input view bool needBuild = true; foreach (InputView view in oldInputViews) { if (view.Input == input) { needBuild = false; if (view.Parent == null) { //bug fixed: this view may be removed from parent by removing its old previous sibling groupView.AddChild(view); } else if (view.Parent != groupView) { //bug fixed: need to remove from the original groupview, maybe it's different now view.Parent.RemoveChild(view); groupView.AddChild(view); } break; } } if (needBuild) { InputView inputView = BuildInputView(input, groupView, blockView); groupView.AddChild(inputView, newLine ? 0 : i); if (Application.isPlaying) { inputView.BindModel(input); } else { //static build block only needs to bind fields' model for initializing fields' properties for (int j = 0; j < inputView.Childs.Count; j++) { FieldView fieldView = inputView.Childs[j] as FieldView; if (fieldView != null) { fieldView.BindModel(input.FieldRow[j]); } } } } } //3. dispose group view without children for (int i = blockView.Childs.Count - 1; i >= 0; i--) { BaseView view = blockView.Childs[i]; if (view.Type == ViewType.LineGroup && view.Childs.Count == 0) { GameObject.DestroyImmediate(view.gameObject); } } }
/// <summary> /// Finish the check. /// If the block view is over bin, drop it. /// </summary> public abstract void FinishCheckBin(BlockView blockView);
/// <summary> /// Check the block view is over the bin area, preparing dropped in bin /// </summary> public abstract bool CheckBin(BlockView blockView);
public void RemoveBlockView(BlockView blockView) { mBlockViews.Remove(blockView.Block.ID); }