source: trunk/eraser/Eraser/AboutForm.cs @ 2245

Revision 2245, 12.2 KB checked in by lowjoel, 4 years ago (diff)

Added a DPI-aware version of the about dialog. There are some hacks here (notably the scale-down of the font size) but it works... Maybe we can review this when we rewrite the code to use DirectWrite??

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By: Kasra Nassiri <cjax@users.sourceforge.net>
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Data;
26using System.Drawing;
27using System.Drawing.Imaging;
28using System.Text;
29using System.Windows.Forms;
30using System.Runtime.InteropServices;
31using System.Reflection;
32using Eraser.Util;
33using System.Diagnostics;
34using System.Globalization;
35
36namespace Eraser
37{
38    public partial class AboutForm : Form
39    {
40        private Bitmap AboutBitmap;
41        private Point AboutBitmapPos;
42        private string AboutText;
43        private Bitmap AboutTextBitmap;
44        private Rectangle AboutTextRect;
45
46        private Bitmap ParentBitmap;
47        private int ParentOpacity;
48        private int AboutTextScrollTop;
49
50        private Rectangle WebsiteRect;
51        private Rectangle DonateRect;
52
53        private Bitmap DoubleBufferBitmap;
54
55        public AboutForm(Control parent)
56        {
57            //Create and position the dialog
58            InitializeComponent();
59            Theming.ApplyTheme(this);
60            ClientSize = new Size(parent.ClientSize.Width, parent.ClientSize.Height);
61            Point point = parent.PointToScreen(new Point(0, 0));
62            Left = point.X;
63            Top = point.Y;
64
65            //Get the parent dialog's screen buffer.
66            ParentBitmap = new Bitmap(parent.ClientSize.Width, parent.ClientSize.Height);
67            using (Graphics dest = Graphics.FromImage(ParentBitmap))
68            {
69                parent.Refresh();
70                Point parentPos = parent.PointToScreen(new Point(0, 0));
71                dest.CopyFromScreen(parentPos, new Point(0, 0), parent.ClientSize);
72            }
73
74            //Load the localised About Text
75            AboutText = S._(@"Eraser is an advanced security tool for Windows, which allows you to completely remove sensitive data from your hard drive by overwriting it several times with carefully selected patterns. Eraser is Free software and its source code is released under GNU General Public License.
76
77Erasure Method Credits:
78Gutmann (35 Pass):      Copyright Peter Gutmann & Colin Plumb
79Gutmann Lite (10 pass):         Copyright Peter Gutmann & Colin Plumb
80US DoD (7 pass):            Copyright United States Department of
81                Defense
82US DoD (3 pass):            Copyright United States Department of
83                Defense
84US Air Force 5020 (3 pass): Copyright United States Department of
85                Defense
86US Army AR380-19 (3 pass):  Copyright United States Department of
87                Defense
88RCMP TSSIT OPS-II (7 pass): Copyright Government of Canada,
89                Royal Canadian Mounted Police
90Schneier's Method (7 pass): Copyright Bruce Schneier
91German VSITR (7 pass):      Copyright Germany BSI Verschlusssachen
92                -IT-Richtlinien
93British HMG IS5 (3 pass):       Copyright British Government
94British HMG IS5 (1 pass):       Copyright British Government
95Russian GOST P50739-95 (2 pass):    Copyright Government of the Soviet
96                Union
97Pseudorandom data (1 pass): Public Domain
98First/Last 16Kb:            Copyright The Eraser Project
99
100Eraser Copyright " + "\u00A9" + @" The Eraser Project
101
102Eraser Project Members:
103" + "\u2022" + @" Sami Tolvanen:        Mentor/Initiator
104" + "\u2022" + @" Garrett Trant:        Mentor/Researcher
105" + "\u2022" + @" Joel Low:     Lead Developer
106" + "\u2022" + @" Kasra Nassiri:        Developer/Security Researcher
107" + "\u2022" + @" Dennis van Lith:      Designer");
108
109            //Create the About bitmap localised for the current version (sans scrolling
110            //text) so it can be drawn quickly later.
111            //First, duplicate the bitmap and scale it according to the resolution of the
112            //monitor.
113            float dpiScale = 0f;
114            using (Graphics controlDC = CreateGraphics())
115            {
116                Debug.Assert(controlDC.DpiX == controlDC.DpiY);
117                dpiScale = controlDC.DpiX / 96.0f;
118            }
119
120            Bitmap sourceBitmap = Properties.Resources.AboutDialog;
121            AboutBitmap = new Bitmap((int)(sourceBitmap.Width * dpiScale),
122                (int)(sourceBitmap.Height * dpiScale));
123            using (Graphics g = Graphics.FromImage(AboutBitmap))
124            {
125                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
126                g.ScaleTransform(dpiScale, dpiScale);
127                g.DrawImage(sourceBitmap, Point.Empty);
128
129                //Scale the font down since we will be using a scale transform later.
130                Font = new Font(Font.FontFamily, Font.SizeInPoints / dpiScale);
131
132                //Version number
133                Font boldFont = new Font(Font, FontStyle.Bold);
134                Font underlineFont = new Font(Font, FontStyle.Underline);
135                Brush textBrush = new SolidBrush(Color.White);
136                PointF eraserPos = new PointF(168, 80);
137                SizeF eraserSize = g.MeasureString(S._("Eraser"), boldFont);
138                g.DrawString(S._("Eraser"), boldFont, textBrush, eraserPos);
139
140                #pragma warning disable 429
141                string versionString = BuildInfo.CustomBuild ?
142                    S._("{0} (Built: {1:F}, special build)") : S._("{0} (Built: {1:F})");
143                #pragma warning restore 429
144
145                g.DrawString(string.Format(CultureInfo.CurrentCulture, versionString,
146                    BuildInfo.AssemblyFileVersion, BuildInfo.BuildDate),
147                    Font, textBrush, new PointF(eraserPos.X + eraserSize.Width + 3, eraserPos.Y));
148
149                //Copyright and Website
150                string copyrightText = S._("copyright \u00a9 2008-2010 The Eraser Project");
151                PointF copyrightPos = new PointF(eraserPos.X, eraserPos.Y + eraserSize.Height);
152                SizeF copyrightSize = g.MeasureString(copyrightText, Font);
153                g.DrawString(copyrightText, Font, textBrush, copyrightPos);
154
155                string websiteText = "http://eraser.heidi.ie/";
156                PointF websitePos = new PointF(copyrightPos.X, copyrightPos.Y + copyrightSize.Height);
157                SizeF websiteSize = g.MeasureString(websiteText, Font);
158                g.DrawString(websiteText, underlineFont, textBrush, websitePos);
159                WebsiteRect = new Rectangle((int)websitePos.X, (int)websitePos.Y,
160                    (int)websiteSize.Width, (int)websiteSize.Height);
161
162                //Open source disclaimer.
163                string disclaimerText = S._("Eraser is free open-source software!");
164                PointF disclaimerPos = new PointF(websitePos.X, websitePos.Y + websiteSize.Height * 1.5f);
165                g.DrawString(disclaimerText, Font, textBrush, disclaimerPos);
166
167                //Donation statement
168                string donationText = S._("Please help us to continue developing Eraser - donate some coffee!");
169                PointF donationPos = new PointF(disclaimerPos.X, disclaimerPos.Y + 170);
170                SizeF donationSize = g.MeasureString(donationText, Font);
171                g.DrawString(donationText, Font, textBrush, donationPos);
172                DonateRect = new Rectangle((int)donationPos.X, (int)donationPos.Y,
173                    (int)donationSize.Width, (int)donationSize.Height);
174            }
175
176            //Calculate the position of the About bitmap
177            AboutBitmapPos = new Point((ClientSize.Width - AboutBitmap.Width) / 2,
178                (ClientSize.Height - AboutBitmap.Height) / 2);
179            WebsiteRect.X = (int)(WebsiteRect.X * dpiScale + AboutBitmapPos.X);
180            WebsiteRect.Y = (int)(WebsiteRect.Y * dpiScale + AboutBitmapPos.Y);
181            WebsiteRect.Width = (int)(WebsiteRect.Width * dpiScale);
182            WebsiteRect.Height = (int)(WebsiteRect.Height * dpiScale);
183            DonateRect.X = (int)(DonateRect.X * dpiScale + AboutBitmapPos.X);
184            DonateRect.Y = (int)(DonateRect.Y * dpiScale + AboutBitmapPos.Y);
185            DonateRect.Width = (int)(DonateRect.Width * dpiScale);
186            DonateRect.Height = (int)(DonateRect.Height * dpiScale);
187
188            //And calculate the bounds of the About Text.
189            AboutTextRect = Rectangle.Truncate(new RectangleF(
190                AboutBitmapPos.X + (19 + 149) * dpiScale,
191                AboutBitmapPos.Y + (20 + 147) * dpiScale,
192                AboutBitmap.Width - (19 + 149 + 20) * dpiScale,
193                130 * dpiScale));
194
195            //Create the About Text laid out on screen.
196            SizeF aboutTextSize = SizeF.Empty;
197            using (Bitmap b = new Bitmap(1, 1))
198            using (Graphics g = Graphics.FromImage(b))
199            {
200                g.ScaleTransform(dpiScale, dpiScale);
201                aboutTextSize = g.MeasureString(AboutText, Font, AboutTextRect.Width);
202            }
203            AboutTextBitmap = new Bitmap(AboutTextRect.Width, (int)aboutTextSize.Height);
204            using (Graphics g = Graphics.FromImage(AboutTextBitmap))
205            {
206                g.Clear(Color.FromArgb(0, 0, 0, 0));
207                g.ScaleTransform(dpiScale, dpiScale);
208                g.DrawString(AboutText, Font, new SolidBrush(Color.White),
209                    new RectangleF(0.0f, 0.0f, AboutTextBitmap.Width / dpiScale,
210                        AboutTextBitmap.Height / dpiScale));
211            }
212
213            AboutTextScrollTop = AboutTextRect.Height / 2;
214            animationTimer_Tick(null, null);
215        }
216
217        private void AboutForm_Click(object sender, EventArgs e)
218        {
219            Point cursorPos = PointToClient(Cursor.Position);
220            try
221            {
222                if (WebsiteRect.IntersectsWith(new Rectangle(cursorPos, new Size(1, 1))))
223                    Process.Start("http://eraser.heidi.ie/");
224                else if (DonateRect.IntersectsWith(new Rectangle(cursorPos, new Size(1, 1))))
225                    Process.Start("http://sourceforge.net/donate/index.php?group_id=37015");
226                else if ((DateTime.Now - mouseDownTime < mouseSpeedUpSpan))
227                    //Dismiss the dialog.
228                    Close();
229            }
230            catch (Win32Exception ex)
231            {
232                //We've got an error executing the the browser to pass the links: show an error
233                //to the user.
234                MessageBox.Show(S._("Could not open the required web page. The error returned " +
235                    "was: {0}", ex.Message), S._("Eraser"), MessageBoxButtons.OK,
236                    MessageBoxIcon.Error, MessageBoxDefaultButton.Button1,
237                    Localisation.IsRightToLeft(this) ?
238                        MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0);
239            }
240        }
241
242        private void AboutForm_Paint(object sender, PaintEventArgs e)
243        {
244            DrawComposite(e.Graphics);
245        }
246
247        private void AboutForm_MouseMove(object sender, MouseEventArgs e)
248        {
249            Cursor.Current = Cursors.Default;
250            if (WebsiteRect.IntersectsWith(new Rectangle(e.Location, new Size(1, 1))) ||
251                DonateRect.IntersectsWith(new Rectangle(e.Location, new Size(1, 1))))
252                Cursor.Current = Cursors.Hand;
253        }
254
255        private void AboutForm_MouseLeave(object sender, EventArgs e)
256        {
257            Cursor.Current = Cursors.Default;
258        }
259
260        private void animationTimer_Tick(object sender, EventArgs e)
261        {
262            if (ParentOpacity <= 128)
263                ParentOpacity += 8;
264
265            if (AboutTextBitmap.Height < -AboutTextScrollTop)
266                AboutTextScrollTop = AboutTextRect.Height;
267            else if (AboutTextBitmap.Height < AboutTextScrollTop)
268                AboutTextScrollTop = -AboutTextRect.Height;
269            else
270            {
271                if (mouseSpeed == 0.0)
272                {
273                    AboutTextScrollTop -= 1;
274                }
275                else
276                {
277                    int speed = (mouseBotton == MouseButtons.Left ? -1 : +1);
278                    speed *= (int)mouseSpeed;
279
280                    AboutTextScrollTop += speed;
281
282                    // clamp so it doesnt go out of hand
283                    mouseSpeed = Math.Min(8.0, mouseSpeed + 0.1);
284                }
285            }
286
287            using (Graphics g = CreateGraphics())
288                DrawComposite(g);
289        }
290
291        private void DrawComposite(Graphics g)
292        {
293            if (DoubleBufferBitmap == null)
294                DoubleBufferBitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
295            using (Graphics bg = Graphics.FromImage(DoubleBufferBitmap))
296            {
297                //Draw the parent image with a fading out effect
298                if (ParentOpacity > 128)
299                    bg.Clip = new Region(AboutTextRect);
300
301                Brush brush = new SolidBrush(Color.FromArgb(ParentOpacity, 0, 0, 0));
302                bg.DrawImageUnscaled(ParentBitmap, 0, 0);
303                bg.FillRectangle(brush, ClientRectangle);
304
305                //Then draw the About bitmap (which we cached in the constructor)
306                bg.DrawImageUnscaled(AboutBitmap, AboutBitmapPos);
307
308                //And the scrolling text
309                bg.Clip = new Region(AboutTextRect);
310                bg.DrawImageUnscaled(AboutTextBitmap, AboutTextRect.Left,
311                    AboutTextRect.Top + AboutTextScrollTop);
312                bg.ResetClip();
313            }
314
315            if (ParentOpacity > 128)
316                if (g.Clip != null)
317                    g.Clip.Complement(new Region(AboutTextRect));
318                else
319                    g.Clip = new Region(AboutTextRect);
320            g.DrawImageUnscaled(DoubleBufferBitmap, 0, 0);
321        }
322
323        private double mouseSpeed;
324        private DateTime mouseDownTime = DateTime.MinValue;
325        private TimeSpan mouseSpeedUpSpan = new TimeSpan(0, 0, 0, 0, 230);
326        private MouseButtons mouseBotton;
327        private void AboutForm_MouseDown(object sender, MouseEventArgs e)
328        {
329            mouseSpeed = 2.0;
330            mouseBotton = e.Button;
331            animationTimer.Interval = 20;
332            mouseDownTime = DateTime.Now;
333        }
334
335        private void AboutForm_MouseUp(object sender, MouseEventArgs e)
336        {
337            mouseSpeed = 0.0;
338            animationTimer.Interval = 50;
339        }
340
341    }
342}
Note: See TracBrowser for help on using the repository browser.