+ |
+
+
diff --git a/CUETools.Codecs/Codecs.cs b/CUETools.Codecs/Codecs.cs
index f696a77..00d5ee8 100644
--- a/CUETools.Codecs/Codecs.cs
+++ b/CUETools.Codecs/Codecs.cs
@@ -1642,9 +1642,11 @@ namespace CUETools.Codecs
bool _haveData = false;
int _bufferPos = 0;
Exception _ex = null;
+ bool own;
- public AudioPipe(IAudioSource source, int size)
+ public AudioPipe(IAudioSource source, int size, bool own)
{
+ this.own = own;
_source = source;
_readBuffer = new AudioBuffer(source, size);
_writeBuffer = new AudioBuffer(source, size);
@@ -1655,7 +1657,9 @@ namespace CUETools.Codecs
private void Decompress(object o)
{
+#if !DEBUG
try
+#endif
{
bool done = false;
do
@@ -1674,8 +1678,8 @@ namespace CUETools.Codecs
Monitor.Pulse(this);
}
} while (!done);
- _source.Close();
}
+#if !DEBUG
catch (Exception ex)
{
lock (this)
@@ -1684,6 +1688,7 @@ namespace CUETools.Codecs
Monitor.Pulse(this);
}
}
+#endif
}
private void Go()
@@ -1712,6 +1717,11 @@ namespace CUETools.Codecs
_workThread.Join();
_workThread = null;
}
+ if (_source != null)
+ {
+ if (own) _source.Close();
+ _source = null;
+ }
if (_readBuffer != null)
{
//_readBuffer.Clear();
diff --git a/CUETools.Processor/Processor.cs b/CUETools.Processor/Processor.cs
index 57c09ab..400dbd2 100644
--- a/CUETools.Processor/Processor.cs
+++ b/CUETools.Processor/Processor.cs
@@ -978,7 +978,7 @@ namespace CUETools.Processor
overwriteCUEData = false;
filenamesANSISafe = true;
bruteForceDTL = false;
- createEACLOG = false;
+ createEACLOG = true;
detectHDCD = true;
wait750FramesForHDCD = true;
decodeHDCD = false;
@@ -1030,7 +1030,7 @@ namespace CUETools.Processor
}
if (Type.GetType("Mono.Runtime", false) == null)
{
- encoders.Add(new CUEToolsUDC("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11", "10", "flake.exe", "-%M - -o %O -p %P"));
+ encoders.Add(new CUEToolsUDC("flake", "flac", true, "0 1 2 3 4 5 6 7 8 9 10 11 12", "8", "flake.exe", "-%M - -o %O -p %P"));
encoders.Add(new CUEToolsUDC("takc", "tak", true, "0 1 2 2e 2m 3 3e 3m 4 4e 4m", "2", "takc.exe", "-e -p%M -overwrite - %O"));
encoders.Add(new CUEToolsUDC("ffmpeg alac", "m4a", true, "", "", "ffmpeg.exe", "-i - -f ipod -acodec alac -y %O"));
encoders.Add(new CUEToolsUDC("lame vbr", "mp3", false, "V9 V8 V7 V6 V5 V4 V3 V2 V1 V0", "V2", "lame.exe", "--vbr-new -%M - %O"));
@@ -1159,7 +1159,7 @@ string status = processor.Go();
sw.Save("OverwriteCUEData", overwriteCUEData);
sw.Save("FilenamesANSISafe", filenamesANSISafe);
if (bruteForceDTL) sw.Save("BruteForceDTL", bruteForceDTL);
- if (createEACLOG) sw.Save("CreateEACLOG", createEACLOG);
+ sw.Save("CreateEACLOG", createEACLOG);
sw.Save("DetectHDCD", detectHDCD);
sw.Save("Wait750FramesForHDCD", wait750FramesForHDCD);
sw.Save("DecodeHDCD", decodeHDCD);
@@ -1292,7 +1292,7 @@ string status = processor.Go();
overwriteCUEData = sr.LoadBoolean("OverwriteCUEData") ?? false;
filenamesANSISafe = sr.LoadBoolean("FilenamesANSISafe") ?? true;
bruteForceDTL = sr.LoadBoolean("BruteForceDTL") ?? false;
- createEACLOG = sr.LoadBoolean("createEACLOG") ?? false;
+ createEACLOG = sr.LoadBoolean("CreateEACLOG") ?? createEACLOG;
detectHDCD = sr.LoadBoolean("DetectHDCD") ?? true;
wait750FramesForHDCD = sr.LoadBoolean("Wait750FramesForHDCD") ?? true;
decodeHDCD = sr.LoadBoolean("DecodeHDCD") ?? false;
@@ -2635,14 +2635,15 @@ string status = processor.Go();
_padding += _eacLog.Length;
}
- public void UseCUEToolsDB()
+ public void UseCUEToolsDB(bool submit, string userAgent)
{
ShowProgress((string)"Contacting CUETools database...", 0, 0, null, null);
- _CUEToolsDB.ContactDB(_accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc));
+ _CUEToolsDB.ContactDB(_accurateRipId ?? AccurateRipVerify.CalculateAccurateRipId(_toc), userAgent);
ShowProgress("", 0.0, 0.0, null, null);
_useCUEToolsDB = true;
+ _useCUEToolsDBSibmit = submit;
}
public void UseAccurateRip()
@@ -3141,6 +3142,50 @@ string status = processor.Go();
}
}
+ public bool PrintErrors(StringWriter logWriter, uint tr_start, uint len)
+ {
+ uint tr_end = (len + 74) / 75;
+ int errCount = 0;
+ for (uint iSecond = 0; iSecond < tr_end; iSecond++)
+ {
+ uint sec_start = tr_start + iSecond * 75;
+ uint sec_end = Math.Min(sec_start + 74, tr_start + len - 1);
+ bool fError = false;
+ for (uint iSector = sec_start; iSector <= sec_end; iSector++)
+ if (_ripper.Errors[(int)iSector])
+ fError = true;
+ if (fError)
+ {
+ uint end = iSecond;
+ for (uint jSecond = iSecond + 1; jSecond < tr_end; jSecond++)
+ {
+ uint jsec_start = tr_start + jSecond * 75;
+ uint jsec_end = Math.Min(jsec_start + 74, tr_start + len - 1);
+ bool jfError = false;
+ for (uint jSector = jsec_start; jSector <= jsec_end; jSector++)
+ if (_ripper.Errors[(int)jSector])
+ jfError = true;
+ if (jfError)
+ end = jSecond;
+ }
+ if (errCount == 0)
+ logWriter.WriteLine();
+ if (errCount++ > 20)
+ break;
+ //"Suspicious position 0:02:20"
+ //" Suspicious position 0:02:23 - 0:02:24"
+ string s1 = CDImageLayout.TimeToString("0:{0:00}:{1:00}", iSecond * 75);
+ string s2 = CDImageLayout.TimeToString("0:{0:00}:{1:00}", end * 75);
+ if (iSecond == end)
+ logWriter.WriteLine(" Suspicious position {0}", s1);
+ else
+ logWriter.WriteLine(" Suspicious position {0} - {1}", s1, s2);
+ iSecond = end;
+ }
+ }
+ return errCount > 0;
+ }
+
public void CreateExactAudioCopyLOG()
{
StringWriter logWriter = new StringWriter(CultureInfo.InvariantCulture);
@@ -3163,7 +3208,7 @@ string status = processor.Go();
"Delete leading and trailing silent blocks : No\r\n" +
"Null samples used in CRC calculations : Yes\r\n" +
"Used interface : Native Win32 interface for Win NT & 2000\r\n" +
- "Gap handling : Appended to previous track\r\n" +
+ "{6}" +
"\r\n" +
"Used output format : Internal WAV Routines\r\n" +
"Sample format : 44.100 Hz; 16 Bit; Stereo\r\n";
@@ -3173,7 +3218,8 @@ string status = processor.Go();
Artist, Title,
_ripper.EACName,
_ripper.CorrectionQuality > 0 ? "Secure" : "Burst",
- _ripper.DriveOffset);
+ _ripper.DriveOffset,
+ (OutputStyle != CUEStyle.SingleFile && OutputStyle != CUEStyle.SingleFileWithCUE) ? "Gap handling : Appended to previous track\r\n" : "" );
logWriter.WriteLine();
logWriter.WriteLine("TOC of the extracted CD");
@@ -3192,6 +3238,7 @@ string status = processor.Go();
bool htoaToFile = ((OutputStyle == CUEStyle.GapsAppended) && _config.preserveHTOA &&
(_toc.Pregap != 0));
int accurateTracks = 0, knownTracks = 0;
+ bool wereErrors = false;
if (OutputStyle != CUEStyle.SingleFile && OutputStyle != CUEStyle.SingleFileWithCUE)
{
logWriter.WriteLine();
@@ -3206,46 +3253,7 @@ string status = processor.Go();
logWriter.WriteLine(" Pre-gap length 0:{0}.{1:00}", CDImageLayout.TimeToString("{0:00}:{1:00}", _toc[track + _toc.FirstAudio].Pregap + (track + _toc.FirstAudio == 1 ? 150U : 0U)), (_toc[track + _toc.FirstAudio].Pregap % 75) * 100 / 75);
}
- int errCount = 0;
- uint tr_start = _toc[track + _toc.FirstAudio].Start;
- uint tr_end = (_toc[track + _toc.FirstAudio].Length + 74) / 75;
- for (uint iSecond = 0; iSecond < tr_end; iSecond ++)
- {
- uint sec_start = tr_start + iSecond * 75;
- uint sec_end = Math.Min(sec_start + 74, _toc[track + _toc.FirstAudio].End);
- bool fError = false;
- for (uint iSector = sec_start; iSector <= sec_end; iSector++)
- if (_ripper.Errors[(int)iSector])
- fError = true;
- if (fError)
- {
- uint end = iSecond;
- for (uint jSecond = iSecond + 1; jSecond < tr_end; jSecond++)
- {
- uint jsec_start = tr_start + jSecond * 75;
- uint jsec_end = Math.Min(jsec_start + 74, _toc[track + _toc.FirstAudio].End);
- bool jfError = false;
- for (uint jSector = jsec_start; jSector <= jsec_end; jSector++)
- if (_ripper.Errors[(int)jSector])
- jfError = true;
- if (jfError)
- end = jSecond;
- }
- if (errCount == 0)
- logWriter.WriteLine();
- if (errCount++ > 20)
- break;
- //"Suspicious position 0:02:20"
- //" Suspicious position 0:02:23 - 0:02:24"
- string s1 = CDImageLayout.TimeToString("0:{0:00}:{1:00}", iSecond * 75);
- string s2 = CDImageLayout.TimeToString("0:{0:00}:{1:00}", end * 75);
- if (iSecond == end)
- logWriter.WriteLine(" Suspicious position {0}", s1);
- else
- logWriter.WriteLine(" Suspicious position {0} - {1}", s1, s2);
- iSecond = end;
- }
- }
+ wereErrors |= PrintErrors(logWriter, _toc[track + _toc.FirstAudio].Start, _toc[track + _toc.FirstAudio].Length);
logWriter.WriteLine();
logWriter.WriteLine(" Peak level {0:F1} %", (Tracks[track].PeakLevel * 1000 / 32768) * 0.1);
@@ -3277,6 +3285,7 @@ string status = processor.Go();
logWriter.WriteLine("Selected range");
logWriter.WriteLine();
logWriter.WriteLine(" Filename {0}", Path.ChangeExtension(Path.GetFullPath(_destPaths[0]), ".wav"));
+ wereErrors = PrintErrors(logWriter, _toc[_toc.FirstAudio][0].Start, _toc.AudioLength);
logWriter.WriteLine();
int PeakLevel = 0;
for (int track = 0; track < TrackCount; track++)
@@ -3288,7 +3297,10 @@ string status = processor.Go();
logWriter.WriteLine(" Copy CRC {0:X8}", _arVerify.CRC32(0));
logWriter.WriteLine(" Copy OK");
logWriter.WriteLine();
- logWriter.WriteLine("No errors occurred");
+ if (wereErrors)
+ logWriter.WriteLine("There were errors");
+ else
+ logWriter.WriteLine("No errors occurred");
logWriter.WriteLine();
logWriter.WriteLine();
logWriter.WriteLine("AccurateRip summary");
@@ -3331,7 +3343,10 @@ string status = processor.Go();
logWriter.WriteLine();
if (OutputStyle != CUEStyle.SingleFile && OutputStyle != CUEStyle.SingleFileWithCUE)
{
- logWriter.WriteLine("No errors occurred");
+ if (wereErrors)
+ logWriter.WriteLine("There were errors");
+ else
+ logWriter.WriteLine("No errors occurred");
logWriter.WriteLine();
}
logWriter.WriteLine("End of status report");
@@ -3383,24 +3398,19 @@ string status = processor.Go();
logWriter.WriteLine("Destination files");
foreach (string path in _destPaths)
logWriter.WriteLine(" {0}", path);
- bool wereErrors = false;
- for (int iTrack = 0; iTrack < _toc.AudioTracks; iTrack++)
+ bool wereErrors = PrintErrors(logWriter, _toc[_toc.FirstAudio][0].Start, _toc.AudioLength);
+ if (wereErrors)
{
- int cdErrors = 0;
- for (uint iSector = _toc[iTrack + 1].Start; iSector <= _toc[iTrack + 1].End; iSector++)
- if (_ripper.Errors[(int)iSector])
- cdErrors++;
- if (cdErrors != 0)
- {
- if (!wereErrors)
- {
- logWriter.WriteLine();
- logWriter.WriteLine("Errors detected");
- logWriter.WriteLine();
- }
- wereErrors = true;
- logWriter.WriteLine("Track {0} contains {1} errors", iTrack + 1, cdErrors);
- }
+ logWriter.WriteLine();
+ if (wereErrors)
+ logWriter.WriteLine("There were errors");
+ else
+ logWriter.WriteLine("No errors occurred");
+ }
+ if (_useCUEToolsDB)
+ {
+ logWriter.WriteLine();
+ GenerateCTDBLog(logWriter);
}
if (_useAccurateRip)
{
@@ -3408,7 +3418,6 @@ string status = processor.Go();
logWriter.WriteLine("AccurateRip summary");
logWriter.WriteLine();
_arVerify.GenerateFullLog(logWriter, true);
- logWriter.WriteLine();
}
logWriter.WriteLine();
logWriter.WriteLine("End of status report");
@@ -3514,6 +3523,28 @@ string status = processor.Go();
return sw.ToString();
}
+ public void GenerateCTDBLog(TextWriter sw)
+ {
+ if (_CUEToolsDB.DBStatus != null)
+ sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.DBStatus);
+ if (_CUEToolsDB.SubStatus != null)
+ sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.SubStatus);
+ if (_CUEToolsDB.DBStatus == null)
+ sw.WriteLine(" [ CTDBID ] Status");
+ foreach (DBEntry entry in _CUEToolsDB.Entries)
+ {
+ string confFormat = (_CUEToolsDB.Total < 10) ? "{0:0}/{1:0}" :
+ (_CUEToolsDB.Total < 100) ? "{0:00}/{1:00}" : "{0:000}/{1:000}";
+ string conf = string.Format(confFormat, entry.conf, _CUEToolsDB.Total);
+ string status =
+ (!entry.hasErrors) ? "Accurately ripped" :
+ entry.canRecover ? string.Format("Contains {0} correctable errors", entry.repair.CorrectableErrors) :
+ (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" :
+ entry.httpStatus.ToString();
+ sw.WriteLine(" [{0:x8}] ({1}) {2}", entry.crc, conf, status);
+ }
+ }
+
public void GenerateAccurateRipLog(TextWriter sw)
{
if (!_processed)
@@ -3544,26 +3575,7 @@ string status = processor.Go();
if (_useCUEToolsDBFix)// && _CUEToolsDB.SelectedEntry != null)
sw.WriteLine("CUETools DB: corrected {0} errors.", _CUEToolsDB.SelectedEntry.repair.CorrectableErrors);
else if (_useCUEToolsDB)
- {
- if (_CUEToolsDB.DBStatus != null)
- sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.DBStatus);
- if (_CUEToolsDB.SubStatus != null)
- sw.WriteLine("CUETools DB: {0}.", _CUEToolsDB.SubStatus);
- if (_CUEToolsDB.DBStatus == null)
- sw.WriteLine(" [ CTDBID ] Status");
- foreach (DBEntry entry in _CUEToolsDB.Entries)
- {
- string confFormat = (_CUEToolsDB.Total < 10) ? "{0:0}/{1:0}" :
- (_CUEToolsDB.Total < 100) ? "{0:00}/{1:00}" : "{0:000}/{1:000}";
- string conf = string.Format(confFormat, entry.conf, _CUEToolsDB.Total);
- string status =
- (!entry.hasErrors) ? "Accurately ripped" :
- entry.canRecover ? string.Format("Contains {0} correctable errors", entry.repair.CorrectableErrors) :
- (entry.httpStatus == 0 || entry.httpStatus == HttpStatusCode.OK) ? "No match" :
- entry.httpStatus.ToString();
- sw.WriteLine(" [{0:x8}] ({1}) {2}", entry.crc, conf, status);
- }
- }
+ GenerateCTDBLog(sw);
_arVerify.GenerateFullLog(sw, _config.arLogVerbose);
}
@@ -4706,7 +4718,7 @@ string status = processor.Go();
{
_ripper.Position = 0;
//audioSource = _ripper;
- audioSource = new AudioPipe(_ripper, 0x100000);
+ audioSource = new AudioPipe(_ripper, 0x100000, false);
} else
if (_isArchive)
audioSource = AudioReadWrite.GetAudioSource(sourceInfo.Path, OpenArchive(sourceInfo.Path, false), _config);
@@ -4719,7 +4731,7 @@ string status = processor.Go();
//if (!(audioSource is AudioPipe) && !(audioSource is UserDefinedReader) && _config.separateDecodingThread)
if (!(audioSource is AudioPipe) && _config.separateDecodingThread)
- audioSource = new AudioPipe(audioSource, 0x10000);
+ audioSource = new AudioPipe(audioSource, 0x10000, true);
return audioSource;
}
@@ -5226,7 +5238,7 @@ string status = processor.Go();
return "AccurateRip: confidence too low";
//if (CTDB.AccResult == HttpStatusCode.OK)
//return "CUEToolsDB: disc already present in database";
- if (CTDB.AccResult != HttpStatusCode.NotFound && CTDB.AccResult != HttpStatusCode.OK)
+ if (CTDB.AccResult != HttpStatusCode.NotFound && CTDB.AccResult != HttpStatusCode.OK)// && CTDB.AccResult != HttpStatusCode.NoContent)
return "CUEToolsDB: " + CTDB.DBStatus;
_useCUEToolsDBSibmit = true;
string status = Go();
@@ -5240,7 +5252,7 @@ string status = processor.Go();
}
case "repair":
{
- UseCUEToolsDB();
+ UseCUEToolsDB(false, "CUETools 205");
Action = CUEAction.Verify;
if (CTDB.DBStatus != null)
return CTDB.DBStatus;
diff --git a/CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj b/CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj
index e7aa6fb..888ddfe 100644
--- a/CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj
+++ b/CUETools.Ripper.SCSI/CUETools.Ripper.SCSI.csproj
@@ -19,10 +19,11 @@
true
full
false
- bin\Debug\
+ ..\bin\Debug\plugins\
DEBUG;TRACE
prompt
4
+ true
pdbonly
diff --git a/CUETools.Ripper.SCSI/SCSIDrive.cs b/CUETools.Ripper.SCSI/SCSIDrive.cs
index 75e979f..ad66e08 100644
--- a/CUETools.Ripper.SCSI/SCSIDrive.cs
+++ b/CUETools.Ripper.SCSI/SCSIDrive.cs
@@ -57,14 +57,14 @@ namespace CUETools.Ripper.SCSI
int m_max_sectors;
int _timeout = 10;
Crc16Ccitt _crc;
- public long[,] UserData;
- public long[,] C2Data;
+ public long[,,] UserData;
+ public byte[,] C2Count;
public byte[,] QData;
public long[] byte2long;
BitArray _errors;
int _errorsCount;
int _crcErrorsCount = 0;
- byte[] _currentData = new byte[MSECTORS * 4 * 588];
+ AudioBuffer currentData = new AudioBuffer(AudioPCMConfig.RedBook, MSECTORS * 588);
short[] _valueScore = new short[256];
bool _debugMessages = false;
ReadCDCommand _readCDCommand = ReadCDCommand.Unknown;
@@ -183,8 +183,8 @@ namespace CUETools.Ripper.SCSI
{
m_logger = new Logger();
_crc = new Crc16Ccitt(InitialCrcValue.Zeros);
- UserData = new long[MSECTORS, 4 * 588];
- C2Data = new long[MSECTORS, 588 / 2];
+ UserData = new long[MSECTORS, 2, 4 * 588];
+ C2Count = new byte[MSECTORS, 294];
QData = new byte[MSECTORS, 16];
byte2long = new long[256];
for (long i = 0; i < 256; i++)
@@ -287,6 +287,8 @@ namespace CUETools.Ripper.SCSI
m_device.Close();
m_device = null;
_toc = null;
+ _currentStart = -1;
+ _currentEnd = -1;
}
public void Dispose()
@@ -511,33 +513,73 @@ namespace CUETools.Ripper.SCSI
return found;
}
+ //int dbg_pass;
+ //FileStream fs_d, fs_c;
+
private unsafe void ReorganiseSectors(int sector, int Sectors2Read)
{
int c2Size = _c2ErrorMode == Device.C2ErrorMode.None ? 0 : _c2ErrorMode == Device.C2ErrorMode.Mode294 ? 294 : 296;
int oldSize = 4 * 588 + c2Size + (_subChannelMode == Device.SubChannelMode.None ? 0 : 16);
- fixed (byte* readBuf = _readBuffer, qBuf = _subchannelBuffer, qData = QData)
- fixed (long* userData = UserData, c2Data = C2Data)
+ fixed (byte* readBuf = _readBuffer, qBuf = _subchannelBuffer, qData = QData, c2Count = C2Count)
+ fixed (long* userData = UserData)
{
for (int iSector = 0; iSector < Sectors2Read; iSector++)
{
byte* sectorPtr = readBuf + iSector * oldSize;
- long* userDataPtr = userData + (sector - _currentStart + iSector) * 4 * 588;
- long* c2DataPtr = c2Data + (sector - _currentStart + iSector) * 294;
+ long* userDataPtr = userData + (sector - _currentStart + iSector) * 8 * 588;
+ byte* c2CountPtr = c2Count + (sector - _currentStart + iSector) * 294;
byte* qDataPtr = qData + (sector - _currentStart + iSector) * 16;
- for (int sample = 0; sample < 4 * 588; sample++)
- userDataPtr[sample] += byte2long[sectorPtr[sample]] * 3;
+ //if (_currentStart > 0)
+ //{
+ // string nm_d = string.Format("Y:\\Temp\\dbg\\{0:x}-{1:00}.bin", _currentStart, dbg_pass);
+ // string nm_c = string.Format("Y:\\Temp\\dbg\\{0:x}-{1:00}.c2", _currentStart, dbg_pass);
+ // if (fs_d != null && fs_d.Name != nm_d) { fs_d.Close(); fs_d = null; }
+ // if (fs_c != null && fs_c.Name != nm_c) { fs_c.Close(); fs_c = null; }
+ // if (fs_d == null) fs_d = new FileStream(nm_d, FileMode.Create);
+ // if (fs_c == null) fs_c = new FileStream(nm_c, FileMode.Create);
+ // fs_d.Seek((sector - _currentStart + iSector) * 4 * 588, SeekOrigin.Begin);
+ // fs_d.Write(_readBuffer, iSector * oldSize, 4 * 588);
+ // fs_c.Seek((sector - _currentStart + iSector) * 296, SeekOrigin.Begin);
+ // fs_c.Write(_readBuffer, iSector * oldSize + 4 * 588, 296);
+ //}
+
if (_c2ErrorMode != Device.C2ErrorMode.None)
{
- for (int c2 = 0; c2 < 294; c2++)
+ int offs = 0;
+ if (c2Size == 296)
{
- byte c2val = sectorPtr[4 * 588 + c2Size - 294 + c2];
- c2DataPtr[c2] += byte2long[c2val];
- if (c2val != 0)
- for (int b = 0; b < 8; b++)
- if (((c2val >> b) & 1) != 0)
- userDataPtr[c2 * 8 + b] += 0x0101010101010101 - byte2long[sectorPtr[c2 * 8 + b]] * 2;
+ // sometimes sector C2 byte is placed after C2 info, not before!!
+ int c2 = 0;
+ for (int pos = 2; pos < 294; pos++)
+ c2 |= sectorPtr[4 * 588 + pos];
+ if (sectorPtr[4 * 588 + 294] == (c2 | sectorPtr[4 * 588 + 0] | sectorPtr[4 * 588 + 1]))
+ offs = 0;
+ else if (sectorPtr[4 * 588] == (c2 | sectorPtr[4 * 588 + 294] | sectorPtr[4 * 588 + 295]))
+ offs = 2;
+ else
+ throw new Exception("invalid C2 pointers");
}
+ for (int pos = 0; pos < 294; pos++)
+ {
+ int c2d = sectorPtr[4 * 588 + pos + offs];
+ int c2 = ((-c2d) >> 31) & 1;
+ c2CountPtr[pos] += (byte)c2;
+ int sample = pos << 3;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]]; sample++;
+ userDataPtr[sample + c2 * 4 * 588] += byte2long[sectorPtr[sample]];
+ }
+ }
+ else
+ {
+ for (int sample = 0; sample < 4 * 588; sample++)
+ userDataPtr[sample] += byte2long[sectorPtr[sample]] * 3;
}
if (_subChannelMode != Device.SubChannelMode.None)
for (int qi = 0; qi < 16; qi++)
@@ -551,10 +593,11 @@ namespace CUETools.Ripper.SCSI
private unsafe void ClearSectors(int sector, int Sectors2Read)
{
- fixed (long* userData = &UserData[sector - _currentStart, 0], c2Data = &C2Data[sector - _currentStart, 0])
+ fixed (long* userData = &UserData[sector - _currentStart, 0, 0])
+ fixed (byte* c2Count = &C2Count[sector - _currentStart, 0])
{
- ZeroMemory((byte*)userData, 8 * 4 * 588 * Sectors2Read);
- ZeroMemory((byte*)c2Data, 4 * 588 * Sectors2Read);
+ ZeroMemory((byte*)userData, 8 * 2 * 4 * 588 * Sectors2Read);
+ ZeroMemory(c2Count, 294 * Sectors2Read);
}
}
@@ -598,10 +641,8 @@ namespace CUETools.Ripper.SCSI
if (FetchSectors(sector + iSector, 1, false, subchannel) != Device.CommandStatus.Success)
{
iErrors ++;
- for (int i = 0; i < 4 * 588; i++)
- UserData[sector + iSector - _currentStart, i] += 0x0101010101010101;
for (int i = 0; i < 294; i++)
- C2Data[sector + iSector - _currentStart, i] += 0x0101010101010101;
+ C2Count[sector + iSector - _currentStart, i] ++;
for (int i = 0; i < 16; i++)
QData[ sector + iSector - _currentStart, i] = 0;
if (_debugMessages)
@@ -745,8 +786,6 @@ namespace CUETools.Ripper.SCSI
for (int iSector = 0; iSector < Sectors2Read; iSector++)
{
int pos = sector - _currentStart + iSector;
- int avg = (pass + 1) * 3 / 2;
- int er_limit = 2 + pass / 2; // allow 25% minority
// avg - pass + 1
// p a l o
// 0 1 1 2
@@ -755,23 +794,30 @@ namespace CUETools.Ripper.SCSI
// 6 10 5
//16 25 10
bool fError = false;
+ const byte c2div = 128;
+ int er_limit = c2div * (1 + _correctionQuality) - 1;
+ // need at least 1 + _correctionQuality good passes
for (int iPar = 0; iPar < 4 * 588; iPar++)
{
- long val = UserData[pos, iPar];
- byte c2 = (byte)(C2Data[pos, iPar >> 3] >> ((iPar & 7) * 8));
+ long val = UserData[pos, 0, iPar];
+ long val1 = UserData[pos, 1, iPar];
+ byte c2 = C2Count[pos, iPar >> 3];
+ int ave = (pass + 1 - c2) * c2div + c2;
int bestValue = 0;
for (int i = 0; i < 8; i++)
{
- int sum = avg - ((int)(val & 0xff));
+ int sum = ave - 2 * (int)((val & 0xff) * c2div + (val1 & 0xff));
int sig = sum >> 31; // bit value
fError |= (sum ^ sig) < er_limit;
bestValue += sig & (1 << i);
val >>= 8;
}
- _currentData[pos * 4 * 588 + iPar] = (byte)bestValue;
+ currentData.Bytes[pos * 4 * 588 + iPar] = (byte)bestValue;
}
- if (fError)
- _currentErrorsCount++;
+ int newerr = (fError ? 1 : 0);
+ //_currentErrorsCount += newerr;
+ _currentErrorsCount += newerr - errtmp[pos];
+ errtmp[pos] = newerr;
if (markErrors)
{
_errors[sector + iSector] |= fError;
@@ -781,6 +827,8 @@ namespace CUETools.Ripper.SCSI
}
+ int[] errtmp = new int[MSECTORS];
+
//private unsafe int CorrectSectorsTest(int start, int end, int c2Score, byte[] realData, int worstScan)
//{
// int[] valueScore = new int[256];
@@ -837,14 +885,24 @@ namespace CUETools.Ripper.SCSI
public unsafe void PrefetchSector(int iSector)
{
- if (_currentStart == MSECTORS * (iSector / MSECTORS))
+ if (iSector >= _currentStart && iSector < _currentEnd)
return;
if (_readCDCommand == ReadCDCommand.Unknown && !TestReadCommand())
throw new Exception("failed to autodetect read command: " + _autodetectResult);
_currentStart = MSECTORS * (iSector / MSECTORS);
- _currentEnd = Math.Min(_currentStart + MSECTORS, (int)_toc.AudioLength);
+ _currentEnd = _currentStart + MSECTORS;
+ if (_currentEnd > (int)_toc.AudioLength)
+ {
+ _currentEnd = (int)_toc.AudioLength;
+ _currentStart = Math.Max(0, _currentEnd - MSECTORS);
+ }
+
+ int neededSize = (_currentEnd - _currentStart) * 588;
+ if (currentData.Size < neededSize)
+ currentData.Prepare(new byte[neededSize * 4], neededSize);
+ currentData.Length = neededSize;
//FileStream correctFile = new FileStream("correct.wav", FileMode.Open);
//byte[] realData = new byte[MSECTORS * 4 * 588];
@@ -853,11 +911,15 @@ namespace CUETools.Ripper.SCSI
// throw new Exception("read");
//correctFile.Close();
- int max_scans = 64;
- for (int pass = 0; pass <= max_scans; pass++)
+ _currentErrorsCount = 0;
+ for (int i = 0; i < MSECTORS; i++)
+ errtmp[i] = 0;
+
+ int max_scans = 16 << _correctionQuality;
+ for (int pass = 0; pass < max_scans; pass++)
{
+// dbg_pass = pass;
DateTime PassTime = DateTime.Now, LastFetch = DateTime.Now;
- _currentErrorsCount = 0;
for (int sector = _currentStart; sector < _currentEnd; sector += m_max_sectors)
{
@@ -875,9 +937,9 @@ namespace CUETools.Ripper.SCSI
if (pass == 0)
ProcessSubchannel(sector, Sectors2Read, true);
//DateTime LastFetched = DateTime.Now;
- if ((pass & 1) == 0)
+ if (pass >= _correctionQuality)
{
- CorrectSectors(pass, sector, Sectors2Read, pass >= max_scans);
+ CorrectSectors(pass, sector, Sectors2Read, pass == max_scans - 1);
PrintErrors(pass, sector, Sectors2Read, /*realData*/null);
}
//TimeSpan delay2 = DateTime.Now - LastFetched;
@@ -889,7 +951,7 @@ namespace CUETools.Ripper.SCSI
//System.Console.WriteLine();
//if (CorrectSectorsTest(start, _currentEnd, 10, realData) == 0)
// break;
- if ((pass & 1) == 0 && pass >= _correctionQuality && _currentErrorsCount == 0)
+ if (pass >= _correctionQuality && _currentErrorsCount == 0)
break;
}
}
@@ -917,8 +979,15 @@ namespace CUETools.Ripper.SCSI
PrefetchSector(_sampleOffset / 588);
buff.Length = Math.Min(buff.Length, (int)Length - _sampleOffset);
buff.Length = Math.Min(buff.Length, _currentEnd * 588 - _sampleOffset);
- fixed (byte* dest = buff.Bytes, src = &_currentData[(_sampleOffset - _currentStart * 588) * 4])
- AudioSamples.MemCpy(dest, src, buff.ByteLength);
+ if ((_sampleOffset - _currentStart * 588) == 0 && (maxLength < 0 || (_currentEnd - _currentStart) * 588 <= buff.Length))
+ {
+ buff.Swap(currentData);
+ _currentStart = -1;
+ _currentEnd = -1;
+ }
+ else
+ fixed (byte* dest = buff.Bytes, src = ¤tData.Bytes[(_sampleOffset - _currentStart * 588) * 4])
+ AudioSamples.MemCpy(dest, src, buff.ByteLength);
_sampleOffset += buff.Length;
return buff.Length;
}
@@ -982,7 +1051,9 @@ namespace CUETools.Ripper.SCSI
_currentTrack = -1;
_currentIndex = -1;
_crcErrorsCount = 0;
- _errorsCount = 0;
+ _errorsCount = 0;
+ _currentStart = -1;
+ _currentEnd = -1;
_errors = new BitArray((int)_toc.AudioLength); // !!!
_sampleOffset = (int)value + _driveOffset;
}
@@ -1017,6 +1088,8 @@ namespace CUETools.Ripper.SCSI
}
set
{
+ if (value < 0 || value > 3)
+ throw new Exception("invalid CorrectionQuality");
_correctionQuality = value;
}
}
@@ -1046,15 +1119,6 @@ namespace CUETools.Ripper.SCSI
bcd &= 0x3f;
return bcd >= ISRC6.Length ? '#' : ISRC6[bcd];
}
-
- public static char[] DrivesAvailable()
- {
- List result = new List();
- foreach (DriveInfo info in DriveInfo.GetDrives())
- if (info.DriveType == DriveType.CDRom)
- result.Add(info.Name[0]);
- return result.ToArray();
- }
}
enum ReadCDCommand
diff --git a/CUETools.Ripper/CUETools.Ripper.csproj b/CUETools.Ripper/CUETools.Ripper.csproj
index 3cc381a..6189b27 100644
--- a/CUETools.Ripper/CUETools.Ripper.csproj
+++ b/CUETools.Ripper/CUETools.Ripper.csproj
@@ -23,6 +23,7 @@
DEBUG;TRACE
prompt
4
+ true
pdbonly
diff --git a/CUETools.Ripper/Ripper.cs b/CUETools.Ripper/Ripper.cs
index d90c41a..7356e13 100644
--- a/CUETools.Ripper/Ripper.cs
+++ b/CUETools.Ripper/Ripper.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Collections;
using System.Collections.Generic;
using CUETools.CDImage;
@@ -22,6 +23,18 @@ namespace CUETools.Ripper
event EventHandler ReadProgress;
}
+ public class CDDrivesList
+ {
+ public static char[] DrivesAvailable()
+ {
+ List result = new List();
+ foreach (DriveInfo info in DriveInfo.GetDrives())
+ if (info.DriveType == DriveType.CDRom)
+ result.Add(info.Name[0]);
+ return result.ToArray();
+ }
+ }
+
public sealed class ReadProgressArgs : EventArgs
{
public int Position;
diff --git a/CUETools/CUETools.sln b/CUETools/CUETools.sln
index eb1e14b..69035cc 100644
--- a/CUETools/CUETools.sln
+++ b/CUETools/CUETools.sln
@@ -153,6 +153,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.CDRepair", "..\CUE
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.CTDB", "..\CUETools.CTDB\CUETools.CTDB.csproj", "{AA2A9A7E-45FB-4632-AD85-85B0E556F818}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProgressODoom", "..\ProgressODoom\ProgressODoom.csproj", "{8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}"
+EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = CUETools1.vsmdi
@@ -560,6 +562,14 @@ Global
{AA2A9A7E-45FB-4632-AD85-85B0E556F818}.Release|Any CPU.Build.0 = Release|Any CPU
{AA2A9A7E-45FB-4632-AD85-85B0E556F818}.Release|Win32.ActiveCfg = Release|Any CPU
{AA2A9A7E-45FB-4632-AD85-85B0E556F818}.Release|x64.ActiveCfg = Release|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|Win32.ActiveCfg = Release|Any CPU
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}.Release|x64.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/CUETools/TestRipper/CDDriveReaderTest.cs b/CUETools/TestRipper/CDDriveReaderTest.cs
index 584fc6c..da7dc22 100644
--- a/CUETools/TestRipper/CDDriveReaderTest.cs
+++ b/CUETools/TestRipper/CDDriveReaderTest.cs
@@ -1,5 +1,6 @@
using System;
using System.Text;
+using System.IO;
using System.Collections.Generic;
using CUETools.Codecs;
using CUETools.Ripper;
@@ -36,19 +37,17 @@ namespace TestRipper
}
}
- const int pass = 16;
- const int Sectors2Read = 10000;
- const int bit_weight = 3;
- const int c2_weight = 1;
+ const int max_pass = 64;
+ const int Sectors2Read = 2400;
bool markErrors = true;
int _currentStart = 0, _realErrors = 0;
byte[] _currentData = new byte[Sectors2Read * 4 * 588];
- static long[,] UserData = new long[Sectors2Read, 4 * 588];
- static long[,] C2Data = new long[Sectors2Read, 4 * 588 / 8];
+ static ulong[,,] UserData = new ulong[Sectors2Read, 2, 4 * 588];
+ static byte[,] C2Count = new byte[Sectors2Read, 4 * 588];
static byte[] _realData = new byte[Sectors2Read * 4 * 588];
- static long[] byte2long = new long[256];
+ static ulong[] byte2long = new ulong[256];
#region Additional test attributes
//
@@ -58,30 +57,58 @@ namespace TestRipper
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
- for (long i = 0; i < 256; i++)
+ for (ulong i = 0; i < 256; i++)
{
- long bl = 0;
+ ulong bl = 0;
for (int b = 0; b < 8; b++)
bl += ((i >> b) & 1) << (b << 3);
byte2long[i] = bl;
}
- Random rnd = new Random(2314);
- rnd.NextBytes(_realData);
+ //Random rnd = new Random(2314);
+ //rnd.NextBytes(_realData);
- for (int p = 0; p <= pass; p++)
- for (int iSector = 0; iSector < Sectors2Read; iSector++)
- for (int iPar = 0; iPar < 4 * 588; iPar++)
+ byte [] c2data = new byte[Sectors2Read * 296];
+ for (int p = 0; p < max_pass; p++)
+ {
+ // string nm_d = string.Format("Y:\\Temp\\dbg\\{0:x}-{1:00}.bin", _currentStart, dbg_pass);
+ using (FileStream fs = new FileStream(string.Format("Y:\\Temp\\dbg\\960\\960-{0:00}.bin", p), FileMode.Open))
+ using (FileStream fs2 = new FileStream(string.Format("Y:\\Temp\\dbg\\960\\960-{0:00}.c2", p), FileMode.Open))
+ {
+ fs.Read(_realData, 0, Sectors2Read * 4 * 588);
+ fs2.Read(c2data, 0, Sectors2Read * 296);
+ for (int iSector = 0; iSector < Sectors2Read; iSector++)
{
- bool error = rnd.NextDouble() < 0.2;
- byte val = error ? (byte)rnd.Next(255) : _realData[iSector * 4 * 588 + iPar];
- UserData[iSector, iPar] += byte2long[val] * bit_weight;
- if (error && rnd.NextDouble() < 0.5)
+ for (int pos = 0; pos < 294; pos++)
{
- C2Data[iSector, iPar >> 3] += (iPar & 7) * 8;
- UserData[iSector, iPar] += 0x0101010101010101 * (bit_weight / 2) + byte2long[val] * (c2_weight - bit_weight);
+ int c2d = c2data[iSector * 296 + pos];
+ for (int sample = (pos << 3); sample < (pos << 3) + 8; sample++)
+ {
+ //int c2 = (c2d >> (7 - (sample & 7))) & 1;
+ //int c2 = (c2d >> ((sample & 7))) & 1;
+ //int c2 = ((c2d >> ((sample & 7))) | (c2d >> (7 - (sample & 7)))) & 1;
+ int c2 = ((-c2d) >> 31) & 1;
+ C2Count[iSector, sample] += (byte)c2;
+ UserData[iSector, c2, sample] += byte2long[_realData[iSector * 4 * 588 + sample]];
+ }
}
}
+ }
+ //for (int iSector = 0; iSector < Sectors2Read; iSector++)
+ // for (int iPar = 0; iPar < 4 * 588; iPar++)
+ // {
+ // bool error = rnd.NextDouble() < 0.2;
+ // byte val = error ? (byte)rnd.Next(255) : _realData[iSector * 4 * 588 + iPar];
+ // UserData[iSector, iPar] += byte2long[val] * bit_weight;
+ // if (error && rnd.NextDouble() < 0.5)
+ // {
+ // C2Data[iSector, iPar >> 3] += (iPar & 7) * 8;
+ // UserData[iSector, iPar] += 0x0101010101010101 * (bit_weight / 2) + byte2long[val] * (c2_weight - bit_weight);
+ // }
+ // }
+ }
+ using (FileStream fs = new FileStream(string.Format("Y:\\Temp\\dbg\\960\\960.bin", 0), FileMode.Open))
+ fs.Read(_realData, 0, Sectors2Read * 4 * 588);
}
//
//Use ClassCleanup to run code after all tests in a class have run
@@ -114,36 +141,39 @@ namespace TestRipper
{
int _currentErrorsCount = 0;
int sector = 0;
-
+ _realErrors = 0;
+ const byte c2div = 128;
+ const int er_limit = c2div * 3;
+ int fErrCnt = 0;
for (int iSector = 0; iSector < Sectors2Read; iSector++)
{
int pos = sector - _currentStart + iSector;
- int avg = (pass + 1) * bit_weight / 2;
- int c2_limit = pass / 3; //
- int er_limit = avg - pass; // allow 33% minority
for (int iPar = 0; iPar < 4 * 588; iPar++)
{
- long val = UserData[pos, iPar];
- byte c2 = (byte)(C2Data[pos, iPar >> 3] >> ((iPar & 7) * 8));
+ ulong val = UserData[pos, 0, iPar];
+ ulong val1 = 0;// UserData[pos, 1, iPar];
+ byte c2 = C2Count[pos, iPar];
+ int ave = (max_pass - c2) * c2div + c2;
int bestValue = 0;
+ bool fError = false;
for (int i = 0; i < 8; i++)
{
- int sum = avg - ((int)(val & 0xff));
- int sig = sum >> 31; // bit value
- if ((sum ^ sig) < er_limit) _currentErrorsCount++;
+ int sum = ave - 2 * (int)((val & 0xff) * c2div + (val1 & 0xff));
+ int sig = sum >> 31;
+ fError |= (sum ^ sig) < er_limit;
bestValue += sig & (1 << i);
val >>= 8;
}
+ if (fError)
+ fErrCnt++;
//if (c2 > c2_limit)
//_currentErrorsCount++;
_currentData[pos * 4 * 588 + iPar] = (byte)bestValue;
+ if (_realData[iSector * 4 * 588 + iPar] != bestValue)
+ _realErrors++;
}
}
- for (int p = 0; p <= pass; p++)
- for (int iSector = 0; iSector < Sectors2Read; iSector++)
- for (int iPar = 0; iPar < 4 * 588; iPar++)
- if (_realData[iSector * 4 * 588 + iPar] != _currentData[iSector * 4 * 588 + iPar])
- _realErrors++;
+ //Assert.AreEqual(0, fErrCnt);
Assert.AreEqual(0, _realErrors, "0 != _realErrors; _currentErrorsCount == " + _currentErrorsCount.ToString());
//CollectionAssert.AreEqual(_realData, _currentData, "_realData != _currentData");
Assert.AreEqual(0, _currentErrorsCount, "_currentErrorsCount != 0");
diff --git a/CUETools/frmCUETools.cs b/CUETools/frmCUETools.cs
index aa69769..fcbabe6 100644
--- a/CUETools/frmCUETools.cs
+++ b/CUETools/frmCUETools.cs
@@ -745,7 +745,7 @@ namespace JDP {
}
if (useCUEToolsDB)
{
- cueSheet.UseCUEToolsDB();
+ cueSheet.UseCUEToolsDB(false, "CUETools 205");
}
if (_batchPaths.Count == 0 && action == CUEAction.Encode)
diff --git a/CUETools/frmCUETools.resx b/CUETools/frmCUETools.resx
index 5924055..4a4a385 100644
--- a/CUETools/frmCUETools.resx
+++ b/CUETools/frmCUETools.resx
@@ -669,6 +669,9 @@
Fill
+
+ NoControl
+
3, 3
diff --git a/ProgressODoom/AbstractProgressBar.cs b/ProgressODoom/AbstractProgressBar.cs
new file mode 100644
index 0000000..81af890
--- /dev/null
+++ b/ProgressODoom/AbstractProgressBar.cs
@@ -0,0 +1,223 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ public enum ProgressType {
+ Smooth, MarqueeWrap, MarqueeBounce, MarqueeBounceDeep, Animated
+ }
+
+ ///
+ public abstract class AbstractProgressBar : Control {
+ protected int minimum = 0;
+ protected int maximum = 100;
+ protected int value = 0;
+ protected Rectangle borderbox;
+ protected Rectangle progressbox;
+ protected Rectangle backbox;
+ private bool showPercent = false;
+ private int padding = 0;
+ #region Marquee
+ protected ProgressType type = ProgressType.Smooth;
+ protected int marqueeSpeed = 30;
+ protected int marqueePercentage = 25;
+ protected int marqueeStep = 1;
+ #endregion
+
+ protected EventHandler OnValueChanged;
+ ///
+ public event EventHandler ValueChanged {
+ add {
+ if (OnValueChanged != null) {
+ foreach (Delegate d in OnValueChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value);
+ }
+ remove { OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value); }
+ }
+
+ public AbstractProgressBar() {
+ this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets whether or not to draw the percentage text"), Browsable(true)]
+ public bool ShowPercentage {
+ get { return showPercent; }
+ set {
+ showPercent = value;
+ Invalidate();
+ if (!showPercent) {
+ this.Text = "";
+ }
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the minimum value"), Browsable(true)]
+ public virtual int Minimum {
+ get { return this.minimum; }
+ set {
+ if (value > maximum) { throw new ArgumentException("Minimum must be smaller than maximum."); }
+ this.minimum = value;
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the maximum value"), Browsable(true)]
+ public virtual int Maximum {
+ get { return this.maximum; }
+ set {
+ if (value < minimum) { throw new ArgumentException("Maximum must be larger than minimum."); }
+ this.maximum = value;
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the current value"), Browsable(true)]
+ public int Value {
+ get { return this.value; }
+ set {
+ if (value < minimum) { throw new ArgumentException("Value must be greater than or equal to minimum."); }
+ if (value > maximum) { throw new ArgumentException("Value must be less than or equal to maximum."); }
+ this.value = value;
+ if (showPercent) {
+ int percent = (int)(((float)this.value / (float)(this.maximum - 1f)) * 100f);
+ if (percent > 0) {
+ if (percent > 100) { percent = 100; }
+ this.Text = string.Format("{0}%", percent.ToString());
+ } else { this.Text = ""; }
+ }
+ if (OnValueChanged != null) {
+ OnValueChanged(this, EventArgs.Empty);
+ }
+ ResizeProgress();
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the number of pixels to pad between the border and progress"), Browsable(true)]
+ public int ProgressPadding {
+ get { return this.padding; }
+ set {
+ this.padding = value;
+ if (OnValueChanged != null) {
+ OnValueChanged(this, EventArgs.Empty);
+ }
+ //ResizeProgress();
+ OnResize(EventArgs.Empty);
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the type of progress"), Browsable(true)]
+ public virtual ProgressType ProgressType {
+ get { return this.type; }
+ set { this.type = value; }
+ }
+
+ #region Marquee
+ ///
+ [Category("Marquee"), Description("Gets or sets the number of milliseconds between marquee steps"), Browsable(true)]
+ public int MarqueeSpeed {
+ get { return this.marqueeSpeed; }
+ set {
+ this.marqueeSpeed = value;
+ if (this.marqueeSpeed < 10) { this.marqueeSpeed = 10; }
+ }
+ }
+
+ ///
+ [Category("Marquee"), Description("Gets or sets the number of pixels to progress the marquee bar"), Browsable(true)]
+ public int MarqueeStep {
+ get { return this.marqueeStep; }
+ set { this.marqueeStep = value; }
+ }
+
+ ///
+ [Category("Marquee"), Description("Gets or sets the percentage of the width that the marquee progress fills"), Browsable(true)]
+ public int MarqueePercentage {
+ get { return this.marqueePercentage; }
+ set {
+ if (value < 5 || value > 95) {
+ throw new ArgumentException("Marquee percentage width must be between 5% and 95%.");
+ }
+ this.marqueePercentage = value;
+ }
+ }
+ #endregion
+
+ ///
+ [Browsable(false)]
+ public Rectangle BorderBox {
+ get { return this.borderbox; }
+ }
+
+ ///
+ [Browsable(false)]
+ public Rectangle BackBox {
+ get { return this.backbox; }
+ }
+
+ ///
+ [Browsable(false)]
+ public Rectangle ProgressBox {
+ get { return this.progressbox; }
+ }
+
+ ///
+ ///
+ protected abstract void PaintBackground(Graphics gr);
+
+ ///
+ ///
+ protected abstract void PaintProgress(Graphics gr);
+
+ ///
+ ///
+ protected abstract void PaintText(Graphics gr);
+
+ ///
+ ///
+ protected abstract void PaintBorder(Graphics gr);
+
+ ///
+ protected abstract void ResizeProgress();
+
+ ///
+ ///
+ protected override void OnResize(EventArgs e) {
+ base.OnResize(e);
+ borderbox = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
+ backbox = new Rectangle(0, 0, this.Width - 1, this.Height - 1);
+ ResizeProgress();
+ }
+
+ ///
+ ///
+ protected override void OnPaint(PaintEventArgs e) {
+ base.OnPaint(e);
+ PaintBackground(e.Graphics);
+ PaintProgress(e.Graphics);
+ e.Graphics.Clip = new Region(new Rectangle(0, 0, this.Width, this.Height));
+ PaintText(e.Graphics);
+ PaintBorder(e.Graphics);
+ }
+
+ ///
+ public abstract void MarqueeStart();
+ ///
+ public abstract void MarqueePause();
+ ///
+ public abstract void MarqueeStop();
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/AbstractProgressPainter.cs b/ProgressODoom/AbstractProgressPainter.cs
new file mode 100644
index 0000000..9b8ffb8
--- /dev/null
+++ b/ProgressODoom/AbstractProgressPainter.cs
@@ -0,0 +1,108 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ public abstract class AbstractProgressPainter : Component, IProgressPainter {
+ protected IGlossPainter gloss;
+ protected IProgressBorderPainter border;
+ internal int padding = 0;
+
+ ///
+ [Category("Painters"), Description("Gets or sets the gloss painter chain"), Browsable(true)]
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Painters"), Description("Gets or sets the border painter for this progress painter"), Browsable(true)]
+ public IProgressBorderPainter ProgressBorderPainter {
+ get { return this.border; }
+ set {
+ this.border = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ ///
+ ///
+ ///
+ public void PaintProgress(Rectangle box, Graphics gr) {
+ PaintThisProgress(box, gr);
+ //if (this.gloss != null && box.Width > 1) {
+ // Rectangle b = new Rectangle(box.X, box.Y, box.Width - 1, box.Height - 1);
+ // //gr.DrawRectangle(Pens.Red, b);
+ // this.gloss.PaintGloss(box, gr);
+ //}
+ if (this.border != null && box.Width > 1) {
+ int w = box.Width;
+ //if (padding > 0) { w += 3; } else { w += 1; }
+ //Rectangle b = new Rectangle(box.X - 1, box.Y - 1, w, box.Height + 3);
+ Rectangle b = new Rectangle(box.X, box.Y, box.Width - 1, box.Height - 1);
+ b.Inflate(1, 1);
+ this.border.PaintBorder(b, gr);
+ }
+ }
+ ///
+ ///
+ ///
+ protected abstract void PaintThisProgress(Rectangle box, Graphics gr);
+
+ ///
+ ///
+ public virtual void Resize(Rectangle box) {
+ if (gloss != null) { gloss.Resize(box); }
+ if (border != null) { border.Resize(box); }
+ ResizeThis(box);
+ }
+ ///
+ ///
+ protected virtual void ResizeThis(Rectangle box) {}
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ ///
+ protected void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ DisposeThis(disposing);
+ }
+
+ ///
+ ///
+ protected virtual void DisposeThis(bool disposing) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/BarberPoleProgressPainter.cs b/ProgressODoom/BarberPoleProgressPainter.cs
new file mode 100644
index 0000000..c99be80
--- /dev/null
+++ b/ProgressODoom/BarberPoleProgressPainter.cs
@@ -0,0 +1,139 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.BarberPoleProgressPainter), "Icons.BarberPoleProgressPainter.ico")]
+ public class BarberPoleProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Color baseColor;
+ private Color highlightColor;
+ private Color stripeColor;
+ private Color baseShadeColor;
+ private Color highlightShadeColor;
+ private Color stripeShadeColor;
+ private int shadeHeight;
+ private int stripeWidth;
+ private Image img;
+ private Rectangle box;
+
+ ///
+ public BarberPoleProgressPainter() {
+ baseColor = Color.FromArgb(226, 138, 078);
+ highlightColor = Color.FromArgb(225, 132, 068);
+ stripeColor = Color.FromArgb(222, 123, 055);
+ baseShadeColor = Color.FromArgb(215, 097, 020);
+ highlightShadeColor = Color.FromArgb(213, 087, 007);
+ stripeShadeColor = Color.FromArgb(210, 078, 000);
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color"), Browsable(true)]
+ public Color Color {
+ get { return baseColor; }
+ set {
+ baseColor = value;
+ HSV baseHsv = new HSV(baseColor);
+
+ bool change = false;
+ if (baseHsv.Saturation > 166) { baseHsv.Saturation = 166; change = true; }
+ if (baseHsv.Value > 239) { baseHsv.Value = 239; change = true; }
+ if (change) { baseColor = baseHsv.Color; }
+
+ highlightColor = HSV.FromHsv(baseHsv.Hue, baseHsv.Saturation + 11, baseHsv.Value);
+ stripeColor = HSV.FromHsv(baseHsv.Hue, baseHsv.Saturation + 25, baseHsv.Value - 4);
+
+ HSV shade = new HSV(baseHsv.Hue, baseHsv.Saturation + 65, baseHsv.Value - 11);
+ baseShadeColor = shade.Color;
+ highlightShadeColor = HSV.FromHsv(shade.Hue, shade.Saturation + 15, shade.Value - 2);
+ stripeShadeColor = HSV.FromHsv(shade.Hue, shade.Saturation + 24, shade.Value - 5);
+
+ try { if (box != null) { RepaintImage(box); } } catch { }
+ FireChange();
+ }
+ }
+
+ private void RepaintImage(Rectangle box) {
+ if (box.Width == 0 || box.Height == 0) { img = null; return; }
+ img = new Bitmap(box.Width - (box.X * 2), box.Height - (box.Y * 2));
+ Bitmap tile = new Bitmap(img.Height * 2, img.Height);
+
+ shadeHeight = (int)((double)box.Height * 0.4D);
+ stripeWidth = box.Height;
+
+ using (Graphics g = Graphics.FromImage(tile)) {
+ g.FillRectangle(new SolidBrush(baseColor), 0, 0, tile.Width, tile.Height);
+ g.FillRectangle(new SolidBrush(baseShadeColor), 0, tile.Height - shadeHeight, tile.Width, tile.Height);
+
+ Pen highlightPen = new Pen(new SolidBrush(highlightColor), 1f);
+ Pen highlightShadePen = new Pen(new SolidBrush(highlightShadeColor), 1f);
+ Pen stripePen = new Pen(new SolidBrush(stripeColor), 1f);
+ Pen stripeShadePen = new Pen(new SolidBrush(stripeShadeColor), 1f);
+
+ for (int y = 0; y < stripeWidth; y++) {
+ if (y < tile.Height - shadeHeight) {
+ g.DrawLine(highlightPen, stripeWidth - y - 1, y, (stripeWidth * 2) - y + 1, y);
+ g.DrawLine(stripePen, stripeWidth - y, y, (stripeWidth * 2) - y, y);
+ } else {
+ g.DrawLine(highlightShadePen, stripeWidth - y - 1, y, (stripeWidth * 2) - y + 1, y);
+ g.DrawLine(stripeShadePen, stripeWidth - y, y, (stripeWidth * 2) - y, y);
+ }
+ }
+ }
+
+ int x = box.X;
+ using (Graphics i = Graphics.FromImage(img)) {
+ while (true) {
+ if (x > img.Width) { break; }
+ i.DrawImageUnscaled(tile, x, box.Y);
+ x += tile.Width;
+ }
+ }
+
+ tile.Dispose();
+ }
+ private Point Offset(Point p, int x, int y) {
+ return new Point(p.X + x, p.Y + y);
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Width -= 1;
+ box.Height -= 1;
+ } catch { }
+ if (box.Width <= 1) { return; }
+
+ if (img == null) { RepaintImage(box); }
+ Rectangle off = new Rectangle(box.Location, box.Size);
+ off.Offset(box.Right - img.Width, 0);
+ g.DrawImageUnscaled(img, off);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ ///
+ protected override void ResizeThis(Rectangle box) {
+ this.box = box;
+ try {
+ box.Width -= 1;
+ box.Height -= 1;
+ } catch {}
+ shadeHeight = (int)((double)box.Height * 0.4D);
+ stripeWidth = box.Height;
+ RepaintImage(box);
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ if (img != null) { img.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/BevelledGradientProgressPainter.cs b/ProgressODoom/BevelledGradientProgressPainter.cs
new file mode 100644
index 0000000..33dbc66
--- /dev/null
+++ b/ProgressODoom/BevelledGradientProgressPainter.cs
@@ -0,0 +1,118 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.BevelledGradientProgressPainter), "Icons.BevelledGradientProgressPainter.ico")]
+ public class BevelledGradientProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private ColorRange min;
+ private ColorRange max;
+
+ ///
+ public BevelledGradientProgressPainter() {
+ this.MinColor = Color.Cornsilk;
+ this.MaxColor = Color.Gold;
+ }
+
+ ///
+ ///
+ ///
+ public BevelledGradientProgressPainter(Color min, Color max) {
+ this.MinColor = min;
+ this.MaxColor = max;
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the left progress color"), Browsable(true)]
+ public Color MinColor {
+ get { return min.BaseColor; }
+ set {
+ min = new ColorRange(value);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the right progress color"), Browsable(true)]
+ public Color MaxColor {
+ get { return max.BaseColor; }
+ set {
+ max = new ColorRange(value);
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Height -= 1;
+ box.Width -= 1;
+ } catch { }
+
+ if (box.Width < 2) { return; }
+
+ Point left = new Point(box.X, box.Y);
+ Point right = new Point(box.Right, box.Y);
+ Brush bottomOuter = new System.Drawing.Drawing2D.LinearGradientBrush(left, right, min.Darker, max.Darker);
+ Brush bottomInner = new System.Drawing.Drawing2D.LinearGradientBrush(left, right, min.Dark, max.Dark);
+ Brush topInner = new System.Drawing.Drawing2D.LinearGradientBrush(left, right, min.Light, max.Light);
+ Brush topOuter = new System.Drawing.Drawing2D.LinearGradientBrush(left, right, min.Lighter, max.Lighter);
+ Brush fill = new System.Drawing.Drawing2D.LinearGradientBrush(left, right, min.BaseColor, max.BaseColor);
+
+ // fill box
+ g.FillRectangle(fill, box);
+
+ using (Pen p = new Pen(topInner, 1)) {
+ // inner top
+ g.DrawLine(p, box.X + 1, box.Y + 1, box.Right - 1, box.Y + 1);
+ }
+ using (Pen p = new Pen(min.Light, 1)) {
+ // inner left
+ g.DrawLine(p, box.X + 1, box.Y + 1, box.X + 1, box.Bottom - 1);
+ }
+
+ using (Pen p = new Pen(topOuter, 1)) {
+ // outer top
+ g.DrawLine(p, box.X, box.Y, box.Right, box.Y);
+ }
+ using (Pen p = new Pen(min.Lighter, 1)) {
+ // outer left
+ g.DrawLine(p, box.X, box.Y, box.X, box.Bottom);
+ }
+
+ // draw border
+ using (Pen p = new Pen(bottomInner, 1)) {
+ // inner bottom
+ g.DrawLine(p, box.X + 1, box.Bottom - 1, box.Right - 1, box.Bottom - 1);
+ }
+ using (Pen p = new Pen(max.Dark, 1)) {
+ // inner right
+ g.DrawLine(p, box.Right - 1, box.Y + 1, box.Right - 1, box.Bottom - 1);
+ }
+
+ using (Pen p = new Pen(bottomOuter, 1)) {
+ // outer bottom
+ g.DrawLine(p, box.X, box.Bottom, box.Right, box.Bottom);
+ }
+ using (Pen p = new Pen(max.Darker, 1)) {
+ // outer right
+ g.DrawLine(p, box.Right, box.Y, box.Right, box.Bottom);
+ }
+
+ bottomOuter.Dispose();
+ bottomInner.Dispose();
+ topInner.Dispose();
+ topOuter.Dispose();
+ fill.Dispose();
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/BevelledProgressPainter.cs b/ProgressODoom/BevelledProgressPainter.cs
new file mode 100644
index 0000000..a66389f
--- /dev/null
+++ b/ProgressODoom/BevelledProgressPainter.cs
@@ -0,0 +1,91 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.BevelledProgressPainter), "Icons.BevelledProgressPainter.ico")]
+ public class BevelledProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private ColorRange bender;
+
+ ///
+ public BevelledProgressPainter() {
+ this.Color = Color.FromArgb(151, 151, 234);
+ }
+
+ ///
+ ///
+ public BevelledProgressPainter(Color color) {
+ this.Color = color;
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color"), Browsable(true)]
+ public Color Color {
+ get { return bender.BaseColor; }
+ set {
+ bender = new ColorRange(value);
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ if (box.Width < 2) { return; }
+ g.PageUnit = GraphicsUnit.Pixel;
+
+ // fill box
+ Rectangle back = new Rectangle(box.X, box.Y, box.Width, box.Height);
+ try {
+ back.Height -= 1;
+ back.Width -= 1;
+ } catch { }
+ using (SolidBrush b = new SolidBrush(bender.BaseColor)) {
+ g.FillRectangle(b, back);
+ }
+
+ box = new Rectangle(box.X, box.Y, box.Width - 1, box.Height - 1);
+
+ using (Pen p = new Pen(bender.Light, 1)) {
+ // inner top
+ g.DrawLine(p, box.X + 1, box.Y + 1, box.Right - 1, box.Y + 1);
+ // inner left
+ g.DrawLine(p, box.X + 1, box.Y + 1, box.X + 1, box.Bottom - 1);
+ }
+
+ using (Pen p = new Pen(bender.Lighter, 1)) {
+ // outer top
+ g.DrawLine(p, box.X, box.Y, box.Right, box.Y);
+ // outer left
+ g.DrawLine(p, box.X, box.Y, box.X, box.Bottom);
+ }
+
+ // draw border
+ using (Pen p = new Pen(bender.Dark, 1)) {
+ // inner bottom
+ g.DrawLine(p, box.X + 1, box.Bottom - 1, box.Right - 1, box.Bottom - 1);
+ // inner right
+ g.DrawLine(p, box.Right - 1, box.Y + 1, box.Right - 1, box.Bottom - 1);
+
+ //g.DrawRectangle(p, box.X + 1, box.Y + 1, box.Width - 3, box.Height - 3);
+ }
+
+ using (Pen p = new Pen(bender.Darker, 1)) {
+ // outer bottom
+ g.DrawLine(p, box.X, box.Bottom, box.Right, box.Bottom);
+ // outer right
+ g.DrawLine(p, box.Right, box.Y, box.Right, box.Bottom);
+
+ //g.DrawRectangle(p, box.X, box.Y, box.Width - 1, box.Height - 1);
+ }
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/CandyCane.png b/ProgressODoom/CandyCane.png
new file mode 100644
index 0000000..8b48247
Binary files /dev/null and b/ProgressODoom/CandyCane.png differ
diff --git a/ProgressODoom/CandyCaneBackgroundPainter.cs b/ProgressODoom/CandyCaneBackgroundPainter.cs
new file mode 100644
index 0000000..bee5250
--- /dev/null
+++ b/ProgressODoom/CandyCaneBackgroundPainter.cs
@@ -0,0 +1,123 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.CandyCaneBackgroundPainter), "Icons.CandyCaneBackgroundPainter.ico")]
+ public class CandyCaneBackgroundPainter : Component, IProgressBackgroundPainter, IDisposable {
+ private Image img;
+ private Rectangle box;
+ private IGlossPainter gloss;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ ///
+ [Category("Painters"), Description("Gets or sets the chain of gloss painters"), Browsable(true)]
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBackground(Rectangle box, Graphics g) {
+ if (img == null) {
+ Resize(box);
+ }
+ g.DrawImageUnscaled(img, box.X, box.Y);
+ //g.FillRectangle(brush, box);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ this.box = box;
+ RepaintImage(box);
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (img != null) {
+ img.Dispose();
+ }
+ }
+
+ private void RepaintImage(Rectangle box) {
+ Bitmap source = BuildTile(box.Width);
+ img = new Bitmap(box.Width, box.Height);
+ using (Graphics g = Graphics.FromImage(img)) {
+ g.DrawImage(source, 0, 0, box.Width, box.Height + 1); // box
+ }
+ source.Dispose();
+
+ //Bitmap source = BuildTile();
+ //Bitmap tile = new Bitmap((int)(((float)box.Height * (float)source.Width) / (float)source.Height), box.Height);
+ //using (Graphics g = Graphics.FromImage(tile)) {
+ // g.DrawImage(source, 0, 0, tile.Width, tile.Height);
+ //}
+ //source.Dispose();
+
+ //img = new Bitmap(box.Width, box.Height);
+ //using (Graphics g = Graphics.FromImage(img)) {
+ // int i = 0;
+ // while (i < box.Width) {
+ // g.DrawImageUnscaled(tile, i, 0);
+ // i += tile.Width;
+ // }
+ //}
+ }
+
+ private Bitmap BuildTile(int width) {
+ Bitmap bmp = new Bitmap(width, 9);
+ Graphics g = Graphics.FromImage(bmp);
+
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(245, 245, 245))), new Point(0, 0), new Point(width - 1, 0));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(236, 236, 236))), new Point(0, 1), new Point(width - 1, 1));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(234, 234, 235))), new Point(0, 2), new Point(width - 1, 2));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(234, 234, 235))), new Point(0, 3), new Point(width - 1, 3));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(222, 222, 222))), new Point(0, 4), new Point(width - 1, 4));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(229, 229, 230))), new Point(0, 5), new Point(width - 1, 5));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(239, 239, 239))), new Point(0, 6), new Point(width - 1, 6));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(247, 247, 247))), new Point(0, 7), new Point(width - 1, 7));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(254, 254, 255))), new Point(0, 8), new Point(width - 1, 8));
+
+ g.Dispose();
+ return bmp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/CandyCaneProgressPainter.cs b/ProgressODoom/CandyCaneProgressPainter.cs
new file mode 100644
index 0000000..389fe2f
--- /dev/null
+++ b/ProgressODoom/CandyCaneProgressPainter.cs
@@ -0,0 +1,164 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.CandyCaneProgressPainter), "Icons.CandyCaneProgressPainter.ico")]
+ public class CandyCaneProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Color baseColor;
+ private Image img;
+ private Rectangle box;
+
+ ///
+ public CandyCaneProgressPainter() {
+ baseColor = Color.FromArgb(049, 129, 222);
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color"), Browsable(true)]
+ public Color Color {
+ get { return baseColor; }
+ set {
+ baseColor = value;
+ try { if (box != null) { RepaintImage(box); } } catch { }
+ FireChange();
+ }
+ }
+
+ private void RepaintImage(Rectangle box) {
+ this.box = box;
+ this.img = new Bitmap(box.Width, box.Height);
+ // BuildTile() then resize it to fix the box.Height, then tile it.
+ Bitmap source = BuildTile(this.baseColor);
+ img = new Bitmap((int)(((float)box.Height * (float)source.Width) / (float)source.Height), box.Height + 1);
+ using (Graphics g = Graphics.FromImage(img)) {
+ g.DrawImage(source, 0, 0, img.Width, img.Height + 1);
+ }
+
+ source.Dispose();
+ }
+ private Point Offset(Point p, int x, int y) {
+ return new Point(p.X + x, p.Y + y);
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ if (img == null) { RepaintImage(box); }
+ if (box.Width <= 1) { return; }
+
+ int x = box.Width - img.Width;
+ while (x > (0 - img.Width)) {
+ g.DrawImageUnscaled(img, x, 0);
+ x -= img.Width;
+ }
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ ///
+ protected override void ResizeThis(Rectangle box) {
+ this.box = box;
+ RepaintImage(box);
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ if (img != null) {
+ img.Dispose();
+ }
+ }
+
+ public Bitmap BuildTile(Color color) {
+ HSV clr = new HSV(color);
+ Bitmap src = GetSource();
+ Bitmap bmp = new Bitmap(src.Width, src.Height);
+ for (int x = 0; x < bmp.Width; x++) {
+ for (int y = 0; y < bmp.Height; y++) {
+ Color original = src.GetPixel(x, y);
+ Color altered = Color.FromArgb(0, 255, 255, 255);
+ HSV orighsv = new HSV(original);
+ Color origrgb = orighsv.Color;
+ origrgb = Color.FromArgb(original.A, origrgb.R, origrgb.G, origrgb.B);
+ if (!origrgb.Equals(altered)) {
+ orighsv.Hue = clr.Hue;
+ //orighsv.Saturation = clr.Saturation;
+ //orighsv.Value = clr.Value;
+ altered = orighsv.Color;
+ altered = Color.FromArgb(original.A, altered.R, altered.G, altered.B);
+ }
+ bmp.SetPixel(x, y, altered);
+ }
+ }
+ src.Dispose();
+ return bmp;
+ }
+ private Bitmap GetSource() {
+ Bitmap bmp = new Bitmap(16, 9);
+ Graphics g = Graphics.FromImage(bmp);
+ g.Clear(Color.FromArgb(0, 255, 255, 255));
+
+ bmp.SetPixel(0, 0, Color.FromArgb(77, 140, 177, 225));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(140, 177, 225))), new Point(1, 0), new Point(7, 0));
+ bmp.SetPixel(8, 0, Color.FromArgb(77, 140, 177, 225));
+
+ bmp.SetPixel(0, 1, Color.FromArgb(38, 99, 158, 222));
+ bmp.SetPixel(1, 1, Color.FromArgb(128, 99, 158, 222));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(99, 158, 222))), new Point(2, 1), new Point(8, 1));
+ bmp.SetPixel(9, 1, Color.FromArgb(64, 99, 158, 222));
+
+ bmp.SetPixel(1, 2, Color.FromArgb(38, 94, 156, 222));
+ bmp.SetPixel(2, 2, Color.FromArgb(205, 94, 156, 222));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(94, 156, 222))), new Point(3, 2), new Point(8, 2));
+ bmp.SetPixel(9, 2, Color.FromArgb(192, 94, 156, 222));
+ bmp.SetPixel(10, 2, Color.FromArgb(38, 94, 156, 222));
+
+ bmp.SetPixel(2, 3, Color.FromArgb(77, 93, 158, 228));
+ bmp.SetPixel(3, 3, Color.FromArgb(251, 93, 158, 228));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(93, 158, 228))), new Point(4, 3), new Point(9, 3));
+ bmp.SetPixel(10, 3, Color.FromArgb(154, 93, 158, 228));
+ bmp.SetPixel(11, 3, Color.FromArgb(26, 93, 158, 228));
+
+ bmp.SetPixel(2, 4, Color.FromArgb(13, 49, 129, 222));
+ bmp.SetPixel(3, 4, Color.FromArgb(51, 49, 129, 222));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(49, 129, 222))), new Point(4, 4), new Point(9, 4));
+ bmp.SetPixel(10, 4, Color.FromArgb(251, 49, 129, 222));
+ bmp.SetPixel(11, 4, Color.FromArgb(90, 49, 129, 222));
+
+ bmp.SetPixel(3, 5, Color.FromArgb(64, 81, 159, 247));
+ bmp.SetPixel(4, 5, Color.FromArgb(205, 81, 159, 247));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(81, 159, 247))), new Point(5, 5), new Point(10, 5));
+ bmp.SetPixel(11, 5, Color.FromArgb(218, 81, 159, 247));
+ bmp.SetPixel(12, 5, Color.FromArgb(77, 81, 159, 247));
+
+ bmp.SetPixel(4, 6, Color.FromArgb(77, 110, 186, 255));
+ bmp.SetPixel(5, 6, Color.FromArgb(243, 110, 186, 255));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(110, 186, 255))), new Point(6, 6), new Point(11, 6));
+ bmp.SetPixel(12, 6, Color.FromArgb(154, 110, 186, 255));
+ bmp.SetPixel(13, 6, Color.FromArgb(38, 110, 186, 255));
+
+ bmp.SetPixel(4, 7, Color.FromArgb(26, 121, 201, 255));
+ bmp.SetPixel(5, 7, Color.FromArgb(141, 121, 201, 255));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(121, 201, 255))), new Point(6, 7), new Point(12, 7));
+ bmp.SetPixel(13, 7, Color.FromArgb(102, 121, 201, 255));
+ bmp.SetPixel(14, 7, Color.FromArgb(26, 121, 201, 255));
+
+ bmp.SetPixel(5, 8, Color.FromArgb(26, 135, 227, 255));
+ bmp.SetPixel(6, 8, Color.FromArgb(192, 135, 227, 255));
+ g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(135, 227, 255))), new Point(7, 8), new Point(12, 8));
+ bmp.SetPixel(13, 8, Color.FromArgb(243, 135, 227, 255));
+ bmp.SetPixel(14, 8, Color.FromArgb(64, 135, 227, 255));
+ bmp.SetPixel(15, 8, Color.FromArgb(13, 135, 227, 255));
+
+ g.Dispose();
+ return bmp;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/ChainedGlossPainter.cs b/ProgressODoom/ChainedGlossPainter.cs
new file mode 100644
index 0000000..b6c66d8
--- /dev/null
+++ b/ProgressODoom/ChainedGlossPainter.cs
@@ -0,0 +1,84 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ /// Extending this class allows you to chain multiple IGlossPainters together.
+ public abstract class ChainedGlossPainter : Component, IGlossPainter, IDisposable {
+ private IGlossPainter successor = null;
+
+ ///
+ [Category("Painters"), Description("Gets or sets the next gloss in the chain"), Browsable(true)]
+ public IGlossPainter Successor {
+ get { return successor; }
+ set {
+ IGlossPainter nextPainter = value;
+ while (nextPainter != null && nextPainter is ChainedGlossPainter) {
+ if (object.ReferenceEquals(this, nextPainter)) {
+ throw new ArgumentException("Gloss cannot eventually be it's own successor, an infinite loop will result");
+ }
+ nextPainter = ((ChainedGlossPainter)nextPainter).Successor;
+ }
+
+ successor = value;
+ if (successor != null) {
+ successor.PropertiesChanged += new EventHandler(successor_PropertiesChanged);
+ }
+ FireChange();
+ }
+ }
+ private void successor_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ ///
+ protected void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintGloss(Rectangle box, Graphics g) {
+ if (box.Width < 1) { return; }
+ PaintThisGloss(box, g);
+ if (successor != null) { successor.PaintGloss(box, g); }
+ }
+
+ ///
+ ///
+ ///
+ protected abstract void PaintThisGloss(Rectangle box, Graphics g);
+
+ ///
+ ///
+ public void Resize(Rectangle box) {
+ ResizeThis(box);
+ if (successor != null) { successor.Resize(box); }
+ }
+
+ protected abstract void ResizeThis(Rectangle box);
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (successor != null) { successor.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/ColorTools.cs b/ProgressODoom/ColorTools.cs
new file mode 100644
index 0000000..6b577ee
--- /dev/null
+++ b/ProgressODoom/ColorTools.cs
@@ -0,0 +1,285 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+
+namespace ProgressODoom {
+ ///
+ public class ColorUtility {
+ static ColorUtility() {
+ }
+
+ ///
+ ///
+ ///
+ public static Color ReverseColor(Color c) {
+ return Color.FromArgb(ReverseInt(c.R), ReverseInt(c.G), ReverseInt(c.B));
+ }
+
+ private static int ReverseInt(int x) {
+ int val = x - 255;
+ if (val < 0) { val = val * -1; }
+ return val;
+ }
+
+ ///
+ ///
+ ///
+ public static string ToHexString(Color c) {
+ string hex = string.Empty;
+ hex += DoHex(c.R);
+ hex += DoHex(c.G);
+ hex += DoHex(c.B);
+ return "#" + hex;
+ }
+
+ private static string DoHex(int xor) {
+ string hex = xor.ToString("x");
+ if (xor < 16) {
+ hex = "0" + hex;
+ }
+ if (xor == 0) {
+ hex = "00";
+ }
+ return hex.ToUpper();
+ }
+
+ private static int DeHex(string input) {
+ int val;
+ int result = 0;
+ for (int i = 0; i < input.Length; i++) {
+ string chunk = input.Substring(i, 1).ToUpper();
+ switch (chunk) {
+ case "A":
+ val = 10; break;
+ case "B":
+ val = 11; break;
+ case "C":
+ val = 12; break;
+ case "D":
+ val = 13; break;
+ case "E":
+ val = 14; break;
+ case "F":
+ val = 15; break;
+ default:
+ val = int.Parse(chunk); break;
+ }
+ if (i == 0) {
+ result += val * 16;
+ } else {
+ result += val;
+ }
+ }
+ return result;
+ }
+ }
+
+ // System.Drawing.Drawing2D.ColorBlend
+ ///
+ public class ColorBlender {
+ private Color colorleft;
+ private Color colorright;
+ private int steps;
+
+ private float step;
+ private float stepsize;
+
+ ///
+ ///
+ ///
+ ///
+ public ColorBlender(int numberofsteps, Color one, Color two) {
+ steps = numberofsteps;
+ colorleft = one;
+ colorright = two;
+ stepsize = 1.0f / Convert.ToSingle(steps);
+ step = 0;
+ }
+
+ ///
+ ///
+ public bool HasNext() {
+ return step < 1;
+ }
+
+ ///
+ ///
+ public Color Next() {
+ if (!HasNext()) { throw new Exception("Past threshold."); }
+ step += stepsize;
+ return Morph(step, colorleft, colorright);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Color Morph(float ratio, Color c1, Color c2) {
+ int r = (int)(c1.R + ratio * (c2.R - c1.R));
+ int g = (int)(c1.G + ratio * (c2.G - c1.G));
+ int b = (int)(c1.B + ratio * (c2.B - c1.B));
+ return Color.FromArgb(r, g, b);
+ }
+ }
+
+ ///
+ public struct ColorRange {
+ ///
+ public Color Light;
+ ///
+ public Color Lighter;
+ ///
+ public Color BaseColor;
+ ///
+ public Color Dark;
+ ///
+ public Color Darker;
+
+ ///
+ ///
+ public ColorRange(Color color) {
+ BaseColor = color;
+ Light = ColorRange.Tint(0.6f, color);
+ Lighter = ColorRange.Tint(0.3f, color);
+ Dark = ColorRange.Shade(0.8f, color);
+ Darker = ColorRange.Shade(0.6f, color);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public ColorRange(Color color, float lightratio, float lighterratio) {
+ BaseColor = color;
+ Light = ColorRange.Tint(lightratio, color);
+ Lighter = ColorRange.Tint(lighterratio, color);
+ Dark = ColorRange.Shade(lightratio, color);
+ Darker = ColorRange.Shade(lighterratio, color);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ColorRange(Color color, float lightratio, float lighterratio, float darkratio, float darkerratio) {
+ BaseColor = color;
+ Light = ColorRange.Tint(lightratio, color);
+ Lighter = ColorRange.Tint(lighterratio, color);
+ Dark = ColorRange.Shade(darkratio, color);
+ Darker = ColorRange.Shade(darkerratio, color);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static Color Tint(float ratio, Color c1) {
+ return Morph(ratio, Color.White, c1);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public static Color Shade(float ratio, Color c1) {
+ return Morph(ratio, Color.Black, c1);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static Color Morph(float ratio, Color c1, Color c2) {
+ int r = (int)(c1.R + ratio * (c2.R - c1.R));
+ int g = (int)(c1.G + ratio * (c2.G - c1.G));
+ int b = (int)(c1.B + ratio * (c2.B - c1.B));
+ return Color.FromArgb(r, g, b);
+ }
+ }
+
+ ///
+ public class ColorSet {
+ private bool shade;
+ private Color color;
+ private float factor;
+ private int colors;
+ private Color[] range;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ColorSet(bool shade, Color color, float factor, int colors) {
+ if (colors < 1) { throw new ArgumentException("Number of colors must be greater than 0."); }
+ if (factor < 0 || factor > 1) { throw new ArgumentException("Factor must be between 0 and 1."); }
+ this.shade = shade;
+ this.color = color;
+ this.factor = factor;
+ this.colors = colors;
+ Build();
+ }
+
+ private void Build() {
+ this.range = new Color[colors];
+ Color current = color;
+ range[0] = current;
+ for (int i = 1; i < colors; i++) {
+ if (shade) {
+ range[i] = ColorRange.Shade(factor, current);
+ } else {
+ range[i] = ColorRange.Tint(factor, current);
+ }
+ current = range[i];
+ }
+ }
+
+ ///
+ public Color[] Colors {
+ get { return range; }
+ }
+ }
+
+ ///
+ public class BlendSet {
+ private Color color1;
+ private Color color2;
+ private float factor;
+ private int colors;
+ private Color[] range;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public BlendSet(Color one, Color two, float factor, int colors) {
+ if (colors < 1) { throw new ArgumentException("Number of colors must be greater than 0."); }
+ if (factor < 0 || factor > 1) { throw new ArgumentException("Factor must be between 0 and 1."); }
+ this.color1 = one;
+ this.color2 = two;
+ this.factor = factor;
+ this.colors = colors;
+ Build();
+ }
+
+ private void Build() {
+ this.range = new Color[colors];
+ Color current = color1;
+ range[0] = current;
+ for (int i = 1; i < colors; i++) {
+ range[i] = ColorRange.Morph(factor, current, color2);
+ current = range[i];
+ }
+ }
+
+ ///
+ public Color[] Colors {
+ get { return range; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/DualProgressBar.cs b/ProgressODoom/DualProgressBar.cs
new file mode 100644
index 0000000..3f1b10c
--- /dev/null
+++ b/ProgressODoom/DualProgressBar.cs
@@ -0,0 +1,159 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.DualProgressBar), "Icons.DualProgressBar.ico")]
+ public class DualProgressBar : ProgressBarEx {
+ private int masterval = 0;
+ private int mastermax = 100;
+ private IProgressPainter masterpainter;
+ private bool masterBottom = false;
+ private Rectangle masterbox;
+ private int padding = 0;
+
+ protected EventHandler OnMasterValueChanged;
+ ///
+ public event EventHandler MasterValueChanged {
+ add {
+ if (OnMasterValueChanged != null) {
+ foreach (Delegate d in OnMasterValueChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ OnMasterValueChanged = (EventHandler)Delegate.Combine(OnMasterValueChanged, value);
+ }
+ remove { OnMasterValueChanged = (EventHandler)Delegate.Remove(OnMasterValueChanged, value); }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the maximum value"), Browsable(true)]
+ public override int Maximum {
+ get { return base.maximum; }
+ set {
+ base.Maximum = value;
+ mastermax = value;
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the value of the master progress"), Browsable(true)]
+ public int MasterValue {
+ get { return this.masterval; }
+ set {
+ this.masterval = value;
+ if (OnMasterValueChanged != null) {
+ OnMasterValueChanged(this, EventArgs.Empty);
+ }
+ ResizeMasterProgress();
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the maximum value for the master progress"), Browsable(true)]
+ public int MasterMaximum {
+ get { return mastermax; }
+ set {
+ this.mastermax = value;
+ ResizeMasterProgress();
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the padding for the master progress"), Browsable(true)]
+ public int MasterProgressPadding {
+ get { return this.padding; }
+ set {
+ this.padding = value;
+ if (OnValueChanged != null) {
+ OnValueChanged(this, EventArgs.Empty);
+ }
+ ResizeMasterProgress();
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Painters"), Description("Paints this progress bar's master progress"), Browsable(true)]
+ public IProgressPainter MasterPainter {
+ get { return this.masterpainter; }
+ set {
+ this.masterpainter = value;
+ if (this.masterpainter is AbstractProgressPainter) {
+ ((AbstractProgressPainter)this.masterpainter).padding = base.ProgressPadding;
+ }
+ this.masterpainter.PropertiesChanged += new EventHandler(component_PropertiesChanged);
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Determines whether or not the master progress is painted under the main progress"), Browsable(true)]
+ public bool PaintMasterFirst {
+ get { return this.masterBottom; }
+ set {
+ this.masterBottom = value;
+ this.Invalidate();
+ }
+ }
+
+ protected override void OnResize(EventArgs e) {
+ base.OnResize(e);
+ ResizeProgress();
+ ResizeMasterProgress();
+ if (this.backgroundpainter != null) { this.backgroundpainter.Resize(borderbox); }
+ if (masterBottom && this.masterpainter != null) { this.masterpainter.Resize(masterbox); }
+ if (this.progresspainter != null) { this.progresspainter.Resize(borderbox); }
+ if (!masterBottom && this.masterpainter != null) { this.masterpainter.Resize(masterbox); }
+ if (this.borderpainter != null) { this.borderpainter.Resize(borderbox); }
+ }
+
+ private void ResizeMasterProgress() {
+ Rectangle newprog = base.borderbox;
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+ base.backbox = newprog;
+
+ int val = masterval; if (val > 0) { val++; }
+ int progWidth = mastermax > 0 ? (backbox.Width * val / mastermax) : 1;
+ if (value >= mastermax && mastermax > 0) {
+ progWidth = backbox.Width;
+ } /*else if (value > 0) {
+ progWidth++;
+ }*/
+ //newprog = new Rectangle(backbox.X + base.ProgressPadding, backbox.Y + base.ProgressPadding, progWidth - (base.ProgressPadding * 2), backbox.Height - (base.ProgressPadding * 2));
+ //newprog = new Rectangle(backbox.X, backbox.Y, progWidth, backbox.Height);
+ newprog = new Rectangle(backbox.X + this.padding, backbox.Y + this.padding, progWidth - (this.padding * 2), backbox.Height - (this.padding * 2));
+ masterbox = newprog;
+ }
+
+ /////
+ //protected override void MarqueeStart() {
+ //}
+ /////
+ //protected override void MarqueePause() {
+ //}
+ /////
+ //protected override void MarqueeStop() {
+ //}
+
+ ///
+ ///
+ protected override void PaintProgress(Graphics g) {
+ if (this.progresspainter != null) {
+ if (masterBottom && this.masterpainter != null) {
+ this.masterpainter.PaintProgress(masterbox, g);
+ }
+ this.progresspainter.PaintProgress(progressbox, g);
+ if (!masterBottom && this.masterpainter != null) {
+ this.masterpainter.PaintProgress(masterbox, g);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/FlatGlossPainter.cs b/ProgressODoom/FlatGlossPainter.cs
new file mode 100644
index 0000000..a173948
--- /dev/null
+++ b/ProgressODoom/FlatGlossPainter.cs
@@ -0,0 +1,107 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.FlatGlossPainter), "Icons.FlatGlossPainter.ico")]
+ public class FlatGlossPainter : ChainedGlossPainter {
+ private GlossStyle style = GlossStyle.Bottom;
+ private int percent = 50;
+ private Rectangle box;
+ private Color color = Color.White;
+ private int alpha = 128;
+ private Brush brush;
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the style for this progress gloss"), Browsable(true)]
+ public GlossStyle Style {
+ get { return this.style; }
+ set {
+ this.style = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the percentage of surface this gloss should cover"), Browsable(true)]
+ public int PercentageCovered {
+ get { return this.percent; }
+ set {
+ if (value < 0 || value > 100) {
+ throw new ArgumentException("Percentage value must be between 0 and 100.");
+ }
+ this.percent = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets color to gloss"), Browsable(true)]
+ public Color Color {
+ get { return this.color; }
+ set {
+ this.color = value;
+ box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the alpha value"), Browsable(true)]
+ public int Alpha {
+ get { return this.alpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.alpha = value;
+ box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ protected override void PaintThisGloss(Rectangle box, Graphics g) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ }
+
+ int y = (int)(((float)box.Height * (float)percent) / 100f);
+ if (box.Y + y > box.Height) { y = box.Height; }
+
+ Rectangle cover = box;
+ switch (style) {
+ case GlossStyle.Bottom:
+ int start = box.Height + box.Y - y;
+ cover = new Rectangle(box.X, start, box.Width, box.Bottom - start);
+ break;
+ case GlossStyle.Top:
+ cover = new Rectangle(box.X, box.Y, box.Width, y + 1);
+ break;
+ case GlossStyle.Both:
+ cover = box;
+ break;
+ }
+
+ Color ccv = Color.FromArgb(alpha, color.R, color.G, color.B);
+ brush = new SolidBrush(ccv);
+ g.FillRectangle(brush, cover);
+ }
+
+ protected override void ResizeThis(Rectangle box) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ }
+ }
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (brush != null) { brush.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/FruityLoopsBackgroundPainter.cs b/ProgressODoom/FruityLoopsBackgroundPainter.cs
new file mode 100644
index 0000000..50338f6
--- /dev/null
+++ b/ProgressODoom/FruityLoopsBackgroundPainter.cs
@@ -0,0 +1,209 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.FruityLoopsBackgroundPainter), "Icons.FruityLoopsBackgroundPainter.ico")]
+ public class FruityLoopsBackgroundPainter : Component, IProgressBackgroundPainter, IDisposable {
+ private IGlossPainter gloss;
+ private FruityLoopsProgressPainter.FruityLoopsProgressType type;
+ private Image img;
+
+ private Color OffLit = Color.FromArgb(49, 69, 74);
+ private Pen pOffLit; // = new Pen(new SolidBrush(OffLit),1f);
+ private Color OffLitTop = Color.FromArgb(66, 85, 90);
+ private Pen pOffLitTop; // = new Pen(new SolidBrush(OffLitTop),1f);
+ private Color OffLitBot = Color.FromArgb(24, 48, 49);
+ private Pen pOffLitBot; // = new Pen(new SolidBrush(OffLitBot),1f);
+
+ private Color OffMid = Color.FromArgb(24, 48, 49);
+ private Pen pOffMid; // = new Pen(new SolidBrush(OffMid),1f);
+ private Color OffMidTop = Color.FromArgb(24, 48, 49);
+ private Pen pOffMidTop; // = new Pen(new SolidBrush(OffMidTop),1f);
+ private Color OffMidBot = Color.FromArgb(8, 28, 24);
+ private Pen pOffMidBot; // = new Pen(new SolidBrush(OffMidBot),1f);
+
+ private Color OffDrk = Color.FromArgb(0, 24, 24);
+ private Pen pOffDrk; // = new Pen(new SolidBrush(OffDrk),1f);
+ private Color OffDrkTop = Color.FromArgb(8, 28, 24);
+ private Pen pOffDrkTop; // = new Pen(new SolidBrush(OffDrkTop),1f);
+ private Color OffDrkBot = Color.FromArgb(0, 16, 16);
+ private Pen pOffDrkBot; // = new Pen(new SolidBrush(OffDrkBot),1f);
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ ///
+ [Category("Painters"), Description("Gets or sets the chain of gloss painters"), Browsable(true)]
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the type of FruityLoops progress style"), Browsable(true)]
+ public FruityLoopsProgressPainter.FruityLoopsProgressType FruityType {
+ get { return type; }
+ set {
+ type = value;
+ if (type == FruityLoopsProgressPainter.FruityLoopsProgressType.DoubleLayer) {
+ OffLit = Color.FromArgb(49, 69, 74);
+ pOffLit = new Pen(new SolidBrush(OffLit), 1f);
+ OffLitTop = Color.FromArgb(57, 77, 82);
+ pOffLitTop = new Pen(new SolidBrush(OffLitTop), 1f);
+ OffLitBot = Color.FromArgb(24, 48, 49);
+ pOffLitBot = new Pen(new SolidBrush(OffLitBot), 1f);
+
+ OffDrk = Color.FromArgb(24, 48, 49);
+ pOffDrk = new Pen(new SolidBrush(OffDrk), 1f);
+ OffDrkTop = Color.FromArgb(16, 40, 41);
+ pOffDrkTop = new Pen(new SolidBrush(OffDrkTop), 1f);
+ OffDrkBot = Color.FromArgb(8, 18, 24);
+ pOffDrkBot = new Pen(new SolidBrush(OffDrkBot), 1f);
+ } else if (type == FruityLoopsProgressPainter.FruityLoopsProgressType.TripleLayer) {
+ OffLit = Color.FromArgb(49, 69, 74);
+ pOffLit = new Pen(new SolidBrush(OffLit), 1f);
+ OffLitTop = Color.FromArgb(66, 85, 90);
+ pOffLitTop = new Pen(new SolidBrush(OffLitTop), 1f);
+ OffLitBot = Color.FromArgb(24, 48, 49);
+ pOffLitBot = new Pen(new SolidBrush(OffLitBot), 1f);
+
+ OffMid = Color.FromArgb(24, 48, 49);
+ pOffMid = new Pen(new SolidBrush(OffMid), 1f);
+ OffMidTop = Color.FromArgb(24, 48, 49);
+ pOffMidTop = new Pen(new SolidBrush(OffMidTop), 1f);
+ OffMidBot = Color.FromArgb(8, 28, 24);
+ pOffMidBot = new Pen(new SolidBrush(OffMidBot), 1f);
+
+ OffDrk = Color.FromArgb(0, 24, 24);
+ pOffDrk = new Pen(new SolidBrush(OffDrk), 1f);
+ OffDrkTop = Color.FromArgb(8, 28, 24);
+ pOffDrkTop = new Pen(new SolidBrush(OffDrkTop), 1f);
+ OffDrkBot = Color.FromArgb(0, 16, 16);
+ pOffDrkBot = new Pen(new SolidBrush(OffDrkBot), 1f);
+ }
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBackground(Rectangle box, Graphics g) {
+ if (img == null) {
+ if (type == FruityLoopsProgressPainter.FruityLoopsProgressType.DoubleLayer) {
+ PaintDouble(box, g);
+ } else if (type == FruityLoopsProgressPainter.FruityLoopsProgressType.TripleLayer) {
+ PaintTriple(box, g);
+ }
+ }
+ g.DrawImageUnscaled(img, 0, 0);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void PaintDouble(Rectangle r, Graphics g) {
+ bool lite = true;
+ img = new Bitmap(r.Width + 1, r.Height + 1);
+ Graphics gi = Graphics.FromImage(img);
+
+ for (int i = 1; i < r.Width + 1; i++) {
+ if (lite) {
+ gi.DrawLine(pOffLitTop, i, r.Y, i, r.Y + 1);
+ gi.DrawLine(pOffLitBot, i, r.Height, i, r.Height - 1);
+ gi.DrawLine(pOffLit, i, r.Y + 1, i, r.Height - 1);
+ } else {
+ gi.DrawLine(pOffDrkTop, i, r.Y, i, r.Y + 1);
+ gi.DrawLine(pOffDrkBot, i, r.Height, i, r.Height - 1);
+ gi.DrawLine(pOffDrk, i, r.Y + 1, i, r.Height - 1);
+ }
+ lite = !lite;
+ }
+ gi.Dispose();
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void PaintTriple(Rectangle r, Graphics g) {
+ int lite = 1;
+ img = new Bitmap(r.Width + 1, r.Height + 1);
+ Graphics gi = Graphics.FromImage(img);
+
+ for (int i = 1; i < r.Width + 1; i++) {
+ if (lite == 2) {
+ gi.DrawLine(pOffLitTop, i, r.Y, i, r.Y + 1);
+ gi.DrawLine(pOffLitBot, i, r.Height, i, r.Height - 1);
+ gi.DrawLine(pOffLit, i, r.Y + 1, i, r.Height - 1);
+ lite = 0;
+ } else if (lite == 1) {
+ gi.DrawLine(pOffMidTop, i, r.Y, i, r.Y + 1);
+ gi.DrawLine(pOffMidBot, i, r.Height, i, r.Height - 1);
+ gi.DrawLine(pOffMid, i, r.Y + 1, i, r.Height - 1);
+ lite = 2;
+ } else if (lite == 0) {
+ gi.DrawLine(pOffDrkTop, i, r.Y, i, r.Y + 1);
+ gi.DrawLine(pOffDrkBot, i, r.Height, i, r.Height - 1);
+ gi.DrawLine(pOffDrk, i, r.Y + 1, i, r.Height - 1);
+ lite = 1;
+ }
+ }
+ gi.Dispose();
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ img = null;
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (img != null) { img.Dispose(); }
+
+ if (pOffLit != null) { pOffLit.Dispose(); }
+ if (pOffLitTop != null) { pOffLitTop.Dispose(); }
+ if (pOffLitBot != null) { pOffLitBot.Dispose(); }
+ if (pOffMid != null) { pOffMid.Dispose(); }
+ if (pOffMidTop != null) { pOffMidTop.Dispose(); }
+ if (pOffMidBot != null) { pOffMidBot.Dispose(); }
+ if (pOffDrk != null) { pOffDrk.Dispose(); }
+ if (pOffDrkTop != null) { pOffDrkTop.Dispose(); }
+ if (pOffDrkBot != null) { pOffDrkBot.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/FruityLoopsProgressPainter.cs b/ProgressODoom/FruityLoopsProgressPainter.cs
new file mode 100644
index 0000000..50a7f19
--- /dev/null
+++ b/ProgressODoom/FruityLoopsProgressPainter.cs
@@ -0,0 +1,169 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.FruityLoopsProgressPainter), "Icons.FruityLoopsProgressPainter.ico")]
+ public class FruityLoopsProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private FruityLoopsProgressType type;
+
+ private Color OnLit = Color.FromArgb(148, 170, 173);
+ private Pen pOnLit; // = new Pen(new SolidBrush(OnLit),1f);
+ private Color OnLitTop = Color.FromArgb(206, 227, 231);
+ private Pen pOnLitTop; // = new Pen(new SolidBrush(OnLitTop),1f);
+ private Color OnLitBot = Color.FromArgb(90, 117, 123);
+ private Pen pOnLitBot; // = new Pen(new SolidBrush(OnLitBot),1f);
+
+ private Color OnMid = Color.FromArgb(107, 130, 132);
+ private Pen pOnMid; // = new Pen(new SolidBrush(OnMid),1f);
+ private Color OnMidTop = Color.FromArgb(140, 154, 156);
+ private Pen pOnMidTop; // = new Pen(new SolidBrush(OnMidTop),1f);
+ private Color OnMidBot = Color.FromArgb(57, 85, 82);
+ private Pen pOnMidBot; // = new Pen(new SolidBrush(OnMidBot),1f);
+
+ private Color OnDrk = Color.FromArgb(57, 85, 82);
+ private Pen pOnDrk; // = new Pen(new SolidBrush(OnDrk),1f);
+ private Color OnDrkTop = Color.FromArgb(107, 125, 123);
+ private Pen pOnDrkTop; // = new Pen(new SolidBrush(OnDrkTop),1f);
+ private Color OnDrkBot = Color.FromArgb(33, 60, 66);
+ private Pen pOnDrkBot; // = new Pen(new SolidBrush(OnDrkBot),1f);
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the type of FruityLoops progress style"), Browsable(true)]
+ public FruityLoopsProgressType FruityType {
+ get { return type; }
+ set {
+ type = value;
+ if (type == FruityLoopsProgressType.DoubleLayer) {
+ OnLit = Color.FromArgb(148, 170, 173);
+ pOnLit = new Pen(new SolidBrush(OnLit), 1f);
+ OnLitTop = Color.FromArgb(206, 227, 231);
+ pOnLitTop = new Pen(new SolidBrush(OnLitTop), 1f);
+ OnLitBot = Color.FromArgb(90, 113, 115);
+ pOnLitBot = new Pen(new SolidBrush(OnLitBot), 1f);
+
+ OnDrk = Color.FromArgb(115, 142, 148);
+ pOnDrk = new Pen(new SolidBrush(OnDrk), 1f);
+ OnDrkTop = Color.FromArgb(181, 199, 198);
+ pOnDrkTop = new Pen(new SolidBrush(OnDrkTop), 1f);
+ OnDrkBot = Color.FromArgb(66, 89, 90);
+ pOnDrkBot = new Pen(new SolidBrush(OnDrkBot), 1f);
+ } else if (type == FruityLoopsProgressType.TripleLayer) {
+ OnLit = Color.FromArgb(148, 170, 173);
+ pOnLit = new Pen(new SolidBrush(OnLit), 1f);
+ OnLitTop = Color.FromArgb(206, 227, 231);
+ pOnLitTop = new Pen(new SolidBrush(OnLitTop), 1f);
+ OnLitBot = Color.FromArgb(90, 117, 123);
+ pOnLitBot = new Pen(new SolidBrush(OnLitBot), 1f);
+
+ OnMid = Color.FromArgb(107, 130, 132);
+ pOnMid = new Pen(new SolidBrush(OnMid), 1f);
+ OnMidTop = Color.FromArgb(140, 154, 156);
+ pOnMidTop = new Pen(new SolidBrush(OnMidTop), 1f);
+ OnMidBot = Color.FromArgb(57, 85, 82);
+ pOnMidBot = new Pen(new SolidBrush(OnMidBot), 1f);
+
+ OnDrk = Color.FromArgb(57, 85, 82);
+ pOnDrk = new Pen(new SolidBrush(OnDrk), 1f);
+ OnDrkTop = Color.FromArgb(107, 125, 123);
+ pOnDrkTop = new Pen(new SolidBrush(OnDrkTop), 1f);
+ OnDrkBot = Color.FromArgb(33, 60, 66);
+ pOnDrkBot = new Pen(new SolidBrush(OnDrkBot), 1f);
+ }
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Height -= 1;
+ } catch { }
+
+ if (box.Width <= 1) { return; }
+ if (type == FruityLoopsProgressType.DoubleLayer) {
+ PaintDouble(box, g);
+ } else if (type == FruityLoopsProgressType.TripleLayer) {
+ PaintTriple(box, g);
+ }
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ private void PaintDouble(Rectangle r, Graphics g) {
+ bool lite = true;
+
+ Brush b = new SolidBrush(pOnLit.Color);
+ g.FillRectangle(b, r);
+ g.DrawLine(pOnLitTop, r.X, r.Y, r.Right - 1, r.Y);
+ g.DrawLine(pOnLitBot, r.X, r.Bottom, r.Right - 1, r.Bottom);
+ for (int i = r.X; i < r.Right; i++) {
+ if (lite) {
+ //g.DrawLine(off ? pOffLitTop : pOnLitTop, i, r.Y, i, r.Y + 1);
+ //g.DrawLine(off ? pOffLitBot : pOnLitBot, i, r.Height, i, r.Height - 1);
+ //g.DrawLine(off ? pOffLit : pOnLit, i, r.Y + 1, i, r.Height - 1);
+ } else {
+ g.DrawLine(pOnDrkTop, i, r.Y, i, r.Y + 1);
+ g.DrawLine(pOnDrkBot, i, r.Bottom, i, r.Bottom - 1);
+ g.DrawLine(pOnDrk, i, r.Y + 1, i, r.Bottom - 1);
+ }
+ lite = !lite;
+ }
+ }
+
+ private void PaintTriple(Rectangle r, Graphics g) {
+ int lite = 1;
+
+ Brush b = new SolidBrush(pOnMid.Color);
+ g.FillRectangle(b, r);
+ g.DrawLine(pOnMidTop, r.X, r.Y, r.Right - 1, r.Y);
+ g.DrawLine(pOnMidBot, r.X, r.Bottom, r.Right - 1, r.Bottom);
+ for (int i = r.X; i < r.Right; i++) {
+ if (lite == 2) {
+ g.DrawLine(pOnLitTop, i, r.Y, i, r.Y + 1);
+ g.DrawLine(pOnLitBot, i, r.Bottom, i, r.Bottom - 1);
+ g.DrawLine(pOnLit, i, r.Y + 1, i, r.Bottom - 1);
+ lite = 0;
+ } else if (lite == 1) {
+ //g.DrawLine(pOnMidTop, i, r.Y, i, r.Y + 1);
+ //g.DrawLine(pOnMidBot, i, r.Height, i, r.Height - 1);
+ //g.DrawLine(pOnMid, i, r.Y + 1, i, r.Height - 1);
+ lite = 2;
+ } else if (lite == 0) {
+ g.DrawLine(pOnDrkTop, i, r.Y, i, r.Y + 1);
+ g.DrawLine(pOnDrkBot, i, r.Bottom, i, r.Bottom - 1);
+ g.DrawLine(pOnDrk, i, r.Y + 1, i, r.Bottom - 1);
+ lite = 1;
+ }
+ }
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ if (pOnLit != null) { pOnLit.Dispose(); }
+ if (pOnLitTop != null) { pOnLitTop.Dispose(); }
+ if (pOnLitBot != null) { pOnLitBot.Dispose(); }
+ if (pOnMid != null) { pOnMid.Dispose(); }
+ if (pOnMidTop != null) { pOnMidTop.Dispose(); }
+ if (pOnMidBot != null) { pOnMidBot.Dispose(); }
+ if (pOnDrk != null) { pOnDrk.Dispose(); }
+ if (pOnDrkTop != null) { pOnDrkTop.Dispose(); }
+ if (pOnDrkBot != null) { pOnDrkBot.Dispose(); }
+ }
+
+ ///
+ public enum FruityLoopsProgressType {
+ ///
+ DoubleLayer,
+ ///
+ TripleLayer
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/GradientBackgroundPainter.cs b/ProgressODoom/GradientBackgroundPainter.cs
new file mode 100644
index 0000000..19f9bc2
--- /dev/null
+++ b/ProgressODoom/GradientBackgroundPainter.cs
@@ -0,0 +1,102 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.GradientBackgroundPainter), "Icons.GradientBackgroundPainter.ico")]
+ public class GradientBackgroundPainter : Component, IProgressBackgroundPainter, IDisposable {
+ private Color top;
+ private Color bottom;
+ private Brush brush;
+ private IGlossPainter gloss;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ ///
+ public GradientBackgroundPainter() {
+ this.top = Color.FromArgb(240, 240, 240);
+ this.bottom = Color.FromArgb(224, 224, 224);
+ }
+
+ ///
+ ///
+ public GradientBackgroundPainter(Color top, Color bottom) {
+ this.top = top;
+ this.bottom = bottom;
+ }
+
+ ///
+ [Category("Painters"), Description("Gets or sets the chain of gloss painters"), Browsable(true)]
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the top gradient color"), Browsable(true)]
+ public Color TopColor {
+ get { return top; }
+ set { top = value; FireChange(); }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the bottom gradient color"), Browsable(true)]
+ public Color BottomColor {
+ get { return bottom; }
+ set { bottom = value; FireChange(); }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBackground(Rectangle box, Graphics g) {
+ Resize(box);
+ g.FillRectangle(brush, box);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(0, box.Height), bottom, top);
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (brush != null) { brush.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/GradientGlossPainter.cs b/ProgressODoom/GradientGlossPainter.cs
new file mode 100644
index 0000000..199d94b
--- /dev/null
+++ b/ProgressODoom/GradientGlossPainter.cs
@@ -0,0 +1,119 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.GradientGlossPainter), "Icons.GradientGlossPainter.ico")]
+ public class GradientGlossPainter : ChainedGlossPainter {
+ private GlossStyle style = GlossStyle.Bottom;
+ private int percent = 50;
+ private Color color = Color.White;
+ private int highAlpha = 240;
+ private int lowAlpha = 0;
+ private float angle = 90f;
+ private Brush brush;
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the style for this progress gloss"), Browsable(true)]
+ public GlossStyle Style {
+ get { return this.style; }
+ set {
+ this.style = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the percentage of surface this gloss should cover"), Browsable(true)]
+ public int PercentageCovered {
+ get { return this.percent; }
+ set {
+ this.percent = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets color to gloss"), Browsable(true)]
+ public Color Color {
+ get { return this.color; }
+ set {
+ this.color = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the high alpha value"), Browsable(true)]
+ public int AlphaHigh {
+ get { return this.highAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.highAlpha = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the low alpha value"), Browsable(true)]
+ public int AlphaLow {
+ get { return this.lowAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.lowAlpha = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets angle for the gradient"), Browsable(true)]
+ public float Angle {
+ get { return this.angle; }
+ set {
+ this.angle = value;
+ FireChange();
+ }
+ }
+
+ protected override void PaintThisGloss(Rectangle box, Graphics g) {
+ int y = (int)(((float)box.Height * (float)percent) / 100f);
+ if (box.Y + y > box.Height) { y = box.Height; }
+
+ Rectangle cover = box;
+ switch (style) {
+ case GlossStyle.Bottom:
+ int start = box.Height + box.Y - y;
+ cover = new Rectangle(box.X, start - 1, box.Width /*- 1*/, box.Bottom - start);
+ break;
+ case GlossStyle.Top:
+ cover = new Rectangle(box.X, box.Y - 1, box.Width /*- 1*/, y + 2);
+ break;
+ case GlossStyle.Both:
+ cover = box;
+ break;
+ }
+
+ Color hcolor = Color.FromArgb(highAlpha, color.R, color.G, color.B);
+ Color lcolor = Color.FromArgb(lowAlpha, color.R, color.G, color.B);
+ brush = new LinearGradientBrush(cover, hcolor, lcolor, angle, true);
+ g.FillRectangle(brush, cover);
+ //g.DrawRectangle(Pens.Red, cover);
+ }
+
+ protected override void ResizeThis(Rectangle box) {
+ }
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (brush != null) { brush.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/HSV.cs b/ProgressODoom/HSV.cs
new file mode 100644
index 0000000..5091da0
--- /dev/null
+++ b/ProgressODoom/HSV.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ public struct HSV {
+ private int hue;
+ private int sat;
+ private int val;
+
+ public HSV(int h, int s, int v) {
+ hue = h;
+ sat = s;
+ val = v;
+ }
+
+ public HSV(Color color) {
+ hue = 0;
+ sat = 0;
+ val = 0;
+ FromRGB(color);
+ }
+
+ public static Color FromHsv(int h, int s, int v) {
+ HSV hsv = new HSV(h, s, v);
+ return hsv.Color;
+ }
+
+ public int Hue {
+ get { return hue; }
+ set { hue = value; }
+ }
+
+ public int Saturation {
+ get { return sat; }
+ set { sat = value; }
+ }
+
+ public int Value {
+ get { return val; }
+ set { val = value; }
+ }
+
+ public Color Color {
+ get { return ToRGB(); }
+ set { FromRGB(value); }
+ }
+
+ private void FromRGB(Color color) {
+ /*
+ if (max = min)
+ h = 0
+ if (max = r)
+ h = (60deg * (g-b)/(max-min) + 0deg) % 360deg
+ if (max = g)
+ h = (60deg * (b-r)/(max-min) + 120deg)
+ if (max = b)
+ h = (60deg * (r-g)/(max-min) + 240deg)
+
+ if (max = 0)
+ s = 0
+ else
+ s = 1 - min/max
+
+ v = max
+ */
+
+ double min;
+ double max;
+ double delta;
+
+ double r = (double)color.R / 255D;
+ double g = (double)color.G / 255D;
+ double b = (double)color.B / 255D;
+
+ double h;
+ double s;
+ double v;
+
+ min = Math.Min(Math.Min(r, g), b);
+ max = Math.Max(Math.Max(r, g), b);
+ v = max;
+ delta = max - min;
+ if (max == 0 || delta == 0) {
+ s = 0;
+ h = 0;
+ } else {
+ s = delta / max;
+ if (r == max) {
+ h = (60D * ((g - b) / delta)) % 360D;
+ } else if (g == max) {
+ h = 60D * ((b - r) / delta) + 120D;
+ } else {
+ h = 60D * ((r - g) / delta) + 240D;
+ }
+ }
+ if (h < 0) {
+ h += 360D;
+ }
+
+ Hue = (int)(h / 360D * 255D);
+ Saturation = (int)(s * 255D);
+ Value = (int)(v * 255D);
+ }
+ private Color ToRGB() {
+ double h;
+ double s;
+ double v;
+
+ double r = 0;
+ double g = 0;
+ double b = 0;
+
+ // Scale Hue to be between 0 and 360. Saturation
+ // and value scale to be between 0 and 1.
+ h = ((double)Hue / 255D * 360D) % 360D;
+ s = (double)Saturation / 255D;
+ v = (double)Value / 255D;
+
+ if (s == 0) {
+ r = v;
+ g = v;
+ b = v;
+ } else {
+ double p;
+ double q;
+ double t;
+
+ double fractionalSector;
+ int sectorNumber;
+ double sectorPos;
+
+ sectorPos = h / 60D;
+ sectorNumber = (int)(Math.Floor(sectorPos));
+
+ fractionalSector = sectorPos - sectorNumber;
+
+ p = v * (1D - s);
+ q = v * (1D - (s * fractionalSector));
+ t = v * (1D - (s * (1D - fractionalSector)));
+
+ switch (sectorNumber) {
+ case 0:
+ r = v;
+ g = t;
+ b = p;
+ break;
+ case 1:
+ r = q;
+ g = v;
+ b = p;
+ break;
+ case 2:
+ r = p;
+ g = v;
+ b = t;
+ break;
+ case 3:
+ r = p;
+ g = q;
+ b = v;
+ break;
+ case 4:
+ r = t;
+ g = p;
+ b = v;
+ break;
+ case 5:
+ r = v;
+ g = p;
+ b = q;
+ break;
+ }
+ }
+ return Color.FromArgb((int)(r * 255D), (int)(g * 255D), (int)(b * 255D));
+ }
+
+ public static bool operator !=(HSV left, HSV right) {
+ return !(left == right);
+ }
+ public static bool operator ==(HSV left, HSV right) {
+ return (left.Hue == right.Hue && left.Value == right.Value && left.Saturation == right.Saturation);
+ }
+ public override string ToString() {
+ string s = string.Format("HSV({0:f2}, {1:f2}, {2:f2})", Hue, Saturation, Value);
+ return s;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/IAnimatedProgressPainter.cs b/ProgressODoom/IAnimatedProgressPainter.cs
new file mode 100644
index 0000000..3de39df
--- /dev/null
+++ b/ProgressODoom/IAnimatedProgressPainter.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ ///
+ public interface IAnimatedProgressPainter : IProgressPainter {
+ /////
+ /////
+ /////
+ /////
+ //void AnimateFrame(Rectangle box, Graphics g, ref int marqueeX);
+
+ ///
+ int AnimationSpeed { get; set; }
+
+ ///
+ bool Animating { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/IGlossPainter.cs b/ProgressODoom/IGlossPainter.cs
new file mode 100644
index 0000000..adf1ea1
--- /dev/null
+++ b/ProgressODoom/IGlossPainter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ public interface IGlossPainter : IDisposable {
+ ///
+ ///
+ ///
+ void PaintGloss(Rectangle box, Graphics g);
+
+ ///
+ void Resize(Rectangle box);
+
+ ///
+ event EventHandler PropertiesChanged;
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/IProgressBackgroundPainter.cs b/ProgressODoom/IProgressBackgroundPainter.cs
new file mode 100644
index 0000000..ae36176
--- /dev/null
+++ b/ProgressODoom/IProgressBackgroundPainter.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ ///
+ public interface IProgressBackgroundPainter : IDisposable {
+ ///
+ IGlossPainter GlossPainter { get; set; }
+
+ ///
+ ///
+ ///
+ void PaintBackground(Rectangle box, Graphics gr);
+
+ ///
+ void Resize(Rectangle box);
+
+ ///
+ event EventHandler PropertiesChanged;
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/IProgressBorderPainter.cs b/ProgressODoom/IProgressBorderPainter.cs
new file mode 100644
index 0000000..21c69d5
--- /dev/null
+++ b/ProgressODoom/IProgressBorderPainter.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ ///
+ public interface IProgressBorderPainter : IDisposable {
+ ///
+ ///
+ ///
+ void PaintBorder(Rectangle box, Graphics gr);
+
+ ///
+ void Resize(Rectangle box);
+
+ ///
+ int BorderWidth { get; }
+
+ ///
+ event EventHandler PropertiesChanged;
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/IProgressPainter.cs b/ProgressODoom/IProgressPainter.cs
new file mode 100644
index 0000000..93a0327
--- /dev/null
+++ b/ProgressODoom/IProgressPainter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Drawing;
+
+namespace ProgressODoom {
+ ///
+ public interface IProgressPainter : IDisposable {
+ ///
+ IGlossPainter GlossPainter { get; set; }
+
+ ///
+ IProgressBorderPainter ProgressBorderPainter { get; set; }
+
+ ///
+ ///
+ ///
+ void PaintProgress(Rectangle box, Graphics gr);
+
+ ///
+ void Resize(Rectangle box);
+
+ ///
+ event EventHandler PropertiesChanged;
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/Icons/BarberPoleProgressPainter.ico b/ProgressODoom/Icons/BarberPoleProgressPainter.ico
new file mode 100644
index 0000000..c2ce723
Binary files /dev/null and b/ProgressODoom/Icons/BarberPoleProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/BevelledGradientProgressPainter.ico b/ProgressODoom/Icons/BevelledGradientProgressPainter.ico
new file mode 100644
index 0000000..036f249
Binary files /dev/null and b/ProgressODoom/Icons/BevelledGradientProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/BevelledProgressPainter.ico b/ProgressODoom/Icons/BevelledProgressPainter.ico
new file mode 100644
index 0000000..230af6a
Binary files /dev/null and b/ProgressODoom/Icons/BevelledProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/CandyCaneBackgroundPainter.ico b/ProgressODoom/Icons/CandyCaneBackgroundPainter.ico
new file mode 100644
index 0000000..1203da7
Binary files /dev/null and b/ProgressODoom/Icons/CandyCaneBackgroundPainter.ico differ
diff --git a/ProgressODoom/Icons/CandyCaneProgressPainter.ico b/ProgressODoom/Icons/CandyCaneProgressPainter.ico
new file mode 100644
index 0000000..ff646f2
Binary files /dev/null and b/ProgressODoom/Icons/CandyCaneProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/DualProgressBar.ico b/ProgressODoom/Icons/DualProgressBar.ico
new file mode 100644
index 0000000..c08d8db
Binary files /dev/null and b/ProgressODoom/Icons/DualProgressBar.ico differ
diff --git a/ProgressODoom/Icons/FlatGlossPainter.ico b/ProgressODoom/Icons/FlatGlossPainter.ico
new file mode 100644
index 0000000..f0b4043
Binary files /dev/null and b/ProgressODoom/Icons/FlatGlossPainter.ico differ
diff --git a/ProgressODoom/Icons/FruityLoopsBackgroundPainter.ico b/ProgressODoom/Icons/FruityLoopsBackgroundPainter.ico
new file mode 100644
index 0000000..782c424
Binary files /dev/null and b/ProgressODoom/Icons/FruityLoopsBackgroundPainter.ico differ
diff --git a/ProgressODoom/Icons/FruityLoopsProgressPainter.ico b/ProgressODoom/Icons/FruityLoopsProgressPainter.ico
new file mode 100644
index 0000000..ac28ea9
Binary files /dev/null and b/ProgressODoom/Icons/FruityLoopsProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/GradientBackgroundPainter.ico b/ProgressODoom/Icons/GradientBackgroundPainter.ico
new file mode 100644
index 0000000..9f22c63
Binary files /dev/null and b/ProgressODoom/Icons/GradientBackgroundPainter.ico differ
diff --git a/ProgressODoom/Icons/GradientGlossPainter.ico b/ProgressODoom/Icons/GradientGlossPainter.ico
new file mode 100644
index 0000000..3134324
Binary files /dev/null and b/ProgressODoom/Icons/GradientGlossPainter.ico differ
diff --git a/ProgressODoom/Icons/JavaProgressPainter.ico b/ProgressODoom/Icons/JavaProgressPainter.ico
new file mode 100644
index 0000000..6f227ad
Binary files /dev/null and b/ProgressODoom/Icons/JavaProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/MetalProgressPainter.ico b/ProgressODoom/Icons/MetalProgressPainter.ico
new file mode 100644
index 0000000..6ebc362
Binary files /dev/null and b/ProgressODoom/Icons/MetalProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/MiddleGlossPainter.ico b/ProgressODoom/Icons/MiddleGlossPainter.ico
new file mode 100644
index 0000000..32f09af
Binary files /dev/null and b/ProgressODoom/Icons/MiddleGlossPainter.ico differ
diff --git a/ProgressODoom/Icons/PlainBackgroundPainter.ico b/ProgressODoom/Icons/PlainBackgroundPainter.ico
new file mode 100644
index 0000000..e51e78f
Binary files /dev/null and b/ProgressODoom/Icons/PlainBackgroundPainter.ico differ
diff --git a/ProgressODoom/Icons/PlainBorderPainter.ico b/ProgressODoom/Icons/PlainBorderPainter.ico
new file mode 100644
index 0000000..de5fcaa
Binary files /dev/null and b/ProgressODoom/Icons/PlainBorderPainter.ico differ
diff --git a/ProgressODoom/Icons/PlainProgressPainter.ico b/ProgressODoom/Icons/PlainProgressPainter.ico
new file mode 100644
index 0000000..bb40f35
Binary files /dev/null and b/ProgressODoom/Icons/PlainProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/ProgressBarEx.ico b/ProgressODoom/Icons/ProgressBarEx.ico
new file mode 100644
index 0000000..d60e0b9
Binary files /dev/null and b/ProgressODoom/Icons/ProgressBarEx.ico differ
diff --git a/ProgressODoom/Icons/RarBackgroundPainter.ico b/ProgressODoom/Icons/RarBackgroundPainter.ico
new file mode 100644
index 0000000..2fb5b1e
Binary files /dev/null and b/ProgressODoom/Icons/RarBackgroundPainter.ico differ
diff --git a/ProgressODoom/Icons/RarBorderPainter.ico b/ProgressODoom/Icons/RarBorderPainter.ico
new file mode 100644
index 0000000..8465005
Binary files /dev/null and b/ProgressODoom/Icons/RarBorderPainter.ico differ
diff --git a/ProgressODoom/Icons/RarProgressBar.ico b/ProgressODoom/Icons/RarProgressBar.ico
new file mode 100644
index 0000000..551130f
Binary files /dev/null and b/ProgressODoom/Icons/RarProgressBar.ico differ
diff --git a/ProgressODoom/Icons/RarProgressPainter.ico b/ProgressODoom/Icons/RarProgressPainter.ico
new file mode 100644
index 0000000..7a78c9e
Binary files /dev/null and b/ProgressODoom/Icons/RarProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/RoundGlossPainter.ico b/ProgressODoom/Icons/RoundGlossPainter.ico
new file mode 100644
index 0000000..fba36f4
Binary files /dev/null and b/ProgressODoom/Icons/RoundGlossPainter.ico differ
diff --git a/ProgressODoom/Icons/StripedProgressPainter.ico b/ProgressODoom/Icons/StripedProgressPainter.ico
new file mode 100644
index 0000000..d91316e
Binary files /dev/null and b/ProgressODoom/Icons/StripedProgressPainter.ico differ
diff --git a/ProgressODoom/Icons/StyledBorderPainter.ico b/ProgressODoom/Icons/StyledBorderPainter.ico
new file mode 100644
index 0000000..e63db19
Binary files /dev/null and b/ProgressODoom/Icons/StyledBorderPainter.ico differ
diff --git a/ProgressODoom/Icons/WaveProgressPainter.ico b/ProgressODoom/Icons/WaveProgressPainter.ico
new file mode 100644
index 0000000..10934d2
Binary files /dev/null and b/ProgressODoom/Icons/WaveProgressPainter.ico differ
diff --git a/ProgressODoom/JavaProgressPainter.cs b/ProgressODoom/JavaProgressPainter.cs
new file mode 100644
index 0000000..fdf2cf6
--- /dev/null
+++ b/ProgressODoom/JavaProgressPainter.cs
@@ -0,0 +1,138 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.JavaProgressPainter), "Icons.JavaProgressPainter.ico")]
+ public class JavaProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Color color;
+ private ColorSet colors;
+
+ ///
+ public JavaProgressPainter() {
+ color = Color.SkyBlue;
+ colors = new ColorSet(false, color, 0.95f, 8);
+ }
+
+ ///
+ ///
+ public JavaProgressPainter(Color color) {
+ this.color = color;
+ colors = new ColorSet(false, color, 0.95f, 8);
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color."), Browsable(true)]
+ public Color Color {
+ get { return color; }
+ set {
+ color = value;
+ colors = new ColorSet(false, color, 0.95f, 8);
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Width -= 1;
+ box.Height -= 1;
+ } catch {}
+ if (box.Width <= 1) { return; }
+
+ float x = (float)box.X;
+ float y = (float)box.Y;
+ float w = (float)box.Right;
+ float h = (float)box.Bottom;
+
+ //Color corner
+ Pen p;
+ x += 2f; //x += 3f; //x += 2f; //x = x + 3f;
+ y += 4f; //y += 5f; //y += 4f; //y = y + 5f;
+ w -= 2f; //w -= 3f; //w -= 1f; //w = w - 2f;
+ h -= 4f; //h -= 6f; //h -= 4f; //h = h - 6f;
+
+ // Progress
+ colors = new ColorSet(true, this.color, 0.95f, (int)h);
+ float z = 2;
+ float ni;
+ float th = box.Height - 4;
+ for (int i = -2; i < th; i++) {
+ //for (int i = -2; i < th; i++) {
+ z = (i < 0 ? i * -1 : i);
+ Color c = colors.Colors[colors.Colors.Length - 1];
+ try {
+ c = colors.Colors[(int)z];
+ } catch {}
+ p = new Pen(c);
+ ni = y + i;
+ g.DrawLine(p, x, ni, w, ni);
+ }
+
+ Color progborder = ColorRange.Morph(0.2f, Color.FromArgb(98, 98, 89), this.color);
+
+ Color fade = Color.FromArgb(64, progborder.R, progborder.G, progborder.B);
+ p = new Pen(new SolidBrush(fade), 1);
+ //g.DrawRectangle(p, x - 1f, y - 3f, w - 1f, h + 1f);
+ Rectangle bbox = box;
+ bbox.Inflate(-1, -1);
+ g.DrawRectangle(p, bbox);
+
+ // Border
+ p = new Pen(progborder, 1);
+ ////g.DrawRectangle(p, x - 1f, y - 3f, w - 1f, h + 1f);
+ //g.DrawLine(p, x, y - 3f, w, y - 3f);
+ //g.DrawLine(p, x, h + 3f, w, h + 3f);
+ //g.DrawLine(p, x - 1f, y - 2f, x - 1f, h + 2f);
+ //g.DrawLine(p, w + 1f, y - 2f, w + 1f, h + 2f);
+ g.DrawLine(p, x + 1f, y - 3f, w - 1f, y - 3f);
+ g.DrawLine(p, x + 1f, h + 3f, w - 1f, h + 3f);
+ g.DrawLine(p, x - 1f, y - 1f, x - 1f, h + 1f);
+ g.DrawLine(p, w + 1f, y - 1f, w + 1f, h + 1f);
+
+ // Border corner skirt
+ //Color skirt = ColorRange.Morph(0.8f, this.color, progborder);
+ Color skirt = Color.FromArgb(210, progborder.R, progborder.G, progborder.B);
+ p = new Pen(skirt, 1);
+ //// Upper Left
+ //g.DrawLine(p, x - 1f, y - 3f, x, y - 3f);
+ //g.DrawLine(p, x - 1f, y - 3f, x - 1f, y - 2f);
+ g.DrawLine(p, x, y - 3f, x - 1f, y - 2f);
+ //// Lower Left
+ //g.DrawLine(p, x - 1f, h + 3f, x - 1f, h + 2f);
+ //g.DrawLine(p, x - 1f, h + 3f, x, h + 3f);
+ g.DrawLine(p, x, h + 3f, x - 1f, h + 2f);
+ //// Upper Right
+ //g.DrawLine(p, w + 1f, y - 3f, w + 1f, y - 2f);
+ //g.DrawLine(p, w + 1f, y - 3f, w, y - 3f);
+ g.DrawLine(p, w, y - 3f, w + 1f, y - 2f);
+ //// Lower Right
+ //g.DrawLine(p, w + 1f, h + 3f, w, h + 3f);
+ //g.DrawLine(p, w + 1f, h + 3f, w + 1f, h + 2f);
+ g.DrawLine(p, w, h + 3f, w + 1f, h + 2f);
+
+ //// Border corner x-1f, y-3f, w-2f, h+1f
+ //Color corners = ColorRange.Morph(0.5f, this.color, progborder); //Color.FromArgb(229, 229, 222)
+ //p = new Pen(corners, 1);
+ //g.DrawLine(p, x - 1f, y - 3f, x, y - 2f); // ul
+ //g.DrawLine(p, x - 1f, h + 3f, x, h + 2f); // ll
+ //g.DrawLine(p, w + 1f, y - 3f, w, y - 2f); // ur
+ //g.DrawLine(p, w + 1f, h + 3f, w, h + 2f); // lr
+
+ ////// Outer corner (Left side only)
+ ////Color outcorner = ColorRange.Morph(0.5f, progborder, Color.FromArgb(229, 229, 222));
+ ////p = new Pen(outcorner, 1);
+ ////g.DrawLine(p, x - 2f, y - 4f, x - 1f, y - 3f);
+ ////g.DrawLine(p, x - 2f, h + 4f, x - 1f, h + 3f);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/MetalProgressPainter.cs b/ProgressODoom/MetalProgressPainter.cs
new file mode 100644
index 0000000..99672a2
--- /dev/null
+++ b/ProgressODoom/MetalProgressPainter.cs
@@ -0,0 +1,153 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.MetalProgressPainter), "Icons.MetalProgressPainter.ico")]
+ public class MetalProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Color progColor = Color.FromArgb(201, 202, 201);
+ private Color bkColor = Color.FromArgb(240, 240, 240);
+
+ #region Default Colors
+ private Color backColor = Color.FromArgb(176, 177, 176);
+ private Color borderColor = Color.FromArgb(69, 68, 69);
+ private Color backtopColor = Color.FromArgb(160, 157, 160);
+ private Color barColor12 = Color.FromArgb(193, 194, 193);
+ private Color barColor3 = Color.FromArgb(201, 202, 201);
+ private Color barColor8 = Color.FromArgb(226, 226, 226);
+ private Color barBorderTopColor = Color.FromArgb(250, 250, 250);
+ private Color barBorderBottomColor = Color.FromArgb(176, 173, 176);
+ #endregion
+
+ #region Pens & Brushes
+ private Pen border;
+ private Pen backtop;
+ private Brush back;
+
+ private Pen bar12;
+ private Pen bar8;
+
+ private Pen barBorderTop;
+ private Pen barBorderBottom;
+
+ private Brush prog;
+ #endregion
+
+ ///
+ public MetalProgressPainter() {
+ progColor = barColor3;
+ back = new SolidBrush(bkColor); //backColor);
+
+ border = new Pen(new SolidBrush(borderColor), 1f);
+ backtop = new Pen(new SolidBrush(backtopColor), 1f);
+
+ bar12 = new Pen(new SolidBrush(barColor12), 1f);
+ bar8 = new Pen(new SolidBrush(barColor8), 1f);
+
+ barBorderTop = new Pen(new SolidBrush(barBorderTopColor), 1f);
+ barBorderBottom = new Pen(new SolidBrush(barBorderBottomColor), 1f);
+
+ prog = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(0, 20), barColor12, barColor8);
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color"), Browsable(true)]
+ public Color Color {
+ get { return progColor; }
+ set {
+ progColor = value;
+ FireChange();
+ }
+ }
+
+ [Category("Appearance"), Description("Gets or sets the color that the highlights are blended with"), Browsable(true)]
+ public Color Highlight {
+ get { return backColor; }
+ set {
+ backColor = value;
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Width -= 1;
+ box.Height -= 1;
+ } catch {}
+ float x = box.X;
+ float y = box.Y;
+ float w = box.Right;
+ float h = box.Bottom;
+ if (w < 2) { return; }
+
+ RebuildBrushes(box.Bottom - 1);
+
+ //g.FillRectangle(prog, x + 1, y + 1, w - 2, h - 1);
+ //
+ //g.DrawRectangle(barBorderBottom, box.X, box.Y, box.Right, box.Height - 1);
+ //g.DrawLine(barBorderTop, box.X, box.Y, box.Width + 2, box.Y);
+ //g.DrawLine(barBorderTop, box.X, box.Y, box.X, box.Height + 2);
+
+ g.FillRectangle(prog, box);
+
+ g.DrawLine(barBorderTop, x, y, w, y); // top
+ g.DrawLine(barBorderTop, x, y, x, h); // left
+ g.DrawLine(barBorderBottom, x, h, w, h); // bottom
+ g.DrawLine(barBorderBottom, w, h, w, y); // right
+
+ //g.DrawRectangle(border, x + 2, y + 2, w - 3, h - 4);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ protected override void ResizeThis(Rectangle box) {
+ //RebuildBrushes();
+ }
+
+ private void RebuildBrushes(int height) {
+ Color top = Cross(barColor3, progColor, barColor12);
+ Color bottom = Cross(barColor3, progColor, barColor8);
+ bar12 = new Pen(new SolidBrush(top), 1f);
+ bar8 = new Pen(new SolidBrush(bottom), 1f);
+ barBorderTop = new Pen(new SolidBrush(Cross(barColor3, progColor, barBorderTopColor)), 1f);
+ barBorderBottom = new Pen(new SolidBrush(Cross(barColor3, progColor, barBorderBottomColor)), 1f);
+ int h = height;
+ //if (h == 0) { h = 20; }
+ prog = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 1), new Point(0, h + 2), top, bottom);
+
+ backtop = new Pen(new SolidBrush(Cross(backColor, bkColor, backtopColor)), 1f);
+ back = new SolidBrush(bkColor);
+ }
+
+ private Color Cross(Color colorX, Color colorY, Color colorX2) {
+ int r = (int)(((float)colorY.R * (float)colorX2.R) / (float)colorX.R);
+ int g = (int)(((float)colorY.G * (float)colorX2.G) / (float)colorX.G);
+ int b = (int)(((float)colorY.B * (float)colorX2.B) / (float)colorX.B);
+ if (r > 255) { r = 255; } else if (r < 0) { r = 0; }
+ if (g > 255) { g = 255; } else if (g < 0) { g = 0; }
+ if (b > 255) { b = 255; } else if (b < 0) { b = 0; }
+ return Color.FromArgb(r, g, b);
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ if (border != null) { border.Dispose(); }
+ if (backtop != null) { backtop.Dispose(); }
+ if (back != null) { back.Dispose(); }
+ if (bar12 != null) { bar12.Dispose(); }
+ if (bar8 != null) { bar8.Dispose(); }
+ if (barBorderTop != null) { barBorderTop.Dispose(); }
+ if (barBorderBottom != null) { barBorderBottom.Dispose(); }
+ if (prog != null) { prog.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/MiddleGlossPainter.cs b/ProgressODoom/MiddleGlossPainter.cs
new file mode 100644
index 0000000..4cf5467
--- /dev/null
+++ b/ProgressODoom/MiddleGlossPainter.cs
@@ -0,0 +1,162 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.MiddleGlossPainter), "Icons.MiddleGlossPainter.ico")]
+ public class MiddleGlossPainter : ChainedGlossPainter {
+ private GlossStyle style = GlossStyle.Both;
+ private int highAlpha = 240;
+ private int lowAlpha = 0;
+ private int fadewidth = 4;
+ private Brush highBrush;
+ private Brush lowBrush;
+ private Brush bothBrush;
+ private Rectangle box;
+ private Color color = Color.White;
+ private Color topColor;
+ private Color botColor;
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the style for this progress gloss"), Browsable(true)]
+ public GlossStyle Style {
+ get { return this.style; }
+ set {
+ this.style = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the high alpha value"), Browsable(true)]
+ public int AlphaHigh {
+ get { return this.highAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.highAlpha = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the low alpha value"), Browsable(true)]
+ public int AlphaLow {
+ get { return this.lowAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.lowAlpha = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+ ///
+ [Category("Blending"), Description("Gets or sets the number of pixels to blend over"), Browsable(true)]
+ public int TaperHeight {
+ get { return this.fadewidth; }
+ set {
+ this.fadewidth = value;
+ this.box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets color to gloss"), Browsable(true)]
+ public Color Color {
+ get { return this.color; }
+ set {
+ this.color = value;
+ this.topColor = Color.FromArgb(highAlpha, this.color.R, this.color.G, this.color.B);
+ this.botColor = Color.FromArgb(lowAlpha, this.color.R, this.color.G, this.color.B);
+ box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ protected override void PaintThisGloss(Rectangle box, Graphics g) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ ResetBrushes(box);
+ }
+
+ int midpoint = box.X + (int)((float)box.Height / 2f);
+ Rectangle topBox = new Rectangle(box.X, midpoint - fadewidth, box.Width - 1, fadewidth);
+ Rectangle botBox = new Rectangle(box.X, midpoint, box.Width - 1, fadewidth);
+ Rectangle fullBox = new Rectangle(box.X, midpoint - fadewidth, box.Width - 1, fadewidth * 2);
+
+ switch (style) {
+ case GlossStyle.Bottom:
+ g.FillRectangle(lowBrush, botBox);
+ //g.DrawRectangle(Pens.Fuchsia, botBox);
+ break;
+ case GlossStyle.Top:
+ g.FillRectangle(highBrush, topBox);
+ //g.DrawRectangle(Pens.Fuchsia, topBox);
+ break;
+ case GlossStyle.Both:
+ //g.FillRectangle(highBrush, topBox);
+ //g.FillRectangle(lowBrush, botBox);
+ g.FillRectangle(bothBrush, fullBox);
+ break;
+ }
+ //g.DrawRectangle(Pens.Purple, fullBox);
+ //g.DrawRectangle(new Pen(new SolidBrush(Color.FromArgb(64, 255, 255, 0))), topBox);
+ //g.DrawRectangle(new Pen(new SolidBrush(Color.FromArgb(64, 0, 255, 0))), botBox);
+ }
+
+ protected override void ResizeThis(Rectangle box) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ ResetBrushes(box);
+ }
+ }
+
+ private void ResetBrushes(Rectangle box) {
+ int midpoint = box.X + (int)((float)box.Height / 2f);
+ Rectangle topBox = new Rectangle(box.X, midpoint - fadewidth, box.Width - 1, fadewidth);
+ Rectangle botBox = new Rectangle(box.X, midpoint, box.Width - 1, fadewidth);
+ Rectangle fullBox = new Rectangle(box.X, midpoint - fadewidth, box.Width - 1, fadewidth * 2);
+
+ //int midpoint = box.X + (int)((float)box.Height / 2f);
+ Point top = new Point(box.X, fullBox.Top);
+ Point topmid = new Point(box.X, topBox.Bottom);
+ Point botmid = new Point(box.X, botBox.Top);
+ Point bot = new Point(box.X, botBox.Bottom);
+ Color high = topColor;
+ Color low = botColor;
+ //Rectangle fullBox = new Rectangle(box.X, midpoint - fadewidth, box.Width - 1, fadewidth * 2);
+ switch (style) {
+ case GlossStyle.Top:
+ highBrush = new LinearGradientBrush(top, topmid, low, high);
+ break;
+ case GlossStyle.Bottom:
+ lowBrush = new LinearGradientBrush(botmid, bot, high, low);
+ break;
+ case GlossStyle.Both:
+ //highBrush = new LinearGradientBrush(top, topmid, low, high);
+ //lowBrush = new LinearGradientBrush(botmid, bot, high, low);
+ bothBrush = new LinearGradientBrush(fullBox, low, high, LinearGradientMode.Vertical);
+ //((LinearGradientBrush)bothBrush).SetSigmaBellShape(0.5f, 0.5f);
+ ((LinearGradientBrush)bothBrush).SetBlendTriangularShape(0.5f);
+ break;
+ }
+ }
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (highBrush != null) { highBrush.Dispose(); }
+ if (lowBrush != null) { lowBrush.Dispose(); }
+ if (bothBrush != null) { bothBrush.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/PlainBackgroundPainter.cs b/ProgressODoom/PlainBackgroundPainter.cs
new file mode 100644
index 0000000..f00284f
--- /dev/null
+++ b/ProgressODoom/PlainBackgroundPainter.cs
@@ -0,0 +1,95 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.PlainBackgroundPainter), "Icons.PlainBackgroundPainter.ico")]
+ public class PlainBackgroundPainter : Component, IProgressBackgroundPainter, IDisposable {
+ private Color color;
+ private Brush brush;
+ private IGlossPainter gloss;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ ///
+ public PlainBackgroundPainter() {
+ this.Color = Color.FromArgb(240, 240, 240);
+ }
+
+ ///
+ ///
+ public PlainBackgroundPainter(Color color) {
+ this.Color = color;
+ }
+
+ ///
+ ///
+ [Category("Painters"), Description("Gets or sets the chain of gloss painters"), Browsable(true)]
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the background color"), Browsable(true)]
+ public Color Color {
+ get { return color; }
+ set {
+ color = value;
+ brush = new SolidBrush(color);
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBackground(Rectangle box, Graphics g) {
+ g.FillRectangle(brush, box);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ brush.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/PlainBorderPainter.cs b/ProgressODoom/PlainBorderPainter.cs
new file mode 100644
index 0000000..f2e6c82
--- /dev/null
+++ b/ProgressODoom/PlainBorderPainter.cs
@@ -0,0 +1,158 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.PlainBorderPainter), "Icons.PlainBorderPainter.ico")]
+ public class PlainBorderPainter : Component, IProgressBorderPainter, IDisposable {
+ private Color color;
+ private Pen pent;
+ private Pen penb;
+ private Pen cleart;
+ private Pen clearb;
+ private bool rounded = false;
+ private PlainBorderStyle style = PlainBorderStyle.Flat;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ public PlainBorderPainter() {
+ this.Color = Color.Black;
+ //this.clear = new Pen(new SolidBrush(SystemColors.Control));
+ }
+
+ ///
+ ///
+ public PlainBorderPainter(Color color) {
+ this.Color = color;
+ //this.clear = new Pen(new SolidBrush(SystemColors.Control));
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the border color"), Browsable(true)]
+ public Color Color {
+ get { return color; }
+ set {
+ color = value;
+ if (style == PlainBorderStyle.Flat) {
+ pent = new Pen(new SolidBrush(color), 1f);
+ penb = pent;
+ this.cleart = new Pen(new SolidBrush(Color.FromArgb(64, color.R, color.G, color.B)));
+ this.clearb = cleart;
+ FireChange();
+ }
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Determines wether or not to make the border a flat sqaure"), Browsable(true)]
+ public bool RoundedCorners {
+ get { return rounded; }
+ set { rounded = value; FireChange(); }
+ }
+
+ [Category("Appearance"), Description("Gets or sets the border style"), Browsable(true)]
+ public PlainBorderStyle Style {
+ get { return style; }
+ set {
+ style = value;
+ switch (style) {
+ case PlainBorderStyle.Flat:
+ pent = new Pen(new SolidBrush(color), 1f);
+ penb = pent;
+ this.cleart = new Pen(new SolidBrush(Color.FromArgb(64, color.R, color.G, color.B)));
+ this.clearb = cleart;
+ break;
+ case PlainBorderStyle.Raised:
+ pent = new Pen(new SolidBrush(SystemColors.ControlLightLight), 1f);
+ penb = new Pen(new SolidBrush(SystemColors.ControlDark), 1f);
+ this.cleart = new Pen(new SolidBrush(Color.FromArgb(64, SystemColors.ControlLightLight.R, SystemColors.ControlLightLight.G, SystemColors.ControlLightLight.B)));
+ this.clearb = new Pen(new SolidBrush(Color.FromArgb(64, SystemColors.ControlDark.R, SystemColors.ControlDark.G, SystemColors.ControlDark.B)));
+ break;
+ case PlainBorderStyle.Sunken:
+ pent = new Pen(new SolidBrush(SystemColors.ControlDark), 1f);
+ penb = new Pen(new SolidBrush(SystemColors.ControlLightLight), 1f);
+ this.cleart = new Pen(new SolidBrush(Color.FromArgb(64, SystemColors.ControlDark.R, SystemColors.ControlDark.G, SystemColors.ControlDark.B)));
+ this.clearb = new Pen(new SolidBrush(Color.FromArgb(64, SystemColors.ControlLightLight.R, SystemColors.ControlLightLight.G, SystemColors.ControlLightLight.B)));
+ break;
+ }
+ FireChange();
+ }
+ }
+
+ ///
+ [Browsable(false)]
+ public int BorderWidth {
+ get { return 1; }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBorder(Rectangle box, Graphics g) {
+ //try {
+ // box.Width -= 1;
+ // box.Height -= 1;
+ //} catch {}
+ if (rounded) {
+ //// draws the left and right side (because they're shorter) to cover the corner pixels.
+ //g.DrawLine(clear, box.X, 0, box.X, box.Height);
+ //g.DrawLine(clear, box.Width, 0, box.Width, box.Height);
+
+ g.DrawLine(cleart, box.X, box.Y, box.Right - 1, box.Y); // top
+ g.DrawLine(cleart, box.X, box.Y, box.X, box.Bottom - 1); // left
+ g.DrawLine(clearb, box.X, box.Bottom, box.Right, box.Bottom); // bottom
+ g.DrawLine(clearb, box.Right, box.Y, box.Right, box.Bottom); // right
+
+ //g.DrawRectangle(clear, box);
+ g.DrawLine(pent, box.X + 1, box.Y, box.Right - 1, box.Y); // top
+ g.DrawLine(penb, box.X + 1, box.Bottom, box.Right - 1, box.Bottom); // bottom
+ g.DrawLine(pent, box.X, box.Y + 1, box.X, box.Bottom - 1); // left
+ g.DrawLine(penb, box.Right, box.Y + 1, box.Right, box.Bottom - 1); // right
+ } else {
+ //g.DrawRectangle(pen, box);
+ g.DrawLine(pent, box.X, box.Y, box.Right, box.Y); // top
+ g.DrawLine(pent, box.X, box.Y, box.X, box.Bottom); // left
+ g.DrawLine(penb, box.X, box.Bottom, box.Right, box.Bottom); // bottom
+ g.DrawLine(penb, box.Right, box.Y, box.Right, box.Bottom); // right
+ }
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ pent.Dispose();
+ penb.Dispose();
+ cleart.Dispose();
+ clearb.Dispose();
+ }
+
+ ///
+ public enum PlainBorderStyle {
+ Flat, Sunken, Raised
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/PlainProgressPainter.cs b/ProgressODoom/PlainProgressPainter.cs
new file mode 100644
index 0000000..fde2806
--- /dev/null
+++ b/ProgressODoom/PlainProgressPainter.cs
@@ -0,0 +1,66 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.PlainProgressPainter), "Icons.PlainProgressPainter.ico")]
+ public class PlainProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Color color;
+ private Brush brush;
+ private Color edge = Color.Transparent;
+
+ ///
+ public PlainProgressPainter() {
+ this.Color = Color.FromArgb(151, 151, 234);
+ }
+
+ ///
+ ///
+ public PlainProgressPainter(Color color) {
+ this.Color = color;
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the color to draw the leading edge of the progress with"), Browsable(true)]
+ public Color LeadingEdge {
+ get { return this.edge; }
+ set { this.edge = value; FireChange(); }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the base progress color"), Browsable(true)]
+ public Color Color {
+ get { return color; }
+ set {
+ color = value;
+ brush = new SolidBrush(color);
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ if (box.Width <= 1) {
+ return;
+ }
+
+ g.FillRectangle(brush, box);
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ if (!edge.Equals(Color.Transparent)) {
+ g.DrawLine(new Pen(new SolidBrush(edge), 1f), box.Right, box.Y, box.Right, box.Bottom - 1);
+ }
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ brush.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/ProgressBarEx.cs b/ProgressODoom/ProgressBarEx.cs
new file mode 100644
index 0000000..ac86d9b
--- /dev/null
+++ b/ProgressODoom/ProgressBarEx.cs
@@ -0,0 +1,340 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.ProgressBarEx), "Icons.ProgressBarEx.ico")]
+ public class ProgressBarEx : AbstractProgressBar {
+ protected IProgressBackgroundPainter backgroundpainter;
+ protected IProgressPainter progresspainter;
+ protected IProgressBorderPainter borderpainter;
+
+ public ProgressBarEx() {
+ backgroundpainter = new PlainBackgroundPainter();
+ progresspainter = new PlainProgressPainter(Color.Gold);
+ borderpainter = new PlainBorderPainter();
+ }
+
+ ///
+ [Category("Painters"), Description("Paints this progress bar's background"), Browsable(true)]
+ public IProgressBackgroundPainter BackgroundPainter {
+ get { return this.backgroundpainter; }
+ set {
+ this.backgroundpainter = value;
+ this.backgroundpainter.PropertiesChanged += new EventHandler(component_PropertiesChanged);
+ this.Invalidate();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ this.Invalidate();
+ }
+
+ ///
+ [Category("Painters"), Description("Paints this progress bar's progress"), Browsable(true)]
+ public IProgressPainter ProgressPainter {
+ get { return this.progresspainter; }
+ set {
+ if (!(value is IAnimatedProgressPainter) && base.ProgressType == ProgressType.Animated) {
+ base.ProgressType = ProgressType.Smooth;
+ }
+ this.progresspainter = value;
+ if (this.progresspainter is AbstractProgressPainter) {
+ ((AbstractProgressPainter)this.progresspainter).padding = base.ProgressPadding;
+ }
+ this.progresspainter.PropertiesChanged += new EventHandler(component_PropertiesChanged);
+ this.Invalidate();
+ }
+ }
+
+ ///
+ [Category("Progress"), Description("Gets or sets the type of progress"), Browsable(true)]
+ public override ProgressType ProgressType {
+ get { return base.type; }
+ set {
+ if (value == ProgressType.Animated && !(progresspainter is IAnimatedProgressPainter)) {
+ throw new ArgumentException("Animated is not available with the current Progress Painter");
+ }
+ this.type = value;
+ }
+ }
+
+ ///
+ [Category("Painters"), Description("Paints this progress bar's border"), Browsable(true)]
+ public IProgressBorderPainter BorderPainter {
+ get { return this.borderpainter; }
+ set {
+ this.borderpainter = value;
+ this.borderpainter.PropertiesChanged += new EventHandler(component_PropertiesChanged);
+ ResizeProgress();
+ this.Invalidate();
+ }
+ }
+
+ protected override void ResizeProgress() {
+ if (base.ProgressType != ProgressType.Smooth) { return; }
+ Rectangle newprog = base.borderbox;
+ //newprog.Inflate(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+ base.backbox = newprog;
+
+ int val = value; if (val > 0) { val++; }
+ int progWidth = maximum > 0 ? (backbox.Width * val / maximum) : 1;
+ if (value >= maximum && maximum > 0) {
+ progWidth = backbox.Width;
+ } /*else if (value > 0) {
+ progWidth++;
+ }*/
+ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ newprog.Width = progWidth - (base.ProgressPadding * 2);
+ //newprog.Offset(base.ProgressPadding, base.ProgressPadding);
+ //newprog = new Rectangle(backbox.X + base.ProgressPadding, backbox.Y + base.ProgressPadding, progWidth - (base.ProgressPadding * 2), backbox.Height - (base.ProgressPadding * 2));
+ base.progressbox = newprog;
+ }
+
+ #region Animation
+ public void StartAnimation() {
+ if (running) { return; }
+ IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter;
+ if (iapp == null) { return; }
+ iapp.Animating = true;
+ running = true;
+ timerMethod = new EventHandler(DoAnimation);
+ timer.Interval = iapp.AnimationSpeed;
+ timer.Tick += timerMethod;
+ timer.Enabled = true;
+ }
+ public void StopAnimation() {
+ timer.Enabled = false;
+ timer.Tick -= timerMethod;
+ running = false;
+ IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter;
+ if (iapp == null) { return; }
+ iapp.Animating = false;
+ }
+ private void DoAnimation(object sender, EventArgs e) {
+ IAnimatedProgressPainter iapp = this.progresspainter as IAnimatedProgressPainter;
+ if (iapp == null) { return; }
+
+ //Rectangle newprog = base.borderbox;
+ //newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ //newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+ ////int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f);
+ //int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f);
+ //newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ //newprog.Width = progWidth - (base.ProgressPadding * 2);
+
+ //base.progressbox = newprog;
+
+ ////iapp.AnimateFrame(newprog, g, ref marqueeX);
+
+ this.Invalidate();
+ this.Refresh();
+ }
+ #endregion
+
+ #region Marquee
+ private bool running = false;
+ private Timer timer = new Timer();
+ private EventHandler timerMethod;
+ ///
+ public override void MarqueeStart() {
+ if (running) { return; }
+ running = true;
+ switch (base.ProgressType) {
+ case ProgressType.MarqueeWrap: timerMethod = new EventHandler(DoMarqueeWrap); break;
+ case ProgressType.MarqueeBounce: timerMethod = new EventHandler(DoMarqueeBounce); break;
+ case ProgressType.MarqueeBounceDeep: timerMethod = new EventHandler(DoMarqueeDeep); break;
+ }
+ timer.Interval = base.marqueeSpeed;
+ timer.Tick += timerMethod;
+ timer.Enabled = true;
+ }
+
+ private int marqueeX = 0;
+ private void DoMarqueeWrap(object sender, EventArgs e) {
+ Rectangle newprog = base.borderbox;
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+
+ int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f);
+
+ marqueeX += marqueeStep;
+ if (marqueeX > backbox.Width) {
+ marqueeX = 0 - progWidth;
+ }
+
+ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ newprog.Width = progWidth - (base.ProgressPadding * 2);
+ newprog.X += marqueeX;
+
+ int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding;
+ int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding);
+ if (marqueeX <= leftBoundry) {
+ newprog.Width -= leftBoundry - marqueeX;
+ newprog.X = leftBoundry;
+ } else if (marqueeX + newprog.Width >= rightBoundry) {
+ newprog.Width -= (marqueeX + newprog.Width + base.ProgressPadding) - rightBoundry;
+ }
+
+ base.progressbox = newprog;
+
+ this.Invalidate();
+ this.Refresh();
+ }
+ private bool marqueeForward = true;
+ private void DoMarqueeBounce(object sender, EventArgs e) {
+ Rectangle newprog = base.borderbox;
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+
+ int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f);
+
+ if (marqueeForward) {
+ marqueeX += marqueeStep;
+ } else {
+ marqueeX -= marqueeStep;
+ }
+
+ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ newprog.Width = progWidth - (base.ProgressPadding * 2);
+ newprog.X += marqueeX;
+
+ int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding;
+ int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding);
+ if (marqueeX + progWidth >= rightBoundry) {
+ marqueeForward = false;
+ } else if (marqueeX <= leftBoundry) {
+ marqueeForward = true;
+ }
+
+ base.progressbox = newprog;
+
+ this.Invalidate();
+ this.Refresh();
+ }
+ private void DoMarqueeDeep(object sender, EventArgs e) {
+ Rectangle newprog = base.borderbox;
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+
+ int progWidth = (int)(((float)marqueePercentage * (float)backbox.Width) / 100f);
+
+ if (marqueeForward) {
+ marqueeX += marqueeStep;
+ } else {
+ marqueeX -= marqueeStep;
+ }
+ if (marqueeX > backbox.Width) {
+ marqueeForward = false;
+ } else if (marqueeX < backbox.X - progWidth) {
+ marqueeForward = true;
+ }
+
+ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ newprog.Width = progWidth - (base.ProgressPadding * 2);
+ newprog.X += marqueeX;
+
+ int leftBoundry = backbox.X + this.borderpainter.BorderWidth + base.ProgressPadding;
+ int rightBoundry = backbox.X + backbox.Width - (this.borderpainter.BorderWidth + base.ProgressPadding);
+ if (marqueeX <= leftBoundry) {
+ newprog.Width -= leftBoundry - marqueeX;
+ newprog.X = leftBoundry;
+ } else if (marqueeX + newprog.Width >= rightBoundry) {
+ newprog.Width -= (marqueeX + newprog.Width + base.ProgressPadding) - rightBoundry;
+ }
+
+ base.progressbox = newprog;
+
+ this.Invalidate();
+ this.Refresh();
+ }
+
+ ///
+ public override void MarqueePause() {
+ running = false;
+ timer.Enabled = false;
+ timer.Tick -= timerMethod;
+ }
+ ///
+ public override void MarqueeStop() {
+ Rectangle newprog = base.borderbox;
+ newprog.Offset(this.borderpainter.BorderWidth, this.borderpainter.BorderWidth);
+ newprog.Size = new Size(newprog.Size.Width - this.borderpainter.BorderWidth, newprog.Size.Height - this.borderpainter.BorderWidth);
+
+ newprog.Inflate(-base.ProgressPadding, -base.ProgressPadding);
+ newprog.Width = 1;
+ base.progressbox = newprog;
+
+ running = false;
+ timer.Enabled = false;
+ timer.Tick -= timerMethod;
+
+ marqueeX = 0;
+ this.Invalidate();
+ }
+ #endregion
+
+ ///
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (running) { running = false; }
+ }
+
+ ///
+ ///
+ protected override void OnResize(EventArgs e) {
+ base.OnResize(e);
+ ResizeProgress();
+ if (this.backgroundpainter != null) { this.backgroundpainter.Resize(borderbox); }
+ if (this.progresspainter != null) { this.progresspainter.Resize(borderbox); }
+ if (this.borderpainter != null) { this.borderpainter.Resize(borderbox); }
+ }
+
+ ///
+ ///
+ protected override void PaintBackground(Graphics g) {
+ if (this.backgroundpainter != null) {
+ this.backgroundpainter.PaintBackground(backbox, g);
+ }
+ }
+
+ ///
+ ///
+ protected override void PaintProgress(Graphics g) {
+ if (this.progresspainter != null) {
+ this.progresspainter.PaintProgress(progressbox, g);
+ }
+ }
+
+ ///
+ ///
+ protected override void PaintText(Graphics g) {
+ if (base.ProgressType != ProgressType.Smooth) { return; }
+ Brush b = new SolidBrush(ForeColor);
+ SizeF sf = g.MeasureString(Text, Font, Convert.ToInt32(Width), StringFormat.GenericDefault);
+ float m = sf.Width;
+ float x = (Width / 2) - (m / 2);
+ float w = (Width / 2) + (m / 2);
+ float h = (float)borderbox.Height - (2f * (float)this.borderpainter.BorderWidth);
+ float y = (float)this.borderpainter.BorderWidth + ((h - sf.Height) / 2f);
+ g.DrawString(Text, Font, b, RectangleF.FromLTRB(x, y, w, Height - 1), StringFormat.GenericDefault);
+ }
+
+ ///
+ ///
+ protected override void PaintBorder(Graphics g) {
+ if (this.borderpainter != null) {
+ this.borderpainter.PaintBorder(borderbox, g);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/ProgressODoom.csproj b/ProgressODoom/ProgressODoom.csproj
new file mode 100644
index 0000000..32f98f1
--- /dev/null
+++ b/ProgressODoom/ProgressODoom.csproj
@@ -0,0 +1,224 @@
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {8DD1E84B-0B03-4C0B-9B42-1E49F75E7CB1}
+ Library
+ Properties
+ ProgressODoom
+ ProgressODoom
+
+
+ 2.0
+
+
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ ..\bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+
+
+
+
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+ Component
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ .NET Framework Client Profile
+ false
+
+
+ False
+ .NET Framework 2.0 %28x86%29
+ true
+
+
+ False
+ .NET Framework 3.0 %28x86%29
+ false
+
+
+ False
+ .NET Framework 3.5
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/ProgressODoom/ProgressODoom.csproj.user b/ProgressODoom/ProgressODoom.csproj.user
new file mode 100644
index 0000000..ce4e607
--- /dev/null
+++ b/ProgressODoom/ProgressODoom.csproj.user
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ en-US
+ false
+
+
\ No newline at end of file
diff --git a/ProgressODoom/Properties/AssemblyInfo.cs b/ProgressODoom/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9ed59a3
--- /dev/null
+++ b/ProgressODoom/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ProgressODoom")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProgressODoom")]
+[assembly: AssemblyCopyright("Copyright © 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("375b7734-9e29-4ae9-8c57-d1bf00450128")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ProgressODoom/RarBackgroundPainter.cs b/ProgressODoom/RarBackgroundPainter.cs
new file mode 100644
index 0000000..882d04f
--- /dev/null
+++ b/ProgressODoom/RarBackgroundPainter.cs
@@ -0,0 +1,83 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.RarBackgroundPainter), "Icons.RarBackgroundPainter.ico")]
+ public class RarBackgroundPainter : Component, IProgressBackgroundPainter, IDisposable {
+ private Brush brush;
+ private IGlossPainter gloss;
+ private Pen outer, inner, border;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ ///
+ ///
+ protected virtual void component_PropertiesChanged(object sender, EventArgs e) {
+ FireChange();
+ }
+
+ public RarBackgroundPainter() {
+ brush = new SolidBrush(Color.FromArgb(148, 110, 110));
+ inner = new Pen(new SolidBrush(Color.FromArgb(158, 128, 128)), 1f);
+ outer = new Pen(new SolidBrush(Color.FromArgb(180, 148, 148)), 1f);
+ border = new Pen(new SolidBrush(Color.FromArgb(096, 096, 096)), 1f);
+ }
+
+ ///
+ public IGlossPainter GlossPainter {
+ get { return this.gloss; }
+ set {
+ this.gloss = value;
+ if (this.gloss != null) { this.gloss.PropertiesChanged += new EventHandler(component_PropertiesChanged); }
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBackground(Rectangle box, Graphics g) {
+ g.FillRectangle(brush, box);
+ g.DrawRectangle(inner, 2, 2, box.Width - 3, box.Height - 4);
+ g.DrawRectangle(outer, 1, 1, box.Width - 1, box.Height - 2);
+ g.DrawLine(border, 1, box.Height, box.Width, box.Height);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ brush.Dispose();
+ inner.Dispose();
+ outer.Dispose();
+ border.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/RarBorderPainter.cs b/ProgressODoom/RarBorderPainter.cs
new file mode 100644
index 0000000..ffd6ba0
--- /dev/null
+++ b/ProgressODoom/RarBorderPainter.cs
@@ -0,0 +1,61 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.RarBorderPainter), "Icons.RarBorderPainter.ico")]
+ public class RarBorderPainter : Component, IProgressBorderPainter, IDisposable {
+ private Pen border;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ public RarBorderPainter() {
+ border = new Pen(new SolidBrush(Color.FromArgb(064, 064, 070)), 1f);
+ }
+
+ ///
+ [Browsable(false)]
+ public int BorderWidth {
+ get { return 1; }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBorder(Rectangle box, Graphics g) {
+ g.DrawRectangle(new Pen(new SolidBrush(SystemColors.Control), 1f), 0, 0, box.Width, box.Height);
+ g.DrawLine(border, 2, box.Height, box.Width, box.Height);
+ g.DrawLine(border, box.Width, 3, box.Width, box.Height);
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ border.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/RarProgressBar.cs b/ProgressODoom/RarProgressBar.cs
new file mode 100644
index 0000000..f16bcf8
--- /dev/null
+++ b/ProgressODoom/RarProgressBar.cs
@@ -0,0 +1,31 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.RarProgressBar), "Icons.RarProgressBar.ico")]
+ public class RarProgressBar : DualProgressBar {
+ public RarProgressBar() {
+ this.MasterPainter = new RarProgressPainter(RarProgressPainter.RarProgressType.Silver);
+ ((RarProgressPainter)this.MasterPainter).ShowEdge = false;
+ this.ProgressPainter = new RarProgressPainter(RarProgressPainter.RarProgressType.Gold);
+ ((RarProgressPainter)this.ProgressPainter).ShowEdge = true;
+ this.BorderPainter = new RarBorderPainter();
+ this.BackgroundPainter = new RarBackgroundPainter();
+ this.PaintMasterFirst = true;
+ this.OnValueChanged += new EventHandler(onValueChanged);
+ this.OnMasterValueChanged += new EventHandler(onValueChanged);
+ }
+
+ private void onValueChanged(object sender, EventArgs e) {
+ bool masterAhead = false;
+ if (this.MasterValue > this.Value) {
+ masterAhead = true;
+ }
+ ((RarProgressPainter)this.MasterPainter).ShowEdge = masterAhead;
+ ((RarProgressPainter)this.ProgressPainter).ShowEdge = !masterAhead;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/RarProgressPainter.cs b/ProgressODoom/RarProgressPainter.cs
new file mode 100644
index 0000000..e547201
--- /dev/null
+++ b/ProgressODoom/RarProgressPainter.cs
@@ -0,0 +1,103 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.RarProgressPainter), "Icons.RarProgressPainter.ico")]
+ public class RarProgressPainter : AbstractProgressPainter, IProgressPainter, IDisposable {
+ private Brush brush;
+ private Pen inner, outer, edge;
+ private bool showEdge = false;
+ private RarProgressType type;
+
+ ///
+ public RarProgressPainter() {
+ this.ProgressType = RarProgressType.Silver;
+ }
+
+ ///
+ ///
+ public RarProgressPainter(RarProgressType type) {
+ this.ProgressType = type;
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the type of rar progress color"), Browsable(true)]
+ public RarProgressType ProgressType {
+ get { return type; }
+ set {
+ this.type = value;
+ switch (type) {
+ case RarProgressType.Silver:
+ brush = new SolidBrush(Color.FromArgb(214, 214, 220));
+ inner = new Pen(new SolidBrush(Color.FromArgb(232, 232, 238)), 1f);
+ outer = new Pen(new SolidBrush(Color.FromArgb(255, 255, 255)), 1f);
+ edge = new Pen(new SolidBrush(Color.FromArgb(096, 096, 096)), 1f);
+ break;
+ case RarProgressType.Gold:
+ brush = new SolidBrush(Color.FromArgb(208, 192, 160));
+ inner = new Pen(new SolidBrush(Color.FromArgb(228, 212, 180)), 1f);
+ outer = new Pen(new SolidBrush(Color.FromArgb(255, 255, 192)), 1f);
+ edge = new Pen(new SolidBrush(Color.FromArgb(096, 096, 096)), 1f);
+ break;
+ }
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets whether or not this progress has a leading edge"), Browsable(true)]
+ public bool ShowEdge {
+ get { return showEdge; }
+ set {
+ showEdge = value;
+ FireChange();
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ try {
+ box.Width -= 1;
+ box.Height -= 1;
+ } catch {}
+ if (box.Width <= 1) {
+ return;
+ }
+
+ g.FillRectangle(brush, box);
+ Rectangle innerBox = box;
+ innerBox.Inflate(-1, -1);
+ g.DrawRectangle(inner, innerBox);
+ g.DrawLine(outer, box.X, box.Y, box.Right, box.Y);
+ g.DrawLine(outer, box.X, box.Y, box.X, box.Bottom);
+ g.DrawLine(edge, box.X, box.Bottom, box.Right, box.Bottom);
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+
+ if (showEdge) {
+ g.DrawLine(edge, box.Right, box.Y, box.Right, box.Bottom);
+ }
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ brush.Dispose();
+ inner.Dispose();
+ outer.Dispose();
+ edge.Dispose();
+ }
+
+ ///
+ public enum RarProgressType {
+ Gold, Silver
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/RoundGlossPainter.cs b/ProgressODoom/RoundGlossPainter.cs
new file mode 100644
index 0000000..9b27e06
--- /dev/null
+++ b/ProgressODoom/RoundGlossPainter.cs
@@ -0,0 +1,172 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ public enum GlossStyle {
+ Top, Bottom, Both
+ }
+
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.RoundGlossPainter), "Icons.RoundGlossPainter.ico")]
+ public class RoundGlossPainter : ChainedGlossPainter {
+ private GlossStyle style = GlossStyle.Both;
+ private int highAlpha = 240;
+ private int lowAlpha = 0;
+ private int fadewidth = 4;
+ private Brush highBrush;
+ private Brush lowBrush;
+ private Rectangle box;
+ private Color color = Color.White;
+ private Color topColor;
+ private Color botColor;
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the style for this progress gloss"), Browsable(true)]
+ public GlossStyle Style {
+ get { return this.style; }
+ set {
+ this.style = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the high alpha value"), Browsable(true)]
+ public int AlphaHigh {
+ get { return this.highAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.highAlpha = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the low alpha value"), Browsable(true)]
+ public int AlphaLow {
+ get { return this.lowAlpha; }
+ set {
+ if (value < 0 || value > 255) {
+ throw new ArgumentException("Alpha values must be between 0 and 255.");
+ }
+ this.lowAlpha = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Blending"), Description("Gets or sets the number of pixels to blend over"), Browsable(true)]
+ public int TaperHeight {
+ get { return this.fadewidth; }
+ set {
+ this.fadewidth = value;
+ FireChange();
+ }
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets color to gloss"), Browsable(true)]
+ public Color Color {
+ get { return this.color; }
+ set {
+ this.color = value;
+ this.topColor = Color.FromArgb(highAlpha, this.color.R, this.color.G, this.color.B);
+ this.botColor = Color.FromArgb(lowAlpha, this.color.R, this.color.G, this.color.B);
+ box = new Rectangle(0, 0, 1, 1);
+ FireChange();
+ }
+ }
+
+ protected override void PaintThisGloss(Rectangle box, Graphics g) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ ResetBrushes(box);
+ }
+
+ //int midpoint = (int)((float)box.Height / 2f);
+ //int toppoint = midpoint > (fadewidth + 2) ? midpoint - (fadewidth / 2) : midpoint;
+ //int botpoint = midpoint > (fadewidth + 2) ? midpoint + (fadewidth / 2) : midpoint;
+
+ //Rectangle topBox = new Rectangle(box.X, box.Y, box.Width - 1, box.Y + fadewidth);
+ //Rectangle botBox = new Rectangle(box.X, box.Bottom - fadewidth - 2, box.Width - 1, fadewidth + 1);
+ Rectangle topBox = new Rectangle(box.X, box.Y, box.Width, fadewidth);
+ Rectangle botBox = new Rectangle(box.X, box.Bottom - fadewidth, box.Width, fadewidth);
+
+ //if (midpoint - fadewidth > 2) { midpoint -= fadewidth; }
+
+ switch (style) {
+ case GlossStyle.Bottom:
+ g.FillRectangle(lowBrush, botBox);
+ break;
+ case GlossStyle.Top:
+ g.FillRectangle(highBrush, topBox);
+ break;
+ case GlossStyle.Both:
+ g.FillRectangle(highBrush, topBox);
+ g.FillRectangle(lowBrush, botBox);
+ //g.DrawRectangle(Pens.Red, topBox);
+ //g.DrawRectangle(Pens.Blue, botBox);
+ break;
+ }
+ //g.DrawRectangle(new Pen(new SolidBrush(Color.FromArgb(64, 255, 0, 0))), topBox);
+ //g.FillRectangle(new SolidBrush(Color.FromArgb(32, 255, 0, 0)), topBox);
+ //g.DrawRectangle(new Pen(new SolidBrush(Color.FromArgb(64, 0, 0, 255))), botBox);
+ //g.FillRectangle(new SolidBrush(Color.FromArgb(32, 0, 0, 255)), botBox);
+ }
+
+ protected override void ResizeThis(Rectangle box) {
+ if (!this.box.Equals(box)) {
+ this.box = box;
+ ResetBrushes(box);
+ }
+ }
+
+ private void ResetBrushes(Rectangle box) {
+ //int midpoint = (int)((float)box.Height / 2f);
+ //int toppoint = midpoint - (fadewidth / 2);
+ //if (toppoint < box.Y + 2) { toppoint = box.Y + 2; }
+ //int botpoint = midpoint + (fadewidth / 2);
+ //if (botpoint > box.Height - 2) { botpoint = box.Height - 2; }
+
+ //Point top = new Point(box.X, box.Y);
+ //Point topmid = new Point(box.X, box.Y + fadewidth + 1);
+ //Point botmid = new Point(box.X, box.Height - fadewidth - 1);
+ //Point bot = new Point(box.X, box.Bottom);
+
+ Rectangle topBox = new Rectangle(box.X, box.Y, box.Width, fadewidth);
+ Rectangle botBox = new Rectangle(box.X, box.Bottom - fadewidth, box.Width, fadewidth);
+ Point top = new Point(box.X, topBox.Top);
+ Point topmid = new Point(box.X, topBox.Bottom);
+ Point botmid = new Point(box.X, botBox.Top - 1);
+ Point bot = new Point(box.X, botBox.Bottom);
+
+ Color high = topColor;
+ Color low = botColor;
+ switch (style) {
+ case GlossStyle.Top:
+ highBrush = new LinearGradientBrush(top, topmid, high, low);
+ break;
+ case GlossStyle.Bottom:
+ lowBrush = new LinearGradientBrush(botmid, bot, low, high);
+ break;
+ case GlossStyle.Both:
+ highBrush = new LinearGradientBrush(top, topmid, high, low);
+ lowBrush = new LinearGradientBrush(botmid, bot, low, high);
+ break;
+ }
+ }
+
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ if (highBrush != null) { highBrush.Dispose(); }
+ if (lowBrush != null) { lowBrush.Dispose(); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/StripedProgressPainter.cs b/ProgressODoom/StripedProgressPainter.cs
new file mode 100644
index 0000000..fc87d7a
--- /dev/null
+++ b/ProgressODoom/StripedProgressPainter.cs
@@ -0,0 +1,183 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.StripedProgressPainter), "Icons.StripedProgressPainter.ico")]
+ public class StripedProgressPainter : AbstractProgressPainter, IProgressPainter, IAnimatedProgressPainter, IDisposable {
+ private Color color1 = Color.FromArgb(110, 195, 248);
+ private Color color2 = Color.FromArgb(056, 150, 230);
+ private Color blend = Color.FromArgb(097, 184, 244);
+ private int spacing = 6;
+ private int marqueeSpeed = 10;
+
+ private int marqueeX = 0;
+
+ private bool isAnimated = false;
+
+ ///
+ public StripedProgressPainter() {
+ }
+
+ ///
+ public Color BaseColor {
+ get { return color1; }
+ set {
+ color1 = value;
+ blend = ColorRange.Morph(0.25f, color1, color2);
+ FireChange();
+ }
+ }
+
+ ///
+ public Color StripeColor {
+ get { return color2; }
+ set {
+ color2 = value;
+ blend = ColorRange.Morph(0.25f, color1, color2);
+ FireChange();
+ }
+ }
+
+ ///
+ public int StripeSpacing {
+ get { return spacing; }
+ set { spacing = value; FireChange(); }
+ }
+
+ ///
+ public int AnimationSpeed {
+ get { return marqueeSpeed; }
+ set { marqueeSpeed = value; FireChange(); }
+ }
+
+ ///
+ public bool Animating {
+ get { return isAnimated; }
+ set { isAnimated = value; }
+ }
+
+ private void AnimateFrame(Rectangle box, Graphics g, ref int marqueeX) {
+ if (box == null || g == null || box.Width <= 1) { return; }
+
+ Pen penb = new Pen(new SolidBrush(blend));
+ g.FillRectangle(new SolidBrush(color1), box);
+ for (int i = box.Right + marqueeX; i > box.Left; i -= ((box.Height * 2) + StripeSpacing - 1)) {
+ Point theoreticalRightTop = new Point(i, box.Top);
+ Point theoreticalRightBottom = new Point(i - box.Height, box.Bottom);
+ Point theoreticalLeftTop = new Point(i - box.Height, box.Top);
+ Point theoreticalLeftBottom = new Point(i - (box.Height * 2), box.Bottom);
+
+ Point leftTop, leftBottom, rightTop, rightBottom;
+ using (GraphicsPath gp = new GraphicsPath()) {
+ if (theoreticalLeftTop.X <= box.Left) {
+ // left triangle
+ int diff = i - box.Height;
+ rightTop = new Point(i, box.Top);
+ rightBottom = new Point(box.Left, box.Bottom + diff);
+ leftTop = new Point(box.Left, box.Top);
+ leftBottom = leftTop;
+
+ if (rightBottom.Equals(rightTop)) { continue; }
+
+ gp.AddLine(rightTop, rightBottom);
+ gp.AddLine(rightBottom, leftTop);
+ gp.AddLine(leftTop, new Point(i, box.Top));
+ } else if (theoreticalLeftBottom.X <= box.Left) {
+ // left pentagon
+ int diff = i - (box.Height * 2);
+ rightTop = new Point(i, box.Top);
+ rightBottom = new Point(i - box.Height, box.Bottom);
+ leftTop = new Point(i - box.Height, box.Top);
+ leftBottom = new Point(box.Left, box.Bottom + diff);
+
+ gp.AddLine(rightTop, rightBottom);
+ gp.AddLine(rightBottom, new Point(box.Left, box.Bottom));
+ gp.AddLine(new Point(box.Left, box.Bottom), leftBottom);
+ gp.AddLine(leftBottom, leftTop);
+ gp.AddLine(leftTop, rightTop);
+ } else if (theoreticalRightBottom.X >= box.Right) {
+ // right triangle
+ int diff = marqueeX - box.Height;
+ leftTop = new Point(box.Right, box.Top + diff); //= something funky
+ leftBottom = theoreticalLeftBottom;
+ rightBottom = new Point(box.Right, box.Bottom);
+ rightTop = rightBottom;
+
+ if (leftBottom.Equals(leftTop)) { continue; }
+
+ gp.AddLine(leftTop, rightBottom);
+ gp.AddLine(rightBottom, leftBottom);
+ gp.AddLine(leftBottom, leftTop);
+ } else if (theoreticalRightTop.X >= box.Right) {
+ // right pentagon
+ int diff = i - box.Right;
+ Point topRight = new Point(box.Right, box.Top);
+ rightTop = new Point(box.Right, box.Top + diff);
+ rightBottom = new Point(i - box.Height, box.Bottom);
+ leftTop = new Point(i - box.Height, box.Top);
+ leftBottom = new Point(i - (box.Height * 2), box.Bottom);
+
+ gp.AddLine(leftTop, topRight);
+ gp.AddLine(topRight, rightTop);
+ gp.AddLine(rightTop, rightBottom);
+ gp.AddLine(rightBottom, leftBottom);
+ gp.AddLine(leftBottom, leftTop);
+ } else {
+ // mid-range rectangle
+ rightTop = new Point(i, box.Top);
+ rightBottom = new Point(i - box.Height, box.Bottom);
+ leftTop = new Point(i - box.Height, box.Top);
+ leftBottom = new Point(i - (box.Height * 2), box.Bottom);
+
+ gp.AddLine(rightTop, rightBottom);
+ gp.AddLine(rightBottom, leftBottom);
+ gp.AddLine(leftBottom, leftTop);
+ gp.AddLine(leftTop, rightTop);
+ }
+ g.FillPath(new SolidBrush(color2), gp);
+ }
+
+ if (!leftTop.Equals(leftBottom)) {
+ g.DrawLine(penb, leftTop, leftBottom);
+ }
+ if (!rightTop.Equals(rightBottom)) {
+ g.DrawLine(penb, rightTop, rightBottom);
+ }
+ }
+ g.DrawLine(penb, new Point(box.Left, box.Bottom), new Point(box.Right, box.Bottom));
+
+ if (++marqueeX > (box.Height * 2) + StripeSpacing) {
+ marqueeX = 1;
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ if (box.Width <= 1) {
+ return;
+ }
+
+ if (isAnimated) {
+ AnimateFrame(box, g, ref marqueeX);
+ } else {
+ int x = 0;
+ AnimateFrame(box, g, ref x);
+ }
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/StyledBorderPainter.cs b/ProgressODoom/StyledBorderPainter.cs
new file mode 100644
index 0000000..a7b08bb
--- /dev/null
+++ b/ProgressODoom/StyledBorderPainter.cs
@@ -0,0 +1,66 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ ///
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.StyledBorderPainter), "Icons.StyledBorderPainter.ico")]
+ public class StyledBorderPainter : Component, IProgressBorderPainter, IDisposable {
+ private Border3DStyle border;
+
+ private EventHandler onPropertiesChanged;
+ ///
+ public event EventHandler PropertiesChanged {
+ add {
+ if (onPropertiesChanged != null) {
+ foreach (Delegate d in onPropertiesChanged.GetInvocationList()) {
+ if (object.ReferenceEquals(d, value)) { return; }
+ }
+ }
+ onPropertiesChanged = (EventHandler)Delegate.Combine(onPropertiesChanged, value);
+ }
+ remove { onPropertiesChanged = (EventHandler)Delegate.Remove(onPropertiesChanged, value); }
+ }
+
+ private void FireChange() {
+ if (onPropertiesChanged != null) { onPropertiesChanged(this, EventArgs.Empty); }
+ }
+
+ ///
+ public StyledBorderPainter() {
+ border = Border3DStyle.Raised;
+ }
+
+ ///
+ [Category("Appearance"), Description("Gets or sets the border style"), Browsable(true)]
+ public Border3DStyle Border3D {
+ get { return border; }
+ set { border = value; FireChange(); }
+ }
+
+ ///
+ [Browsable(false)]
+ public int BorderWidth {
+ get { return 2; }
+ }
+
+ ///
+ ///
+ ///
+ public void PaintBorder(Rectangle box, Graphics g) {
+ Rectangle brd = new Rectangle(box.X, box.Y, box.Width, box.Height + 1);
+ ControlPaint.DrawBorder3D(g, brd, border);
+ }
+
+ ///
+ public void Resize(Rectangle box) {
+ }
+
+ ///
+ protected override void Dispose(bool disposing) {
+ base.Dispose(disposing);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProgressODoom/WaveProgressPainter.cs b/ProgressODoom/WaveProgressPainter.cs
new file mode 100644
index 0000000..69504a0
--- /dev/null
+++ b/ProgressODoom/WaveProgressPainter.cs
@@ -0,0 +1,112 @@
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Windows.Forms;
+using System.Collections.Generic;
+
+namespace ProgressODoom {
+ [ToolboxBitmapAttribute(typeof(ProgressODoom.WaveProgressPainter), "Icons.WaveProgressPainter.ico")]
+ public class WaveProgressPainter : AbstractProgressPainter, IProgressPainter, IAnimatedProgressPainter, IDisposable {
+ private Color color1 = Color.FromArgb(110, 195, 248);
+ private Color color2 = Color.FromArgb(056, 150, 230);
+ private int marqueeSpeed = 10;
+ private int marqueeX = 0;
+ private int animateX = 0;
+ private bool isAnimated = false;
+
+ ///
+ public Color BaseColor {
+ get { return color1; }
+ set {
+ color1 = value;
+ FireChange();
+ }
+ }
+
+ ///
+ public Color WaveColor {
+ get { return color2; }
+ set {
+ color2 = value;
+ FireChange();
+ }
+ }
+
+ ///
+ public int AnimationSpeed {
+ get { return marqueeSpeed; }
+ set { marqueeSpeed = value; FireChange(); }
+ }
+
+ ///
+ public bool Animating {
+ get { return isAnimated; }
+ set { isAnimated = value; }
+ }
+
+ private void AnimateFrame(Rectangle box, Graphics g, ref int marqueeX) {
+ if (box == null || g == null || box.Width <= 1) { return; }
+
+ g.SmoothingMode = SmoothingMode.AntiAlias;
+ //g.Clip = new Region(box);
+
+ g.FillRectangle(new SolidBrush(color1), box);
+ int h = box.Height;
+ int hm = (int)((float)h / 2f);
+
+ using (GraphicsPath gp = new GraphicsPath()) {
+ Point MidLeft = new Point(0, hm);
+ Point MidRight = new Point(h * 2, hm);
+
+ int currentX = box.Right + animateX; // Increment currentX to animate
+ int left = currentX - (h * 2);
+ if (left < box.Left) { left = box.Left; }
+ while (currentX > box.Left) {
+ left = currentX - (h * 2);
+
+ MidLeft = new Point(left, hm);
+ MidRight = new Point(currentX, hm);
+
+ int crestX = currentX - h;
+ gp.AddBezier(MidRight, new Point(crestX, 0), new Point(crestX, h), MidLeft);
+ currentX -= h * 2;
+ }
+ gp.AddLine(MidLeft, new Point(box.Left, box.Bottom)); // left side
+ gp.AddLine(new Point(box.Left, box.Bottom), new Point(box.Right, box.Bottom)); // bottom
+ gp.AddLine(new Point(box.Right, box.Bottom), new Point(box.Right, hm)); // right side
+
+ g.FillPath(new SolidBrush(color2), gp);
+ }
+ g.SmoothingMode = SmoothingMode.Default;
+
+ if (isAnimated && ++animateX > (box.Height * 2)) {
+ animateX = 1;
+ }
+ }
+
+ ///
+ ///
+ ///
+ protected override void PaintThisProgress(Rectangle box, Graphics g) {
+ if (box.Width <= 1) {
+ return;
+ }
+
+ if (isAnimated) {
+ AnimateFrame(box, g, ref marqueeX);
+ } else {
+ int x = 0;
+ AnimateFrame(box, g, ref x);
+ }
+
+ if (gloss != null) {
+ gloss.PaintGloss(box, g);
+ }
+ }
+
+ ///
+ protected override void DisposeThis(bool disposing) {
+ }
+ }
+}
\ No newline at end of file
|