FRSideControl.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. using System;
  2. using System.ComponentModel;
  3. using System.Linq;
  4. using System.Windows.Forms;
  5. using FastReport.Design;
  6. using FastReport.Utils;
  7. namespace FastReport.Controls
  8. {
  9. internal class FRSideControl : Panel
  10. {
  11. private UIStyle style;
  12. private Designer designer;
  13. private Splitter splitter;
  14. private ControlStorageService storage;
  15. /// <summary>
  16. /// Gets storage service.
  17. /// </summary>
  18. public ControlStorageService Storage
  19. {
  20. get
  21. {
  22. if (storage == null)
  23. storage = new ControlStorageService(this, "Designer," + Name);
  24. return storage;
  25. }
  26. }
  27. public FRTabControl TopPanel { get; }
  28. public FRTabControl BottomPanel { get; }
  29. public UIStyle Style
  30. {
  31. get => style;
  32. set
  33. {
  34. style = value;
  35. var table = UIStyleUtils.GetColorTable(value);
  36. TopPanel.Style = BottomPanel.Style = table.ToolWindow;
  37. splitter.BackColor = table.Workspace.SplitterBackColor;
  38. }
  39. }
  40. public FRSideControl OtherSideControl { get; set; }
  41. public bool IsEmpty => VisiblePanelCount == 0;
  42. public event EventHandler LayoutChanged;
  43. private int VisiblePanelCount => (TopPanel.Tabs.Count > 0 ? 1 : 0) + (BottomPanel.Tabs.Count > 0 ? 1 : 0);
  44. private string GetControls(FRTabControl panel) => string.Join(",", panel.Tabs.Cast<Control>().Select(c => c.Name));
  45. private void SetControls(FRTabControl panel, string controls)
  46. {
  47. panel.Tabs.Clear();
  48. foreach (var name in controls.Split(','))
  49. {
  50. var plugin = designer.Plugins.Find(name) as PageControlPage;
  51. if (plugin != null)
  52. {
  53. plugin.Dock = DockStyle.Fill;
  54. panel.Tabs.Add(plugin);
  55. }
  56. }
  57. }
  58. private void topPanelMenu_Opening(object sender, CancelEventArgs e)
  59. {
  60. TopPanel.Menu.Items.Clear();
  61. TopPanel.Menu.Font = this.Font;
  62. var selectedTab = TopPanel.SelectedTab;
  63. var selectedTabText = "\"" + selectedTab.Text + "\"";
  64. var res = new MyRes("Designer,ToolWindow");
  65. var menuDockToBottom = new ToolStripMenuItem(string.Format(res.Get("DockToBottom"), selectedTabText));
  66. menuDockToBottom.Click += (s, args) =>
  67. {
  68. AddToBottomPanel(selectedTab);
  69. RefreshLayout();
  70. };
  71. if (VisiblePanelCount > 1 || TopPanel.Tabs.Count > 1)
  72. TopPanel.Menu.Items.Add(menuDockToBottom);
  73. var menuDockToOtherSide = new ToolStripMenuItem(string.Format(res.Get("DockToOtherSide"), selectedTabText));
  74. menuDockToOtherSide.Click += (s, args) =>
  75. {
  76. OtherSideControl.AddToTopPanel(selectedTab);
  77. RefreshLayout();
  78. OtherSideControl.RefreshLayout();
  79. };
  80. TopPanel.Menu.Items.Add(menuDockToOtherSide);
  81. }
  82. private void bottomPanelMenu_Opening(object sender, CancelEventArgs e)
  83. {
  84. BottomPanel.Menu.Items.Clear();
  85. BottomPanel.Menu.Font = this.Font;
  86. var selectedTab = BottomPanel.SelectedTab;
  87. var selectedTabText = "\"" + selectedTab.Text + "\"";
  88. var res = new MyRes("Designer,ToolWindow");
  89. var menuDockToTop = new ToolStripMenuItem(string.Format(res.Get("DockToTop"), selectedTabText));
  90. menuDockToTop.Click += (s, args) =>
  91. {
  92. AddToTopPanel(selectedTab);
  93. RefreshLayout();
  94. };
  95. if (VisiblePanelCount > 1 || BottomPanel.Tabs.Count > 1)
  96. BottomPanel.Menu.Items.Add(menuDockToTop);
  97. var menuDockToOtherSide = new ToolStripMenuItem(string.Format(res.Get("DockToOtherSide"), selectedTabText));
  98. menuDockToOtherSide.Click += (s, args) =>
  99. {
  100. OtherSideControl.AddToBottomPanel(selectedTab);
  101. RefreshLayout();
  102. OtherSideControl.RefreshLayout();
  103. };
  104. BottomPanel.Menu.Items.Add(menuDockToOtherSide);
  105. }
  106. private void AddToPanel(FRTabControl panel, PageControlPage page)
  107. {
  108. page.Dock = DockStyle.Fill;
  109. panel.Tabs.Add(page);
  110. // workaround SWF behavior (page is added somewhere in the middle of the Controls list)
  111. page.SendToBack();
  112. }
  113. public void AddToTopPanel(PageControlPage page) => AddToPanel(TopPanel, page);
  114. public void AddToBottomPanel(PageControlPage page) => AddToPanel(BottomPanel, page);
  115. public void RefreshLayout()
  116. {
  117. bool splitterWasVisible = splitter.Visible;
  118. TopPanel.Visible = TopPanel.Tabs.Count > 0;
  119. BottomPanel.Visible = BottomPanel.Tabs.Count > 0;
  120. splitter.Visible = VisiblePanelCount == 2;
  121. TopPanel.Dock = BottomPanel.Tabs.Count > 0 ? DockStyle.Top : DockStyle.Fill;
  122. if (!splitterWasVisible && splitter.Visible)
  123. TopPanel.Height = Height / 2;
  124. TopPanel.Refresh();
  125. TopPanel.SelectedTabIndex = 0;
  126. BottomPanel.Refresh();
  127. BottomPanel.SelectedTabIndex = 0;
  128. LayoutChanged?.Invoke(this, EventArgs.Empty);
  129. }
  130. public void UpdateDpiDependencies()
  131. {
  132. TopPanel.UpdateDpiDependencies();
  133. BottomPanel.UpdateDpiDependencies();
  134. splitter.Height = this.LogicalToDevice(3);
  135. }
  136. public void UpdateText()
  137. {
  138. TopPanel.UpdateText();
  139. BottomPanel.UpdateText();
  140. }
  141. public void SaveState()
  142. {
  143. Storage.SetDip("Width", Width);
  144. Storage.SetDip("TopPanelHeight", Math.Min(TopPanel.Height, Height - 50));
  145. Storage.SetStr("TopPanelControls", GetControls(TopPanel));
  146. Storage.SetStr("BottomPanelControls", GetControls(BottomPanel));
  147. }
  148. public void RestoreState()
  149. {
  150. if (Storage.HasProperties)
  151. {
  152. Width = Storage.GetDip("Width", 280, 50, 1000);
  153. SetControls(TopPanel, Storage.GetStr("TopPanelControls"));
  154. SetControls(BottomPanel, Storage.GetStr("BottomPanelControls"));
  155. RefreshLayout();
  156. TopPanel.Height = Storage.GetDip("TopPanelHeight", 350);
  157. }
  158. }
  159. public FRSideControl(Designer designer)
  160. {
  161. this.designer = designer;
  162. Name = "SideControl";
  163. TopPanel = new FRTabControl();
  164. TopPanel.Dock = DockStyle.Top;
  165. TopPanel.CloseButtons = false;
  166. TopPanel.Menu = new ContextMenuStrip();
  167. TopPanel.Menu.Items.Add(new ToolStripMenuItem("dummy"));
  168. TopPanel.Menu.Opening += topPanelMenu_Opening;
  169. BottomPanel = new FRTabControl();
  170. BottomPanel.Dock = DockStyle.Fill;
  171. BottomPanel.CloseButtons = false;
  172. BottomPanel.Menu = new ContextMenuStrip();
  173. BottomPanel.Menu.Items.Add(new ToolStripMenuItem("dummy"));
  174. BottomPanel.Menu.Opening += bottomPanelMenu_Opening;
  175. splitter = new Splitter();
  176. splitter.Dock = DockStyle.Top;
  177. splitter.MinSize = 0;
  178. splitter.MinExtra = 0;
  179. Controls.AddRange(new Control[] { BottomPanel, splitter, TopPanel });
  180. }
  181. }
  182. }