private void OnCellSelectTimelineNewFrame(object o, NewFrameArgs args) { if (visible_actor_count <= 0 || visible_grid_width <= 0) { return; } int target_x = 0, target_y = 0; Clone cell_target = null; while (cell_target == null) { int index = random.Next(0, visible_actor_count); target_x = index % visible_grid_width; target_y = index / visible_grid_width; cell_target = grid[target_x, target_y]; if (waiting_for_slot.Contains(cell_target) || history_slots.Contains(cell_target)) { cell_target = null; } } var cell_source = new Clone(GetRandomActor()) { Visible = true, Parent = this }; cell_source.Allocate(new ActorBox() { X1 = target_x * 100, Y1 = target_y * 100, X2 = target_x * 100 + 100, Y2 = target_y * 100 + 100 }, AllocationFlags.DelegateLayout); waiting_for_slot.Insert(0, cell_source); history_slots.Enqueue(cell_source); if (history_slots.Count > 5) { history_slots.Dequeue(); } cell_target.AnimationChain .SetEasing(AnimationMode.EaseInQuad) .SetDuration((uint)random.Next(300, 1500)) .WhenFinished((a) => { grid[target_x, target_y] = cell_source; waiting_for_slot.Remove(cell_source); QueueRedraw(); }) .Animate("opacity", 0); }
private void BuildCloneGrid() { if (grid != null) { return; } float pixel_x = 0; float pixel_y = 0; float size = (float)ActorSize; int grid_width = (int)(Math.Ceiling(Gdk.Screen.Default.Width / size)); int grid_height = (int)(Math.Ceiling(Gdk.Screen.Default.Height / size)); int x = 0, y = 0; grid = new Clone[grid_width, grid_height]; // Populate a collection with enough clones to build // a grid large enough to cover the entire screen for (int i = 0; i < actor_cache.MaxCount; i++) { var slot = new Clone(null) { Parent = this, Visible = true }; slot.Allocate(new ActorBox() { X1 = pixel_x, Y1 = pixel_y, X2 = size, Y2 = size }, AllocationFlags.DelegateLayout); grid[x, y] = slot; pixel_x += size; if (x++ == grid_width - 1) { x = 0; y++; pixel_x = 0; pixel_y += size; } } }