source: trunk/sources/HeuristicLab.MainForm.WindowsForms/3.3/Controls/ProgressView.cs @ 9849

Last change on this file since 9849 was 9849, checked in by jkarder, 6 years ago

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

File size: 7.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.ComponentModel;
24using System.Windows.Forms;
25
26namespace HeuristicLab.MainForm.WindowsForms {
27  [View("ProgressView")]
28  [Content(typeof(IProgress), true)]
29  public partial class ProgressView : AsynchronousContentView {
30    private const int DefaultCancelTimeoutMs = 3000;
31    private readonly IView parentView;
32
33    [Category("Custom"), Description("The time that the process is allowed to exit.")]
34    [DefaultValue(DefaultCancelTimeoutMs)]
35    public int CancelTimeoutMs { get; set; }
36    private bool ShouldSerializeCancelTimeoutMs() { return CancelTimeoutMs != DefaultCancelTimeoutMs; }
37
38    public new IProgress Content {
39      get { return (IProgress)base.Content; }
40      set { base.Content = value; }
41    }
42
43    private Control Control {
44      get { return (Control)parentView; }
45    }
46
47    public bool DisposeOnFinish { get; set; }
48
49    public ProgressView() {
50      InitializeComponent();
51    }
52    public ProgressView(IProgress progress)
53      : this() {
54      Content = progress;
55    }
56    public ProgressView(IView parentView)
57      : this() {
58      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");
60      this.parentView = parentView;
61    }
62    public ProgressView(IView parentView, IProgress progress)
63      : this(parentView) {
64      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      };
71    }
72
73    protected override void RegisterContentEvents() {
74      Content.StatusChanged += new EventHandler(progress_StatusChanged);
75      Content.ProgressValueChanged += new EventHandler(progress_ProgressValueChanged);
76      Content.ProgressStateChanged += new EventHandler(Content_ProgressStateChanged);
77      Content.CanBeCanceledChanged += new EventHandler(Content_CanBeCanceledChanged);
78      base.RegisterContentEvents();
79    }
80
81    protected override void DeregisterContentEvents() {
82      base.DeregisterContentEvents();
83      Content.StatusChanged -= new EventHandler(progress_StatusChanged);
84      Content.ProgressValueChanged -= new EventHandler(progress_ProgressValueChanged);
85      Content.ProgressStateChanged -= new EventHandler(Content_ProgressStateChanged);
86      Content.CanBeCanceledChanged -= new EventHandler(Content_CanBeCanceledChanged);
87    }
88
89    protected override void OnContentChanged() {
90      base.OnContentChanged();
91      if (Content == null) {
92        HideProgress();
93      } else {
94        if (Content.ProgressState == ProgressState.Started)
95          ShowProgress();
96      }
97    }
98
99    protected override void SetEnabledStateOfControls() {
100      base.SetEnabledStateOfControls();
101      cancelButton.Visible = Content != null && Content.CanBeCanceled;
102      cancelButton.Enabled = Content != null && Content.CanBeCanceled && !ReadOnly;
103    }
104
105    private void ShowProgress() {
106      if (InvokeRequired) Invoke((Action)ShowProgress);
107      else {
108        if (parentView != null) {
109          this.Left = (Control.ClientRectangle.Width / 2) - (this.Width / 2);
110          this.Top = (Control.ClientRectangle.Height / 2) - (this.Height / 2);
111          this.Anchor = AnchorStyles.None;
112
113          LockBackground();
114
115          if (!Control.Controls.Contains(this))
116            Control.Controls.Add(this);
117
118          BringToFront();
119        }
120        UpdateProgressValue();
121        UpdateProgressStatus();
122        Visible = true;
123      }
124    }
125
126    private void HideProgress() {
127      if (InvokeRequired) Invoke((Action)HideProgress);
128      else {
129        if (parentView != null) {
130          if (Control.Controls.Contains(this))
131            Control.Controls.Remove(this);
132
133          UnlockBackground();
134        }
135        Visible = false;
136      }
137    }
138
139    private void progress_StatusChanged(object sender, EventArgs e) {
140      UpdateProgressStatus();
141    }
142
143    private void progress_ProgressValueChanged(object sender, EventArgs e) {
144      UpdateProgressValue();
145    }
146
147    private void Content_ProgressStateChanged(object sender, EventArgs e) {
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      }
159    }
160
161    private void Content_CanBeCanceledChanged(object sender, EventArgs e) {
162      SetEnabledStateOfControls();
163    }
164
165    private void LockBackground() {
166      if (InvokeRequired) {
167        Invoke((Action)LockBackground);
168      } else {
169        parentView.Enabled = false;
170        Enabled = true;
171      }
172    }
173
174    private void UnlockBackground() {
175      if (InvokeRequired) Invoke((Action)UnlockBackground);
176      else {
177        parentView.Enabled = true;
178        Enabled = false;
179      }
180    }
181
182    private void UpdateProgressValue() {
183      if (InvokeRequired) Invoke((Action)UpdateProgressValue);
184      else {
185        if (Content != null) {
186          double progressValue = Content.ProgressValue;
187          if (progressValue <= 0.0 || progressValue > 1.0) {
188            if (progressBar.Style != ProgressBarStyle.Marquee)
189              progressBar.Style = ProgressBarStyle.Marquee;
190          } else {
191            if (progressBar.Style != ProgressBarStyle.Blocks)
192              progressBar.Style = ProgressBarStyle.Blocks;
193            progressBar.Value = (int)Math.Round(progressBar.Minimum + progressValue * (progressBar.Maximum - progressBar.Minimum));
194          }
195        }
196      }
197    }
198
199    private void UpdateProgressStatus() {
200      if (InvokeRequired) Invoke((Action)UpdateProgressStatus);
201      else if (Content != null)
202        statusLabel.Text = Content.Status;
203    }
204
205    private void cancelButton_Click(object sender, EventArgs e) {
206      if (Content != null) {
207        try {
208          Content.Cancel(CancelTimeoutMs);
209          ReadOnly = true;
210          cancelButtonTimer.Interval = CancelTimeoutMs;
211          cancelButtonTimer.Start();
212        } catch (NotSupportedException nse) {
213          PluginInfrastructure.ErrorHandling.ShowErrorDialog(nse);
214        }
215      }
216    }
217
218    private void cancelButtonTimer_Tick(object sender, EventArgs e) {
219      cancelButtonTimer.Stop();
220      if (Visible) ReadOnly = false;
221    }
222  }
223}
Note: See TracBrowser for help on using the repository browser.