123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- using FastReport.Design.PageDesigners.Dialog;
- using FastReport.Design.Toolbars;
- using FastReport.Utils;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Linq;
- using System.Windows.Forms;
- namespace FastReport.Design.StandardDesigner
- {
- /// <summary>
- /// Represents the standard report designer.
- /// </summary>
- /// <remarks>
- /// This control extends the <see cref="FastReport.Design.Designer"/> control with
- /// standard menu, status bar, and toolbars.
- /// <para/>To choose toolbars and tool windows in design-time, click the "View" menu
- /// in this control and select what you want to see. Toolbars can be reordered using the mouse.
- /// <para/>To restore the designer layout at runtime, you need to call the
- /// <see cref="FastReport.Design.Designer.RefreshLayout">RefreshLayout</see> method in your
- /// form's <b>Load</b> event handler.
- /// </remarks>
- [ToolboxItem(true), ToolboxBitmap(typeof(Report), "Resources.DesignerControl.bmp")]
- public partial class DesignerControl : Designer
- {
- #region Fields
- private DesignerMenu mainMenu;
- private DesignerStatusBar statusBar;
- private Panel toolStripPanel;
- private StandardToolbar standardToolbar;
- private TextToolbar textToolbar;
- private BorderToolbar borderToolbar;
- private LayoutToolbar layoutToolbar;
- private StyleToolbar styleToolbar;
- private PolygonToolbar polygonToolbar;
- private ContextMenuStrip mnuContext;
- private bool showMainMenu;
- private bool showStatusBar;
- #endregion
- #region Properties
- /// <summary>
- /// Gets the main menu.
- /// </summary>
- [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public DesignerMenu MainMenu
- {
- get { return mainMenu; }
- }
- /// <summary>
- /// Gets or sets a value indicating whether the main menu should be displayed or not.
- /// </summary>
- [SRCategory("Toolbars")]
- [DefaultValue(true)]
- public bool ShowMainMenu
- {
- get { return showMainMenu; }
- set
- {
- showMainMenu = value;
- mainMenu.Visible = value;
- }
- }
- /// <summary>
- /// Gets or sets a value indicating whether the status bar should be displayed or not.
- /// </summary>
- [SRCategory("Toolbars")]
- [DefaultValue(true)]
- public bool ShowStatusBar
- {
- get { return showStatusBar; }
- set
- {
- showStatusBar = value;
- statusBar.Visible = value;
- }
- }
- #endregion
- #region Private Methods
- private void CreateToolbarMenu()
- {
- mnuContext = new ContextMenuStrip();
- toolStripPanel.ContextMenuStrip = mnuContext;
- mnuContext.Opening += mnuContext_Opening;
- foreach (IDesignerPlugin plugin in Plugins)
- {
- if (plugin is DesignerToolbarBase)
- {
- var menuItem = new ToolStripMenuItem();
- menuItem.Text = (plugin as DesignerToolbarBase).Text;
- menuItem.Tag = plugin;
- menuItem.Click += toolbar_Click;
- mnuContext.Items.Add(menuItem);
- }
- }
- }
- private void mnuContext_Opening(object sender, EventArgs e)
- {
- mnuContext.Renderer = UIStyleUtils.GetToolStripRenderer(UIStyle);
- foreach (ToolStripItem item in mnuContext.Items)
- {
- var menuItem = item as ToolStripMenuItem;
- var toolbar = item.Tag as DesignerToolbarBase;
- menuItem.Text = toolbar.Text;
- menuItem.Checked = toolbar.Visible;
- }
- }
- private void toolbar_Click(object sender, EventArgs e)
- {
- var toolbar = (sender as ToolStripItem).Tag as DesignerToolbarBase;
- toolbar.Visible = !toolbar.Visible;
- LayoutToolbars();
- }
- private int LayoutToolbar(DesignerToolbarBase toolbar, int left, int top)
- {
- bool rtl = RightToLeft == RightToLeft.Yes;
- toolbar.Location = new Point(rtl ? Width - left - toolbar.Width : left, top);
- return left + toolbar.Width;
- }
- internal void LayoutToolbars()
- {
- var rowHeight = standardToolbar.Height;
- if (rowHeight == 0)
- return;
- // get list of visible toolbars
- var toolbars = toolStripPanel.Controls.OfType<DesignerToolbarBase>().Where(tb => tb.Visible).ToList();
- List<List<DesignerToolbarBase>> rows = new List<List<DesignerToolbarBase>>();
- int maxRows = Height / rowHeight;
- // find toolbars on each row
- for (int i = -1; i < maxRows; i++)
- {
- var row = new List<DesignerToolbarBase>();
- rows.Add(row);
- int rowTop = i * rowHeight - rowHeight / 2;
- int rowBottom = rowTop + rowHeight;
- if (i == -1)
- {
- // handle special case when toolbar is dragged out of parent bounds (above the first row)
- rowTop = -1000;
- }
- // find toolbars on this row
- for (int j = 0; j < toolbars.Count; j++)
- {
- var tb = toolbars[j];
- if (tb.Top >= rowTop && tb.Top <= rowBottom)
- {
- row.Add(tb);
- // remove from toolbars list to avoid having one toolbar on multiple rows (due to math errors)
- toolbars.RemoveAt(j);
- j--;
- }
- }
- if (toolbars.Count == 0)
- break;
- }
- // sort each row by Left (Right in opposite order in case of rtl)
- bool rtl = RightToLeft == RightToLeft.Yes;
- rows.ForEach(row => row.Sort((x, y) => rtl ? y.Right.CompareTo(x.Right) : x.Left.CompareTo(y.Left)));
- // remove empty rows
- rows.RemoveAll(row => row.Count == 0);
- // layout toolbars
- for (int i = 0; i < rows.Count; i++)
- {
- int x = 0;
- int y = i * rowHeight;
- rows[i].ForEach(tb => x = LayoutToolbar(tb, x, y));
- }
-
- // set overall height
- toolStripPanel.Height = rows.Count * rowHeight;
- }
- private void toolStripPanel_Paint(object sender, PaintEventArgs e)
- {
- var ct = UIStyleUtils.GetColorTable(UIStyle);
- Rectangle rect = new Rectangle(0, 0, toolStripPanel.Width, toolStripPanel.Height);
- using (var brush = new LinearGradientBrush(rect, ct.ToolStripPanelGradientBegin, ct.ToolStripPanelGradientEnd, LinearGradientMode.Horizontal))
- e.Graphics.FillRectangle(brush, rect);
- int _1 = this.LogicalToDevice(1);
- using (var brush = new SolidBrush(ct.ToolStripBorder))
- e.Graphics.FillRectangle(brush, 0, rect.Height - _1, rect.Width, _1);
- }
- #endregion
- #region Protected Methods
- internal override void AfterRestoreState()
- {
- base.AfterRestoreState();
- #if AVALONIA
- // this should be deferred to get correct toolbars size
- this.control.Loaded += (s,e) =>
- #endif
- LayoutToolbars();
- }
- /// <inheritdoc/>
- protected override void OnResize(EventArgs e)
- {
- base.OnResize(e);
- if (RightToLeft == RightToLeft.Yes)
- LayoutToolbars();
- }
- /// <inheritdoc/>
- protected override void InitPlugins()
- {
- base.InitPlugins();
- toolStripPanel = new Panel();
- toolStripPanel.Dock = DockStyle.Top;
- toolStripPanel.Paint += toolStripPanel_Paint;
- Controls.Add(toolStripPanel);
- mainMenu = new DesignerMenu(this);
- statusBar = new DesignerStatusBar(this);
- // create toolbars and make default toolbar layout
- standardToolbar = new StandardToolbar(this) { Left = 0, Top = 0 };
- layoutToolbar = new LayoutToolbar(this) { Left = standardToolbar.Right, Top = 0 };
- textToolbar = new TextToolbar(this) { Left = 0, Top = standardToolbar.Bottom };
- borderToolbar = new BorderToolbar(this) { Left = textToolbar.Right, Top = textToolbar.Top };
- styleToolbar = new StyleToolbar(this) { Left = borderToolbar.Right, Top = textToolbar.Top };
- polygonToolbar = new PolygonToolbar(this) { Left = styleToolbar.Right, Top = textToolbar.Top };
- var toolbars = new Control[] { standardToolbar, layoutToolbar, textToolbar, borderToolbar, styleToolbar, polygonToolbar };
- foreach (var toolbar in toolbars)
- {
- // WPF/Avalonia: occurs when toolbar is dragged to a new position. Not used in Mono
- toolbar.DragDrop += (s, e) => LayoutToolbars();
- }
- toolStripPanel.Controls.AddRange(toolbars);
- Plugins.AddRange(new IDesignerPlugin[] {
- mainMenu, statusBar, standardToolbar, textToolbar, borderToolbar,
- layoutToolbar, styleToolbar, polygonToolbar });
- CreateToolbarMenu();
- }
- #endregion
- #region Public Methods
- /// <inheritdoc/>
- public override void ShowStatus(string location, string size, string text, string locationRightBot)
- {
- statusBar.UpdateLocationAndSize(location, size, locationRightBot);
- statusBar.UpdateText(text);
- }
- /// <inheritdoc/>
- public override void UpdateUIStyle()
- {
- base.UpdateUIStyle();
- toolStripPanel.Refresh();
- }
- /// <inheritdoc/>
- public override void UpdateDpiDependencies(object sender)
- {
- base.UpdateDpiDependencies(sender);
- mnuContext.Font = this.Font;
- LayoutToolbars();
- }
- internal void UpdateFirstDialogPage()
- {
- // WPF bug: designer workspace is not initialized if the dialog form is the first page in a report (reason: visible designer form is needed)
- if (ActiveReportTab != null && ActiveReportTab.ActivePageDesigner is DialogPageDesigner pd)
- pd.UpdateDpiDependencies();
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="DesignerControl"/> class with default settings.
- /// </summary>
- public DesignerControl()
- {
- ShowMainMenu = true;
- ShowStatusBar = true;
- }
- }
- }
|