PageRenderTime 675ms CodeModel.GetById 18ms RepoModel.GetById 2ms app.codeStats 0ms

/src/LayerControl.cs

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