private void SetRandomPositionInSpawnZone(int index, ref Vector2 point, PointArea area) { int lenght = curveComp.points.Length; float newX; newX = Random.Range(spawnLimits.lowerLeftMax.position.x, (spawnLimits.lowerLeftMin.position.x - offset)); if (area == PointArea.Left) { point.x = newX; } else if (area == PointArea.Right) { point.x = -newX; } else if (area == PointArea.Up) { float newOffset = offset / 2f; if (index == 0) { if (finalPointArea == PointArea.Left) { newX = Random.Range(newOffset, -spawnLimits.lowerLeftMax.position.x); } else { newX = Random.Range(spawnLimits.lowerLeftMax.position.x, newOffset); } } else if (index == lenght - 1) { if (initPointArea == PointArea.Left) { newX = Random.Range(newOffset, -spawnLimits.lowerLeftMax.position.x); } else { newX = Random.Range(spawnLimits.lowerLeftMax.position.x, newOffset); } } point.x = newX; point.y = Random.Range(spawnLimits.upperLeftMin.position.y, spawnLimits.upperLeftMax.position.y) + Random.Range(0.5f, offset); return; } point.y = Random.Range(spawnLimits.lowerLeftMin.position.y, spawnLimits.upperLeftMin.position.y); }
private void GetCurveAndSetPointAreas() { curveComp = newCurve.GetComponent <BezierCurve>(); PointArea[] areas = { PointArea.Left, PointArea.Up, PointArea.Right }; int index = Random.Range(0, 2); // Left or Up initPointArea = areas[index]; if (initPointArea == PointArea.Up) { index = Random.Range(0, 2) * 2; //Left Or Right } else if (initPointArea == PointArea.Left) { index = Random.Range(1, 3); // Up or Right } finalPointArea = areas[index]; }
/// <summary> /// Called when a mouse button has been released /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mRenderPanel_MouseUp(object sender, MouseEventArgs e) { mPointArea = PointArea.None; if (e.Button == MouseButtons.Left) { // We just finished placing a control - override frame 0 with the // control's new layout, without interfering with the command manager's undo/redo if (mAddControlCommand != null) { Otter.UI.Animation.GUIAnimation onActivate = mAddControlCommand.Controls[0].ParentView.Animations["OnActivate"]; if (onActivate != null) onActivate.CreateKeyFrame(mAddControlCommand.Controls[0], 0); mAddControlCommand = null; } else if (PrimaryControl != null) { if (mControlStartPos != PrimaryControl.Location) mCommandManager.AddCommand(new MoveControlCommand(SelectedControls, new PointF(PrimaryControl.Location.X - mControlStartPos.X, PrimaryControl.Location.Y - mControlStartPos.Y)), false); if (mControlStartSize != PrimaryControl.Size || mControlStartCenter != PrimaryControl.Center) { mCommandManager.AddCommand(new ResizeControlCommand(PrimaryControl, mControlStartCenter, mControlStartSize, PrimaryControl.Center, PrimaryControl.Size), false); } } } }
/// <summary> /// User clicked on the render panel. See if we selected any controls. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void mRenderPanel_MouseDown(object sender, MouseEventArgs e) { PointF hitLocation = ClientToViewport(e.Location); mLastMousePos = hitLocation; mMouseMoveStartPos = hitLocation; if (ActiveView == null) return; if (e.Button == MouseButtons.Left) { mPointArea = PointArea.None; if (CreateControlType != null) { System.Reflection.ConstructorInfo constructorInfo = CreateControlType.GetConstructor(System.Type.EmptyTypes); GUIControl control = constructorInfo.Invoke(null) as GUIControl; control.AnchorFlags = Otter.Editor.Properties.Settings.Default.AnchorFlags; if (control != null) { control.Location = new PointF(hitLocation.X, hitLocation.Y); control.ID = mActiveView.NextControlID++; control.Scene = ActiveView.Scene; control.Name = GetUniqueControlName(control); // Label Specific if (control is GUILabel && GUIProject.CurrentProject.Fonts.Count > 0) { ((GUILabel)control).FontID = GUIProject.CurrentProject.Fonts[0].ID; } // Slider Specific if (control is GUISlider) { ((GUISlider)control).StartTexture = GetTexture("Textures/Slider_Start.png", "Otter.Editor.res.ControlTextures.Slider_Start.png"); ((GUISlider)control).MiddleTexture = GetTexture("Textures/Slider_Middle.png", "Otter.Editor.res.ControlTextures.Slider_Middle.png"); ((GUISlider)control).EndTexture = GetTexture("Textures/Slider_End.png", "Otter.Editor.res.ControlTextures.Slider_End.png"); ; ((GUISlider)control).ThumbTexture = GetTexture("Textures/Slider_Thumb.png", "Otter.Editor.res.ControlTextures.Slider_Thumb.png"); ; } // Toggle Specific if (control is GUIToggle) { ((GUIToggle)control).OnTexture = GetTexture("Textures/Toggle_On.png", "Otter.Editor.res.ControlTextures.Toggle_On.png"); ((GUIToggle)control).OffTexture = GetTexture("Textures/Toggle_Off.png", "Otter.Editor.res.ControlTextures.Toggle_Off.png"); } mAddControlCommand = new AddControlCommand(ActiveView, null, control); mCommandManager.AddCommand(mAddControlCommand, true); SelectedControls.Clear(); SelectedControls.Add(control); mPointArea = PointArea.Bottom | PointArea.Right; } CreateControlType = null; } // Hit test the selected controls else { // Check to see if we've hit any of our selected controls in the body (only). // If so, move the control to the front of the list and apply the point area accordingly. foreach (GUIControl control in SelectedControls) { PointF localPoint = ViewportToControl(hitLocation, control); mPointArea = control.GetPointArea(localPoint); if (mPointArea == PointArea.Body) { PrimaryControl = control; Vector4 absPos = Vector4.Transform(new Vector4(control.Center.X, control.Center.Y, 0.0f, 1.0f), control.FullTransform); mLocationOffset = new PointF(hitLocation.X - absPos.X, hitLocation.Y - absPos.Y); break; } } if (SelectedControls.Count > 1 && mPointArea != PointArea.Body) mPointArea = PointArea.None; } // If we clicked outside of the control select a new one if possible. // Uncomment the PointArea.Body to select a new control if the body was hit if (mPointArea == PointArea.None) // || mPointArea == PointArea.Body) { GUIControl control = ActiveView.HitTest(hitLocation); control = (control is GUIView) ? null : control; // Make sure we don't select the view if (!(control is GUIView) && !SelectedControls.Contains(control)) { if (Control.ModifierKeys != Keys.Control) SelectedControls.Clear(); if(control != null) SelectedControls.Add(control); PrimaryControl = control; mPointArea = PointArea.None; // TODO : The below if-else is a copy-paste from above. FIX IT. foreach (GUIControl selectedControl in SelectedControls) { PointF localPoint = ViewportToControl(hitLocation, selectedControl); mPointArea = selectedControl.GetPointArea(localPoint); if (mPointArea == PointArea.Body) { Vector4 absPos = Vector4.Transform(new Vector4(control.Center.X, control.Center.Y, 0.0f, 1.0f), PrimaryControl.FullTransform); mLocationOffset = new PointF(hitLocation.X - absPos.X, hitLocation.Y - absPos.Y); break; } } if (SelectedControls.Count > 1 && mPointArea != PointArea.Body) mPointArea = PointArea.None; } } if (PrimaryControl != null) { mControlStartPos = PrimaryControl.Location; mControlStartCenter = PrimaryControl.Center; mControlStartSize = PrimaryControl.Size; } RefreshRenderPanel(); } }
/// <summary> /// Snaps a control to the provided line segment. /// </summary> /// <param name="control"></param> /// <param name="pointArea"></param> /// <param name="lineStart"></param> /// <param name="lineEnd"></param> private bool SnapControl(GUIControl control, PointArea pointArea, ref Vector4 lineStart, ref Vector4 lineEnd) { PointF newLoc = control.Location; PointF newCenter = control.Center; SizeF newSize = control.Size; // Transform the snap line to the control's coordinate space, that way our math is slightly // easier to manage Matrix transform = control.FullTransform; Matrix invert = control.FullTransformInv; Vector4 ls = Vector4.Transform(lineStart, invert); Vector4 le = Vector4.Transform(lineEnd, invert); PointF lv = new PointF(le.X - ls.X, le.Y - ls.Y); float llen = (float)Math.Sqrt(lv.X * lv.X + lv.Y * lv.Y); PointF ln = new PointF(lv.X / llen, lv.Y / llen); int tolerance = Otter.Editor.Properties.Settings.Default.ViewSnapTolerance; // If the line is vertical or horizontal, we have an eas(ier) case, // and we can do edge-snapping too. if (ln.X == 0.0f && ln.Y == 1.0f || ln.X == 1.0f && ln.Y == 0.0f) { PointF delta = new PointF(0.0f, 0.0f); bool bSnapped = false; // Left / Right Edge if (ln.Y == 1.0f && ls.Y <= control.Size.Height && le.Y >= 0.0f) { // Left Edge if (Math.Abs(ls.X) < tolerance) { if ((pointArea & PointArea.Left) != 0) { newSize = new SizeF(newSize.Width - ls.X, newSize.Height); newCenter = new PointF(newCenter.X - ls.X, newCenter.Y); } else { newLoc = new PointF(newLoc.X + ls.X, newLoc.Y); } bSnapped = true; } // Right Edge else if (Math.Abs(ls.X - control.Size.Width) < tolerance) { if ((pointArea & PointArea.Right) != 0) { newSize = new SizeF(newSize.Width + (ls.X - control.Size.Width), newSize.Height); } else { newLoc = new PointF(newLoc.X + ls.X - control.Size.Width, newLoc.Y); } bSnapped = true; } } // Top / Bottom Edge if (ln.X == 1.0f && ls.X <= control.Size.Width && le.X >= 0.0f) { // Top Edge if (Math.Abs(ls.Y) < tolerance) { if ((pointArea & PointArea.Top) != 0) { newSize = new SizeF(newSize.Width, newSize.Height - ls.Y); newCenter = new PointF(newCenter.X, newCenter.Y - ls.Y); } else { newLoc = new PointF(newLoc.X, newLoc.Y + ls.Y); } bSnapped = true; } // Bottom Edge else if (Math.Abs(ls.Y - control.Size.Height) < tolerance) { if ((pointArea & PointArea.Bottom) != 0) { newSize = new SizeF(newSize.Width, newSize.Height + (ls.Y - control.Size.Height)); } else { newLoc = new PointF(newLoc.X, newLoc.Y + (ls.Y - control.Size.Height)); } bSnapped = true; } } if (bSnapped) { control.Center = newCenter; control.Location = newLoc; control.Size = newSize; } return bSnapped; } // Get the corners of the control's bounds for (int i = 0; i < 4; i++) { PointF vertex = PointF.Empty; bool bContinue = false; switch (i) { // Top Left case 0: { if ((pointArea & PointArea.Body) != 0 || (pointArea & PointArea.Top) != 0 && (pointArea & PointArea.Left) != 0) { vertex = new PointF(0.0f, 0.0f); bContinue = true; } break; } // Top Right case 1: { if ((pointArea & PointArea.Body) != 0 || (pointArea & PointArea.Top) != 0 && (pointArea & PointArea.Right) != 0) { vertex = new PointF(newSize.Width, 0.0f); bContinue = true; } break; } // Bottom Left case 2: { if ((pointArea & PointArea.Body) != 0 || (pointArea & PointArea.Bottom) != 0 && (pointArea & PointArea.Left) != 0) { vertex = new PointF(0.0f, newSize.Height); bContinue = true; } break; } // Bottom Right case 3: { if ((pointArea & PointArea.Body) != 0 || (pointArea & PointArea.Bottom) != 0 && (pointArea & PointArea.Right) != 0) { vertex = new PointF(newSize.Width, newSize.Height); bContinue = true; } break; } } if (!bContinue) continue; // Let's snap the top left for now, and then see if we can make everything else "fit" PointF toVertex = new PointF(vertex.X - ls.X, vertex.Y - ls.Y); float toVertexLen = (float)Math.Sqrt(toVertex.X * toVertex.X + toVertex.Y * toVertex.Y); PointF toVertexNormal = new PointF(toVertex.X / toVertexLen, toVertex.Y / toVertexLen); float dot = toVertex.X * ln.X + toVertex.Y * ln.Y; if (dot >= 0.0f && dot <= llen) { PointF closestPt = new PointF(ls.X + ln.X * dot, ls.Y + ln.Y * dot); PointF toClosestPt = new PointF(closestPt.X - vertex.X, closestPt.Y - vertex.Y); float dist = (float)Math.Sqrt(toClosestPt.X * toClosestPt.X + toClosestPt.Y * toClosestPt.Y); if (dist <= tolerance) { // We need to snap Vector4 tmp = Vector4.Transform(new Vector4(vertex.X, vertex.Y, 0.0f, 1.0f), transform); Vector4 tgt = Vector4.Transform(new Vector4(closestPt.X, closestPt.Y, 0.0f, 1.0f), transform); // Ok, we have the snap location .. now to figure out what to do with this thing. // Simple case - dragging the entire body area. Just offset the location. if ((pointArea & PointArea.Body) != 0) { PointF delta = new PointF(tgt.X - tmp.X, tgt.Y - tmp.Y); newLoc = new PointF(newLoc.X + delta.X, newLoc.Y + delta.Y); } else { // Since we've calculated the closest point in the control's space, // it's easier to manipulate the size / center etc using the untransformed // points PointF delta = new PointF(closestPt.X - vertex.X, closestPt.Y - vertex.Y); switch (i) { // Top Left case 0: { newSize = new SizeF(newSize.Width - delta.X, newSize.Height - delta.Y); newCenter = new PointF(newCenter.X - delta.X, newCenter.Y - delta.Y); break; } // Top Right case 1: { newSize = new SizeF(newSize.Width + delta.X, newSize.Height - delta.Y); newCenter = new PointF(newCenter.X, newCenter.Y - delta.Y); break; } // Bottom Left case 2: { newSize = new SizeF(newSize.Width - delta.X, newSize.Height + delta.Y); newCenter = new PointF(newCenter.X - delta.X, newCenter.Y); break; } // Bottom Right case 3: { newSize = new SizeF(newSize.Width + delta.X, newSize.Height + delta.Y); break; } } } control.Center = newCenter; control.Location = newLoc; control.Size = newSize; return true; } } } return false; }
/// <summary> /// Gets the area that a point lies in. Location /// is relative to the control itself. /// </summary> /// <param name="location"></param> /// <returns></returns> public virtual PointArea GetPointArea(PointF location) { float halfWidth = Layout.Size.Width / 2.0f; float halfHeight = Layout.Size.Height / 2.0f; PointArea pointArea = PointArea.None; /* * if (location.X >= (Center.X - 4) && location.X <= (Center.X + 4) && * location.Y >= (Center.Y - 4) && location.Y <= (Center.Y + 4)) * { * pointArea |= PointArea.Center; * } */ if (location.X >= 0 && location.X <= Layout.Size.Width && location.Y >= 0 && location.Y <= Layout.Size.Height) { pointArea |= PointArea.Body; } { bool xl = (location.X >= -8 && location.X <= 0); bool xm = (location.X >= (halfWidth - 4) && location.X < (halfWidth + 4)); bool xr = (location.X >= (Layout.Size.Width) && location.X <= (Layout.Size.Width + 8)); bool yt = (location.Y >= -8 && location.Y <= 0); bool ym = (location.Y >= (halfHeight - 4) && location.Y < (halfHeight + 4)); bool yb = (location.Y >= (Layout.Size.Height) && location.Y <= (Layout.Size.Height + 8)); // Left Edge if (xl) { if (yt) { pointArea |= PointArea.Top | PointArea.Left; } else if (ym) { pointArea |= PointArea.Left; } else if (yb) { pointArea |= PointArea.Bottom | PointArea.Left; } } // Middle else if (xm) { if (yt) { pointArea |= PointArea.Top; } else if (yb) { pointArea |= PointArea.Bottom; } } // Right Edge else if (xr) { if (yt) { pointArea |= PointArea.Top | PointArea.Right; } else if (ym) { pointArea |= PointArea.Right; } else if (yb) { pointArea |= PointArea.Bottom | PointArea.Right; } } } return(pointArea); }