/// <summary> /// Searches for a bubble group in which the specified bubble /// is a member. If a group is found, this object's BubblesInGroup /// collection will contain the bubbles in that group afterwards. /// </summary> /// <param name="bubble"> /// The bubble with which to begin searching for a group. /// </param> /// <returns> /// Returns this object, enabling a fluid-style API usage. /// </returns> internal BubbleGroup FindBubbleGroup(BubbleViewModel bubble) { if (bubble == null) { throw new ArgumentNullException("bubble"); } bool isBubbleInCurrentGroup = this.BubblesInGroup.Contains(bubble); if (!isBubbleInCurrentGroup) { this.BubblesInGroup.Clear(); this.SearchForGroup(bubble); bool addOriginalBubble = this.HasBubbles && !this.BubblesInGroup.Contains(bubble); if (addOriginalBubble) { this.BubblesInGroup.Add(bubble); } } return(this); }
private void ProcessMerge(BubbleViewModel bubbleViewModel) { var matchingBubbles = GetConnectedMatchingBubbles(bubbleViewModel); if (matchingBubbles.Count <= 0) { _isMerging.Value = false; return; } var resultExponent = bubbleViewModel.Exponent.Value + matchingBubbles.Count; matchingBubbles.Add(bubbleViewModel); var mergeTarget = GetMergeTarget(matchingBubbles, resultExponent); matchingBubbles.Remove(mergeTarget); matchingBubbles.ForEach(bubble => { bubble.SetMergeTarget(mergeTarget.GridPosition.Value); RemoveBubble(bubble); }); mergeTarget.SetExponentAfterMerge(resultExponent); mergeTarget.Exponent .SkipLatestValueOnSubscribe() .Subscribe(_ => ProcessMerge(mergeTarget)) .AddTo(_mergeSubscriptionDisposer); }
/// <summary> /// Thumb drag completed event handler /// </summary> private void MoveThumbDragCompleted(object sender, DragCompletedEventArgs e) { if (this.DataContext is BaseQuestionViewModel) { // move question BaseQuestionViewModel questionViewModel = (BaseQuestionViewModel)this.DataContext; double deltaTop = this.startTop - questionViewModel.Top; double deltaLeft = this.startLeft - questionViewModel.Left; if (Math.Abs(deltaTop) > 0.01 || Math.Abs(deltaLeft) > 0.01) { if (questionViewModel.ParentTemplate != null) { // moving choicebox question, check all other selected questions List <BaseQuestionViewModel> selectedItems = questionViewModel.ParentTemplate.SelectedElements.ToList(); ActionTracker.TrackChangeQuestionsPosition(selectedItems, deltaTop, deltaLeft, 1, 1); if (questionViewModel.ParentTemplate.GotSnapLines) { questionViewModel.ParentTemplate.CleanSnapLines(); } } else if (questionViewModel is ChoiceBoxViewModel) { if (((ChoiceBoxViewModel)questionViewModel).ParentGrid != null) { // moving choicebox child of grid question ActionTracker.TrackChangeQuestionsPosition(new List <BaseQuestionViewModel>() { questionViewModel }, deltaTop, deltaLeft, 1, 1); } } } if (questionViewModel.ParentTemplate != null) { if (questionViewModel.ParentTemplate.GotSnapLines) { questionViewModel.ParentTemplate.CleanSnapLines(); } } } else if (this.DataContext is BubbleViewModel) { // move bubble BubbleViewModel bubbleViewModel = (BubbleViewModel)this.DataContext; double deltaTop = this.bubbleStartTop - bubbleViewModel.Top; double deltaLeft = this.bubbleStartLeft - bubbleViewModel.Left; if (Math.Abs(deltaTop) > 0.01 || Math.Abs(deltaLeft) > 0.01) { ActionTracker.TrackChangeBubble(new List <BubbleViewModel> { bubbleViewModel }, deltaTop, deltaLeft, 1, 1); } } }
static Duration CalculateDuration(BubbleTaskGroup taskGroup, BubbleViewModel bubble, int millisecondsPerUnit) { var bubbleTask = taskGroup.SingleOrDefault(t => t.Bubble == bubble); int totalMilliseconds; switch (taskGroup.TaskType) { case BubbleTaskType.Burst: case BubbleTaskType.Add: totalMilliseconds = millisecondsPerUnit; break; case BubbleTaskType.MoveDown: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubbleTask.MoveDistance); break; case BubbleTaskType.MoveRight: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubbleTask.MoveDistance); break; default: throw new ArgumentException("Unrecognized BubblesTaskType value: " + taskGroup.TaskType, "taskType"); } return(new Duration(TimeSpan.FromMilliseconds(totalMilliseconds))); }
/// <summary> /// Thumb drag started event handler /// </summary> private void ResizeThumbDragStarted(object sender, DragStartedEventArgs e) { if (this.DataContext is BaseQuestionViewModel) { // resize question BaseQuestionViewModel questionViewModel = (BaseQuestionViewModel)this.DataContext; // remember starting top and left position for measuring delta when drag is completed this.startWidth = questionViewModel.Width; this.startHeight = questionViewModel.Height; this.startTop = questionViewModel.Top; this.startLeft = questionViewModel.Left; } else if (this.DataContext is BubbleViewModel) { // resize bubble BubbleViewModel bubbleViewModel = (BubbleViewModel)this.DataContext; BubbleViewModel bubble = bubbleViewModel.ParentQuestion.Bubbles[0]; this.bubbleStartWidth = bubble.Width; this.bubbleStartHeight = bubble.Height; this.bubbleStartTop = bubble.Top; this.bubbleStartLeft = bubble.Left; } }
IEnumerable <BubbleViewModel> FindMatchingNeighbors(BubbleViewModel bubble) { var matches = new List <BubbleViewModel>(); // Check above. var match = this.TryFindMatch(bubble.Row - 1, bubble.Column, bubble.BubbleType); if (match != null) { matches.Add(match); } // Check below. match = this.TryFindMatch(bubble.Row + 1, bubble.Column, bubble.BubbleType); if (match != null) { matches.Add(match); } // Check left. match = this.TryFindMatch(bubble.Row, bubble.Column - 1, bubble.BubbleType); if (match != null) { matches.Add(match); } // Check right. match = this.TryFindMatch(bubble.Row, bubble.Column + 1, bubble.BubbleType); if (match != null) { matches.Add(match); } return(matches); }
static Duration CalculateDuration( BubblesTaskType taskType, BubbleViewModel bubble, int millisecondsPerUnit) { int totalMilliseconds; switch (taskType) { case BubblesTaskType.Burst: totalMilliseconds = millisecondsPerUnit; break; case BubblesTaskType.MoveDown: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubble.Row - bubble.PreviousRow); break; case BubblesTaskType.MoveRight: totalMilliseconds = millisecondsPerUnit * Math.Abs(bubble.Column - bubble.PreviousColumn); break; default: throw new ArgumentException("Unrecognized BubblesTaskType value: " + taskType, "taskType"); } return(new Duration(TimeSpan.FromMilliseconds(totalMilliseconds))); }
/// <summary> /// Creates choice box view model from choice box model /// </summary> /// <param name="choiceBox">Choice box model data</param> /// <param name="templateViewModel">Parent template</param> /// <returns>Created choice box view model</returns> private static ChoiceBoxViewModel CreateChoiceBoxViewModel(ChoiceBoxElement choiceBox, TemplateViewModel templateViewModel) { ChoiceBoxViewModel choiceBoxViewModel = new ChoiceBoxViewModel( choiceBox.Name, choiceBox.Top, choiceBox.Left, choiceBox.Width, choiceBox.Height, templateViewModel, null); foreach (OmrBubble modelBubble in choiceBox.Bubbles) { BubbleViewModel bubbleViewModel = new BubbleViewModel( choiceBox.BubbleWidth, choiceBox.BubbleHeight, modelBubble.Top - choiceBox.Top, modelBubble.Left - choiceBox.Left, choiceBoxViewModel); bubbleViewModel.Name = modelBubble.Value; bubbleViewModel.IsValid = modelBubble.IsValid; choiceBoxViewModel.Bubbles.Add(bubbleViewModel); } return(choiceBoxViewModel); }
private List <BubbleViewModel> GetEqualExponentNeighbors(BubbleViewModel bubbleViewModel) { var gridPos = bubbleViewModel.GridPosition.Value; var exponent = bubbleViewModel.Exponent.Value; var neighbors = GetNeighbors(gridPos) .Where(bubble => bubble.Exponent.Value == exponent).ToList(); return(neighbors); }
private void StartMerging(BubbleViewModel bubbleViewModel) { _mergeSubscriptionDisposer.Clear(); _isMerging.Value = true; var mergeGridPos = bubbleViewModel.GridPosition.Value; var neighbors = GetNeighbors(mergeGridPos); neighbors.ForEach(n => n.SetAddedNeighbor(mergeGridPos)); ProcessMerge(bubbleViewModel); }
public void AddBubble(BubbleViewModel bubbleViewModel, bool processMerges = false) { _bubbleViewModels.Add(bubbleViewModel.GridPosition.Value, bubbleViewModel); if (processMerges) { _bubbleAddedSerialDisposable.Disposable = bubbleViewModel.IsOnGrid .SkipLatestValueOnSubscribe() .IfTrue() .Subscribe(_ => StartMerging(bubbleViewModel)); } }
/// <summary> /// Creates grid view model from grid model /// </summary> /// <param name="gridElement">Grid model data</param> /// <param name="templateViewModel">Parent template</param> /// <returns>Created grid view model</returns> private static GridViewModel CreateGridViewModel(GridElement gridElement, TemplateViewModel templateViewModel) { GridViewModel gridViewModel = new GridViewModel( gridElement.Name, gridElement.Top, gridElement.Left, gridElement.Width, gridElement.Height, templateViewModel, gridElement.Orientation); gridViewModel.ChoiceBoxes.Clear(); List <ChoiceBoxViewModel> choiceBoxes = new List <ChoiceBoxViewModel>(); foreach (var omrElement in gridElement.ChoiceBoxes) { var choiceBox = (ChoiceBoxElement)omrElement; ChoiceBoxViewModel choiceBoxViewModel = new ChoiceBoxViewModel( choiceBox.Name, choiceBox.Top - gridElement.Top, choiceBox.Left - gridElement.Left, choiceBox.Width, choiceBox.Height, null, gridViewModel); foreach (OmrBubble modelBubble in choiceBox.Bubbles) { BubbleViewModel bubbleViewModel = new BubbleViewModel( choiceBox.BubbleWidth, choiceBox.BubbleHeight, modelBubble.Top - choiceBox.Top, modelBubble.Left - choiceBox.Left, choiceBoxViewModel); bubbleViewModel.Name = modelBubble.Value; bubbleViewModel.IsValid = modelBubble.IsValid; choiceBoxViewModel.Bubbles.Add(bubbleViewModel); } choiceBoxes.Add(choiceBoxViewModel); } gridViewModel.InitiWithChoiceBoxes(choiceBoxes); return(gridViewModel); }
private List <BubbleViewModel> GetConnectedMatchingBubbles(BubbleViewModel bubbleViewModel) { var connectedBubbles = GetEqualExponentNeighbors(bubbleViewModel); for (var idx = 0; idx < connectedBubbles.Count; idx++) { var neighbor = connectedBubbles[idx]; var unknownNeighbors = GetEqualExponentNeighbors(neighbor) .Where(n => !connectedBubbles.Contains(n) && n != bubbleViewModel).ToList(); connectedBubbles.AddRange(unknownNeighbors); } return(connectedBubbles); }
private (int MinExponentDiff, int MinExponentDiffMatchCount) GetNeighborsSortingInfo( BubbleViewModel bubble, List <BubbleViewModel> bubblesToExclude, int resultExponent) { var neighborDiffs = GetNeighbors(bubble.GridPosition.Value) .Where(n => !bubblesToExclude.Contains(n)) .Select(n => new { Bubble = n, Diff = n.Exponent.Value - resultExponent }) .Where(tuple => tuple.Diff >= 0) .ToList(); var min = neighborDiffs.Count > 0 ? neighborDiffs.Min(tuple => tuple.Diff) : int.MaxValue; var count = neighborDiffs.Count(tuple => tuple.Diff == min); return(MinExponentDiff : min, MinExponentDiffMatchCount : count); }
void SearchForGroup(BubbleViewModel bubble) { if (bubble == null) { throw new ArgumentNullException("bubble"); } foreach (BubbleViewModel groupMember in this.FindMatchingNeighbors(bubble)) { if (!this.BubblesInGroup.Contains(groupMember)) { this.BubblesInGroup.Add(groupMember); this.SearchForGroup(groupMember); } } }
/// <summary> /// Thumb drag started event handler /// </summary> private void MoveThumbDragStarted(object sender, DragStartedEventArgs e) { if (this.DataContext is BaseQuestionViewModel) { // move question BaseQuestionViewModel questionViewModel = (BaseQuestionViewModel)this.DataContext; this.startTop = questionViewModel.Top; this.startLeft = questionViewModel.Left; } else if (this.DataContext is BubbleViewModel) { // move bubble BubbleViewModel bubbleViewModel = (BubbleViewModel)this.DataContext; this.bubbleStartTop = bubbleViewModel.Top; this.bubbleStartLeft = bubbleViewModel.Left; } }
/// <summary> /// Creates grid view model from grid model /// </summary> /// <param name="gridElement">Grid model data</param> /// <returns>Created grid view model</returns> private static GridViewModel CreateGridViewModel(GridElement gridElement) { GridViewModel gridViewModel = new GridViewModel( gridElement.Name, gridElement.Top, gridElement.Left, gridElement.Width, gridElement.Height); gridViewModel.Orientation = gridElement.Orientation; gridViewModel.ChoiceBoxes.Clear(); foreach (var omrElement in gridElement.ChoiceBoxes) { var choiceBox = (ChoiceBoxElement)omrElement; ChoiceBoxViewModel choiceBoxViewModel = new ChoiceBoxViewModel( choiceBox.Name, choiceBox.Top - gridElement.Top, choiceBox.Left - gridElement.Left, choiceBox.Width, choiceBox.Height); foreach (OmrBubble modelBubble in choiceBox.Bubbles) { BubbleViewModel bubbleViewModel = new BubbleViewModel( choiceBox.BubbleWidth, choiceBox.BubbleHeight, modelBubble.Top - choiceBox.Top, modelBubble.Left - choiceBox.Left); bubbleViewModel.Name = modelBubble.Value; bubbleViewModel.IsValid = modelBubble.IsValid; choiceBoxViewModel.Bubbles.Add(bubbleViewModel); } gridViewModel.ChoiceBoxes.Add(choiceBoxViewModel); } return(gridViewModel); }
/// <summary> /// Thumb drag completed event handler /// </summary> private void ResizeThumbDragCompleted(object sender, DragCompletedEventArgs e) { if (this.DataContext is BaseQuestionViewModel) { // resize question BaseQuestionViewModel questionViewModel = (BaseQuestionViewModel)this.DataContext; double deltaTop = this.startTop - questionViewModel.Top; double deltaLeft = this.startLeft - questionViewModel.Left; double widthKoef = this.startWidth / questionViewModel.Width; double heightKoef = this.startHeight / questionViewModel.Height; if (questionViewModel.ParentTemplate != null) { List<BaseQuestionViewModel> selectedItems = questionViewModel.ParentTemplate.SelectedElements.ToList(); ActionTracker.TrackChangeQuestionsPosition(selectedItems, deltaTop, deltaLeft, widthKoef, heightKoef); } else if (questionViewModel is ChoiceBoxViewModel) { var choiceBoxViewModel = (ChoiceBoxViewModel) questionViewModel; List<BaseQuestionViewModel> selectedItems = choiceBoxViewModel.ParentGrid.ChoiceBoxes .Cast<BaseQuestionViewModel>() .ToList(); ActionTracker.TrackChangeQuestionsPosition(selectedItems, deltaTop, deltaLeft, widthKoef, heightKoef); } } else if (this.DataContext is BubbleViewModel) { // resize bubble BubbleViewModel bubbleViewModel = (BubbleViewModel)this.DataContext; List<BubbleViewModel> bubbles = bubbleViewModel.ParentQuestion.Bubbles.ToList(); double deltaTop = this.bubbleStartTop - bubbles[0].Top; double deltaLeft = this.bubbleStartLeft - bubbles[0].Left; double widthKoef = this.bubbleStartWidth / bubbles[0].Width; double heightKoef = this.bubbleStartHeight / bubbles[0].Height; ActionTracker.TrackChangeBubble(bubbles, deltaTop, deltaLeft, widthKoef, heightKoef); } }
private void UpdateConnectedToCeilingForBubble(BubbleViewModel bubbleViewModel) { var connectedBubbles = GetNeighbors(bubbleViewModel.GridPosition.Value); if (bubbleViewModel.GridPosition.Value.y == CurrentTopGridY.Value) { bubbleViewModel.SetIsConnectedToCeiling(true); return; } for (var idx = 0; idx < connectedBubbles.Count; idx++) { var neighbor = connectedBubbles[idx]; var unknownNeighbors = GetNeighbors(neighbor.GridPosition.Value) .Where(n => !connectedBubbles.Contains(n) && n != bubbleViewModel).ToList(); connectedBubbles.AddRange(unknownNeighbors); } var isConnectedToCeiling = connectedBubbles.Any(b => b.GridPosition.Value.y == CurrentTopGridY.Value); bubbleViewModel.SetIsConnectedToCeiling(isConnectedToCeiling); }
private void Page_Loaded(object sender, RoutedEventArgs e) { Mouse.OverrideCursor = Cursors.Wait; if (BrowserInteropHelper.IsBrowserHosted) { bCreateFile.Visibility = Visibility.Collapsed; } try { BubbleViewModel bubbleViewModel = new BubbleViewModel(); for (int i = 0; i < bubbleViewModel.Bubbles.Count; i++) { Bubble bubble = bubbleViewModel.Bubbles[i]; Perspective.Wpf3D.Shapes.Spherical3D s = new Perspective.Wpf3D.Shapes.Spherical3D(); s.Material = (Material)this.FindResource("GlossyMaterial"); s.ParallelCount = 100; Transform3DGroup transformGroup = new Transform3DGroup(); TranslateTransform3D translation = new TranslateTransform3D( bubble.X, bubble.Y, bubble.Z); transformGroup.Children.Add(translation); ScaleTransform3D scaling = new ScaleTransform3D( bubble.Value, bubble.Value, bubble.Value); transformGroup.Children.Add(scaling); s.Transform = transformGroup; workshop.Children.Add(s); } } finally { Mouse.OverrideCursor = null; } }
private void RemoveBubble(BubbleViewModel bubbleViewModel) { _bubbleViewModels.Remove(bubbleViewModel.GridPosition.Value); }