Changeset 9849


Ignore:
Timestamp:
08/05/13 16:16:31 (6 years ago)
Author:
jkarder
Message:

#1042: ProgressView overlays are now shown to indicate save operations

Location:
trunk/sources
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs

    r9456 r9849  
    2929  public partial class ProgressView : AsynchronousContentView {
    3030    private const int DefaultCancelTimeoutMs = 3000;
    31     private ContentView parentView;
     31    private readonly IView parentView;
    3232
    3333    [Category("Custom"), Description("The time that the process is allowed to exit.")]
     
    4141    }
    4242
     43    private Control Control {
     44      get { return (Control)parentView; }
     45    }
     46
     47    public bool DisposeOnFinish { get; set; }
     48
    4349    public ProgressView() {
    4450      InitializeComponent();
     
    4854      Content = progress;
    4955    }
    50     public ProgressView(ContentView parentView)
     56    public ProgressView(IView parentView)
    5157      : this() {
    5258      if (parentView == null) throw new ArgumentNullException("parentView", "The parent view is null.");
     59      if (!(parentView is Control)) throw new ArgumentException("The parent view is not a control.", "parentView");
    5360      this.parentView = parentView;
    5461    }
    55     public ProgressView(ContentView parentView, IProgress progress)
     62    public ProgressView(IView parentView, IProgress progress)
    5663      : this(parentView) {
    5764      Content = progress;
     65    }
     66
     67    public static ProgressView Attach(IView parentView, IProgress progress, bool disposeOnFinish = false) {
     68      return new ProgressView(parentView, progress) {
     69        DisposeOnFinish = disposeOnFinish
     70      };
    5871    }
    5972
     
    94107      else {
    95108        if (parentView != null) {
    96           this.Left = (parentView.ClientRectangle.Width / 2) - (this.Width / 2);
    97           this.Top = (parentView.ClientRectangle.Height / 2) - (this.Height / 2);
     109          this.Left = (Control.ClientRectangle.Width / 2) - (this.Width / 2);
     110          this.Top = (Control.ClientRectangle.Height / 2) - (this.Height / 2);
    98111          this.Anchor = AnchorStyles.None;
    99112
    100113          LockBackground();
    101114
    102           if (!parentView.Controls.Contains(this))
    103             parentView.Controls.Add(this);
     115          if (!Control.Controls.Contains(this))
     116            Control.Controls.Add(this);
    104117
    105118          BringToFront();
     
    115128      else {
    116129        if (parentView != null) {
    117           if (parentView.Controls.Contains(this))
    118             parentView.Controls.Remove(this);
     130          if (Control.Controls.Contains(this))
     131            Control.Controls.Remove(this);
    119132
    120133          UnlockBackground();
     
    133146
    134147    private void Content_ProgressStateChanged(object sender, EventArgs e) {
    135       if (Content.ProgressState == ProgressState.Finished
    136         || Content.ProgressState == ProgressState.Canceled)
    137         HideProgress();
    138       if (Content.ProgressState == ProgressState.Started)
    139         ShowProgress();
     148      switch (Content.ProgressState) {
     149        case ProgressState.Finished:
     150          HideProgress();
     151          if (DisposeOnFinish) {
     152            Content = null;
     153            Dispose();
     154          }
     155          break;
     156        case ProgressState.Canceled: HideProgress(); break;
     157        case ProgressState.Started: ShowProgress(); break;
     158      }
    140159    }
    141160
     
    148167        Invoke((Action)LockBackground);
    149168      } else {
    150         parentView.Locked = true;
    151         parentView.ReadOnly = true;
    152         Locked = false;
    153         ReadOnly = false;
     169        parentView.Enabled = false;
     170        Enabled = true;
    154171      }
    155172    }
     
    158175      if (InvokeRequired) Invoke((Action)UnlockBackground);
    159176      else {
    160         parentView.Locked = false;
    161         parentView.ReadOnly = false;
    162         Locked = true;
    163         ReadOnly = true;
     177        parentView.Enabled = true;
     178        Enabled = false;
    164179      }
    165180    }
  • trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/MainForms/MainForm.cs

    r9626 r9849  
    3030namespace HeuristicLab.MainForm.WindowsForms {
    3131  public partial class MainForm : Form, IMainForm {
     32    private readonly Dictionary<IContent, IProgress> contentProgressLookup;
     33    private readonly Dictionary<IView, IProgress> viewProgressLookup;
    3234    private bool initialized;
    3335    private int appStartingCursors;
     
    3941      this.views = new Dictionary<IView, Form>();
    4042      this.userInterfaceItems = new List<IUserInterfaceItem>();
     43      this.contentProgressLookup = new Dictionary<IContent, IProgress>();
     44      this.viewProgressLookup = new Dictionary<IView, IProgress>();
    4145      this.initialized = false;
    4246      this.showContentInViewHost = false;
     
    343347        CloseView(view, closeReason);
    344348    }
     349
     350    /// <summary>
     351    /// Adds a <see cref="ProgressView"/> to the <see cref="ContentView"/>s showing the specified content.
     352    /// </summary>
     353    public void AddOperationProgressToContent(IContent content, IProgress progress, bool addToObjectGraphObjects = true) {
     354      if (contentProgressLookup.ContainsKey(content))
     355        throw new ArgumentException("A progress is already registered for the specified content.", "content");
     356
     357      var contentViews = Enumerable.Empty<IContentView>();
     358      if (addToObjectGraphObjects) {
     359        var containedObjects = content.GetObjectGraphObjects();
     360        contentViews = views.Keys.OfType<IContentView>().Where(v => containedObjects.Contains(v.Content));
     361      } else
     362        contentViews = views.Keys.OfType<IContentView>().Where(v => v.Content == content);
     363
     364      foreach (var contentView in contentViews)
     365        ProgressView.Attach(contentView, progress, true);
     366
     367      contentProgressLookup[content] = progress;
     368    }
     369
     370    /// <summary>
     371    /// Adds a <see cref="ProgressView"/> to the specified view.
     372    /// </summary>
     373    public void AddOperationProgressToView(IView view, Progress progress) {
     374      if (viewProgressLookup.ContainsKey(view))
     375        throw new ArgumentException("A progress is already registered for the specified view.", "view");
     376
     377      ProgressView.Attach(view, progress, true);
     378      viewProgressLookup[view] = progress;
     379    }
     380
     381    /// <summary>
     382    /// Removes an existing <see cref="ProgressView"/> from the <see cref="ContentView"/>s showing the specified content.
     383    /// </summary>
     384    public void RemoveOperationProgressFromContent(IContent content) {
     385      IProgress progress;
     386      if (!contentProgressLookup.TryGetValue(content, out progress))
     387        throw new ArgumentException("No progress is registered for the specified content.", "content");
     388
     389      progress.Finish();
     390      contentProgressLookup.Remove(content);
     391    }
     392
     393    /// <summary>
     394    /// Removes an existing <see cref="ProgressView"/> from the specified view.
     395    /// </summary>
     396    public void RemoveOperationProgressFromView(IView view) {
     397      IProgress progress;
     398      if (!viewProgressLookup.TryGetValue(view, out progress))
     399        throw new ArgumentException("No progress is registered for the specified view.", "view");
     400
     401      progress.Finish();
     402      viewProgressLookup.Remove(view);
     403    }
    345404    #endregion
    346405
  • trunk/sources/HeuristicLab.MainForm/3.3/Interfaces/IProgress.cs

    r9456 r9849  
    2828  public interface IProgress : IContent {
    2929    /// <summary>
    30     /// Gets the currently associated status text with the progress.
     30    /// Gets or sets the currently associated status text with the progress.
    3131    /// </summary>
    32     string Status { get; }
     32    string Status { get; set; }
    3333    /// <summary>
    34     /// Gets the currently associated progress value in the range (0;1].
     34    /// Gets or sets the currently associated progress value in the range (0;1].
    3535    ///  Values outside this range are permitted and need to be handled in some feasible manner.
    3636    /// </summary>
    37     double ProgressValue { get; }
     37    double ProgressValue { get; set; }
    3838    /// <summary>
    39     /// Gets the current state of the progress. Every progress starts in state
     39    /// Gets or sets the current state of the progress. Every progress starts in state
    4040    /// Started and then becomes either Canceled or Finished.
    4141    /// If it is reused it may be Started again.
    4242    /// </summary>
    43     ProgressState ProgressState { get; }
     43    ProgressState ProgressState { get; set; }
    4444    /// <summary>
    4545    /// Returns whether the operation can be canceled or not.
     
    5656    /// <param name="timeoutMs">The operation is given a certain timeout to cancel. If the operation doesn't cancel in this time it will be forcibly closed.</param>
    5757    void Cancel(int timeoutMs);
     58    /// <summary>
     59    /// Sets the ProgressValue to 1 and the ProgressState to Finished.
     60    /// </summary>
     61    void Finish();
    5862
    5963    /// <summary>
  • trunk/sources/HeuristicLab.MainForm/3.3/Progress.cs

    r9456 r9849  
    8686    }
    8787
    88     /// <summary>
    89     /// Sets the ProgressValue to 1 and the ProgressState to Finished.
    90     /// </summary>
    9188    public void Finish() {
    9289      if (ProgressValue != 1.0) ProgressValue = 1.0;
  • trunk/sources/HeuristicLab.Optimizer/3.3/FileManager.cs

    r9456 r9849  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Linq;
     24using System.IO;
    2525using System.Windows.Forms;
    2626using HeuristicLab.Common;
     
    9898          SaveAs(view);
    9999        else {
    100           ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).SetAppStartingCursor();
     100          MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().SetAppStartingCursor();
    101101          SetEnabledStateOfContentViews(content, false);
    102102          ContentManager.SaveAsync(content, content.Filename, true, SavingCompleted);
     
    123123
    124124        if (saveFileDialog.ShowDialog() == DialogResult.OK) {
    125           ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).SetAppStartingCursor();
     125          MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().SetAppStartingCursor();
    126126          SetEnabledStateOfContentViews(content, false);
    127127          if (saveFileDialog.FilterIndex == 1) {
     
    135135    private static void SavingCompleted(IStorableContent content, Exception error) {
    136136      try {
    137         SetEnabledStateOfContentViews(content, true);
    138137        if (error != null) throw error;
    139138        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().UpdateTitle();
     
    143142      }
    144143      finally {
    145         ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).ResetAppStartingCursor();
     144        SetEnabledStateOfContentViews(content, true);
     145        MainFormManager.GetMainForm<HeuristicLab.MainForm.WindowsForms.MainForm>().ResetAppStartingCursor();
    146146      }
    147147    }
     
    152152      // removed the InvokeRequired check because of Mono
    153153      mainForm.Invoke((Action)delegate {
    154         var views = MainFormManager.MainForm.Views.OfType<IContentView>().Where(v => v.Content == content).ToList();
    155         views.ForEach(v => v.Enabled = enabled);
     154        if (enabled)
     155          mainForm.RemoveOperationProgressFromContent(content);
     156        else
     157          mainForm.AddOperationProgressToContent(content, new Progress(string.Format("Saving file \"{0}\"...", Path.GetFileName(content.Filename))));
    156158      });
    157159      #endregion
Note: See TracChangeset for help on using the changeset viewer.