PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/LayerControl.cs

https://bitbucket.org/tuldok89/openpdn
C# | 582 lines | 456 code | 88 blank | 38 comment | 54 complexity | bd9ac2898aeb0490109251e0c43460f9 MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. using System;
  10. using System.Collections.Generic;
  11. using System.ComponentModel;
  12. using System.Drawing;
  13. using System.Windows.Forms;
  14. using PaintDotNet.Base;
  15. namespace PaintDotNet
  16. {
  17. internal class LayerControl
  18. : UserControl
  19. {
  20. private class PanelWithLayout
  21. : PanelEx
  22. {
  23. private LayerControl _parentLayerControl;
  24. public LayerControl ParentLayerControl
  25. {
  26. get
  27. {
  28. return _parentLayerControl;
  29. }
  30. set
  31. {
  32. _parentLayerControl = value;
  33. }
  34. }
  35. public PanelWithLayout()
  36. {
  37. HideHScroll = true;
  38. }
  39. public void PositionLayers()
  40. {
  41. if (_parentLayerControl == null || _parentLayerControl._layerControls == null) return;
  42. int cursor = AutoScrollPosition.Y;
  43. int newWidth = ClientRectangle.Width;
  44. for (int i = _parentLayerControl._layerControls.Count - 1; i >= 0; --i)
  45. {
  46. LayerElement lec = _parentLayerControl._layerControls[i];
  47. lec.Width = newWidth;
  48. lec.Top = cursor;
  49. cursor += lec.Height;
  50. }
  51. }
  52. protected override void OnResize(EventArgs eventargs)
  53. {
  54. SystemLayer.UI.SuspendControlPainting(this);
  55. PositionLayers();
  56. AutoScrollPosition = new Point(0, -AutoScrollOffset.Y);
  57. base.OnResize(eventargs);
  58. SystemLayer.UI.ResumeControlPainting(this);
  59. Invalidate(true);
  60. }
  61. protected override void OnLayout(LayoutEventArgs levent)
  62. {
  63. PositionLayers();
  64. base.OnLayout(levent);
  65. }
  66. }
  67. public void PositionLayers()
  68. {
  69. _layerControlPanel.PositionLayers();
  70. }
  71. private readonly EventHandler _elementClickDelegate;
  72. private readonly EventHandler _elementDoubleClickDelegate;
  73. private readonly EventHandler _documentChangedDelegate;
  74. private readonly EventHandler<EventArgs<Document>> _documentChangingDelegate;
  75. private readonly EventHandler _layerChangedDelegate;
  76. private readonly KeyEventHandler _keyUpDelegate;
  77. private readonly IndexEventHandler _layerInsertedDelegate;
  78. private readonly IndexEventHandler _layerRemovedDelegate;
  79. private readonly int _elementHeight;
  80. private readonly int _thumbnailSize;
  81. private AppWorkspace _appWorkspace;
  82. private Document _document;
  83. private readonly List<LayerElement> _layerControls;
  84. private PanelWithLayout _layerControlPanel;
  85. private ThumbnailManager _thumbnailManager;
  86. [Browsable(false)]
  87. public LayerElement[] Layers
  88. {
  89. get {
  90. return _layerControls == null ? new LayerElement[0] : _layerControls.ToArray();
  91. }
  92. }
  93. public Layer ActiveLayer
  94. {
  95. get
  96. {
  97. int[] selected = SelectedLayerIndexes;
  98. return selected.Length == 1 ? Layers[selected[0]].Layer : null;
  99. }
  100. }
  101. public int ActiveLayerIndex
  102. {
  103. get
  104. {
  105. int[] selected = SelectedLayerIndexes;
  106. if (selected.Length == 1)
  107. {
  108. return selected[0];
  109. }
  110. return -1;
  111. }
  112. }
  113. private int[] SelectedLayerIndexes
  114. {
  115. get
  116. {
  117. LayerElement[] layers = Layers;
  118. var layerIndexes = new List<int>();
  119. for (int i = 0; i < layers.Length; ++i)
  120. {
  121. if (layers[i].IsSelected)
  122. {
  123. layerIndexes.Add(i);
  124. }
  125. }
  126. return layerIndexes.ToArray();
  127. }
  128. }
  129. public void ClearLayerSelection()
  130. {
  131. LayerElement[] layers = Layers;
  132. foreach (LayerElement t in layers)
  133. {
  134. t.IsSelected = false;
  135. }
  136. }
  137. public new BorderStyle BorderStyle
  138. {
  139. get
  140. {
  141. return _layerControlPanel.BorderStyle;
  142. }
  143. set
  144. {
  145. _layerControlPanel.BorderStyle = value;
  146. }
  147. }
  148. /// <summary>
  149. /// Required designer variable.
  150. /// </summary>
  151. private Container _components = null;
  152. public LayerControl()
  153. {
  154. _elementHeight = 6 + SystemLayer.UI.ScaleWidth(LayerElement.ThumbSizePreScaling);
  155. // This call is required by the Windows.Forms Form Designer.
  156. InitializeComponent();
  157. _elementClickDelegate = new EventHandler(ElementClickHandler);
  158. _elementDoubleClickDelegate = new EventHandler(ElementDoubleClickHandler);
  159. _documentChangedDelegate = new EventHandler(DocumentChangedHandler);
  160. _documentChangingDelegate = DocumentChangingHandler;
  161. _layerInsertedDelegate = new IndexEventHandler(LayerInsertedHandler);
  162. _layerRemovedDelegate = new IndexEventHandler(LayerRemovedHandler);
  163. _layerChangedDelegate = new EventHandler(LayerChangedHandler);
  164. _keyUpDelegate = new KeyEventHandler(KeyUpHandler);
  165. _thumbnailManager = new ThumbnailManager(this);
  166. _thumbnailSize = SystemLayer.UI.ScaleWidth(LayerElement.ThumbSizePreScaling);
  167. _layerControls = new List<LayerElement>();
  168. }
  169. private void SetupNewDocument(Document newDocument)
  170. {
  171. //thumbnailManager.ClearQueue();
  172. // Subscribe to the eevents
  173. _document = newDocument;
  174. _document.Layers.Inserted += _layerInsertedDelegate;
  175. _document.Layers.RemovedAt += _layerRemovedDelegate;
  176. SystemLayer.UI.SuspendControlPainting(_layerControlPanel);
  177. for (int i = 0; i < _document.Layers.Count; ++i)
  178. {
  179. LayerInsertedHandler(this, new IndexEventArgs(i));
  180. }
  181. if (_appWorkspace != null)
  182. {
  183. foreach (LayerElement lec in _layerControls)
  184. {
  185. lec.IsSelected = lec.Layer == _appWorkspace.ActiveDocumentWorkspace.ActiveLayer;
  186. }
  187. }
  188. SystemLayer.UI.ResumeControlPainting(_layerControlPanel);
  189. _layerControlPanel.Invalidate(true);
  190. OnActiveLayerChanged(ActiveLayer);
  191. }
  192. private void TearDownOldDocument()
  193. {
  194. SuspendLayout();
  195. foreach (LayerElement lec in _layerControls)
  196. {
  197. lec.Click -= _elementClickDelegate;
  198. lec.DoubleClick -= _elementDoubleClickDelegate;
  199. lec.KeyUp -= _keyUpDelegate;
  200. lec.Layer = null;
  201. _layerControlPanel.Controls.Remove(lec);
  202. lec.Dispose();
  203. }
  204. ResumeLayout(true);
  205. _layerControls.Clear();
  206. //thumbnailManager.ClearQueue();
  207. // Unsubscribe to the Events
  208. if (_document == null) return;
  209. _document.Layers.Inserted -= _layerInsertedDelegate;
  210. _document.Layers.RemovedAt -= _layerRemovedDelegate;
  211. _document = null;
  212. }
  213. private void DocumentChangingHandler(object sender, EventArgs<Document> e)
  214. {
  215. TearDownOldDocument();
  216. }
  217. private void DocumentChangedHandler(object sender, EventArgs e)
  218. {
  219. SetupNewDocument(_appWorkspace.ActiveDocumentWorkspace.Document);
  220. }
  221. private void LayerRemovedHandler(object sender, IndexEventArgs e)
  222. {
  223. LayerElement lec = _layerControls[e.Index];
  224. _thumbnailManager.RemoveFromQueue(lec.Layer);
  225. lec.Click -= _elementClickDelegate;
  226. lec.DoubleClick -= _elementDoubleClickDelegate;
  227. lec.KeyUp -= _keyUpDelegate;
  228. lec.Layer = null;
  229. _layerControls.Remove(lec);
  230. _layerControlPanel.Controls.Remove(lec);
  231. lec.Dispose();
  232. PerformLayout();
  233. }
  234. private void InitializeLayerElement(LayerElement lec, Layer l)
  235. {
  236. lec.Height = _elementHeight;
  237. lec.Layer = l;
  238. lec.Click += _elementClickDelegate;
  239. lec.DoubleClick += _elementDoubleClickDelegate;
  240. lec.KeyUp += _keyUpDelegate;
  241. lec.IsSelected = false;
  242. }
  243. private void SetActive(LayerElement lec)
  244. {
  245. SetActive(lec.Layer);
  246. }
  247. private void SetActive(Layer layer)
  248. {
  249. foreach (LayerElement lec in _layerControls)
  250. {
  251. bool active = (lec.Layer == layer);
  252. lec.IsSelected = active;
  253. if (!active) continue;
  254. OnActiveLayerChanged(lec.Layer);
  255. _layerControlPanel.ScrollControlIntoView(lec);
  256. lec.Select();
  257. Update();
  258. }
  259. }
  260. private void LayerInsertedHandler(object sender, IndexEventArgs e)
  261. {
  262. SuspendLayout();
  263. _layerControlPanel.SuspendLayout();
  264. var layer = (Layer)_document.Layers[e.Index];
  265. var lec = new LayerElement {ThumbnailManager = _thumbnailManager, ThumbnailSize = _thumbnailSize};
  266. InitializeLayerElement(lec, layer);
  267. _layerControls.Insert(e.Index, lec);
  268. _layerControlPanel.Controls.Add(lec);
  269. _layerControlPanel.ScrollControlIntoView(lec);
  270. lec.Select();
  271. SetActive(lec);
  272. lec.RefreshPreview();
  273. _layerControlPanel.ResumeLayout(false);
  274. ResumeLayout(false);
  275. _layerControlPanel.PerformLayout();
  276. PerformLayout();
  277. Refresh();
  278. }
  279. public void RefreshPreviews()
  280. {
  281. foreach (LayerElement t in _layerControls)
  282. {
  283. t.RefreshPreview();
  284. }
  285. }
  286. public event EventHandler RelinquishFocus;
  287. protected void OnRelinquishFocus()
  288. {
  289. if (RelinquishFocus != null)
  290. {
  291. RelinquishFocus(this, EventArgs.Empty);
  292. }
  293. }
  294. protected override void OnClick(EventArgs e)
  295. {
  296. OnRelinquishFocus();
  297. base.OnClick(e);
  298. }
  299. /// <summary>
  300. /// This event is raised whenever the user clicks on a layer within the
  301. /// LayerControl to activate it.
  302. /// </summary>
  303. public event EventHandler<EventArgs<Layer>> ClickedOnLayer;
  304. private void OnClickedOnLayer(Layer layer)
  305. {
  306. if (ClickedOnLayer != null)
  307. {
  308. ClickedOnLayer(this, new EventArgs<Layer>(layer));
  309. }
  310. }
  311. /// <summary>
  312. /// This event is raised whenever the selected layer is changed. Note that
  313. /// this can occur without user intervention, which distinguishes this event
  314. /// from ClickedOnLayer.
  315. /// </summary>
  316. public event EventHandler<EventArgs<Layer>> ActiveLayerChanged;
  317. private void OnActiveLayerChanged(Layer layer)
  318. {
  319. if (ActiveLayerChanged != null)
  320. {
  321. ActiveLayerChanged(this, new EventArgs<Layer>(layer));
  322. }
  323. }
  324. public event EventHandler<EventArgs<Layer>> DoubleClickedOnLayer;
  325. private void OnDoubleClickedOnLayer(Layer layer)
  326. {
  327. if (DoubleClickedOnLayer != null)
  328. {
  329. DoubleClickedOnLayer(this, new EventArgs<Layer>(layer));
  330. }
  331. }
  332. private void ElementClickHandler(object sender, EventArgs e)
  333. {
  334. var lec = (LayerElement)sender;
  335. if (ModifierKeys == Keys.Control)
  336. {
  337. lec.IsSelected = !lec.IsSelected;
  338. }
  339. else
  340. {
  341. ClearLayerSelection();
  342. lec.IsSelected = true;
  343. }
  344. SetActive(lec);
  345. OnClickedOnLayer(lec.Layer);
  346. }
  347. private void ElementDoubleClickHandler(object sender, EventArgs e)
  348. {
  349. OnDoubleClickedOnLayer(((LayerElement)sender).Layer);
  350. }
  351. private void LayerChangedHandler(object sender, EventArgs e)
  352. {
  353. SetActive(_appWorkspace.ActiveDocumentWorkspace.ActiveLayer);
  354. }
  355. public void SuspendLayerPreviewUpdates()
  356. {
  357. foreach (LayerElement element in _layerControls)
  358. {
  359. element.SuspendPreviewUpdates();
  360. }
  361. }
  362. public void ResumeLayerPreviewUpdates()
  363. {
  364. foreach (LayerElement element in _layerControls)
  365. {
  366. element.ResumePreviewUpdates();
  367. }
  368. }
  369. private void KeyUpHandler(object sender, KeyEventArgs e)
  370. {
  371. OnKeyUp(e);
  372. }
  373. [Browsable(false)]
  374. public AppWorkspace AppWorkspace
  375. {
  376. get
  377. {
  378. return _appWorkspace;
  379. }
  380. set
  381. {
  382. if (_appWorkspace == value) return;
  383. if (_appWorkspace != null)
  384. {
  385. TearDownOldDocument();
  386. _appWorkspace.ActiveDocumentWorkspaceChanging -= WorkspaceActiveDocumentWorkspaceChanging;
  387. _appWorkspace.ActiveDocumentWorkspaceChanged -= WorkspaceActiveDocumentWorkspaceChanged;
  388. }
  389. _appWorkspace = value;
  390. if (_appWorkspace == null) return;
  391. _appWorkspace.ActiveDocumentWorkspaceChanging += WorkspaceActiveDocumentWorkspaceChanging;
  392. _appWorkspace.ActiveDocumentWorkspaceChanged += WorkspaceActiveDocumentWorkspaceChanged;
  393. if (_appWorkspace.ActiveDocumentWorkspace != null)
  394. {
  395. SetupNewDocument(_appWorkspace.ActiveDocumentWorkspace.Document);
  396. }
  397. }
  398. }
  399. private void WorkspaceActiveDocumentWorkspaceChanging(object sender, EventArgs e)
  400. {
  401. TearDownOldDocument();
  402. if (_appWorkspace.ActiveDocumentWorkspace == null) return;
  403. _appWorkspace.ActiveDocumentWorkspace.DocumentChanging -= _documentChangingDelegate;
  404. _appWorkspace.ActiveDocumentWorkspace.DocumentChanged -= _documentChangedDelegate;
  405. _appWorkspace.ActiveDocumentWorkspace.ActiveLayerChanged -= _layerChangedDelegate;
  406. }
  407. private void WorkspaceActiveDocumentWorkspaceChanged(object sender, EventArgs e)
  408. {
  409. if (_appWorkspace.ActiveDocumentWorkspace == null) return;
  410. _appWorkspace.ActiveDocumentWorkspace.DocumentChanging += _documentChangingDelegate;
  411. _appWorkspace.ActiveDocumentWorkspace.DocumentChanged += _documentChangedDelegate;
  412. _appWorkspace.ActiveDocumentWorkspace.ActiveLayerChanged += _layerChangedDelegate;
  413. if (_appWorkspace.ActiveDocumentWorkspace.Document != null)
  414. {
  415. SetupNewDocument(_appWorkspace.ActiveDocumentWorkspace.Document);
  416. }
  417. }
  418. [Browsable(false)]
  419. public Document Document
  420. {
  421. get
  422. {
  423. return _document;
  424. }
  425. set
  426. {
  427. if (_appWorkspace != null)
  428. {
  429. throw new InvalidOperationException("Workspace property is already set");
  430. }
  431. if (_document != null)
  432. {
  433. TearDownOldDocument();
  434. }
  435. if (value != null)
  436. {
  437. SetupNewDocument(value);
  438. }
  439. }
  440. }
  441. /// <summary>
  442. /// Clean up any resources being used.
  443. /// </summary>
  444. protected override void Dispose(bool disposing)
  445. {
  446. if (disposing)
  447. {
  448. if (_components != null)
  449. {
  450. _components.Dispose();
  451. _components = null;
  452. }
  453. if (_thumbnailManager != null)
  454. {
  455. _thumbnailManager.Dispose();
  456. _thumbnailManager = null;
  457. }
  458. }
  459. base.Dispose(disposing);
  460. }
  461. private void LayerControlPanelClick(object sender, EventArgs e)
  462. {
  463. OnRelinquishFocus();
  464. }
  465. #region Component Designer generated code
  466. /// <summary>
  467. /// Required method for Designer support - do not modify
  468. /// the contents of this method with the code editor.
  469. /// </summary>
  470. private void InitializeComponent()
  471. {
  472. this._layerControlPanel = new PanelWithLayout();
  473. this.SuspendLayout();
  474. //
  475. // layerControlPanel
  476. //
  477. this._layerControlPanel.AutoScroll = true;
  478. this._layerControlPanel.Dock = System.Windows.Forms.DockStyle.Fill;
  479. this._layerControlPanel.Location = new System.Drawing.Point(0, 0);
  480. this._layerControlPanel.Name = "_layerControlPanel";
  481. this._layerControlPanel.ParentLayerControl = this;
  482. this._layerControlPanel.Size = new System.Drawing.Size(150, 150);
  483. this._layerControlPanel.TabIndex = 2;
  484. this._layerControlPanel.Click += new EventHandler(LayerControlPanelClick);
  485. //
  486. // LayerControl
  487. //
  488. this.Controls.Add(this._layerControlPanel);
  489. this.Name = "LayerControl";
  490. this.ResumeLayout(false);
  491. }
  492. #endregion
  493. }
  494. }