#region License Information /* HeuristicLab * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using HeuristicLab.MainForm; using HeuristicLab.Common; namespace HeuristicLab.MainForm.WindowsForms { [Content(typeof(object))] public sealed partial class ViewHost : AsynchronousContentView { public ViewHost() { InitializeComponent(); cachedViews = new Dictionary(); viewType = null; startDragAndDrop = false; viewContextMenuStrip.IgnoredViewTypes = new List() { typeof(ViewHost) }; activeView = null; Content = null; OnContentChanged(); } public ViewHost(IContent content) : this() { this.Content = content; } public ViewHost(IContentView contentView) : this() { this.viewType = contentView.GetType(); this.Content = contentView.Content; this.cachedViews.Add(contentView.GetType(), contentView); this.activeView = contentView; this.RegisterActiveViewEvents(); this.OnViewTypeChanged(); this.ActiveViewChanged(); } private Dictionary cachedViews; public IEnumerable Views { get { return cachedViews.Values; } } private IContentView activeView; public IContentView ActiveView { get { return this.activeView; } private set { if (activeView != value) { if (activeView != null) { DeregisterActiveViewEvents(); View view = activeView as View; if (view != null) view.OnHidden(EventArgs.Empty); } activeView = value; if (activeView != null) { RegisterActiveViewEvents(); View view = activeView as View; if (view != null) view.OnShown(new ViewShownEventArgs(view, false)); } ActiveViewChanged(); OnViewTypeChanged(); } } } private Type viewType; public Type ViewType { get { return this.viewType; } set { if (viewType != value) { if (value != null && !ViewCanShowContent(value, Content)) throw new ArgumentException(string.Format("View \"{0}\" cannot display content \"{1}\".", value, Content.GetType())); viewType = value; OnViewTypeChanged(); } } } public new IContent Content { get { return base.Content; } set { if (value == null || this.Content == null || value.GetType() != this.Content.GetType()) cachedViews.Clear(); base.Content = value; } } public new bool Enabled { get { return base.Enabled; } set { this.SuspendRepaint(); base.Enabled = value; this.viewsLabel.Enabled = value; this.ResumeRepaint(true); } } protected override void OnContentChanged() { messageLabel.Visible = false; viewsLabel.Visible = false; viewPanel.Visible = false; viewContextMenuStrip.Item = Content; if (Content != null) { if (viewContextMenuStrip.Items.Count == 0) messageLabel.Visible = true; else { viewsLabel.Visible = true; viewPanel.Visible = true; } if (!ViewCanShowContent(viewType, Content)) { ViewType = MainFormManager.GetDefaultViewType(Content.GetType()); if ((viewType == null) && (viewContextMenuStrip.Items.Count > 0)) // create first available view if default view is not available ViewType = (Type)viewContextMenuStrip.Items[0].Tag; } UpdateActiveMenuItem(); foreach (IContentView view in cachedViews.Values) view.Content = this.Content; } else { if (viewPanel.Controls.Count > 0) viewPanel.Controls[0].Dispose(); viewPanel.Controls.Clear(); cachedViews.Clear(); } } private void OnViewTypeChanged() { viewPanel.Controls.Clear(); if (viewType == null || Content == null) return; if (!ViewCanShowContent(viewType, Content)) throw new InvalidOperationException(string.Format("View \"{0}\" cannot display content \"{1}\".", viewType, Content.GetType())); UpdateActiveMenuItem(); IContentView view; if (cachedViews.ContainsKey(ViewType)) view = cachedViews[ViewType]; else { view = MainFormManager.CreateView(viewType); view.ReadOnly = this.ReadOnly; view.Locked = this.Locked; cachedViews.Add(viewType, view); } this.ActiveView = view; Control control = (Control)view; control.Dock = DockStyle.Fill; viewPanel.Controls.Add(control); viewPanel.Visible = true; view.Content = Content; } private void RegisterActiveViewEvents() { activeView.Changed += new EventHandler(activeView_Changed); activeView.CaptionChanged += new EventHandler(activeView_CaptionChanged); } private void DeregisterActiveViewEvents() { activeView.Changed -= new EventHandler(activeView_Changed); activeView.CaptionChanged -= new EventHandler(activeView_CaptionChanged); } private void activeView_CaptionChanged(object sender, EventArgs e) { this.ActiveViewChanged(); } private void activeView_Changed(object sender, EventArgs e) { this.ActiveViewChanged(); } private void ActiveViewChanged() { if (ActiveView != null) { this.Caption = this.ActiveView.Caption; this.Locked = this.ActiveView.Locked; } } #region forwarding of view events protected override void OnReadOnlyChanged() { base.OnReadOnlyChanged(); foreach (IContentView view in cachedViews.Values) view.ReadOnly = this.ReadOnly; } protected override void OnLockedChanged() { base.OnLockedChanged(); foreach (IContentView view in cachedViews.Values) view.Locked = this.Locked; } internal protected override void OnShown(ViewShownEventArgs e) { base.OnShown(e); View view = this.ActiveView as View; if (view != null) view.OnShown(e); } internal protected override void OnHidden(EventArgs e) { base.OnHidden(e); View view = this.ActiveView as View; if (view != null) view.OnHidden(e); } internal protected override void OnClosing(FormClosingEventArgs e) { base.OnClosing(e); foreach (View view in this.Views.OfType()) view.OnClosing(e); } internal protected override void OnClosed(FormClosedEventArgs e) { base.OnClosed(e); foreach (View view in this.Views.OfType()) view.OnClosed(e); } #endregion #region GUI actions private void UpdateActiveMenuItem() { foreach (KeyValuePair item in viewContextMenuStrip.MenuItems) { if (item.Key == viewType) { item.Value.Checked = true; item.Value.Enabled = false; } else { item.Value.Checked = false; item.Value.Enabled = true; } } } private bool ViewCanShowContent(Type viewType, object content) { if (content == null) // every view can display null return true; if (viewType == null) return false; return ContentAttribute.CanViewType(viewType, Content.GetType()) && viewContextMenuStrip.MenuItems.Any(item => item.Key == viewType); } private void viewsLabel_DoubleClick(object sender, EventArgs e) { IContentView view = MainFormManager.CreateView(viewType, Content); view.ReadOnly = this.ReadOnly; view.Locked = this.Locked; view.Show(); } private void viewContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { Type viewType = (Type)e.ClickedItem.Tag; ViewType = viewType; } private bool startDragAndDrop; private void viewsLabel_MouseDown(object sender, MouseEventArgs e) { if (!Locked) { startDragAndDrop = true; viewsLabel.Capture = false; viewsLabel.Focus(); } } private void viewsLabel_MouseLeave(object sender, EventArgs e) { if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left && startDragAndDrop) { DataObject data = new DataObject(); data.SetData("Type", Content.GetType()); data.SetData("Value", Content); DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link); } else startDragAndDrop = false; } #endregion } }