using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using FastReport.Design;
using FastReport.Utils;
namespace FastReport.Controls
{
internal class FRSideControl : Panel
{
private UIStyle style;
private Designer designer;
private Splitter splitter;
private ControlStorageService storage;
///
/// Gets storage service.
///
public ControlStorageService Storage
{
get
{
if (storage == null)
storage = new ControlStorageService(this, "Designer," + Name);
return storage;
}
}
public FRTabControl TopPanel { get; }
public FRTabControl BottomPanel { get; }
public UIStyle Style
{
get => style;
set
{
style = value;
var table = UIStyleUtils.GetColorTable(value);
TopPanel.Style = BottomPanel.Style = table.ToolWindow;
splitter.BackColor = table.Workspace.SplitterBackColor;
}
}
public FRSideControl OtherSideControl { get; set; }
public bool IsEmpty => VisiblePanelCount == 0;
public event EventHandler LayoutChanged;
private int VisiblePanelCount => (TopPanel.Tabs.Count > 0 ? 1 : 0) + (BottomPanel.Tabs.Count > 0 ? 1 : 0);
private string GetControls(FRTabControl panel) => string.Join(",", panel.Tabs.Cast().Select(c => c.Name));
private void SetControls(FRTabControl panel, string controls)
{
panel.Tabs.Clear();
foreach (var name in controls.Split(','))
{
var plugin = designer.Plugins.Find(name) as PageControlPage;
if (plugin != null)
{
plugin.Dock = DockStyle.Fill;
panel.Tabs.Add(plugin);
}
}
}
private void topPanelMenu_Opening(object sender, CancelEventArgs e)
{
TopPanel.Menu.Items.Clear();
TopPanel.Menu.Font = this.Font;
var selectedTab = TopPanel.SelectedTab;
var selectedTabText = "\"" + selectedTab.Text + "\"";
var res = new MyRes("Designer,ToolWindow");
var menuDockToBottom = new ToolStripMenuItem(string.Format(res.Get("DockToBottom"), selectedTabText));
menuDockToBottom.Click += (s, args) =>
{
AddToBottomPanel(selectedTab);
RefreshLayout();
};
if (VisiblePanelCount > 1 || TopPanel.Tabs.Count > 1)
TopPanel.Menu.Items.Add(menuDockToBottom);
var menuDockToOtherSide = new ToolStripMenuItem(string.Format(res.Get("DockToOtherSide"), selectedTabText));
menuDockToOtherSide.Click += (s, args) =>
{
OtherSideControl.AddToTopPanel(selectedTab);
RefreshLayout();
OtherSideControl.RefreshLayout();
};
TopPanel.Menu.Items.Add(menuDockToOtherSide);
}
private void bottomPanelMenu_Opening(object sender, CancelEventArgs e)
{
BottomPanel.Menu.Items.Clear();
BottomPanel.Menu.Font = this.Font;
var selectedTab = BottomPanel.SelectedTab;
var selectedTabText = "\"" + selectedTab.Text + "\"";
var res = new MyRes("Designer,ToolWindow");
var menuDockToTop = new ToolStripMenuItem(string.Format(res.Get("DockToTop"), selectedTabText));
menuDockToTop.Click += (s, args) =>
{
AddToTopPanel(selectedTab);
RefreshLayout();
};
if (VisiblePanelCount > 1 || BottomPanel.Tabs.Count > 1)
BottomPanel.Menu.Items.Add(menuDockToTop);
var menuDockToOtherSide = new ToolStripMenuItem(string.Format(res.Get("DockToOtherSide"), selectedTabText));
menuDockToOtherSide.Click += (s, args) =>
{
OtherSideControl.AddToBottomPanel(selectedTab);
RefreshLayout();
OtherSideControl.RefreshLayout();
};
BottomPanel.Menu.Items.Add(menuDockToOtherSide);
}
private void AddToPanel(FRTabControl panel, PageControlPage page)
{
page.Dock = DockStyle.Fill;
panel.Tabs.Add(page);
// workaround SWF behavior (page is added somewhere in the middle of the Controls list)
page.SendToBack();
}
public void AddToTopPanel(PageControlPage page) => AddToPanel(TopPanel, page);
public void AddToBottomPanel(PageControlPage page) => AddToPanel(BottomPanel, page);
public void RefreshLayout()
{
bool splitterWasVisible = splitter.Visible;
TopPanel.Visible = TopPanel.Tabs.Count > 0;
BottomPanel.Visible = BottomPanel.Tabs.Count > 0;
splitter.Visible = VisiblePanelCount == 2;
TopPanel.Dock = BottomPanel.Tabs.Count > 0 ? DockStyle.Top : DockStyle.Fill;
if (!splitterWasVisible && splitter.Visible)
TopPanel.Height = Height / 2;
TopPanel.Refresh();
TopPanel.SelectedTabIndex = 0;
BottomPanel.Refresh();
BottomPanel.SelectedTabIndex = 0;
LayoutChanged?.Invoke(this, EventArgs.Empty);
}
public void UpdateDpiDependencies()
{
TopPanel.UpdateDpiDependencies();
BottomPanel.UpdateDpiDependencies();
splitter.Height = this.LogicalToDevice(3);
}
public void UpdateText()
{
TopPanel.UpdateText();
BottomPanel.UpdateText();
}
public void SaveState()
{
Storage.SetDip("Width", Width);
Storage.SetDip("TopPanelHeight", Math.Min(TopPanel.Height, Height - 50));
Storage.SetStr("TopPanelControls", GetControls(TopPanel));
Storage.SetStr("BottomPanelControls", GetControls(BottomPanel));
}
public void RestoreState()
{
if (Storage.HasProperties)
{
Width = Storage.GetDip("Width", 280, 50, 1000);
SetControls(TopPanel, Storage.GetStr("TopPanelControls"));
SetControls(BottomPanel, Storage.GetStr("BottomPanelControls"));
RefreshLayout();
TopPanel.Height = Storage.GetDip("TopPanelHeight", 350);
}
}
public FRSideControl(Designer designer)
{
this.designer = designer;
Name = "SideControl";
TopPanel = new FRTabControl();
TopPanel.Dock = DockStyle.Top;
TopPanel.CloseButtons = false;
TopPanel.Menu = new ContextMenuStrip();
TopPanel.Menu.Items.Add(new ToolStripMenuItem("dummy"));
TopPanel.Menu.Opening += topPanelMenu_Opening;
BottomPanel = new FRTabControl();
BottomPanel.Dock = DockStyle.Fill;
BottomPanel.CloseButtons = false;
BottomPanel.Menu = new ContextMenuStrip();
BottomPanel.Menu.Items.Add(new ToolStripMenuItem("dummy"));
BottomPanel.Menu.Opening += bottomPanelMenu_Opening;
splitter = new Splitter();
splitter.Dock = DockStyle.Top;
splitter.MinSize = 0;
splitter.MinExtra = 0;
Controls.AddRange(new Control[] { BottomPanel, splitter, TopPanel });
}
}
}