/* * Greenshot - a free and open source screenshot tool * Copyright (C) 2007-2010 Thomas Braun, Jens Klingen, Robin Krom * * For more information see: http://getgreenshot.org/ * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using Greenshot.Drawing.Fields; using Greenshot.Plugin; namespace Greenshot.Drawing { /// /// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers. /// [Serializable()] public class DrawableContainerList : List { public DrawableContainerList() { } public EditStatus Status { get { return this[Count-1].Status; } set { foreach(DrawableContainer dc in this) dc.Status = value; } } /// /// Gets or sets the selection status of the elements. /// If several elements are in the list, true is only returned when all elements are selected. /// public bool Selected { get { bool ret = true; foreach(DrawableContainer dc in this) ret &= dc.Selected; return ret; } set { foreach(DrawableContainer dc in this) dc.Selected = value; } } /// /// Gets or sets the parent control of the elements in the list. /// If there are several elements, the parent control of the last added is returned. /// public ISurface Parent { get { if(Count > 0) return this[Count-1].Parent; return null; } set { foreach(DrawableContainer dc in this) dc.Parent = value; } } /// /// Moves all elements in the list by the given amount of pixels. /// /// pixels to move horizontally /// pixels to move vertically public void MoveBy(int dx, int dy) { foreach(DrawableContainer dc in this) { dc.Left += dx; dc.Top += dy; } } /// /// Hides the grippers of all elements in the list. /// public void HideGrippers() { foreach(DrawableContainer dc in this) { dc.HideGrippers(); } } /// /// Shows the grippers of all elements in the list. /// public void ShowGrippers() { foreach(DrawableContainer dc in this) { dc.ShowGrippers(); } } /// /// Indicates whether on of the elements is clickable at the given location /// /// x coordinate to be checked /// y coordinate to be checked /// true if one of the elements in the list is clickable at the given location, false otherwise public bool ClickableAt(int x, int y) { bool ret = false; foreach(DrawableContainer dc in this) { ret |= dc.ClickableAt(x, y); } return ret; } /// /// retrieves the topmost element being clickable at the given location /// /// x coordinate to be checked /// y coordinate to be checked /// the topmost element from the list being clickable at the given location, null if there is no clickable element public DrawableContainer ClickableElementAt(int x, int y) { for(int i=Count-1; i>=0; i--) { if(this[i].ClickableAt(x,y)) return this[i]; } return null; } /// /// Dispatches OnDoubleClick to all elements in the list. /// public void OnDoubleClick() { foreach(DrawableContainer dc in this) { dc.OnDoubleClick(); } } /// /// Triggers all elements in the list ot be redrawn. /// /// the related Graphics object /// the rendermode in which the element is to be drawn public void Draw(Graphics g, Bitmap bitmap, RenderMode rm) { foreach(DrawableContainer dc in this) { dc.DrawContent(g, bitmap, rm); } } /// /// Indicates whether the given list of elements can be pulled up, /// i.e. whether there is at least one unselected element higher in hierarchy /// /// list of elements to pull up /// true if the elements could be pulled up public bool CanPullUp(DrawableContainerList elements) { if(elements.Count == 0 || elements.Count == this.Count) return false; foreach(DrawableContainer element in elements) { if(this.IndexOf(element) < this.Count - elements.Count) return true; } return false; } /// /// Pulls one or several elements up one level in hierarchy (z-index). /// /// list of elements to pull up public void PullElementsUp(DrawableContainerList elements) { for(int i=this.Count-1; i>=0; i--) { DrawableContainer dc = this[i]; if(elements.Contains(dc)) { if(Count > (i+1) && !elements.Contains(this[i+1])) SwapElements(i,i+1); } } } /// /// Pulls one or several elements up to the topmost level(s) in hierarchy (z-index). /// /// of elements to pull to top public void PullElementsToTop(DrawableContainerList elements) { DrawableContainer[] dcs = this.ToArray(); for(int i=0; i /// Indicates whether the given list of elements can be pushed down, /// i.e. whether there is at least one unselected element lower in hierarchy /// /// list of elements to push down /// true if the elements could be pushed down public bool CanPushDown(DrawableContainerList elements) { if(elements.Count == 0 || elements.Count == this.Count) return false; foreach(DrawableContainer element in elements) { if(this.IndexOf(element) >= elements.Count) return true; } return false; } /// /// Pushes one or several elements down one level in hierarchy (z-index). /// /// list of elements to push down public void PushElementsDown(DrawableContainerList elements) { for(int i=0; i0) && !elements.Contains(this[i-1])) SwapElements(i,i-1); } } } /// /// Pushes one or several elements down to the bottommost level(s) in hierarchy (z-index). /// /// of elements to push to bottom public void PushElementsToBottom(DrawableContainerList elements) { DrawableContainer[] dcs = this.ToArray(); for(int i=dcs.Length-1; i>=0; i--) { DrawableContainer dc = dcs[i]; if(elements.Contains(dc)) { this.Remove(dc); this.Insert(0, dc); } } } /// /// swaps two elements in hierarchy (z-index), /// checks both indices to be in range /// /// index of the 1st element /// index of the 2nd element private void SwapElements(int index1, int index2) { if(index1 >= 0 && index1 < Count && index2 >= 0 && index2 < Count && index1 != index2) { DrawableContainer dc = this[index1]; this[index1] = this[index2]; this[index2] = dc; } } } }