Fixed some interface usage, also cleanup of the surface & editor code. This should theoretically allow usage of home made IDrawableContainer objects, which plug-ins supply.

Also made it possible to reuse the editor, currently only available editors which have a non modified surface can be reused. And only than if the configuration is set to do so.

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2100 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-09-26 16:57:16 +00:00
commit f9abcac063
13 changed files with 233 additions and 154 deletions

View file

@ -24,12 +24,10 @@ using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.Plugin.Drawing;
using Greenshot.Memento;
using System.Drawing.Drawing2D;
@ -87,7 +85,16 @@ namespace Greenshot.Drawing {
}
[NonSerialized]
public EditStatus Status = EditStatus.UNDRAWN;
private EditStatus status = EditStatus.UNDRAWN;
public EditStatus Status {
get {
return status;
}
set {
status = value;
}
}
private int left = 0;
public int Left {

View file

@ -35,8 +35,8 @@ namespace Greenshot.Drawing {
/// <summary>
/// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers.
/// </summary>
[Serializable()]
public class DrawableContainerList : List<DrawableContainer> {
[Serializable()]
public class DrawableContainerList : List<IDrawableContainer> {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static System.ComponentModel.ComponentResourceManager editorFormResources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
@ -48,7 +48,9 @@ namespace Greenshot.Drawing {
return this[Count-1].Status;
}
set {
foreach(DrawableContainer dc in this) dc.Status = value;
foreach (DrawableContainer dc in this) {
dc.Status = value;
}
}
}
@ -178,9 +180,9 @@ namespace Greenshot.Drawing {
/// <param name="x">x coordinate to be checked</param>
/// <param name="y">y coordinate to be checked</param>
/// <returns>the topmost element from the list being clickable at the given location, null if there is no clickable element</returns>
public DrawableContainer ClickableElementAt(int x, int y) {
for(int i=Count-1; i>=0; i--) {
if(this[i].ClickableAt(x,y)) {
public IDrawableContainer ClickableElementAt(int x, int y) {
for (int i=Count-1; i>=0; i--) {
if (this[i].ClickableAt(x,y)) {
return this[i];
}
}
@ -280,7 +282,7 @@ namespace Greenshot.Drawing {
/// <param name="elements">list of elements to pull up</param>
public void PullElementsUp(DrawableContainerList elements) {
for(int i=this.Count-1; i>=0; i--) {
DrawableContainer dc = this[i];
IDrawableContainer dc = this[i];
if (elements.Contains(dc)) {
if (Count > (i+1) && !elements.Contains(this[i+1])) {
SwapElements(i,i+1);
@ -294,9 +296,9 @@ namespace Greenshot.Drawing {
/// </summary>
/// <param name="elements">of elements to pull to top</param>
public void PullElementsToTop(DrawableContainerList elements) {
DrawableContainer[] dcs = this.ToArray();
IDrawableContainer[] dcs = this.ToArray();
for(int i=0; i<dcs.Length; i++) {
DrawableContainer dc = dcs[i];
IDrawableContainer dc = dcs[i];
if (elements.Contains(dc)) {
this.Remove(dc);
this.Add(dc);
@ -329,7 +331,7 @@ namespace Greenshot.Drawing {
/// <param name="elements">list of elements to push down</param>
public void PushElementsDown(DrawableContainerList elements) {
for(int i=0; i<Count; i++) {
DrawableContainer dc = this[i];
IDrawableContainer dc = this[i];
if(elements.Contains(dc)) {
if((i>0) && !elements.Contains(this[i-1])) {
SwapElements(i,i-1);
@ -343,9 +345,9 @@ namespace Greenshot.Drawing {
/// </summary>
/// <param name="elements">of elements to push to bottom</param>
public void PushElementsToBottom(DrawableContainerList elements) {
DrawableContainer[] dcs = this.ToArray();
IDrawableContainer[] dcs = this.ToArray();
for(int i=dcs.Length-1; i>=0; i--) {
DrawableContainer dc = dcs[i];
IDrawableContainer dc = dcs[i];
if(elements.Contains(dc)) {
this.Remove(dc);
this.Insert(0, dc);
@ -362,7 +364,7 @@ namespace Greenshot.Drawing {
/// <param name="index2">index of the 2nd element</param>
private void SwapElements(int index1, int index2) {
if(index1 >= 0 && index1 < Count && index2 >= 0 && index2 < Count && index1 != index2) {
DrawableContainer dc = this[index1];
IDrawableContainer dc = this[index1];
this[index1] = this[index2];
this[index2] = dc;
Parent.Modified = true;

View file

@ -24,6 +24,7 @@ using System.ComponentModel;
using Greenshot.Configuration;
using Greenshot.IniFile;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Fields {
/// <summary>
@ -39,7 +40,7 @@ namespace Greenshot.Drawing.Fields {
/// </summary>
public class FieldAggregator : AbstractFieldHolder {
private List<DrawableContainer> boundContainers;
private List<IDrawableContainer> boundContainers;
private bool internalUpdateRunning = false;
enum Status {IDLE, BINDING, UPDATING};
@ -52,7 +53,7 @@ namespace Greenshot.Drawing.Fields {
Field field = new Field(fieldType, GetType());
AddField(field);
}
boundContainers = new List<DrawableContainer>();
boundContainers = new List<IDrawableContainer>();
}
public override void AddField(Field field) {
@ -66,31 +67,38 @@ namespace Greenshot.Drawing.Fields {
}
}
public void BindElement(DrawableContainer dc) {
if (!boundContainers.Contains(dc)) {
boundContainers.Add(dc);
dc.ChildrenChanged += delegate { UpdateFromBoundElements(); };
public void BindElement(IDrawableContainer dc) {
DrawableContainer container = dc as DrawableContainer;
if (container != null && !boundContainers.Contains(container)) {
boundContainers.Add(container);
container.ChildrenChanged += delegate {
UpdateFromBoundElements();
};
UpdateFromBoundElements();
}
}
public void BindAndUpdateElement(DrawableContainer dc) {
public void BindAndUpdateElement(IDrawableContainer dc) {
UpdateElement(dc);
BindElement(dc);
}
public void UpdateElement(DrawableContainer dc) {
public void UpdateElement(IDrawableContainer dc) {
DrawableContainer container = dc as DrawableContainer;
if (container == null) {
return;
}
internalUpdateRunning = true;
foreach(Field field in GetFields()) {
if (dc.HasField(field.FieldType) && field.HasValue) {
if (container.HasField(field.FieldType) && field.HasValue) {
//if(LOG.IsDebugEnabled) LOG.Debug(" "+field+ ": "+field.Value);
dc.SetFieldValue(field.FieldType, field.Value);
container.SetFieldValue(field.FieldType, field.Value);
}
}
internalUpdateRunning = false;
}
public void UnbindElement(DrawableContainer dc) {
public void UnbindElement(IDrawableContainer dc) {
if (boundContainers.Contains(dc)) {
boundContainers.Remove(dc);
UpdateFromBoundElements();
@ -129,28 +137,33 @@ namespace Greenshot.Drawing.Fields {
}
private List<Field> FindCommonFields() {
List<Field> ret = null;
List<Field> returnFields = null;
if (boundContainers.Count > 0) {
// take all fields from the least selected container...
ret = boundContainers[boundContainers.Count-1].GetFields();
for(int i=0;i<boundContainers.Count-1; i++) {
DrawableContainer dc = boundContainers[i];
List<Field> fieldsToRemove = new List<Field>();
foreach(Field f in ret) {
// ... throw out those that do not apply to one of the other containers
if (!dc.HasField(f.FieldType)) {
fieldsToRemove.Add(f);
DrawableContainer leastSelectedContainer = boundContainers[boundContainers.Count - 1] as DrawableContainer;
if (leastSelectedContainer != null) {
returnFields = leastSelectedContainer.GetFields();
for (int i = 0; i < boundContainers.Count - 1; i++) {
DrawableContainer dc = boundContainers[i] as DrawableContainer;
if (dc != null) {
List<Field> fieldsToRemove = new List<Field>();
foreach (Field f in returnFields) {
// ... throw out those that do not apply to one of the other containers
if (!dc.HasField(f.FieldType)) {
fieldsToRemove.Add(f);
}
}
foreach (Field f in fieldsToRemove) {
returnFields.Remove(f);
}
}
}
foreach(Field f in fieldsToRemove) {
ret.Remove(f);
}
}
}
if (ret == null) {
ret = new List<Field>();
if (returnFields == null) {
returnFields = new List<Field>();
}
return ret;
return returnFields;
}
public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) {

View file

@ -39,10 +39,6 @@ using System.Drawing.Drawing2D;
using GreenshotPlugin.Controls;
namespace Greenshot.Drawing {
public delegate void SurfaceElementEventHandler(object source, DrawableContainerList element);
public delegate void SurfaceDrawingModeEventHandler(object source, DrawingModes drawingMode);
public enum DrawingModes { None, Rect, Ellipse, Text, Line, Arrow, Crop, Highlight, Obfuscate, Bitmap, Path }
/// <summary>
/// Description of Surface.
@ -155,7 +151,7 @@ namespace Greenshot.Drawing {
/// The selected element for the mouse down, do not serialize
/// </summary>
[NonSerialized]
private DrawableContainer mouseDownElement = null;
private IDrawableContainer mouseDownElement = null;
/// <summary>
/// all selected elements, do not serialize
@ -167,19 +163,19 @@ namespace Greenshot.Drawing {
/// the element we are drawing with, do not serialize
/// </summary>
[NonSerialized]
private DrawableContainer drawingElement = null;
private IDrawableContainer drawingElement = null;
/// <summary>
/// the element we want to draw with (not yet drawn), do not serialize
/// </summary>
[NonSerialized]
private DrawableContainer undrawnElement = null;
private IDrawableContainer undrawnElement = null;
/// <summary>
/// the cropcontainer, when cropping this is set, do not serialize
/// </summary>
[NonSerialized]
private DrawableContainer cropContainer = null;
private IDrawableContainer cropContainer = null;
/// <summary>
/// the brush which is used for transparent backgrounds, set by the editor, do not serialize
@ -319,8 +315,12 @@ namespace Greenshot.Drawing {
}
public ICaptureDetails CaptureDetails {
get {return captureDetails;}
set {captureDetails = value;}
get {
return captureDetails;
}
set {
captureDetails = value;
}
}
public Surface() : base(){
@ -338,6 +338,7 @@ namespace Greenshot.Drawing {
this.elements.Parent = this;
// Make sure we are visible
this.Visible = true;
this.TabStop = false;
// Enable double buffering
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.ContainerControl | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
@ -447,6 +448,7 @@ namespace Greenshot.Drawing {
}
}
}
public LangKey RedoActionKey {
get {
if (CanRedo) {
@ -932,7 +934,7 @@ namespace Greenshot.Drawing {
selectedList = selectedElements;
} else {
// Single element
DrawableContainer rightClickedContainer = elements.ClickableElementAt(mouseStart.X, mouseStart.Y);
IDrawableContainer rightClickedContainer = elements.ClickableElementAt(mouseStart.X, mouseStart.Y);
if (rightClickedContainer != null) {
selectedList = new DrawableContainerList();
selectedList.Add(rightClickedContainer);
@ -996,7 +998,7 @@ namespace Greenshot.Drawing {
mouseDownElement = null;
if (DrawingMode == DrawingModes.None) {
// check whether an existing element was clicked
DrawableContainer element = elements.ClickableElementAt(currentMouse.X, currentMouse.Y);
IDrawableContainer element = elements.ClickableElementAt(currentMouse.X, currentMouse.Y);
bool shiftModifier = (Control.ModifierKeys & Keys.Shift) == Keys.Shift;
if (element != null) {
element.Invalidate();
@ -1166,7 +1168,7 @@ namespace Greenshot.Drawing {
/// Wrapper for makeUndoable flag which was introduced later, will call AddElement with makeundoable set to true
/// </summary>
/// <param name="element">the new element</param>
public void AddElement(DrawableContainer element) {
public void AddElement(IDrawableContainer element) {
AddElement(element, true);
}
@ -1175,11 +1177,14 @@ namespace Greenshot.Drawing {
/// </summary>
/// <param name="element">the new element</param>
/// <param name="makeUndoable">true if the adding should be undoable</param>
public void AddElement(DrawableContainer element, bool makeUndoable) {
public void AddElement(IDrawableContainer element, bool makeUndoable) {
elements.Add(element);
element.FieldChanged += element_FieldChanged;
DrawableContainer container = element as DrawableContainer;
if (container != null) {
container.FieldChanged += element_FieldChanged;
}
element.PropertyChanged += ElementPropertyChanged;
if(element.Status == EditStatus.UNDRAWN) {
if (element.Status == EditStatus.UNDRAWN) {
element.Status = EditStatus.IDLE;
}
element.Invalidate();
@ -1190,21 +1195,23 @@ namespace Greenshot.Drawing {
}
public void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable) {
DeselectElement(elementToRemove);
elements.Remove(elementToRemove);
DrawableContainer element = elementToRemove as DrawableContainer;
DeselectElement(element);
elements.Remove(element);
element.FieldChanged -= element_FieldChanged;
element.PropertyChanged -= ElementPropertyChanged;
if (element != null) {
element.FieldChanged -= element_FieldChanged;
}
elementToRemove.PropertyChanged -= ElementPropertyChanged;
// Do not dispose, the memento should!! element.Dispose();
element.Invalidate();
elementToRemove.Invalidate();
if (makeUndoable) {
MakeUndoable(new DeleteElementMemento(this, element), false);
MakeUndoable(new DeleteElementMemento(this, elementToRemove), false);
}
modified = true;
}
public void AddElements(DrawableContainerList elementsToAdd) {
foreach(DrawableContainer element in elementsToAdd) {
foreach(IDrawableContainer element in elementsToAdd) {
AddElement(element, true);
}
}
@ -1248,8 +1255,8 @@ namespace Greenshot.Drawing {
public void ConfirmSelectedConfirmableElements(bool confirm){
// create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel)
List<DrawableContainer> selectedDCs = new List<DrawableContainer>(selectedElements);
foreach(DrawableContainer dc in selectedDCs){
List<IDrawableContainer> selectedDCs = new List<IDrawableContainer>(selectedElements);
foreach(IDrawableContainer dc in selectedDCs){
if(dc.Equals(cropContainer)){
DrawingMode = DrawingModes.None;
// No undo memento for the cropcontainer itself, only for the effect
@ -1314,11 +1321,10 @@ namespace Greenshot.Drawing {
}
public void DeselectElement(IDrawableContainer container) {
DrawableContainer element = container as DrawableContainer;
element.HideGrippers();
element.Selected = false;
selectedElements.Remove(element);
FieldAggregator.UnbindElement(element);
container.HideGrippers();
container.Selected = false;
selectedElements.Remove(container);
FieldAggregator.UnbindElement(container);
if (movingElementChanged != null) {
movingElementChanged(this, selectedElements);
}
@ -1327,7 +1333,7 @@ namespace Greenshot.Drawing {
public void DeselectAllElements() {
if (HasSelectedElements()) {
while(selectedElements.Count > 0) {
DrawableContainer element = selectedElements[0];
IDrawableContainer element = selectedElements[0];
element.Invalidate();
element.HideGrippers();
element.Selected = false;
@ -1341,16 +1347,15 @@ namespace Greenshot.Drawing {
}
public void SelectElement(IDrawableContainer container) {
DrawableContainer element = container as DrawableContainer;
if(!selectedElements.Contains(element)) {
selectedElements.Add(element);
element.ShowGrippers();
element.Selected = true;
FieldAggregator.BindElement(element);
if (!selectedElements.Contains(container)) {
selectedElements.Add(container);
container.ShowGrippers();
container.Selected = true;
FieldAggregator.BindElement(container);
if (movingElementChanged != null) {
movingElementChanged(this, selectedElements);
}
element.Invalidate();
container.Invalidate();
}
}