first commit
121
LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.csproj
Normal file
@@ -0,0 +1,121 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyTitle>Aga.Controls</AssemblyTitle>
|
||||
<Description>http://sourceforge.net/projects/treeviewadv/</Description>
|
||||
<Copyright>Copyright © Andrey Gliznetsov 2006 - 2009</Copyright>
|
||||
<AssemblyVersion>1.7.0.0</AssemblyVersion>
|
||||
<FileVersion>1.7.0.0</FileVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<OutputPath>..\bin\$(Configuration)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugType>full</DebugType>
|
||||
<DefineConstants>TRACE;DEBUG;PERF_TEST</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeIntegerTextBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeDecimalTextBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="NumericTextBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\ExpandingIcon.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\InteractiveControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.Draw.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.Editor.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.Input.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeNumericUpDown.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.Properties.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\BaseTextControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\EditableControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeComboBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeColumn.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\BindableControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeCheckBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeIcon.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodePlusMinus.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeTextBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\NodeControls\NodeStateIcon.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Tree\TreeViewAdv.Designer.cs">
|
||||
<DependentUpon>TreeViewAdv.cs</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Resources\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Update="Tree\TreeViewAdv.resx">
|
||||
<DependentUpon>TreeViewAdv.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Tree\ClassDiagram.cd" />
|
||||
<None Include="Tree\NodeControls\ClassDiagram.cd" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Tree\ColumnCollection.cs" />
|
||||
<Compile Remove="Tree\NativeMethods.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
20
LibreHardwareMonitor-0.9.4/Aga.Controls/Aga.Controls.sln
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aga.Controls", "Aga.Controls.csproj", "{E73BB233-D88B-44A7-A98F-D71EE158381D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E73BB233-D88B-44A7-A98F-D71EE158381D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E73BB233-D88B-44A7-A98F-D71EE158381D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E73BB233-D88B-44A7-A98F-D71EE158381D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E73BB233-D88B-44A7-A98F-D71EE158381D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
46
LibreHardwareMonitor-0.9.4/Aga.Controls/BitmapHelper.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
public static class BitmapHelper
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct PixelData
|
||||
{
|
||||
public byte B;
|
||||
public byte G;
|
||||
public byte R;
|
||||
public byte A;
|
||||
}
|
||||
|
||||
public static void SetAlphaChanelValue(Bitmap image, byte value)
|
||||
{
|
||||
if (image == null)
|
||||
throw new ArgumentNullException("image");
|
||||
if (image.PixelFormat != PixelFormat.Format32bppArgb)
|
||||
throw new ArgumentException("Wrong PixelFormat");
|
||||
|
||||
BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
|
||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
unsafe
|
||||
{
|
||||
PixelData* pPixel = (PixelData*)bitmapData.Scan0;
|
||||
for (int i = 0; i < bitmapData.Height; i++)
|
||||
{
|
||||
for (int j = 0; j < bitmapData.Width; j++)
|
||||
{
|
||||
pPixel->A = value;
|
||||
pPixel++;
|
||||
}
|
||||
pPixel += bitmapData.Stride - (bitmapData.Width * 4);
|
||||
}
|
||||
}
|
||||
image.UnlockBits(bitmapData);
|
||||
}
|
||||
}
|
||||
}
|
||||
864
LibreHardwareMonitor-0.9.4/Aga.Controls/GifDecoder.cs
Normal file
@@ -0,0 +1,864 @@
|
||||
#pragma warning disable 675 // Bitwise-or operator used on a sign-extended operand
|
||||
|
||||
#region Java Info
|
||||
/**
|
||||
* Class GifDecoder - Decodes a GIF file into one or more frames.
|
||||
* <br><pre>
|
||||
* Example:
|
||||
* GifDecoder d = new GifDecoder();
|
||||
* d.read("sample.gif");
|
||||
* int n = d.getFrameCount();
|
||||
* for (int i = 0; i < n; i++) {
|
||||
* BufferedImage frame = d.getFrame(i); // frame i
|
||||
* int t = d.getDelay(i); // display duration of frame in milliseconds
|
||||
* // do something with frame
|
||||
* }
|
||||
* </pre>
|
||||
* No copyright asserted on the source code of this class. May be used for
|
||||
* any purpose, however, refer to the Unisys LZW patent for any additional
|
||||
* restrictions. Please forward any corrections to kweiner@fmsware.com.
|
||||
*
|
||||
* @author Kevin Weiner, FM Software; LZW decoder adapted from John Cristy's ImageMagick.
|
||||
* @version 1.03 November 2003
|
||||
*
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
public class GifFrame
|
||||
{
|
||||
private Image _image;
|
||||
public Image Image
|
||||
{
|
||||
get { return _image; }
|
||||
}
|
||||
|
||||
private int _delay;
|
||||
public int Delay
|
||||
{
|
||||
get { return _delay; }
|
||||
}
|
||||
|
||||
public GifFrame(Image im, int del)
|
||||
{
|
||||
_image = im;
|
||||
_delay = del;
|
||||
}
|
||||
}
|
||||
|
||||
public class GifDecoder
|
||||
{
|
||||
public const int StatusOK = 0;//File read status: No errors.
|
||||
public const int StatusFormatError = 1; //File read status: Error decoding file (may be partially decoded)
|
||||
public const int StatusOpenError = 2; //Unable to open source.
|
||||
|
||||
private Stream inStream;
|
||||
private int status;
|
||||
|
||||
private int width; // full image width
|
||||
private int height; // full image height
|
||||
private bool gctFlag; // global color table used
|
||||
private int gctSize; // size of global color table
|
||||
private int loopCount = 1; // iterations; 0 = repeat forever
|
||||
|
||||
private int[] gct; // global color table
|
||||
private int[] lct; // local color table
|
||||
private int[] act; // active color table
|
||||
|
||||
private int bgIndex; // background color index
|
||||
private int bgColor; // background color
|
||||
private int lastBgColor; // previous bg color
|
||||
private int pixelAspect; // pixel aspect ratio
|
||||
|
||||
private bool lctFlag; // local color table flag
|
||||
private bool interlace; // interlace flag
|
||||
private int lctSize; // local color table size
|
||||
|
||||
private int ix, iy, iw, ih; // current image rectangle
|
||||
private Rectangle lastRect; // last image rect
|
||||
private Image image; // current frame
|
||||
private Bitmap bitmap;
|
||||
private Image lastImage; // previous frame
|
||||
|
||||
private byte[] block = new byte[256]; // current data block
|
||||
private int blockSize = 0; // block size
|
||||
|
||||
// last graphic control extension info
|
||||
private int dispose = 0;
|
||||
// 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
|
||||
private int lastDispose = 0;
|
||||
private bool transparency = false; // use transparent color
|
||||
private int delay = 0; // delay in milliseconds
|
||||
private int transIndex; // transparent color index
|
||||
|
||||
private const int MaxStackSize = 4096;
|
||||
// max decoder pixel stack size
|
||||
|
||||
// LZW decoder working arrays
|
||||
private short[] prefix;
|
||||
private byte[] suffix;
|
||||
private byte[] pixelStack;
|
||||
private byte[] pixels;
|
||||
|
||||
private ArrayList frames; // frames read from current file
|
||||
private int frameCount;
|
||||
private bool _makeTransparent;
|
||||
|
||||
/**
|
||||
* Gets the number of frames read from file.
|
||||
* @return frame count
|
||||
*/
|
||||
public int FrameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return frameCount;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first (or only) image read.
|
||||
*
|
||||
* @return BufferedImage containing first frame, or null if none.
|
||||
*/
|
||||
public Image Image
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetFrame(0).Image;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "Netscape" iteration count, if any.
|
||||
* A count of 0 means repeat indefinitiely.
|
||||
*
|
||||
* @return iteration count if one was specified, else 1.
|
||||
*/
|
||||
public int LoopCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return loopCount;
|
||||
}
|
||||
}
|
||||
|
||||
public GifDecoder(Stream stream, bool makeTransparent)
|
||||
{
|
||||
_makeTransparent = makeTransparent;
|
||||
if (Read(stream) != 0)
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new frame image from current data (and previous
|
||||
* frames as specified by their disposition codes).
|
||||
*/
|
||||
private int[] GetPixels(Bitmap bitmap)
|
||||
{
|
||||
int [] pixels = new int [ 3 * image.Width * image.Height ];
|
||||
int count = 0;
|
||||
for (int th = 0; th < image.Height; th++)
|
||||
{
|
||||
for (int tw = 0; tw < image.Width; tw++)
|
||||
{
|
||||
Color color = bitmap.GetPixel(tw, th);
|
||||
pixels[count] = color.R;
|
||||
count++;
|
||||
pixels[count] = color.G;
|
||||
count++;
|
||||
pixels[count] = color.B;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
private void SetPixels(int[] pixels)
|
||||
{
|
||||
int count = 0;
|
||||
for (int th = 0; th < image.Height; th++)
|
||||
{
|
||||
for (int tw = 0; tw < image.Width; tw++)
|
||||
{
|
||||
Color color = Color.FromArgb( pixels[count++] );
|
||||
bitmap.SetPixel( tw, th, color );
|
||||
}
|
||||
}
|
||||
if (_makeTransparent)
|
||||
bitmap.MakeTransparent(bitmap.GetPixel(0, 0));
|
||||
}
|
||||
|
||||
private void SetPixels()
|
||||
{
|
||||
// expose destination image's pixels as int array
|
||||
// int[] dest =
|
||||
// (( int ) image.getRaster().getDataBuffer()).getData();
|
||||
int[] dest = GetPixels( bitmap );
|
||||
|
||||
// fill in starting image contents based on last image's dispose code
|
||||
if (lastDispose > 0)
|
||||
{
|
||||
if (lastDispose == 3)
|
||||
{
|
||||
// use image before last
|
||||
int n = frameCount - 2;
|
||||
if (n > 0)
|
||||
{
|
||||
lastImage = GetFrame(n - 1).Image;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastImage = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastImage != null)
|
||||
{
|
||||
// int[] prev =
|
||||
// ((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData();
|
||||
int[] prev = GetPixels( new Bitmap( lastImage ) );
|
||||
Array.Copy(prev, 0, dest, 0, width * height);
|
||||
// copy pixels
|
||||
|
||||
if (lastDispose == 2)
|
||||
{
|
||||
// fill last image rect area with background color
|
||||
Graphics g = Graphics.FromImage( image );
|
||||
Color c = Color.Empty;
|
||||
if (transparency)
|
||||
{
|
||||
c = Color.FromArgb( 0, 0, 0, 0 ); // assume background is transparent
|
||||
}
|
||||
else
|
||||
{
|
||||
c = Color.FromArgb( lastBgColor ) ;
|
||||
// c = new Color(lastBgColor); // use given background color
|
||||
}
|
||||
Brush brush = new SolidBrush( c );
|
||||
g.FillRectangle( brush, lastRect );
|
||||
brush.Dispose();
|
||||
g.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy each source line to the appropriate place in the destination
|
||||
int pass = 1;
|
||||
int inc = 8;
|
||||
int iline = 0;
|
||||
for (int i = 0; i < ih; i++)
|
||||
{
|
||||
int line = i;
|
||||
if (interlace)
|
||||
{
|
||||
if (iline >= ih)
|
||||
{
|
||||
pass++;
|
||||
switch (pass)
|
||||
{
|
||||
case 2 :
|
||||
iline = 4;
|
||||
break;
|
||||
case 3 :
|
||||
iline = 2;
|
||||
inc = 4;
|
||||
break;
|
||||
case 4 :
|
||||
iline = 1;
|
||||
inc = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = iline;
|
||||
iline += inc;
|
||||
}
|
||||
line += iy;
|
||||
if (line < height)
|
||||
{
|
||||
int k = line * width;
|
||||
int dx = k + ix; // start of line in dest
|
||||
int dlim = dx + iw; // end of dest line
|
||||
if ((k + width) < dlim)
|
||||
{
|
||||
dlim = k + width; // past dest edge
|
||||
}
|
||||
int sx = i * iw; // start of line in source
|
||||
while (dx < dlim)
|
||||
{
|
||||
// map color and insert in destination
|
||||
int index = ((int) pixels[sx++]) & 0xff;
|
||||
int c = act[index];
|
||||
if (c != 0)
|
||||
{
|
||||
dest[dx] = c;
|
||||
}
|
||||
dx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
SetPixels( dest );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image contents of frame n.
|
||||
*
|
||||
* @return BufferedImage representation of frame.
|
||||
*/
|
||||
public GifFrame GetFrame(int n)
|
||||
{
|
||||
if ((n >= 0) && (n < frameCount))
|
||||
return (GifFrame)frames[n];
|
||||
else
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets image size.
|
||||
*
|
||||
* @return GIF image dimensions
|
||||
*/
|
||||
public Size FrameSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Size(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads GIF image from stream
|
||||
*
|
||||
* @param BufferedInputStream containing GIF file.
|
||||
* @return read status code (0 = no errors)
|
||||
*/
|
||||
private int Read( Stream inStream )
|
||||
{
|
||||
Init();
|
||||
if ( inStream != null)
|
||||
{
|
||||
this.inStream = inStream;
|
||||
ReadHeader();
|
||||
if (!Error())
|
||||
{
|
||||
ReadContents();
|
||||
if (frameCount < 0)
|
||||
{
|
||||
status = StatusFormatError;
|
||||
}
|
||||
}
|
||||
inStream.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = StatusOpenError;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes LZW image data into pixel array.
|
||||
* Adapted from John Cristy's ImageMagick.
|
||||
*/
|
||||
private void DecodeImageData()
|
||||
{
|
||||
int NullCode = -1;
|
||||
int npix = iw * ih;
|
||||
int available,
|
||||
clear,
|
||||
code_mask,
|
||||
code_size,
|
||||
end_of_information,
|
||||
in_code,
|
||||
old_code,
|
||||
bits,
|
||||
code,
|
||||
count,
|
||||
i,
|
||||
datum,
|
||||
data_size,
|
||||
first,
|
||||
top,
|
||||
bi,
|
||||
pi;
|
||||
|
||||
if ((pixels == null) || (pixels.Length < npix))
|
||||
{
|
||||
pixels = new byte[npix]; // allocate new pixel array
|
||||
}
|
||||
if (prefix == null) prefix = new short[MaxStackSize];
|
||||
if (suffix == null) suffix = new byte[MaxStackSize];
|
||||
if (pixelStack == null) pixelStack = new byte[MaxStackSize + 1];
|
||||
|
||||
// Initialize GIF data stream decoder.
|
||||
|
||||
data_size = Read();
|
||||
clear = 1 << data_size;
|
||||
end_of_information = clear + 1;
|
||||
available = clear + 2;
|
||||
old_code = NullCode;
|
||||
code_size = data_size + 1;
|
||||
code_mask = (1 << code_size) - 1;
|
||||
for (code = 0; code < clear; code++)
|
||||
{
|
||||
prefix[code] = 0;
|
||||
suffix[code] = (byte) code;
|
||||
}
|
||||
|
||||
// Decode GIF pixel stream.
|
||||
|
||||
datum = bits = count = first = top = pi = bi = 0;
|
||||
|
||||
for (i = 0; i < npix;)
|
||||
{
|
||||
if (top == 0)
|
||||
{
|
||||
if (bits < code_size)
|
||||
{
|
||||
// Load bytes until there are enough bits for a code.
|
||||
if (count == 0)
|
||||
{
|
||||
// Read a new data block.
|
||||
count = ReadBlock();
|
||||
if (count <= 0)
|
||||
break;
|
||||
bi = 0;
|
||||
}
|
||||
datum += (((int) block[bi]) & 0xff) << bits;
|
||||
bits += 8;
|
||||
bi++;
|
||||
count--;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the next code.
|
||||
|
||||
code = datum & code_mask;
|
||||
datum >>= code_size;
|
||||
bits -= code_size;
|
||||
|
||||
// Interpret the code
|
||||
|
||||
if ((code > available) || (code == end_of_information))
|
||||
break;
|
||||
if (code == clear)
|
||||
{
|
||||
// Reset decoder.
|
||||
code_size = data_size + 1;
|
||||
code_mask = (1 << code_size) - 1;
|
||||
available = clear + 2;
|
||||
old_code = NullCode;
|
||||
continue;
|
||||
}
|
||||
if (old_code == NullCode)
|
||||
{
|
||||
pixelStack[top++] = suffix[code];
|
||||
old_code = code;
|
||||
first = code;
|
||||
continue;
|
||||
}
|
||||
in_code = code;
|
||||
if (code == available)
|
||||
{
|
||||
pixelStack[top++] = (byte) first;
|
||||
code = old_code;
|
||||
}
|
||||
while (code > clear)
|
||||
{
|
||||
pixelStack[top++] = suffix[code];
|
||||
code = prefix[code];
|
||||
}
|
||||
first = ((int) suffix[code]) & 0xff;
|
||||
|
||||
// Add a new string to the string table,
|
||||
|
||||
if (available >= MaxStackSize)
|
||||
break;
|
||||
pixelStack[top++] = (byte) first;
|
||||
prefix[available] = (short) old_code;
|
||||
suffix[available] = (byte) first;
|
||||
available++;
|
||||
if (((available & code_mask) == 0)
|
||||
&& (available < MaxStackSize))
|
||||
{
|
||||
code_size++;
|
||||
code_mask += available;
|
||||
}
|
||||
old_code = in_code;
|
||||
}
|
||||
|
||||
// Pop a pixel off the pixel stack.
|
||||
|
||||
top--;
|
||||
pixels[pi++] = pixelStack[top];
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = pi; i < npix; i++)
|
||||
{
|
||||
pixels[i] = 0; // clear missing pixels
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an error was encountered during reading/decoding
|
||||
*/
|
||||
private bool Error()
|
||||
{
|
||||
return status != StatusOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes or re-initializes reader
|
||||
*/
|
||||
private void Init()
|
||||
{
|
||||
status = StatusOK;
|
||||
frameCount = 0;
|
||||
frames = new ArrayList();
|
||||
gct = null;
|
||||
lct = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single byte from the input stream.
|
||||
*/
|
||||
private int Read()
|
||||
{
|
||||
int curByte = 0;
|
||||
try
|
||||
{
|
||||
curByte = inStream.ReadByte();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
status = StatusFormatError;
|
||||
}
|
||||
return curByte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads next variable length block from input.
|
||||
*
|
||||
* @return number of bytes stored in "buffer"
|
||||
*/
|
||||
private int ReadBlock()
|
||||
{
|
||||
blockSize = Read();
|
||||
int n = 0;
|
||||
if (blockSize > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
int count = 0;
|
||||
while (n < blockSize)
|
||||
{
|
||||
count = inStream.Read(block, n, blockSize - n);
|
||||
if (count == -1)
|
||||
break;
|
||||
n += count;
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
|
||||
if (n < blockSize)
|
||||
{
|
||||
status = StatusFormatError;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads color table as 256 RGB integer values
|
||||
*
|
||||
* @param ncolors int number of colors to read
|
||||
* @return int array containing 256 colors (packed ARGB with full alpha)
|
||||
*/
|
||||
private int[] ReadColorTable(int ncolors)
|
||||
{
|
||||
int nbytes = 3 * ncolors;
|
||||
int[] tab = null;
|
||||
byte[] c = new byte[nbytes];
|
||||
int n = 0;
|
||||
try
|
||||
{
|
||||
n = inStream.Read(c, 0, c.Length );
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
if (n < nbytes)
|
||||
{
|
||||
status = StatusFormatError;
|
||||
}
|
||||
else
|
||||
{
|
||||
tab = new int[256]; // max size to avoid bounds checks
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
while (i < ncolors)
|
||||
{
|
||||
int r = ((int) c[j++]) & 0xff;
|
||||
int g = ((int) c[j++]) & 0xff;
|
||||
int b = ((int) c[j++]) & 0xff;
|
||||
tab[i++] = ( int ) ( 0xff000000 | (r << 16) | (g << 8) | b );
|
||||
}
|
||||
}
|
||||
return tab;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main file parser. Reads GIF content blocks.
|
||||
*/
|
||||
private void ReadContents()
|
||||
{
|
||||
// read GIF file content blocks
|
||||
bool done = false;
|
||||
while (!(done || Error()))
|
||||
{
|
||||
int code = Read();
|
||||
switch (code)
|
||||
{
|
||||
|
||||
case 0x2C : // image separator
|
||||
ReadImage();
|
||||
break;
|
||||
|
||||
case 0x21 : // extension
|
||||
code = Read();
|
||||
switch (code)
|
||||
{
|
||||
case 0xf9 : // graphics control extension
|
||||
ReadGraphicControlExt();
|
||||
break;
|
||||
|
||||
case 0xff : // application extension
|
||||
ReadBlock();
|
||||
String app = "";
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
app += (char) block[i];
|
||||
}
|
||||
if (app.Equals("NETSCAPE2.0"))
|
||||
{
|
||||
ReadNetscapeExt();
|
||||
}
|
||||
else
|
||||
Skip(); // don't care
|
||||
break;
|
||||
|
||||
default : // uninteresting extension
|
||||
Skip();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3b : // terminator
|
||||
done = true;
|
||||
break;
|
||||
|
||||
case 0x00 : // bad byte, but keep going and see what happens
|
||||
break;
|
||||
|
||||
default :
|
||||
status = StatusFormatError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Graphics Control Extension values
|
||||
*/
|
||||
private void ReadGraphicControlExt()
|
||||
{
|
||||
Read(); // block size
|
||||
int packed = Read(); // packed fields
|
||||
dispose = (packed & 0x1c) >> 2; // disposal method
|
||||
if (dispose == 0)
|
||||
{
|
||||
dispose = 1; // elect to keep old image if discretionary
|
||||
}
|
||||
transparency = (packed & 1) != 0;
|
||||
delay = ReadShort() * 10; // delay in milliseconds
|
||||
transIndex = Read(); // transparent color index
|
||||
Read(); // block terminator
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads GIF file header information.
|
||||
*/
|
||||
private void ReadHeader()
|
||||
{
|
||||
String id = "";
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
id += (char) Read();
|
||||
}
|
||||
if (!id.StartsWith("GIF"))
|
||||
{
|
||||
status = StatusFormatError;
|
||||
return;
|
||||
}
|
||||
|
||||
ReadLSD();
|
||||
if (gctFlag && !Error())
|
||||
{
|
||||
gct = ReadColorTable(gctSize);
|
||||
bgColor = gct[bgIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads next frame image
|
||||
*/
|
||||
private void ReadImage()
|
||||
{
|
||||
ix = ReadShort(); // (sub)image position & size
|
||||
iy = ReadShort();
|
||||
iw = ReadShort();
|
||||
ih = ReadShort();
|
||||
|
||||
int packed = Read();
|
||||
lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
|
||||
interlace = (packed & 0x40) != 0; // 2 - interlace flag
|
||||
// 3 - sort flag
|
||||
// 4-5 - reserved
|
||||
lctSize = 2 << (packed & 7); // 6-8 - local color table size
|
||||
|
||||
if (lctFlag)
|
||||
{
|
||||
lct = ReadColorTable(lctSize); // read table
|
||||
act = lct; // make local table active
|
||||
}
|
||||
else
|
||||
{
|
||||
act = gct; // make global table active
|
||||
if (bgIndex == transIndex)
|
||||
bgColor = 0;
|
||||
}
|
||||
int save = 0;
|
||||
if (transparency)
|
||||
{
|
||||
save = act[transIndex];
|
||||
act[transIndex] = 0; // set transparent color if specified
|
||||
}
|
||||
|
||||
if (act == null)
|
||||
{
|
||||
status = StatusFormatError; // no color table defined
|
||||
}
|
||||
|
||||
if (Error()) return;
|
||||
|
||||
DecodeImageData(); // decode pixel data
|
||||
Skip();
|
||||
|
||||
if (Error()) return;
|
||||
|
||||
frameCount++;
|
||||
|
||||
// create new image to receive frame data
|
||||
// image =
|
||||
// new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
|
||||
|
||||
bitmap = new Bitmap( width, height );
|
||||
image = bitmap;
|
||||
SetPixels(); // transfer pixel data to image
|
||||
|
||||
frames.Add(new GifFrame(bitmap, delay)); // add image to frame list
|
||||
|
||||
if (transparency)
|
||||
{
|
||||
act[transIndex] = save;
|
||||
}
|
||||
ResetFrame();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Logical Screen Descriptor
|
||||
*/
|
||||
private void ReadLSD()
|
||||
{
|
||||
|
||||
// logical screen size
|
||||
width = ReadShort();
|
||||
height = ReadShort();
|
||||
|
||||
// packed fields
|
||||
int packed = Read();
|
||||
gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
|
||||
// 2-4 : color resolution
|
||||
// 5 : gct sort flag
|
||||
gctSize = 2 << (packed & 7); // 6-8 : gct size
|
||||
|
||||
bgIndex = Read(); // background color index
|
||||
pixelAspect = Read(); // pixel aspect ratio
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads Netscape extenstion to obtain iteration count
|
||||
*/
|
||||
private void ReadNetscapeExt()
|
||||
{
|
||||
do
|
||||
{
|
||||
ReadBlock();
|
||||
if (block[0] == 1)
|
||||
{
|
||||
// loop count sub-block
|
||||
int b1 = ((int) block[1]) & 0xff;
|
||||
int b2 = ((int) block[2]) & 0xff;
|
||||
loopCount = (b2 << 8) | b1;
|
||||
}
|
||||
} while ((blockSize > 0) && !Error());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads next 16-bit value, LSB first
|
||||
*/
|
||||
private int ReadShort()
|
||||
{
|
||||
// read 16-bit value, LSB first
|
||||
return Read() | (Read() << 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets frame state for reading next image.
|
||||
*/
|
||||
private void ResetFrame()
|
||||
{
|
||||
lastDispose = dispose;
|
||||
lastRect = new Rectangle(ix, iy, iw, ih);
|
||||
lastImage = image;
|
||||
lastBgColor = bgColor;
|
||||
// int dispose = 0;
|
||||
lct = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips variable length blocks up to and including
|
||||
* next zero length block.
|
||||
*/
|
||||
private void Skip()
|
||||
{
|
||||
do
|
||||
{
|
||||
ReadBlock();
|
||||
} while ((blockSize > 0) && !Error());
|
||||
}
|
||||
}
|
||||
}
|
||||
189
LibreHardwareMonitor-0.9.4/Aga.Controls/NumericTextBox.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Restricts the entry of characters to digits, the negative sign,
|
||||
/// the decimal point, and editing keystrokes (backspace).
|
||||
/// It does not handle the AltGr key so any keys that can be created in any
|
||||
/// combination with AltGr these are not filtered
|
||||
/// </summary>
|
||||
public class NumericTextBox : TextBox
|
||||
{
|
||||
private const int WM_PASTE = 0x302;
|
||||
private NumberStyles numberStyle = NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign;
|
||||
|
||||
/// <summary>
|
||||
/// Restricts the entry of characters to digits, the negative sign,
|
||||
/// the decimal point, and editing keystrokes (backspace).
|
||||
/// It does not handle the AltGr key
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
||||
{
|
||||
base.OnKeyPress(e);
|
||||
|
||||
e.Handled = invalidNumeric(e.KeyChar);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Main method for verifying allowed keypresses.
|
||||
/// This does not catch cut paste copy ... operations.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
private bool invalidNumeric(char key)
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
|
||||
string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
|
||||
string negativeSign = numberFormatInfo.NegativeSign;
|
||||
|
||||
string keyString = key.ToString();
|
||||
|
||||
if (Char.IsDigit(key))
|
||||
{
|
||||
// Digits are OK
|
||||
}
|
||||
else if (AllowDecimalSeparator && keyString.Equals(decimalSeparator))
|
||||
{
|
||||
if (Text.IndexOf(decimalSeparator) >= 0)
|
||||
{
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if (AllowNegativeSign && keyString.Equals(negativeSign))
|
||||
{
|
||||
if (Text.IndexOf(negativeSign) >= 0)
|
||||
{
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else if (key == '\b')
|
||||
{
|
||||
// Backspace key is OK
|
||||
}
|
||||
else if ((ModifierKeys & (Keys.Control)) != 0)
|
||||
{
|
||||
// Let the edit control handle control and alt key combinations
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swallow this invalid key and beep
|
||||
handled = true;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Method invoked when Windows sends a message.
|
||||
/// </summary>
|
||||
/// <param name="m">Message from Windows.</param>
|
||||
/// <remarks>
|
||||
/// This is over-ridden so that the user can not use
|
||||
/// cut or paste operations to bypass the TextChanging event.
|
||||
/// This catches ContextMenu Paste, Shift+Insert, Ctrl+V,
|
||||
/// While it is generally frowned upon to override WndProc, no
|
||||
/// other simple mechanism was apparent to simultaneously and
|
||||
/// transparently intercept so many different operations.
|
||||
/// </remarks>
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
// Switch to handle message...
|
||||
switch (m.Msg)
|
||||
{
|
||||
case WM_PASTE:
|
||||
{
|
||||
// Get clipboard object to paste
|
||||
IDataObject clipboardData = Clipboard.GetDataObject();
|
||||
|
||||
// Get text from clipboard data
|
||||
string pasteText = (string)clipboardData.GetData(
|
||||
DataFormats.UnicodeText);
|
||||
|
||||
// Get the number of characters to replace
|
||||
int selectionLength = SelectionLength;
|
||||
|
||||
// If no replacement or insertion, we are done
|
||||
if (pasteText.Length == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (selectionLength != 0)
|
||||
{
|
||||
base.Text = base.Text.Remove(SelectionStart, selectionLength);
|
||||
}
|
||||
|
||||
bool containsInvalidChars = false;
|
||||
foreach (char c in pasteText)
|
||||
{
|
||||
if (containsInvalidChars)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (invalidNumeric(c))
|
||||
{
|
||||
containsInvalidChars = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!containsInvalidChars)
|
||||
{
|
||||
base.Text = base.Text.Insert(SelectionStart, pasteText);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
|
||||
public int IntValue
|
||||
{
|
||||
get
|
||||
{
|
||||
int intValue;
|
||||
Int32.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out intValue);
|
||||
return intValue;
|
||||
}
|
||||
}
|
||||
|
||||
public decimal DecimalValue
|
||||
{
|
||||
get
|
||||
{
|
||||
decimal decimalValue;
|
||||
Decimal.TryParse(this.Text, numberStyle, CultureInfo.CurrentCulture.NumberFormat, out decimalValue);
|
||||
return decimalValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool allowNegativeSign;
|
||||
[DefaultValue(true)]
|
||||
public bool AllowNegativeSign
|
||||
{
|
||||
get { return allowNegativeSign; }
|
||||
set { allowNegativeSign = value; }
|
||||
}
|
||||
|
||||
private bool allowDecimalSeparator;
|
||||
[DefaultValue(true)]
|
||||
public bool AllowDecimalSeparator
|
||||
{
|
||||
get { return allowDecimalSeparator; }
|
||||
set { allowDecimalSeparator = value; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
136
LibreHardwareMonitor-0.9.4/Aga.Controls/PerformanceAnalyzer.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Is used to analyze code performance
|
||||
/// </summary>
|
||||
public static class PerformanceAnalyzer
|
||||
{
|
||||
public class PerformanceInfo
|
||||
{
|
||||
private string _name;
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
private int _count = 0;
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
set { _count = value; }
|
||||
}
|
||||
|
||||
private double _totalTime = 0;
|
||||
public double TotalTime
|
||||
{
|
||||
get { return _totalTime; }
|
||||
set { _totalTime = value; }
|
||||
}
|
||||
|
||||
private Int64 _start;
|
||||
public Int64 Start
|
||||
{
|
||||
get { return _start; }
|
||||
set { _start = value; }
|
||||
}
|
||||
|
||||
public PerformanceInfo(string name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, PerformanceInfo> _performances = new Dictionary<string, PerformanceInfo>();
|
||||
|
||||
public static IEnumerable<PerformanceInfo> Performances
|
||||
{
|
||||
get
|
||||
{
|
||||
return _performances.Values;
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void Start(string pieceOfCode)
|
||||
{
|
||||
PerformanceInfo info = null;
|
||||
lock(_performances)
|
||||
{
|
||||
if (_performances.ContainsKey(pieceOfCode))
|
||||
info = _performances[pieceOfCode];
|
||||
else
|
||||
{
|
||||
info = new PerformanceInfo(pieceOfCode);
|
||||
_performances.Add(pieceOfCode, info);
|
||||
}
|
||||
|
||||
info.Count++;
|
||||
info.Start = TimeCounter.GetStartValue();
|
||||
}
|
||||
}
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void Finish(string pieceOfCode)
|
||||
{
|
||||
lock (_performances)
|
||||
{
|
||||
if (_performances.ContainsKey(pieceOfCode))
|
||||
{
|
||||
PerformanceInfo info = _performances[pieceOfCode];
|
||||
info.Count++;
|
||||
info.TotalTime += TimeCounter.Finish(info.Start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
_performances.Clear();
|
||||
}
|
||||
|
||||
public static string GenerateReport()
|
||||
{
|
||||
return GenerateReport(0);
|
||||
}
|
||||
|
||||
public static string GenerateReport(string mainPieceOfCode)
|
||||
{
|
||||
if (_performances.ContainsKey(mainPieceOfCode))
|
||||
return GenerateReport(_performances[mainPieceOfCode].TotalTime);
|
||||
else
|
||||
return GenerateReport(0);
|
||||
}
|
||||
|
||||
public static string GenerateReport(double totalTime)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int len = 0;
|
||||
foreach (PerformanceInfo info in Performances)
|
||||
len = Math.Max(info.Name.Length, len);
|
||||
|
||||
sb.AppendLine("Name".PadRight(len) + " Count Total Time, ms Avg. Time, ms Percentage, %");
|
||||
sb.AppendLine("----------------------------------------------------------------------------------------------");
|
||||
foreach (PerformanceInfo info in Performances)
|
||||
{
|
||||
sb.Append(info.Name.PadRight(len));
|
||||
double p = 0;
|
||||
double avgt = 0;
|
||||
if (totalTime != 0)
|
||||
p = info.TotalTime / totalTime;
|
||||
if (info.Count > 0)
|
||||
avgt = info.TotalTime * 1000 / info.Count;
|
||||
string c = info.Count.ToString("0,0").PadRight(20);
|
||||
string tt = (info.TotalTime * 1000).ToString("0,0.00").PadRight(20);
|
||||
string t = avgt.ToString("0.0000").PadRight(20);
|
||||
string sp = (p * 100).ToString("###").PadRight(20);
|
||||
sb.AppendFormat(" " + c + tt + t + sp + "\n");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
133
LibreHardwareMonitor-0.9.4/Aga.Controls/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,133 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.235
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Aga.Controls.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Aga.Controls.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap check {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("check", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static byte[] DVSplit {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("DVSplit", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap Folder {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Folder", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap FolderClosed {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("FolderClosed", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap Leaf {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Leaf", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static byte[] loading_icon {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("loading_icon", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap minus {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("minus", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap plus {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("plus", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap uncheck {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("uncheck", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
internal static System.Drawing.Bitmap unknown {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("unknown", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="check" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\check.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="DVSplit" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\DVSplit.cur;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="Folder" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Folder.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="FolderClosed" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\FolderClosed.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Leaf" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Leaf.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="loading_icon" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\loading_icon;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="minus" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\minus.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="plus" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\plus.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="uncheck" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\uncheck.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="unknown" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\unknown.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
48
LibreHardwareMonitor-0.9.4/Aga.Controls/ResourceHelper.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
public static class ResourceHelper
|
||||
{
|
||||
// VSpilt Cursor with Innerline (symbolisize hidden column)
|
||||
private static Cursor _dVSplitCursor = GetCursor(Properties.Resources.DVSplit);
|
||||
public static Cursor DVSplitCursor
|
||||
{
|
||||
get { return _dVSplitCursor; }
|
||||
}
|
||||
|
||||
private static GifDecoder _loadingIcon = GetGifDecoder(Properties.Resources.loading_icon);
|
||||
public static GifDecoder LoadingIcon
|
||||
{
|
||||
get { return _loadingIcon; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Help function to convert byte[] from resource into Cursor Type
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
private static Cursor GetCursor(byte[] data)
|
||||
{
|
||||
using (MemoryStream s = new MemoryStream(data))
|
||||
return new Cursor(s);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Help function to convert byte[] from resource into GifDecoder Type
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
private static GifDecoder GetGifDecoder(byte[] data)
|
||||
{
|
||||
using(MemoryStream ms = new MemoryStream(data))
|
||||
return new GifDecoder(ms, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/DVSplit.cur
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Folder.bmp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 822 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/Leaf.bmp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/check.bmp
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/loading_icon
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/minus.bmp
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/plus.bmp
Normal file
|
After Width: | Height: | Size: 306 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/uncheck.bmp
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
LibreHardwareMonitor-0.9.4/Aga.Controls/Resources/unknown.bmp
Normal file
|
After Width: | Height: | Size: 574 B |
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel.Design;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
public class StringCollectionEditor : CollectionEditor
|
||||
{
|
||||
public StringCollectionEditor(Type type): base(type)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Type CreateCollectionItemType()
|
||||
{
|
||||
return typeof(string);
|
||||
}
|
||||
|
||||
protected override object CreateInstance(Type itemType)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
45
LibreHardwareMonitor-0.9.4/Aga.Controls/TextHelper.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
public static class TextHelper
|
||||
{
|
||||
public static StringAlignment TranslateAligment(HorizontalAlignment alignment)
|
||||
{
|
||||
if (alignment == HorizontalAlignment.Left)
|
||||
return StringAlignment.Near;
|
||||
else if (alignment == HorizontalAlignment.Right)
|
||||
return StringAlignment.Far;
|
||||
else
|
||||
return StringAlignment.Center;
|
||||
}
|
||||
|
||||
public static TextFormatFlags TranslateAligmentToFlag(HorizontalAlignment alignment)
|
||||
{
|
||||
if (alignment == HorizontalAlignment.Left)
|
||||
return TextFormatFlags.Left;
|
||||
else if (alignment == HorizontalAlignment.Right)
|
||||
return TextFormatFlags.Right;
|
||||
else
|
||||
return TextFormatFlags.HorizontalCenter;
|
||||
}
|
||||
|
||||
public static TextFormatFlags TranslateTrimmingToFlag(StringTrimming trimming)
|
||||
{
|
||||
if (trimming == StringTrimming.EllipsisCharacter)
|
||||
return TextFormatFlags.EndEllipsis;
|
||||
else if (trimming == StringTrimming.EllipsisPath)
|
||||
return TextFormatFlags.PathEllipsis;
|
||||
if (trimming == StringTrimming.EllipsisWord)
|
||||
return TextFormatFlags.WordEllipsis;
|
||||
if (trimming == StringTrimming.Word)
|
||||
return TextFormatFlags.WordBreak;
|
||||
else
|
||||
return TextFormatFlags.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
// Stephen Toub
|
||||
// stoub@microsoft.com
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Aga.Controls.Threading
|
||||
{
|
||||
public class AbortableThreadPool
|
||||
{
|
||||
private LinkedList<WorkItem> _callbacks = new LinkedList<WorkItem>();
|
||||
private Dictionary<WorkItem, Thread> _threads = new Dictionary<WorkItem, Thread>();
|
||||
|
||||
public WorkItem QueueUserWorkItem(WaitCallback callback)
|
||||
{
|
||||
return QueueUserWorkItem(callback, null);
|
||||
}
|
||||
|
||||
public WorkItem QueueUserWorkItem(WaitCallback callback, object state)
|
||||
{
|
||||
if (callback == null) throw new ArgumentNullException("callback");
|
||||
|
||||
WorkItem item = new WorkItem(callback, state, ExecutionContext.Capture());
|
||||
lock (_callbacks)
|
||||
{
|
||||
_callbacks.AddLast(item);
|
||||
}
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleItem));
|
||||
return item;
|
||||
}
|
||||
|
||||
private void HandleItem(object ignored)
|
||||
{
|
||||
WorkItem item = null;
|
||||
try
|
||||
{
|
||||
lock (_callbacks)
|
||||
{
|
||||
if (_callbacks.Count > 0)
|
||||
{
|
||||
item = _callbacks.First.Value;
|
||||
_callbacks.RemoveFirst();
|
||||
}
|
||||
if (item == null)
|
||||
return;
|
||||
_threads.Add(item, Thread.CurrentThread);
|
||||
|
||||
}
|
||||
ExecutionContext.Run(item.Context,
|
||||
delegate { item.Callback(item.State); }, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock (_callbacks)
|
||||
{
|
||||
if (item != null)
|
||||
_threads.Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMyThread(Thread thread)
|
||||
{
|
||||
lock (_callbacks)
|
||||
{
|
||||
foreach (Thread t in _threads.Values)
|
||||
{
|
||||
if (t == thread)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public WorkItemStatus Cancel(WorkItem item, bool allowAbort)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
lock (_callbacks)
|
||||
{
|
||||
LinkedListNode<WorkItem> node = _callbacks.Find(item);
|
||||
if (node != null)
|
||||
{
|
||||
_callbacks.Remove(node);
|
||||
return WorkItemStatus.Queued;
|
||||
}
|
||||
else if (_threads.ContainsKey(item))
|
||||
{
|
||||
if (allowAbort)
|
||||
{
|
||||
_threads[item].Abort();
|
||||
_threads.Remove(item);
|
||||
return WorkItemStatus.Aborted;
|
||||
}
|
||||
else
|
||||
return WorkItemStatus.Executing;
|
||||
}
|
||||
else
|
||||
return WorkItemStatus.Completed;
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelAll(bool allowAbort)
|
||||
{
|
||||
lock (_callbacks)
|
||||
{
|
||||
_callbacks.Clear();
|
||||
if (allowAbort)
|
||||
{
|
||||
foreach (Thread t in _threads.Values)
|
||||
t.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Aga.Controls.Threading
|
||||
{
|
||||
public sealed class WorkItem
|
||||
{
|
||||
private WaitCallback _callback;
|
||||
private object _state;
|
||||
private ExecutionContext _ctx;
|
||||
|
||||
internal WorkItem(WaitCallback wc, object state, ExecutionContext ctx)
|
||||
{
|
||||
_callback = wc;
|
||||
_state = state;
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
internal WaitCallback Callback
|
||||
{
|
||||
get
|
||||
{
|
||||
return _callback;
|
||||
}
|
||||
}
|
||||
|
||||
internal object State
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
internal ExecutionContext Context
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ctx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Threading
|
||||
{
|
||||
public enum WorkItemStatus
|
||||
{
|
||||
Completed,
|
||||
Queued,
|
||||
Executing,
|
||||
Aborted
|
||||
}
|
||||
}
|
||||
59
LibreHardwareMonitor-0.9.4/Aga.Controls/TimeCounter.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Aga.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// High resolution timer, used to test performance
|
||||
/// </summary>
|
||||
public static class TimeCounter
|
||||
{
|
||||
private static Int64 _start;
|
||||
|
||||
/// <summary>
|
||||
/// Start time counting
|
||||
/// </summary>
|
||||
public static void Start()
|
||||
{
|
||||
_start = 0;
|
||||
QueryPerformanceCounter(ref _start);
|
||||
}
|
||||
|
||||
public static Int64 GetStartValue()
|
||||
{
|
||||
Int64 t = 0;
|
||||
QueryPerformanceCounter(ref t);
|
||||
return t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finish time counting
|
||||
/// </summary>
|
||||
/// <returns>time in seconds elapsed from Start till Finish </returns>
|
||||
public static double Finish()
|
||||
{
|
||||
return Finish(_start);
|
||||
}
|
||||
|
||||
public static double Finish(Int64 start)
|
||||
{
|
||||
Int64 finish = 0;
|
||||
QueryPerformanceCounter(ref finish);
|
||||
|
||||
Int64 freq = 0;
|
||||
QueryPerformanceFrequency(ref freq);
|
||||
return (finish - start) / (double)freq;
|
||||
}
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool QueryPerformanceCounter(ref Int64 performanceCount);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
static extern bool QueryPerformanceFrequency(ref Int64 frequency);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class AutoRowHeightLayout: IRowLayout
|
||||
{
|
||||
private DrawContext _measureContext;
|
||||
private TreeViewAdv _treeView;
|
||||
private List<Rectangle> _rowCache;
|
||||
|
||||
public AutoRowHeightLayout(TreeViewAdv treeView, int rowHeight)
|
||||
{
|
||||
_rowCache = new List<Rectangle>();
|
||||
_treeView = treeView;
|
||||
PreferredRowHeight = rowHeight;
|
||||
_measureContext = new DrawContext();
|
||||
_measureContext.Graphics = Graphics.FromImage(new Bitmap(1, 1));
|
||||
}
|
||||
|
||||
private int _rowHeight;
|
||||
public int PreferredRowHeight
|
||||
{
|
||||
get { return _rowHeight; }
|
||||
set { _rowHeight = value; }
|
||||
}
|
||||
|
||||
|
||||
public int PageRowCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_treeView.RowCount == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
|
||||
int y = 0;
|
||||
for (int i = _treeView.RowCount - 1; i >= 0; i--)
|
||||
{
|
||||
y += GetRowHeight(i);
|
||||
if (y > pageHeight)
|
||||
return Math.Max(0, _treeView.RowCount - 1 - i);
|
||||
}
|
||||
return _treeView.RowCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int CurrentPageSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_treeView.RowCount == 0)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
|
||||
int y = 0;
|
||||
for (int i = _treeView.FirstVisibleRow; i < _treeView.RowCount; i++)
|
||||
{
|
||||
y += GetRowHeight(i);
|
||||
if (y > pageHeight)
|
||||
return Math.Max(0, i - _treeView.FirstVisibleRow);
|
||||
}
|
||||
return Math.Max(0, _treeView.RowCount - _treeView.FirstVisibleRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle GetRowBounds(int rowNo)
|
||||
{
|
||||
if (rowNo >= _rowCache.Count)
|
||||
{
|
||||
int count = _rowCache.Count;
|
||||
int y = count > 0 ? _rowCache[count - 1].Bottom : 0;
|
||||
for (int i = count; i <= rowNo; i++)
|
||||
{
|
||||
int height = GetRowHeight(i);
|
||||
_rowCache.Add(new Rectangle(0, y, 0, height));
|
||||
y += height;
|
||||
}
|
||||
if (rowNo < _rowCache.Count - 1)
|
||||
return Rectangle.Empty;
|
||||
}
|
||||
if (rowNo >= 0 && rowNo < _rowCache.Count)
|
||||
return _rowCache[rowNo];
|
||||
else
|
||||
return Rectangle.Empty;
|
||||
}
|
||||
|
||||
private int GetRowHeight(int rowNo)
|
||||
{
|
||||
if (rowNo < _treeView.RowMap.Count)
|
||||
{
|
||||
TreeNodeAdv node = _treeView.RowMap[rowNo];
|
||||
if (node.Height == null)
|
||||
{
|
||||
int res = 0;
|
||||
_measureContext.Font = _treeView.Font;
|
||||
foreach (NodeControl nc in _treeView.NodeControls)
|
||||
{
|
||||
int h = nc.GetActualSize(node, _measureContext).Height;
|
||||
if (h > res)
|
||||
res = h;
|
||||
}
|
||||
node.Height = res;
|
||||
}
|
||||
return node.Height.Value;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int GetRowAt(Point point)
|
||||
{
|
||||
int py = point.Y - _treeView.ColumnHeaderHeight;
|
||||
int y = 0;
|
||||
for (int i = _treeView.FirstVisibleRow; i < _treeView.RowCount; i++)
|
||||
{
|
||||
int h = GetRowHeight(i);
|
||||
if (py >= y && py < y + h)
|
||||
return i;
|
||||
else
|
||||
y += h;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int GetFirstRow(int lastPageRow)
|
||||
{
|
||||
int pageHeight = _treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight;
|
||||
int y = 0;
|
||||
for (int i = lastPageRow; i >= 0; i--)
|
||||
{
|
||||
y += GetRowHeight(i);
|
||||
if (y > pageHeight)
|
||||
return Math.Max(0, i + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
_rowCache.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
84
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ClassDiagram.cd
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="FullSignature">
|
||||
<Font Name="Microsoft Sans Serif" Size="8.25" />
|
||||
<Class Name="Aga.Controls.Tree.TreeModel" BaseTypeListCollapsed="true">
|
||||
<Position X="0.5" Y="7" Width="3.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\TreeModel.cs</FileName>
|
||||
<HashCode>AAAkgAAAAAAQAGQAAAAAEAAAEAACQAAAUAAAAAAAAQE=</HashCode>
|
||||
</TypeIdentifier>
|
||||
<Members>
|
||||
<Field Name="_root" Hidden="true" />
|
||||
</Members>
|
||||
<Compartments>
|
||||
<Compartment Name="Fields" Collapsed="true" />
|
||||
</Compartments>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.TreePath">
|
||||
<Position X="4.5" Y="4.25" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\TreePath.cs</FileName>
|
||||
<HashCode>GABAAAAAAAACAAAAAAIAAAAAAAAACAAAAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
<Members>
|
||||
<Field Name="_path" Hidden="true" />
|
||||
<Field Name="Empty" Hidden="true" />
|
||||
<Method Name="TreePath" Hidden="true" />
|
||||
</Members>
|
||||
<Compartments>
|
||||
<Compartment Name="Fields" Collapsed="true" />
|
||||
</Compartments>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.Node">
|
||||
<Position X="4.75" Y="7" Width="2.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\Node.cs</FileName>
|
||||
<HashCode>AAAgABAAgCAAAAAAAgAEVAAQAAAQAAAIAAsgCAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
<Members>
|
||||
<Field Name="_checkState" Hidden="true" />
|
||||
<Field Name="_model" Hidden="true" />
|
||||
<Field Name="_nodes" Hidden="true" />
|
||||
<Field Name="_parent" Hidden="true" />
|
||||
<Field Name="_text" Hidden="true" />
|
||||
</Members>
|
||||
<Compartments>
|
||||
<Compartment Name="Fields" Collapsed="true" />
|
||||
</Compartments>
|
||||
<NestedTypes>
|
||||
<Class Name="Aga.Controls.Tree.Node.NodeCollection" Collapsed="true">
|
||||
<TypeIdentifier>
|
||||
<NewMemberFileName>Tree\Node.cs</NewMemberFileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
</NestedTypes>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeControl">
|
||||
<Position X="0.5" Y="0.5" Width="3.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeControl.cs</FileName>
|
||||
<HashCode>AAAAAAAAgAAAgsIAAAhAQAAwAAAAEAAAAEAIAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
<Members>
|
||||
<Field Name="_column" Hidden="true" />
|
||||
<Field Name="_parent" Hidden="true" />
|
||||
<Field Name="_toolTipProvider" Hidden="true" />
|
||||
<Method Name="AssignParent" Hidden="true" />
|
||||
</Members>
|
||||
</Class>
|
||||
<Interface Name="Aga.Controls.Tree.ITreeModel">
|
||||
<Position X="0.5" Y="4.25" Width="3.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\ITreeModel.cs</FileName>
|
||||
<HashCode>AAAEAAAAAAAAAEQAAAAAEAAAEAAAQAAAAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Interface Name="Aga.Controls.Tree.IToolTipProvider">
|
||||
<Position X="4.5" Y="0.5" Width="2.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\IToolTipProvider.cs</FileName>
|
||||
<HashCode>AAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
/*internal class ColumnCollection: Collection<Column>
|
||||
{
|
||||
public int TotalWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
int res = 0;
|
||||
foreach (Column c in Items)
|
||||
res += c.Width;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
60
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DrawContext.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public struct DrawContext
|
||||
{
|
||||
private Graphics _graphics;
|
||||
public Graphics Graphics
|
||||
{
|
||||
get { return _graphics; }
|
||||
set { _graphics = value; }
|
||||
}
|
||||
|
||||
private Rectangle _bounds;
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get { return _bounds; }
|
||||
set { _bounds = value; }
|
||||
}
|
||||
|
||||
private Font _font;
|
||||
public Font Font
|
||||
{
|
||||
get { return _font; }
|
||||
set { _font = value; }
|
||||
}
|
||||
|
||||
private DrawSelectionMode _drawSelection;
|
||||
public DrawSelectionMode DrawSelection
|
||||
{
|
||||
get { return _drawSelection; }
|
||||
set { _drawSelection = value; }
|
||||
}
|
||||
|
||||
private bool _drawFocus;
|
||||
public bool DrawFocus
|
||||
{
|
||||
get { return _drawFocus; }
|
||||
set { _drawFocus = value; }
|
||||
}
|
||||
|
||||
private NodeControl _currentEditorOwner;
|
||||
public NodeControl CurrentEditorOwner
|
||||
{
|
||||
get { return _currentEditorOwner; }
|
||||
set { _currentEditorOwner = value; }
|
||||
}
|
||||
|
||||
private bool _enabled;
|
||||
public bool Enabled
|
||||
{
|
||||
get { return _enabled; }
|
||||
set { _enabled = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class DropNodeValidatingEventArgs: EventArgs
|
||||
{
|
||||
Point _point;
|
||||
TreeNodeAdv _node;
|
||||
|
||||
public DropNodeValidatingEventArgs(Point point, TreeNodeAdv node)
|
||||
{
|
||||
_point = point;
|
||||
_node = node;
|
||||
}
|
||||
|
||||
public Point Point
|
||||
{
|
||||
get { return _point; }
|
||||
}
|
||||
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
set { _node = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
23
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/DropPosition.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public struct DropPosition
|
||||
{
|
||||
private TreeNodeAdv _node;
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
set { _node = value; }
|
||||
}
|
||||
|
||||
private NodePosition _position;
|
||||
public NodePosition Position
|
||||
{
|
||||
get { return _position; }
|
||||
set { _position = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public struct EditorContext
|
||||
{
|
||||
private TreeNodeAdv _currentNode;
|
||||
public TreeNodeAdv CurrentNode
|
||||
{
|
||||
get { return _currentNode; }
|
||||
set { _currentNode = value; }
|
||||
}
|
||||
|
||||
private Control _editor;
|
||||
public Control Editor
|
||||
{
|
||||
get { return _editor; }
|
||||
set { _editor = value; }
|
||||
}
|
||||
|
||||
private NodeControl _owner;
|
||||
public NodeControl Owner
|
||||
{
|
||||
get { return _owner; }
|
||||
set { _owner = value; }
|
||||
}
|
||||
|
||||
private Rectangle _bounds;
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get { return _bounds; }
|
||||
set { _bounds = value; }
|
||||
}
|
||||
|
||||
private DrawContext _drawContext;
|
||||
public DrawContext DrawContext
|
||||
{
|
||||
get { return _drawContext; }
|
||||
set { _drawContext = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
65
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Enums.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public enum DrawSelectionMode
|
||||
{
|
||||
None, Active, Inactive, FullRowSelect
|
||||
}
|
||||
|
||||
public enum TreeSelectionMode
|
||||
{
|
||||
Single, Multi, MultiSameParent
|
||||
}
|
||||
|
||||
public enum NodePosition
|
||||
{
|
||||
Inside, Before, After
|
||||
}
|
||||
|
||||
public enum VerticalAlignment
|
||||
{
|
||||
Top, Bottom, Center
|
||||
}
|
||||
|
||||
public enum IncrementalSearchMode
|
||||
{
|
||||
None, Standard, Continuous
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum GridLineStyle
|
||||
{
|
||||
None = 0,
|
||||
Horizontal = 1,
|
||||
Vertical = 2,
|
||||
HorizontalAndVertical = 3
|
||||
}
|
||||
|
||||
public enum ImageScaleMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Don't scale
|
||||
/// </summary>
|
||||
Clip,
|
||||
/// <summary>
|
||||
/// Scales image to fit the display rectangle, aspect ratio is not fixed.
|
||||
/// </summary>
|
||||
Fit,
|
||||
/// <summary>
|
||||
/// Scales image down if it is larger than display rectangle, taking aspect ratio into account
|
||||
/// </summary>
|
||||
ScaleDown,
|
||||
/// <summary>
|
||||
/// Scales image up if it is smaller than display rectangle, taking aspect ratio into account
|
||||
/// </summary>
|
||||
ScaleUp,
|
||||
/// <summary>
|
||||
/// Scales image to match the display rectangle, taking aspect ratio into account
|
||||
/// </summary>
|
||||
AlwaysScale,
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class FixedRowHeightLayout : IRowLayout
|
||||
{
|
||||
private TreeViewAdv _treeView;
|
||||
|
||||
public FixedRowHeightLayout(TreeViewAdv treeView, int rowHeight)
|
||||
{
|
||||
_treeView = treeView;
|
||||
PreferredRowHeight = rowHeight;
|
||||
}
|
||||
|
||||
private int _rowHeight;
|
||||
public int PreferredRowHeight
|
||||
{
|
||||
get { return _rowHeight; }
|
||||
set { _rowHeight = value; }
|
||||
}
|
||||
|
||||
public Rectangle GetRowBounds(int rowNo)
|
||||
{
|
||||
return new Rectangle(0, rowNo * _rowHeight, 0, _rowHeight);
|
||||
}
|
||||
|
||||
public int PageRowCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return Math.Max((_treeView.DisplayRectangle.Height - _treeView.ColumnHeaderHeight) / _rowHeight, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int CurrentPageSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return PageRowCount;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetRowAt(Point point)
|
||||
{
|
||||
point = new Point(point.X, point.Y + (_treeView.FirstVisibleRow * _rowHeight) - _treeView.ColumnHeaderHeight);
|
||||
return point.Y / _rowHeight;
|
||||
}
|
||||
|
||||
public int GetFirstRow(int lastPageRow)
|
||||
{
|
||||
return Math.Max(0, lastPageRow - PageRowCount + 1);
|
||||
}
|
||||
|
||||
public void ClearCache()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
34
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/IRowLayout.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal interface IRowLayout
|
||||
{
|
||||
int PreferredRowHeight
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
int PageRowCount
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
int CurrentPageSize
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
Rectangle GetRowBounds(int rowNo);
|
||||
|
||||
int GetRowAt(Point point);
|
||||
|
||||
int GetFirstRow(int lastPageRow);
|
||||
|
||||
void ClearCache();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public interface IToolTipProvider
|
||||
{
|
||||
string GetToolTip(TreeNodeAdv node, NodeControl nodeControl);
|
||||
}
|
||||
}
|
||||
18
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ITreeModel.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public interface ITreeModel
|
||||
{
|
||||
IEnumerable GetChildren(TreePath treePath);
|
||||
bool IsLeaf(TreePath treePath);
|
||||
|
||||
event EventHandler<TreeModelEventArgs> NodesChanged;
|
||||
event EventHandler<TreeModelEventArgs> NodesInserted;
|
||||
event EventHandler<TreeModelEventArgs> NodesRemoved;
|
||||
event EventHandler<TreePathEventArgs> StructureChanged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class IncrementalSearch
|
||||
{
|
||||
private const int SearchTimeout = 300; //end of incremental search timeot in msec
|
||||
|
||||
private TreeViewAdv _tree;
|
||||
private TreeNodeAdv _currentNode;
|
||||
private string _searchString = "";
|
||||
private DateTime _lastKeyPressed = DateTime.Now;
|
||||
|
||||
public IncrementalSearch(TreeViewAdv tree)
|
||||
{
|
||||
_tree = tree;
|
||||
}
|
||||
|
||||
public void Search(Char value)
|
||||
{
|
||||
if (!Char.IsControl(value))
|
||||
{
|
||||
Char ch = Char.ToLowerInvariant(value);
|
||||
DateTime dt = DateTime.Now;
|
||||
TimeSpan ts = dt - _lastKeyPressed;
|
||||
_lastKeyPressed = dt;
|
||||
if (ts.TotalMilliseconds < SearchTimeout)
|
||||
{
|
||||
if (_searchString == value.ToString())
|
||||
FirstCharSearch(ch);
|
||||
else
|
||||
ContinuousSearch(ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
FirstCharSearch(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ContinuousSearch(Char value)
|
||||
{
|
||||
if (value == ' ' && String.IsNullOrEmpty(_searchString))
|
||||
return; //Ingnore leading space
|
||||
|
||||
_searchString += value;
|
||||
DoContinuousSearch();
|
||||
}
|
||||
|
||||
private void FirstCharSearch(Char value)
|
||||
{
|
||||
if (value == ' ')
|
||||
return;
|
||||
|
||||
_searchString = value.ToString();
|
||||
TreeNodeAdv node = null;
|
||||
if (_tree.SelectedNode != null)
|
||||
node = _tree.SelectedNode.NextVisibleNode;
|
||||
if (node == null)
|
||||
node = _tree.Root.NextVisibleNode;
|
||||
|
||||
if (node != null)
|
||||
foreach (string label in IterateNodeLabels(node))
|
||||
{
|
||||
if (label.StartsWith(_searchString))
|
||||
{
|
||||
_tree.SelectedNode = _currentNode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void EndSearch()
|
||||
{
|
||||
_currentNode = null;
|
||||
_searchString = "";
|
||||
}
|
||||
|
||||
protected IEnumerable<string> IterateNodeLabels(TreeNodeAdv start)
|
||||
{
|
||||
_currentNode = start;
|
||||
while(_currentNode != null)
|
||||
{
|
||||
foreach (string label in GetNodeLabels(_currentNode))
|
||||
yield return label;
|
||||
|
||||
_currentNode = _currentNode.NextVisibleNode;
|
||||
if (_currentNode == null)
|
||||
_currentNode = _tree.Root;
|
||||
|
||||
if (start == _currentNode)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetNodeLabels(TreeNodeAdv node)
|
||||
{
|
||||
foreach (NodeControl nc in _tree.NodeControls)
|
||||
{
|
||||
BindableControl bc = nc as BindableControl;
|
||||
if (bc != null && bc.IncrementalSearchEnabled)
|
||||
{
|
||||
object obj = bc.GetValue(node);
|
||||
if (obj != null)
|
||||
yield return obj.ToString().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool DoContinuousSearch()
|
||||
{
|
||||
bool found = false;
|
||||
if (!String.IsNullOrEmpty(_searchString))
|
||||
{
|
||||
TreeNodeAdv node = null;
|
||||
if (_tree.SelectedNode != null)
|
||||
node = _tree.SelectedNode;
|
||||
if (node == null)
|
||||
node = _tree.Root.NextVisibleNode;
|
||||
|
||||
if (!String.IsNullOrEmpty(_searchString))
|
||||
{
|
||||
foreach (string label in IterateNodeLabels(node))
|
||||
{
|
||||
if (label.StartsWith(_searchString))
|
||||
{
|
||||
found = true;
|
||||
_tree.SelectedNode = _currentNode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class ClickColumnState : ColumnState
|
||||
{
|
||||
private Point _location;
|
||||
|
||||
public ClickColumnState(TreeViewAdv tree, TreeColumn column, Point location)
|
||||
: base(tree, column)
|
||||
{
|
||||
_location = location;
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool MouseMove(MouseEventArgs args)
|
||||
{
|
||||
if (TreeViewAdv.Dist(_location, args.Location) > TreeViewAdv.ItemDragSensivity
|
||||
&& Tree.AllowColumnReorder)
|
||||
{
|
||||
Tree.Input = new ReorderColumnState(Tree, Column, args.Location);
|
||||
Tree.UpdateView();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
Tree.ChangeInput();
|
||||
Tree.UpdateView();
|
||||
Tree.OnColumnClicked(Column);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal abstract class ColumnState : InputState
|
||||
{
|
||||
private TreeColumn _column;
|
||||
public TreeColumn Column
|
||||
{
|
||||
get { return _column; }
|
||||
}
|
||||
|
||||
public ColumnState(TreeViewAdv tree, TreeColumn column)
|
||||
: base(tree)
|
||||
{
|
||||
_column = column;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal abstract class InputState
|
||||
{
|
||||
private TreeViewAdv _tree;
|
||||
|
||||
public TreeViewAdv Tree
|
||||
{
|
||||
get { return _tree; }
|
||||
}
|
||||
|
||||
public InputState(TreeViewAdv tree)
|
||||
{
|
||||
_tree = tree;
|
||||
}
|
||||
|
||||
public abstract void KeyDown(System.Windows.Forms.KeyEventArgs args);
|
||||
public abstract void MouseDown(TreeNodeAdvMouseEventArgs args);
|
||||
public abstract void MouseUp(TreeNodeAdvMouseEventArgs args);
|
||||
|
||||
/// <summary>
|
||||
/// handle OnMouseMove event
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns>true if event was handled and should be dispatched</returns>
|
||||
public virtual bool MouseMove(MouseEventArgs args)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class InputWithControl: NormalInputState
|
||||
{
|
||||
public InputWithControl(TreeViewAdv tree): base(tree)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void DoMouseOperation(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (Tree.SelectionMode == TreeSelectionMode.Single)
|
||||
{
|
||||
base.DoMouseOperation(args);
|
||||
}
|
||||
else if (CanSelect(args.Node))
|
||||
{
|
||||
args.Node.IsSelected = !args.Node.IsSelected;
|
||||
Tree.SelectionStart = args.Node;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void MouseDownAtEmptySpace(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class InputWithShift: NormalInputState
|
||||
{
|
||||
public InputWithShift(TreeViewAdv tree): base(tree)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void FocusRow(TreeNodeAdv node)
|
||||
{
|
||||
Tree.SuspendSelectionEvent = true;
|
||||
try
|
||||
{
|
||||
if (Tree.SelectionMode == TreeSelectionMode.Single || Tree.SelectionStart == null)
|
||||
base.FocusRow(node);
|
||||
else if (CanSelect(node))
|
||||
{
|
||||
SelectAllFromStart(node);
|
||||
Tree.CurrentNode = node;
|
||||
Tree.ScrollTo(node);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tree.SuspendSelectionEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void DoMouseOperation(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (Tree.SelectionMode == TreeSelectionMode.Single || Tree.SelectionStart == null)
|
||||
{
|
||||
base.DoMouseOperation(args);
|
||||
}
|
||||
else if (CanSelect(args.Node))
|
||||
{
|
||||
Tree.SuspendSelectionEvent = true;
|
||||
try
|
||||
{
|
||||
SelectAllFromStart(args.Node);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tree.SuspendSelectionEvent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void MouseDownAtEmptySpace(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
private void SelectAllFromStart(TreeNodeAdv node)
|
||||
{
|
||||
Tree.ClearSelectionInternal();
|
||||
int a = node.Row;
|
||||
int b = Tree.SelectionStart.Row;
|
||||
for (int i = Math.Min(a, b); i <= Math.Max(a, b); i++)
|
||||
{
|
||||
if (Tree.SelectionMode == TreeSelectionMode.Multi || Tree.RowMap[i].Parent == node.Parent)
|
||||
Tree.RowMap[i].IsSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class NormalInputState : InputState
|
||||
{
|
||||
private bool _mouseDownFlag = false;
|
||||
|
||||
public NormalInputState(TreeViewAdv tree) : base(tree)
|
||||
{
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
if (Tree.CurrentNode == null && Tree.Root.Nodes.Count > 0)
|
||||
Tree.CurrentNode = Tree.Root.Nodes[0];
|
||||
|
||||
if (Tree.CurrentNode != null)
|
||||
{
|
||||
switch (args.KeyCode)
|
||||
{
|
||||
case Keys.Right:
|
||||
if (!Tree.CurrentNode.IsExpanded)
|
||||
Tree.CurrentNode.IsExpanded = true;
|
||||
else if (Tree.CurrentNode.Nodes.Count > 0)
|
||||
Tree.SelectedNode = Tree.CurrentNode.Nodes[0];
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.Left:
|
||||
if (Tree.CurrentNode.IsExpanded)
|
||||
Tree.CurrentNode.IsExpanded = false;
|
||||
else if (Tree.CurrentNode.Parent != Tree.Root)
|
||||
Tree.SelectedNode = Tree.CurrentNode.Parent;
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.Down:
|
||||
NavigateForward(1);
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.Up:
|
||||
NavigateBackward(1);
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.PageDown:
|
||||
NavigateForward(Math.Max(1, Tree.CurrentPageSize - 1));
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.PageUp:
|
||||
NavigateBackward(Math.Max(1, Tree.CurrentPageSize - 1));
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.Home:
|
||||
if (Tree.RowMap.Count > 0)
|
||||
FocusRow(Tree.RowMap[0]);
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.End:
|
||||
if (Tree.RowMap.Count > 0)
|
||||
FocusRow(Tree.RowMap[Tree.RowMap.Count-1]);
|
||||
args.Handled = true;
|
||||
break;
|
||||
case Keys.Subtract:
|
||||
Tree.CurrentNode.Collapse();
|
||||
args.Handled = true;
|
||||
args.SuppressKeyPress = true;
|
||||
break;
|
||||
case Keys.Add:
|
||||
Tree.CurrentNode.Expand();
|
||||
args.Handled = true;
|
||||
args.SuppressKeyPress = true;
|
||||
break;
|
||||
case Keys.Multiply:
|
||||
Tree.CurrentNode.ExpandAll();
|
||||
args.Handled = true;
|
||||
args.SuppressKeyPress = true;
|
||||
break;
|
||||
case Keys.A:
|
||||
if (args.Modifiers == Keys.Control)
|
||||
Tree.SelectAllNodes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (args.Node != null)
|
||||
{
|
||||
Tree.ItemDragMode = true;
|
||||
Tree.ItemDragStart = args.Location;
|
||||
|
||||
if (args.Button == MouseButtons.Left || args.Button == MouseButtons.Right)
|
||||
{
|
||||
Tree.BeginUpdate();
|
||||
try
|
||||
{
|
||||
Tree.CurrentNode = args.Node;
|
||||
if (args.Node.IsSelected)
|
||||
_mouseDownFlag = true;
|
||||
else
|
||||
{
|
||||
_mouseDownFlag = false;
|
||||
DoMouseOperation(args);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tree.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Tree.ItemDragMode = false;
|
||||
MouseDownAtEmptySpace(args);
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
Tree.ItemDragMode = false;
|
||||
if (_mouseDownFlag && args.Node != null)
|
||||
{
|
||||
if (args.Button == MouseButtons.Left)
|
||||
DoMouseOperation(args);
|
||||
else if (args.Button == MouseButtons.Right)
|
||||
Tree.CurrentNode = args.Node;
|
||||
}
|
||||
_mouseDownFlag = false;
|
||||
}
|
||||
|
||||
|
||||
private void NavigateBackward(int n)
|
||||
{
|
||||
int row = Math.Max(Tree.CurrentNode.Row - n, 0);
|
||||
if (row != Tree.CurrentNode.Row)
|
||||
FocusRow(Tree.RowMap[row]);
|
||||
}
|
||||
|
||||
private void NavigateForward(int n)
|
||||
{
|
||||
int row = Math.Min(Tree.CurrentNode.Row + n, Tree.RowCount - 1);
|
||||
if (row != Tree.CurrentNode.Row)
|
||||
FocusRow(Tree.RowMap[row]);
|
||||
}
|
||||
|
||||
protected virtual void MouseDownAtEmptySpace(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
Tree.ClearSelection();
|
||||
}
|
||||
|
||||
protected virtual void FocusRow(TreeNodeAdv node)
|
||||
{
|
||||
Tree.SuspendSelectionEvent = true;
|
||||
try
|
||||
{
|
||||
Tree.ClearSelectionInternal();
|
||||
Tree.CurrentNode = node;
|
||||
Tree.SelectionStart = node;
|
||||
node.IsSelected = true;
|
||||
Tree.ScrollTo(node);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tree.SuspendSelectionEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool CanSelect(TreeNodeAdv node)
|
||||
{
|
||||
if (Tree.SelectionMode == TreeSelectionMode.MultiSameParent)
|
||||
{
|
||||
return (Tree.SelectionStart == null || node.Parent == Tree.SelectionStart.Parent);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void DoMouseOperation(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (Tree.SelectedNodes.Count == 1 && args.Node != null && args.Node.IsSelected)
|
||||
return;
|
||||
|
||||
Tree.SuspendSelectionEvent = true;
|
||||
try
|
||||
{
|
||||
Tree.ClearSelectionInternal();
|
||||
if (args.Node != null)
|
||||
args.Node.IsSelected = true;
|
||||
Tree.SelectionStart = args.Node;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Tree.SuspendSelectionEvent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class ReorderColumnState : ColumnState
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private Point _location;
|
||||
public Point Location
|
||||
{
|
||||
get { return _location; }
|
||||
}
|
||||
|
||||
private Bitmap _ghostImage;
|
||||
public Bitmap GhostImage
|
||||
{
|
||||
get { return _ghostImage; }
|
||||
}
|
||||
|
||||
private TreeColumn _dropColumn;
|
||||
public TreeColumn DropColumn
|
||||
{
|
||||
get { return _dropColumn; }
|
||||
}
|
||||
|
||||
private int _dragOffset;
|
||||
public int DragOffset
|
||||
{
|
||||
get { return _dragOffset; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public ReorderColumnState(TreeViewAdv tree, TreeColumn column, Point initialMouseLocation)
|
||||
: base(tree, column)
|
||||
{
|
||||
_location = new Point(initialMouseLocation.X + Tree.OffsetX, 0);
|
||||
_dragOffset = tree.GetColumnX(column) - initialMouseLocation.X;
|
||||
_ghostImage = column.CreateGhostImage(new Rectangle(0, 0, column.Width, tree.ColumnHeaderHeight), tree.Font);
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
args.Handled = true;
|
||||
if (args.KeyCode == Keys.Escape)
|
||||
FinishResize();
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
FinishResize();
|
||||
}
|
||||
|
||||
public override bool MouseMove(MouseEventArgs args)
|
||||
{
|
||||
_dropColumn = null;
|
||||
_location = new Point(args.X + Tree.OffsetX, 0);
|
||||
int x = 0;
|
||||
foreach (TreeColumn c in Tree.Columns)
|
||||
{
|
||||
if (c.IsVisible)
|
||||
{
|
||||
if (_location.X < x + c.Width / 2)
|
||||
{
|
||||
_dropColumn = c;
|
||||
break;
|
||||
}
|
||||
x += c.Width;
|
||||
}
|
||||
}
|
||||
Tree.UpdateHeaders();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void FinishResize()
|
||||
{
|
||||
Tree.ChangeInput();
|
||||
if (Column == DropColumn)
|
||||
Tree.UpdateView();
|
||||
else
|
||||
{
|
||||
Tree.Columns.Remove(Column);
|
||||
if (DropColumn == null)
|
||||
Tree.Columns.Add(Column);
|
||||
else
|
||||
Tree.Columns.Insert(Tree.Columns.IndexOf(DropColumn), Column);
|
||||
|
||||
Tree.OnColumnReordered(Column);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Security.Permissions;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class ResizeColumnState: ColumnState
|
||||
{
|
||||
private Point _initLocation;
|
||||
private int _initWidth;
|
||||
|
||||
public ResizeColumnState(TreeViewAdv tree, TreeColumn column, Point p)
|
||||
: base(tree, column)
|
||||
{
|
||||
_initLocation = p;
|
||||
_initWidth = column.Width;
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
args.Handled = true;
|
||||
if (args.KeyCode == Keys.Escape)
|
||||
FinishResize();
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
FinishResize();
|
||||
}
|
||||
|
||||
private void FinishResize()
|
||||
{
|
||||
Tree.ChangeInput();
|
||||
Tree.FullUpdate();
|
||||
Tree.OnColumnWidthChanged(Column);
|
||||
}
|
||||
|
||||
public override bool MouseMove(MouseEventArgs args)
|
||||
{
|
||||
Column.Width = _initWidth + args.Location.X - _initLocation.X;
|
||||
Tree.UpdateView();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
Tree.AutoSizeColumn(Column);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/ListModel.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class ListModel : TreeModelBase
|
||||
{
|
||||
private IList _list;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _list.Count; }
|
||||
}
|
||||
|
||||
public ListModel()
|
||||
{
|
||||
_list = new List<object>();
|
||||
}
|
||||
|
||||
public ListModel(IList list)
|
||||
{
|
||||
_list = list;
|
||||
}
|
||||
|
||||
public override IEnumerable GetChildren(TreePath treePath)
|
||||
{
|
||||
return _list;
|
||||
}
|
||||
|
||||
public override bool IsLeaf(TreePath treePath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable items)
|
||||
{
|
||||
foreach (object obj in items)
|
||||
_list.Add(obj);
|
||||
OnStructureChanged(new TreePathEventArgs(TreePath.Empty));
|
||||
}
|
||||
|
||||
public void Add(object item)
|
||||
{
|
||||
_list.Add(item);
|
||||
OnNodesInserted(new TreeModelEventArgs(TreePath.Empty, new int[] { _list.Count - 1 }, new object[] { item }));
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_list.Clear();
|
||||
OnStructureChanged(new TreePathEventArgs(TreePath.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal static class NativeMethods
|
||||
{
|
||||
public const int DCX_WINDOW = 0x01;
|
||||
public const int DCX_CACHE = 0x02;
|
||||
public const int DCX_NORESETATTRS = 0x04;
|
||||
public const int DCX_CLIPCHILDREN = 0x08;
|
||||
public const int DCX_CLIPSIBLINGS = 0x10;
|
||||
public const int DCX_PARENTCLIP = 0x20;
|
||||
public const int DCX_EXCLUDERGN = 0x40;
|
||||
public const int DCX_INTERSECTRGN = 0x80;
|
||||
public const int DCX_EXCLUDEUPDATE = 0x100;
|
||||
public const int DCX_INTERSECTUPDATE = 0x200;
|
||||
public const int DCX_LOCKWINDOWUPDATE = 0x400;
|
||||
public const int DCX_VALIDATE = 0x200000;
|
||||
|
||||
public const int WM_THEMECHANGED = 0x031A;
|
||||
public const int WM_NCPAINT = 0x85;
|
||||
public const int WM_NCCALCSIZE = 0x83;
|
||||
|
||||
public const int WS_BORDER = 0x800000;
|
||||
public const int WS_EX_CLIENTEDGE = 0x200;
|
||||
|
||||
public const int WVR_HREDRAW = 0x100;
|
||||
public const int WVR_VREDRAW = 0x200;
|
||||
public const int WVR_REDRAW = (WVR_HREDRAW | WVR_VREDRAW);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct NCCALCSIZE_PARAMS
|
||||
{
|
||||
public RECT rgrc0, rgrc1, rgrc2;
|
||||
public IntPtr lppos;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public static RECT FromRectangle(Rectangle rectangle)
|
||||
{
|
||||
RECT result = new RECT();
|
||||
result.Left = rectangle.Left;
|
||||
result.Top = rectangle.Top;
|
||||
result.Right = rectangle.Right;
|
||||
result.Bottom = rectangle.Bottom;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Rectangle ToRectangle()
|
||||
{
|
||||
return new Rectangle(Left, Top, Right - Left, Bottom - Top);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, int flags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
||||
}
|
||||
}
|
||||
257
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/Node.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class Node
|
||||
{
|
||||
#region NodeCollection
|
||||
|
||||
private class NodeCollection : Collection<Node>
|
||||
{
|
||||
private Node _owner;
|
||||
|
||||
public NodeCollection(Node owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
while (this.Count != 0)
|
||||
this.RemoveAt(this.Count - 1);
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, Node item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
|
||||
if (item.Parent != _owner)
|
||||
{
|
||||
if (item.Parent != null)
|
||||
item.Parent.Nodes.Remove(item);
|
||||
item._parent = _owner;
|
||||
item._index = index;
|
||||
for (int i = index; i < Count; i++)
|
||||
this[i]._index++;
|
||||
base.InsertItem(index, item);
|
||||
|
||||
TreeModel model = _owner.FindModel();
|
||||
if (model != null)
|
||||
model.OnNodeInserted(_owner, index, item);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
Node item = this[index];
|
||||
item._parent = null;
|
||||
item._index = -1;
|
||||
for (int i = index + 1; i < Count; i++)
|
||||
this[i]._index--;
|
||||
base.RemoveItem(index);
|
||||
|
||||
TreeModel model = _owner.FindModel();
|
||||
if (model != null)
|
||||
model.OnNodeRemoved(_owner, index, item);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, Node item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
|
||||
RemoveAt(index);
|
||||
InsertItem(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
private TreeModel _model;
|
||||
internal TreeModel Model
|
||||
{
|
||||
get { return _model; }
|
||||
set { _model = value; }
|
||||
}
|
||||
|
||||
private NodeCollection _nodes;
|
||||
public Collection<Node> Nodes
|
||||
{
|
||||
get { return _nodes; }
|
||||
}
|
||||
|
||||
private Node _parent;
|
||||
public Node Parent
|
||||
{
|
||||
get { return _parent; }
|
||||
set
|
||||
{
|
||||
if (value != _parent)
|
||||
{
|
||||
if (_parent != null)
|
||||
_parent.Nodes.Remove(this);
|
||||
|
||||
if (value != null)
|
||||
value.Nodes.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _index = -1;
|
||||
public int Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
}
|
||||
|
||||
public Node PreviousNode
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = Index;
|
||||
if (index > 0)
|
||||
return _parent.Nodes[index - 1];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Node NextNode
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = Index;
|
||||
if (index >= 0 && index < _parent.Nodes.Count - 1)
|
||||
return _parent.Nodes[index + 1];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string _text;
|
||||
public virtual string Text
|
||||
{
|
||||
get { return _text; }
|
||||
set
|
||||
{
|
||||
if (_text != value)
|
||||
{
|
||||
_text = value;
|
||||
NotifyModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CheckState _checkState;
|
||||
public virtual CheckState CheckState
|
||||
{
|
||||
get { return _checkState; }
|
||||
set
|
||||
{
|
||||
if (_checkState != value)
|
||||
{
|
||||
_checkState = value;
|
||||
NotifyModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Image _image;
|
||||
public Image Image
|
||||
{
|
||||
get { return _image; }
|
||||
set
|
||||
{
|
||||
if (_image != value)
|
||||
{
|
||||
_image = value;
|
||||
NotifyModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object _tag;
|
||||
public object Tag
|
||||
{
|
||||
get { return _tag; }
|
||||
set { _tag = value; }
|
||||
}
|
||||
|
||||
public bool IsChecked
|
||||
{
|
||||
get
|
||||
{
|
||||
return CheckState != CheckState.Unchecked;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
CheckState = CheckState.Checked;
|
||||
else
|
||||
CheckState = CheckState.Unchecked;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsLeaf
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Node()
|
||||
: this(string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public Node(string text)
|
||||
{
|
||||
_text = text;
|
||||
_nodes = new NodeCollection(this);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Text;
|
||||
}
|
||||
|
||||
private TreeModel FindModel()
|
||||
{
|
||||
Node node = this;
|
||||
while (node != null)
|
||||
{
|
||||
if (node.Model != null)
|
||||
return node.Model;
|
||||
node = node.Parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void NotifyModel()
|
||||
{
|
||||
TreeModel model = FindModel();
|
||||
if (model != null && Parent != null)
|
||||
{
|
||||
TreePath path = model.GetPath(Parent);
|
||||
if (path != null)
|
||||
{
|
||||
TreeModelEventArgs args = new TreeModelEventArgs(path, new int[] { Index }, new object[] { this });
|
||||
model.OnNodesChanged(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public struct NodeControlInfo
|
||||
{
|
||||
public static readonly NodeControlInfo Empty = new NodeControlInfo(null, Rectangle.Empty, null);
|
||||
|
||||
private NodeControl _control;
|
||||
public NodeControl Control
|
||||
{
|
||||
get { return _control; }
|
||||
}
|
||||
|
||||
private Rectangle _bounds;
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get { return _bounds; }
|
||||
}
|
||||
|
||||
private TreeNodeAdv _node;
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
}
|
||||
|
||||
public NodeControlInfo(NodeControl control, Rectangle bounds, TreeNodeAdv node)
|
||||
{
|
||||
_control = control;
|
||||
_bounds = bounds;
|
||||
_node = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public abstract class BaseTextControl : EditableControl
|
||||
{
|
||||
private TextFormatFlags _baseFormatFlags;
|
||||
private TextFormatFlags _formatFlags;
|
||||
private Pen _focusPen;
|
||||
private StringFormat _format;
|
||||
|
||||
#region Properties
|
||||
|
||||
private Font _font = null;
|
||||
public Font Font
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_font == null)
|
||||
return Control.DefaultFont;
|
||||
else
|
||||
return _font;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == Control.DefaultFont)
|
||||
_font = null;
|
||||
else
|
||||
_font = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool ShouldSerializeFont()
|
||||
{
|
||||
return (_font != null);
|
||||
}
|
||||
|
||||
private HorizontalAlignment _textAlign = HorizontalAlignment.Left;
|
||||
[DefaultValue(HorizontalAlignment.Left)]
|
||||
public HorizontalAlignment TextAlign
|
||||
{
|
||||
get { return _textAlign; }
|
||||
set
|
||||
{
|
||||
_textAlign = value;
|
||||
SetFormatFlags();
|
||||
}
|
||||
}
|
||||
|
||||
private StringTrimming _trimming = StringTrimming.None;
|
||||
[DefaultValue(StringTrimming.None)]
|
||||
public StringTrimming Trimming
|
||||
{
|
||||
get { return _trimming; }
|
||||
set
|
||||
{
|
||||
_trimming = value;
|
||||
SetFormatFlags();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _displayHiddenContentInToolTip = true;
|
||||
[DefaultValue(true)]
|
||||
public bool DisplayHiddenContentInToolTip
|
||||
{
|
||||
get { return _displayHiddenContentInToolTip; }
|
||||
set { _displayHiddenContentInToolTip = value; }
|
||||
}
|
||||
|
||||
private bool _useCompatibleTextRendering = false;
|
||||
[DefaultValue(false)]
|
||||
public bool UseCompatibleTextRendering
|
||||
{
|
||||
get { return _useCompatibleTextRendering; }
|
||||
set { _useCompatibleTextRendering = value; }
|
||||
}
|
||||
|
||||
[DefaultValue(false)]
|
||||
public bool TrimMultiLine
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected BaseTextControl()
|
||||
{
|
||||
IncrementalSearchEnabled = true;
|
||||
_focusPen = new Pen(Color.Black);
|
||||
_focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
|
||||
|
||||
_format = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoClip | StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces);
|
||||
_baseFormatFlags = TextFormatFlags.PreserveGraphicsClipping |
|
||||
TextFormatFlags.PreserveGraphicsTranslateTransform;
|
||||
SetFormatFlags();
|
||||
LeftMargin = 3;
|
||||
}
|
||||
|
||||
private void SetFormatFlags()
|
||||
{
|
||||
_format.Alignment = TextHelper.TranslateAligment(TextAlign);
|
||||
_format.Trimming = Trimming;
|
||||
|
||||
_formatFlags = _baseFormatFlags | TextHelper.TranslateAligmentToFlag(TextAlign)
|
||||
| TextHelper.TranslateTrimmingToFlag(Trimming);
|
||||
}
|
||||
|
||||
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
return GetLabelSize(node, context);
|
||||
}
|
||||
|
||||
protected Size GetLabelSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
return GetLabelSize(node, context, GetLabel(node));
|
||||
}
|
||||
|
||||
protected Size GetLabelSize(TreeNodeAdv node, DrawContext context, string label)
|
||||
{
|
||||
PerformanceAnalyzer.Start("GetLabelSize");
|
||||
CheckThread();
|
||||
Font font = GetDrawingFont(node, context, label);
|
||||
Size s = Size.Empty;
|
||||
if (UseCompatibleTextRendering)
|
||||
s = TextRenderer.MeasureText(label, font);
|
||||
else
|
||||
{
|
||||
SizeF sf = context.Graphics.MeasureString(label, font);
|
||||
s = new Size((int)Math.Ceiling(sf.Width), (int)Math.Ceiling(sf.Height));
|
||||
}
|
||||
PerformanceAnalyzer.Finish("GetLabelSize");
|
||||
|
||||
if (!s.IsEmpty)
|
||||
return s;
|
||||
else
|
||||
return new Size(10, Font.Height);
|
||||
}
|
||||
|
||||
protected Font GetDrawingFont(TreeNodeAdv node, DrawContext context, string label)
|
||||
{
|
||||
Font font = context.Font;
|
||||
if (DrawTextMustBeFired(node))
|
||||
{
|
||||
DrawEventArgs args = new DrawEventArgs(node, this, context, label);
|
||||
args.Font = context.Font;
|
||||
OnDrawText(args);
|
||||
font = args.Font;
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
protected void SetEditControlProperties(Control control, TreeNodeAdv node)
|
||||
{
|
||||
string label = GetLabel(node);
|
||||
DrawContext context = new DrawContext();
|
||||
context.Font = control.Font;
|
||||
control.Font = GetDrawingFont(node, context, label);
|
||||
}
|
||||
|
||||
public override void Draw(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
if (context.CurrentEditorOwner == this && node == Parent.CurrentNode)
|
||||
return;
|
||||
|
||||
PerformanceAnalyzer.Start("BaseTextControl.Draw");
|
||||
string label = GetLabel(node);
|
||||
Rectangle bounds = GetBounds(node, context);
|
||||
Rectangle focusRect = new Rectangle(bounds.X, context.Bounds.Y,
|
||||
bounds.Width, context.Bounds.Height);
|
||||
|
||||
Brush backgroundBrush;
|
||||
Color textColor;
|
||||
Font font;
|
||||
CreateBrushes(node, context, label, out backgroundBrush, out textColor, out font, ref label);
|
||||
|
||||
if (backgroundBrush != null)
|
||||
context.Graphics.FillRectangle(backgroundBrush, focusRect);
|
||||
if (context.DrawFocus)
|
||||
{
|
||||
focusRect.Width--;
|
||||
focusRect.Height--;
|
||||
if (context.DrawSelection == DrawSelectionMode.None)
|
||||
_focusPen.Color = SystemColors.ControlText;
|
||||
else
|
||||
_focusPen.Color = SystemColors.InactiveCaption;
|
||||
context.Graphics.DrawRectangle(_focusPen, focusRect);
|
||||
}
|
||||
|
||||
PerformanceAnalyzer.Start("BaseTextControl.DrawText");
|
||||
if (UseCompatibleTextRendering)
|
||||
TextRenderer.DrawText(context.Graphics, label, font, bounds, textColor, _formatFlags);
|
||||
else
|
||||
context.Graphics.DrawString(label, font, GetFrush(textColor), bounds, _format);
|
||||
PerformanceAnalyzer.Finish("BaseTextControl.DrawText");
|
||||
|
||||
PerformanceAnalyzer.Finish("BaseTextControl.Draw");
|
||||
}
|
||||
|
||||
private static Dictionary<Color, Brush> _brushes = new Dictionary<Color,Brush>();
|
||||
private static Brush GetFrush(Color color)
|
||||
{
|
||||
Brush br;
|
||||
if (_brushes.ContainsKey(color))
|
||||
br = _brushes[color];
|
||||
else
|
||||
{
|
||||
br = new SolidBrush(color);
|
||||
_brushes.Add(color, br);
|
||||
}
|
||||
return br;
|
||||
}
|
||||
|
||||
private void CreateBrushes(TreeNodeAdv node, DrawContext context, string text, out Brush backgroundBrush, out Color textColor, out Font font, ref string label)
|
||||
{
|
||||
textColor = Parent.ForeColor;
|
||||
backgroundBrush = null;
|
||||
font = context.Font;
|
||||
if (context.DrawSelection == DrawSelectionMode.Active)
|
||||
{
|
||||
textColor = SystemColors.HighlightText;
|
||||
backgroundBrush = SystemBrushes.Highlight;
|
||||
}
|
||||
else if (context.DrawSelection == DrawSelectionMode.Inactive)
|
||||
{
|
||||
textColor = Parent.ForeColor;
|
||||
backgroundBrush = SystemBrushes.InactiveBorder;
|
||||
}
|
||||
else if (context.DrawSelection == DrawSelectionMode.FullRowSelect)
|
||||
textColor = Parent.ForeColor;
|
||||
|
||||
if (!context.Enabled)
|
||||
textColor = SystemColors.GrayText;
|
||||
|
||||
if (DrawTextMustBeFired(node))
|
||||
{
|
||||
DrawEventArgs args = new DrawEventArgs(node, this, context, text);
|
||||
args.Text = label;
|
||||
args.TextColor = textColor;
|
||||
args.BackgroundBrush = backgroundBrush;
|
||||
args.Font = font;
|
||||
|
||||
OnDrawText(args);
|
||||
|
||||
textColor = args.TextColor;
|
||||
backgroundBrush = args.BackgroundBrush;
|
||||
font = args.Font;
|
||||
label = args.Text;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetLabel(TreeNodeAdv node)
|
||||
{
|
||||
if (node != null && node.Tag != null)
|
||||
{
|
||||
object obj = GetValue(node);
|
||||
if (obj != null)
|
||||
return FormatLabel(obj);
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
protected virtual string FormatLabel(object obj)
|
||||
{
|
||||
var res = obj.ToString();
|
||||
if (TrimMultiLine && res != null)
|
||||
{
|
||||
string[] parts = res.Split('\n');
|
||||
if (parts.Length > 1)
|
||||
return parts[0] + "...";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public void SetLabel(TreeNodeAdv node, string value)
|
||||
{
|
||||
SetValue(node, value);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
{
|
||||
_focusPen.Dispose();
|
||||
_format.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires when control is going to draw a text. Can be used to change text or back color
|
||||
/// </summary>
|
||||
public event EventHandler<DrawEventArgs> DrawText;
|
||||
protected virtual void OnDrawText(DrawEventArgs args)
|
||||
{
|
||||
TreeViewAdv tree = args.Node.Tree;
|
||||
if (tree != null)
|
||||
tree.FireDrawControl(args);
|
||||
if (DrawText != null)
|
||||
DrawText(this, args);
|
||||
}
|
||||
|
||||
protected virtual bool DrawTextMustBeFired(TreeNodeAdv node)
|
||||
{
|
||||
return DrawText != null || (node.Tree != null && node.Tree.DrawControlMustBeFired());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public abstract class BindableControl : NodeControl
|
||||
{
|
||||
private struct MemberAdapter
|
||||
{
|
||||
private object _obj;
|
||||
private PropertyInfo _pi;
|
||||
private FieldInfo _fi;
|
||||
|
||||
public static readonly MemberAdapter Empty = new MemberAdapter();
|
||||
|
||||
public Type MemberType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pi != null)
|
||||
return _pi.PropertyType;
|
||||
else if (_fi != null)
|
||||
return _fi.FieldType;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public object Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pi != null && _pi.CanRead)
|
||||
return _pi.GetValue(_obj, null);
|
||||
else if (_fi != null)
|
||||
return _fi.GetValue(_obj);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_pi != null && _pi.CanWrite)
|
||||
_pi.SetValue(_obj, value, null);
|
||||
else if (_fi != null)
|
||||
_fi.SetValue(_obj, value);
|
||||
}
|
||||
}
|
||||
|
||||
public MemberAdapter(object obj, PropertyInfo pi)
|
||||
{
|
||||
_obj = obj;
|
||||
_pi = pi;
|
||||
_fi = null;
|
||||
}
|
||||
|
||||
public MemberAdapter(object obj, FieldInfo fi)
|
||||
{
|
||||
_obj = obj;
|
||||
_fi = fi;
|
||||
_pi = null;
|
||||
}
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
private bool _virtualMode = false;
|
||||
[DefaultValue(false), Category("Data")]
|
||||
public bool VirtualMode
|
||||
{
|
||||
get { return _virtualMode; }
|
||||
set { _virtualMode = value; }
|
||||
}
|
||||
|
||||
private string _propertyName = "";
|
||||
[DefaultValue(""), Category("Data")]
|
||||
public string DataPropertyName
|
||||
{
|
||||
get { return _propertyName; }
|
||||
set
|
||||
{
|
||||
if (_propertyName == null)
|
||||
_propertyName = string.Empty;
|
||||
_propertyName = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _incrementalSearchEnabled = false;
|
||||
[DefaultValue(false)]
|
||||
public bool IncrementalSearchEnabled
|
||||
{
|
||||
get { return _incrementalSearchEnabled; }
|
||||
set { _incrementalSearchEnabled = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual object GetValue(TreeNodeAdv node)
|
||||
{
|
||||
if (VirtualMode)
|
||||
{
|
||||
NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
|
||||
OnValueNeeded(args);
|
||||
return args.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetMemberAdapter(node).Value;
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
if (ex.InnerException != null)
|
||||
throw new ArgumentException(ex.InnerException.Message, ex.InnerException);
|
||||
else
|
||||
throw new ArgumentException(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetValue(TreeNodeAdv node, object value)
|
||||
{
|
||||
if (VirtualMode)
|
||||
{
|
||||
NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
|
||||
args.Value = value;
|
||||
OnValuePushed(args);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
MemberAdapter ma = GetMemberAdapter(node);
|
||||
ma.Value = value;
|
||||
}
|
||||
catch (TargetInvocationException ex)
|
||||
{
|
||||
if (ex.InnerException != null)
|
||||
throw new ArgumentException(ex.InnerException.Message, ex.InnerException);
|
||||
else
|
||||
throw new ArgumentException(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Type GetPropertyType(TreeNodeAdv node)
|
||||
{
|
||||
return GetMemberAdapter(node).MemberType;
|
||||
}
|
||||
|
||||
private MemberAdapter GetMemberAdapter(TreeNodeAdv node)
|
||||
{
|
||||
if (node.Tag != null && !string.IsNullOrEmpty(DataPropertyName))
|
||||
{
|
||||
Type type = node.Tag.GetType();
|
||||
PropertyInfo pi = type.GetProperty(DataPropertyName);
|
||||
if (pi != null)
|
||||
return new MemberAdapter(node.Tag, pi);
|
||||
else
|
||||
{
|
||||
FieldInfo fi = type.GetField(DataPropertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (fi != null)
|
||||
return new MemberAdapter(node.Tag, fi);
|
||||
}
|
||||
}
|
||||
return MemberAdapter.Empty;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (string.IsNullOrEmpty(DataPropertyName))
|
||||
return GetType().Name;
|
||||
else
|
||||
return string.Format("{0} ({1})", GetType().Name, DataPropertyName);
|
||||
}
|
||||
|
||||
public event EventHandler<NodeControlValueEventArgs> ValueNeeded;
|
||||
private void OnValueNeeded(NodeControlValueEventArgs args)
|
||||
{
|
||||
if (ValueNeeded != null)
|
||||
ValueNeeded(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<NodeControlValueEventArgs> ValuePushed;
|
||||
private void OnValuePushed(NodeControlValueEventArgs args)
|
||||
{
|
||||
if (ValuePushed != null)
|
||||
ValuePushed(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Font Name="Microsoft Sans Serif" Size="8.25" />
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeStateIcon" Collapsed="true">
|
||||
<Position X="0.5" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeStateIcon.cs</FileName>
|
||||
<HashCode>ABAAAAAAAAQAQAAAAAAAAAAAAAAAAAAAQIAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.BindableControl" Collapsed="true">
|
||||
<Position X="2.75" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\BindableControl.cs</FileName>
|
||||
<HashCode>FAAAAAAQIBAQCgAEAAAAIAAAAAAAAAEMAAACAAAAAAE=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeCheckBox" Collapsed="true">
|
||||
<Position X="5" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeCheckBox.cs</FileName>
|
||||
<HashCode>AAEAAAAAAAACgkQCAAAAAAigAgAAEGABAAAIAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeControl" Collapsed="true">
|
||||
<Position X="1.5" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeControl.cs</FileName>
|
||||
<HashCode>AAAAAJAAgIgBkkoQAAgAQAAwAAABEIQAAEBIAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
<Compartments>
|
||||
<Compartment Name="Fields" Collapsed="true" />
|
||||
</Compartments>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeIcon" Collapsed="true">
|
||||
<Position X="0.5" Y="2.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeIcon.cs</FileName>
|
||||
<HashCode>ABAAAAAAAAAAAgAAAAAAAAAgAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodePlusMinus" Collapsed="true">
|
||||
<Position X="0.5" Y="1.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodePlusMinus.cs</FileName>
|
||||
<HashCode>AAAAAAAAAAAAAgAAAAAAAEAgAAAAMCAAAAAIACAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.BaseTextControl" Collapsed="true">
|
||||
<Position X="3" Y="5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\BaseTextControl.cs</FileName>
|
||||
<HashCode>AAAAICBQACAAIgACBCAEAQA8AgmFoAAwAAAAACACAMA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeTextBox" Collapsed="true">
|
||||
<Position X="1" Y="6" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeTextBox.cs</FileName>
|
||||
<HashCode>QQQAhAAAADAMgAAAABAAAAAAAgEAIAAAAAAAAIAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.EditableControl" Collapsed="true">
|
||||
<Position X="3" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\EditableControl.cs</FileName>
|
||||
<HashCode>QQAgAAAACGgkAMAABAEEkADAEAAUEAAABAGoAAAAAQA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeComboBox" Collapsed="true">
|
||||
<Position X="3" Y="6" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeComboBox.cs</FileName>
|
||||
<HashCode>wQACAAAAAAAMAEBAAAAAAABAAAAAAAABAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeNumericUpDown" Collapsed="true">
|
||||
<Position X="5" Y="6" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeNumericUpDown.cs</FileName>
|
||||
<HashCode>wQAAAACAAAAEAABAIAAQIAAAAAAAAAABAAAIAAAAAII=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.InteractiveControl" Collapsed="true">
|
||||
<Position X="4" Y="2.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\InteractiveControl.cs</FileName>
|
||||
<HashCode>AAAABAAAAAAAAAAACAAAAAAAABAAAQAAAAAAAAIAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeDecimalTextBox" Collapsed="true">
|
||||
<Position X="2.5" Y="7" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeDecimalTextBox.cs</FileName>
|
||||
<HashCode>AQAAAAAAAACAAAACAAAAAAQAAAAAIAAAAAgAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="Aga.Controls.Tree.NodeControls.NodeIntegerTextBox" Collapsed="true">
|
||||
<Position X="0.5" Y="7" Width="1.75" />
|
||||
<TypeIdentifier>
|
||||
<FileName>Tree\NodeControls\NodeIntegerTextBox.cs</FileName>
|
||||
<HashCode>AQAAAAAAAAAAAAACAAAAAAQAAAAAIAAAAAAAAAAAAAA=</HashCode>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class DrawEventArgs : NodeEventArgs
|
||||
{
|
||||
private DrawContext _context;
|
||||
public DrawContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
|
||||
private Brush _textBrush;
|
||||
[Obsolete("Use TextColor")]
|
||||
public Brush TextBrush
|
||||
{
|
||||
get { return _textBrush; }
|
||||
set { _textBrush = value; }
|
||||
}
|
||||
|
||||
private Brush _backgroundBrush;
|
||||
public Brush BackgroundBrush
|
||||
{
|
||||
get { return _backgroundBrush; }
|
||||
set { _backgroundBrush = value; }
|
||||
}
|
||||
|
||||
private Font _font;
|
||||
public Font Font
|
||||
{
|
||||
get { return _font; }
|
||||
set { _font = value; }
|
||||
}
|
||||
|
||||
private Color _textColor;
|
||||
public Color TextColor
|
||||
{
|
||||
get { return _textColor; }
|
||||
set { _textColor = value; }
|
||||
}
|
||||
|
||||
private string _text;
|
||||
public string Text
|
||||
{
|
||||
get { return _text; }
|
||||
set { _text = value; }
|
||||
}
|
||||
|
||||
|
||||
private EditableControl _control;
|
||||
public EditableControl Control
|
||||
{
|
||||
get { return _control; }
|
||||
}
|
||||
|
||||
public DrawEventArgs(TreeNodeAdv node, EditableControl control, DrawContext context, string text)
|
||||
: base(node)
|
||||
{
|
||||
_control = control;
|
||||
_context = context;
|
||||
_text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class EditEventArgs : NodeEventArgs
|
||||
{
|
||||
private Control _control;
|
||||
public Control Control
|
||||
{
|
||||
get { return _control; }
|
||||
}
|
||||
|
||||
public EditEventArgs(TreeNodeAdv node, Control control)
|
||||
: base(node)
|
||||
{
|
||||
_control = control;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public abstract class EditableControl : InteractiveControl
|
||||
{
|
||||
private Timer _timer;
|
||||
private bool _editFlag;
|
||||
|
||||
#region Properties
|
||||
|
||||
private bool _editOnClick = false;
|
||||
[DefaultValue(false)]
|
||||
public bool EditOnClick
|
||||
{
|
||||
get { return _editOnClick; }
|
||||
set { _editOnClick = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected EditableControl()
|
||||
{
|
||||
_timer = new Timer();
|
||||
_timer.Interval = 500;
|
||||
_timer.Tick += new EventHandler(TimerTick);
|
||||
}
|
||||
|
||||
private void TimerTick(object sender, EventArgs e)
|
||||
{
|
||||
_timer.Stop();
|
||||
if (_editFlag)
|
||||
BeginEdit();
|
||||
_editFlag = false;
|
||||
}
|
||||
|
||||
public void SetEditorBounds(EditorContext context)
|
||||
{
|
||||
Size size = CalculateEditorSize(context);
|
||||
context.Editor.Bounds = new Rectangle(context.Bounds.X, context.Bounds.Y,
|
||||
Math.Min(size.Width, context.Bounds.Width),
|
||||
Math.Min(size.Height, Parent.ClientSize.Height - context.Bounds.Y)
|
||||
);
|
||||
}
|
||||
|
||||
protected abstract Size CalculateEditorSize(EditorContext context);
|
||||
|
||||
protected virtual bool CanEdit(TreeNodeAdv node)
|
||||
{
|
||||
return (node.Tag != null) && IsEditEnabled(node);
|
||||
}
|
||||
|
||||
public void BeginEdit()
|
||||
{
|
||||
if (Parent != null && Parent.CurrentNode != null && CanEdit(Parent.CurrentNode))
|
||||
{
|
||||
CancelEventArgs args = new CancelEventArgs();
|
||||
OnEditorShowing(args);
|
||||
if (!args.Cancel)
|
||||
{
|
||||
var editor = CreateEditor(Parent.CurrentNode);
|
||||
Parent.DisplayEditor(editor, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void EndEdit(bool applyChanges)
|
||||
{
|
||||
if (Parent != null)
|
||||
if (Parent.HideEditor(applyChanges))
|
||||
OnEditorHided();
|
||||
}
|
||||
|
||||
public virtual void UpdateEditor(Control control)
|
||||
{
|
||||
}
|
||||
|
||||
internal void ApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
DoApplyChanges(node, editor);
|
||||
OnChangesApplied();
|
||||
}
|
||||
|
||||
internal void DoDisposeEditor(Control editor)
|
||||
{
|
||||
DisposeEditor(editor);
|
||||
}
|
||||
|
||||
protected abstract void DoApplyChanges(TreeNodeAdv node, Control editor);
|
||||
|
||||
protected abstract Control CreateEditor(TreeNodeAdv node);
|
||||
|
||||
protected abstract void DisposeEditor(Control editor);
|
||||
|
||||
public virtual void Cut(Control control)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Copy(Control control)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Paste(Control control)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Delete(Control control)
|
||||
{
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
_editFlag = (!EditOnClick && args.Button == MouseButtons.Left
|
||||
&& args.ModifierKeys == Keys.None && args.Node.IsSelected);
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (args.Node.IsSelected)
|
||||
{
|
||||
if (EditOnClick && args.Button == MouseButtons.Left && args.ModifierKeys == Keys.None)
|
||||
{
|
||||
Parent.ItemDragMode = false;
|
||||
BeginEdit();
|
||||
args.Handled = true;
|
||||
}
|
||||
else if (_editFlag)// && args.Node.IsSelected)
|
||||
_timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
_editFlag = false;
|
||||
_timer.Stop();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
_timer.Dispose();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
public event CancelEventHandler EditorShowing;
|
||||
protected void OnEditorShowing(CancelEventArgs args)
|
||||
{
|
||||
if (EditorShowing != null)
|
||||
EditorShowing(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler EditorHided;
|
||||
protected void OnEditorHided()
|
||||
{
|
||||
if (EditorHided != null)
|
||||
EditorHided(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler ChangesApplied;
|
||||
protected void OnChangesApplied()
|
||||
{
|
||||
if (ChangesApplied != null)
|
||||
ChangesApplied(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays an animated icon for those nodes, who are in expanding state.
|
||||
/// Parent TreeView must have AsyncExpanding property set to true.
|
||||
/// </summary>
|
||||
public class ExpandingIcon: NodeControl
|
||||
{
|
||||
private static GifDecoder _gif = ResourceHelper.LoadingIcon;
|
||||
private static int _index = 0;
|
||||
private static volatile Thread _animatingThread;
|
||||
private static object _lock = new object();
|
||||
|
||||
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
return ResourceHelper.LoadingIcon.FrameSize;
|
||||
}
|
||||
|
||||
protected override void OnIsVisibleValueNeeded(NodeControlValueEventArgs args)
|
||||
{
|
||||
args.Value = args.Node.IsExpandingNow;
|
||||
base.OnIsVisibleValueNeeded(args);
|
||||
}
|
||||
|
||||
public override void Draw(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
Rectangle rect = GetBounds(node, context);
|
||||
Image img = _gif.GetFrame(_index).Image;
|
||||
context.Graphics.DrawImage(img, rect.Location);
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_animatingThread == null)
|
||||
{
|
||||
_index = 0;
|
||||
_animatingThread = new Thread(new ThreadStart(IterateIcons));
|
||||
_animatingThread.IsBackground = true;
|
||||
_animatingThread.Priority = ThreadPriority.Lowest;
|
||||
_animatingThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_index = 0;
|
||||
_animatingThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void IterateIcons()
|
||||
{
|
||||
while (_animatingThread != null)
|
||||
{
|
||||
if (_index < _gif.FrameCount - 1)
|
||||
_index++;
|
||||
else
|
||||
_index = 0;
|
||||
|
||||
if (IconChanged != null)
|
||||
IconChanged(null, EventArgs.Empty);
|
||||
|
||||
int delay = _gif.GetFrame(_index).Delay;
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine("IterateIcons Stopped");
|
||||
}
|
||||
|
||||
public static event EventHandler IconChanged;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public abstract class InteractiveControl : BindableControl
|
||||
{
|
||||
private bool _editEnabled = false;
|
||||
[DefaultValue(false)]
|
||||
public bool EditEnabled
|
||||
{
|
||||
get { return _editEnabled; }
|
||||
set { _editEnabled = value; }
|
||||
}
|
||||
|
||||
protected bool IsEditEnabled(TreeNodeAdv node)
|
||||
{
|
||||
if (EditEnabled)
|
||||
{
|
||||
NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
|
||||
args.Value = true;
|
||||
OnIsEditEnabledValueNeeded(args);
|
||||
return Convert.ToBoolean(args.Value);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public event EventHandler<NodeControlValueEventArgs> IsEditEnabledValueNeeded;
|
||||
private void OnIsEditEnabledValueNeeded(NodeControlValueEventArgs args)
|
||||
{
|
||||
if (IsEditEnabledValueNeeded != null)
|
||||
IsEditEnabledValueNeeded(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class LabelEventArgs : EventArgs
|
||||
{
|
||||
private object _subject;
|
||||
public object Subject
|
||||
{
|
||||
get { return _subject; }
|
||||
}
|
||||
|
||||
private string _oldLabel;
|
||||
public string OldLabel
|
||||
{
|
||||
get { return _oldLabel; }
|
||||
}
|
||||
|
||||
private string _newLabel;
|
||||
public string NewLabel
|
||||
{
|
||||
get { return _newLabel; }
|
||||
}
|
||||
|
||||
public LabelEventArgs(object subject, string oldLabel, string newLabel)
|
||||
{
|
||||
_subject = subject;
|
||||
_oldLabel = oldLabel;
|
||||
_newLabel = newLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Properties;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeCheckBox : InteractiveControl
|
||||
{
|
||||
public const int ImageSize = 13;
|
||||
|
||||
private Bitmap _check;
|
||||
private Bitmap _uncheck;
|
||||
private Bitmap _unknown;
|
||||
|
||||
#region Properties
|
||||
|
||||
private bool _threeState;
|
||||
[DefaultValue(false)]
|
||||
public bool ThreeState
|
||||
{
|
||||
get { return _threeState; }
|
||||
set { _threeState = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public NodeCheckBox()
|
||||
: this(string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public NodeCheckBox(string propertyName)
|
||||
{
|
||||
_check = Resources.check;
|
||||
_uncheck = Resources.uncheck;
|
||||
_unknown = Resources.unknown;
|
||||
DataPropertyName = propertyName;
|
||||
LeftMargin = 0;
|
||||
}
|
||||
|
||||
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
|
||||
int scaledY = node.Tree.GetScaledSize(ImageSize);
|
||||
return new Size(scaledX, scaledY);
|
||||
}
|
||||
|
||||
public override void Draw(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
Rectangle bounds = GetBounds(node, context);
|
||||
CheckState state = GetCheckState(node);
|
||||
if (TreeViewAdv.CustomCheckRenderFunc != null)
|
||||
{
|
||||
TreeViewAdv.CustomCheckRenderFunc(context.Graphics, bounds, state == CheckState.Checked);
|
||||
}
|
||||
else if (Application.RenderWithVisualStyles)
|
||||
{
|
||||
VisualStyleRenderer renderer;
|
||||
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
|
||||
int scaledY = node.Tree.GetScaledSize(ImageSize);
|
||||
if (state == CheckState.Indeterminate)
|
||||
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.MixedNormal);
|
||||
else if (state == CheckState.Checked)
|
||||
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.CheckedNormal);
|
||||
else
|
||||
renderer = new VisualStyleRenderer(VisualStyleElement.Button.CheckBox.UncheckedNormal);
|
||||
renderer.DrawBackground(context.Graphics, new Rectangle(bounds.X, bounds.Y, scaledX, scaledY));
|
||||
}
|
||||
else
|
||||
{
|
||||
Image img;
|
||||
if (state == CheckState.Indeterminate)
|
||||
img = _unknown;
|
||||
else if (state == CheckState.Checked)
|
||||
img = _check;
|
||||
else
|
||||
img = _uncheck;
|
||||
context.Graphics.DrawImage(img, bounds.Location);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual CheckState GetCheckState(TreeNodeAdv node)
|
||||
{
|
||||
object obj = GetValue(node);
|
||||
if (obj is CheckState)
|
||||
return (CheckState)obj;
|
||||
else if (obj is bool)
|
||||
return (bool)obj ? CheckState.Checked : CheckState.Unchecked;
|
||||
else
|
||||
return CheckState.Unchecked;
|
||||
}
|
||||
|
||||
protected virtual void SetCheckState(TreeNodeAdv node, CheckState value)
|
||||
{
|
||||
if (VirtualMode)
|
||||
{
|
||||
SetValue(node, value);
|
||||
OnCheckStateChanged(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Type type = GetPropertyType(node);
|
||||
if (type == typeof(CheckState))
|
||||
{
|
||||
SetValue(node, value);
|
||||
OnCheckStateChanged(node);
|
||||
}
|
||||
else if (type == typeof(bool))
|
||||
{
|
||||
SetValue(node, value != CheckState.Unchecked);
|
||||
OnCheckStateChanged(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (args.Button == MouseButtons.Left && IsEditEnabled(args.Node))
|
||||
{
|
||||
DrawContext context = new DrawContext();
|
||||
context.Bounds = args.ControlBounds;
|
||||
Rectangle rect = GetBounds(args.Node, context);
|
||||
if (rect.Contains(args.ViewLocation))
|
||||
{
|
||||
CheckState state = GetCheckState(args.Node);
|
||||
state = GetNewState(state);
|
||||
SetCheckState(args.Node, state);
|
||||
Parent.UpdateView();
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private CheckState GetNewState(CheckState state)
|
||||
{
|
||||
if (state == CheckState.Indeterminate)
|
||||
return CheckState.Unchecked;
|
||||
else if(state == CheckState.Unchecked)
|
||||
return CheckState.Checked;
|
||||
else
|
||||
return ThreeState ? CheckState.Indeterminate : CheckState.Unchecked;
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
if (args.KeyCode == Keys.Space && EditEnabled)
|
||||
{
|
||||
Parent.BeginUpdate();
|
||||
try
|
||||
{
|
||||
if (Parent.CurrentNode != null)
|
||||
{
|
||||
CheckState value = GetNewState(GetCheckState(Parent.CurrentNode));
|
||||
foreach (TreeNodeAdv node in Parent.Selection)
|
||||
if (IsEditEnabled(node))
|
||||
SetCheckState(node, value);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Parent.EndUpdate();
|
||||
}
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<TreePathEventArgs> CheckStateChanged;
|
||||
protected void OnCheckStateChanged(TreePathEventArgs args)
|
||||
{
|
||||
if (CheckStateChanged != null)
|
||||
CheckStateChanged(this, args);
|
||||
}
|
||||
|
||||
protected void OnCheckStateChanged(TreeNodeAdv node)
|
||||
{
|
||||
TreePath path = this.Parent.GetPath(node);
|
||||
OnCheckStateChanged(new TreePathEventArgs(path));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Design;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeComboBox : BaseTextControl
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private int _editorWidth = 100;
|
||||
[DefaultValue(100)]
|
||||
public int EditorWidth
|
||||
{
|
||||
get { return _editorWidth; }
|
||||
set { _editorWidth = value; }
|
||||
}
|
||||
|
||||
private int _editorHeight = 100;
|
||||
[DefaultValue(100)]
|
||||
public int EditorHeight
|
||||
{
|
||||
get { return _editorHeight; }
|
||||
set { _editorHeight = value; }
|
||||
}
|
||||
|
||||
private List<object> _dropDownItems;
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
|
||||
[Editor(typeof(StringCollectionEditor), typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public List<object> DropDownItems
|
||||
{
|
||||
get { return _dropDownItems; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public event EventHandler<EditEventArgs> CreatingEditor;
|
||||
|
||||
public NodeComboBox()
|
||||
{
|
||||
_dropDownItems = new List<object>();
|
||||
}
|
||||
|
||||
protected override Size CalculateEditorSize(EditorContext context)
|
||||
{
|
||||
if (Parent.UseColumns)
|
||||
{
|
||||
if (context.Editor is CheckedListBox)
|
||||
return new Size(context.Bounds.Size.Width, EditorHeight);
|
||||
else
|
||||
return context.Bounds.Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (context.Editor is CheckedListBox)
|
||||
return new Size(EditorWidth, EditorHeight);
|
||||
else
|
||||
return new Size(EditorWidth, context.Bounds.Height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override Control CreateEditor(TreeNodeAdv node)
|
||||
{
|
||||
Control c;
|
||||
object value = GetValue(node);
|
||||
if (IsCheckedListBoxRequired(node))
|
||||
c = CreateCheckedListBox(node);
|
||||
else
|
||||
c = CreateCombo(node);
|
||||
OnCreatingEditor(new EditEventArgs(node, c));
|
||||
return c;
|
||||
}
|
||||
|
||||
protected override void DisposeEditor(Control editor)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnCreatingEditor(EditEventArgs args)
|
||||
{
|
||||
if (CreatingEditor != null)
|
||||
CreatingEditor(this, args);
|
||||
}
|
||||
|
||||
protected virtual bool IsCheckedListBoxRequired(TreeNodeAdv node)
|
||||
{
|
||||
object value = GetValue(node);
|
||||
if (value != null)
|
||||
{
|
||||
Type t = value.GetType();
|
||||
object[] arr = t.GetCustomAttributes(typeof(FlagsAttribute), false);
|
||||
return (t.IsEnum && arr.Length == 1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Control CreateCombo(TreeNodeAdv node)
|
||||
{
|
||||
ComboBox comboBox = new ComboBox();
|
||||
if (DropDownItems != null)
|
||||
comboBox.Items.AddRange(DropDownItems.ToArray());
|
||||
comboBox.SelectedItem = GetValue(node);
|
||||
comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox.DropDownClosed += new EventHandler(EditorDropDownClosed);
|
||||
SetEditControlProperties(comboBox, node);
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
private Control CreateCheckedListBox(TreeNodeAdv node)
|
||||
{
|
||||
CheckedListBox listBox = new CheckedListBox();
|
||||
listBox.CheckOnClick = true;
|
||||
|
||||
object value = GetValue(node);
|
||||
Type enumType = GetEnumType(node);
|
||||
foreach (object obj in Enum.GetValues(enumType))
|
||||
{
|
||||
object[] attributes = enumType.GetField(obj.ToString()).GetCustomAttributes(typeof(BrowsableAttribute), false);
|
||||
if (attributes.Length == 0 || ((BrowsableAttribute)attributes[0]).Browsable)
|
||||
listBox.Items.Add(obj, IsContain(value, obj));
|
||||
}
|
||||
|
||||
SetEditControlProperties(listBox, node);
|
||||
if (CreatingEditor != null)
|
||||
CreatingEditor(this, new EditEventArgs(node, listBox));
|
||||
return listBox;
|
||||
}
|
||||
|
||||
protected virtual Type GetEnumType(TreeNodeAdv node)
|
||||
{
|
||||
object value = GetValue(node);
|
||||
return value.GetType();
|
||||
}
|
||||
|
||||
private bool IsContain(object value, object enumElement)
|
||||
{
|
||||
if (value == null || enumElement == null)
|
||||
return false;
|
||||
if (value.GetType().IsEnum)
|
||||
{
|
||||
int i1 = (int)value;
|
||||
int i2 = (int)enumElement;
|
||||
return (i1 & i2) == i2;
|
||||
}
|
||||
else
|
||||
{
|
||||
var arr = value as object[];
|
||||
foreach (object obj in arr)
|
||||
if ((int)obj == (int)enumElement)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string FormatLabel(object obj)
|
||||
{
|
||||
var arr = obj as object[];
|
||||
if (arr != null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (object t in arr)
|
||||
{
|
||||
if (sb.Length > 0)
|
||||
sb.Append(", ");
|
||||
sb.Append(t);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
else
|
||||
return base.FormatLabel(obj);
|
||||
}
|
||||
|
||||
void EditorDropDownClosed(object sender, EventArgs e)
|
||||
{
|
||||
EndEdit(true);
|
||||
}
|
||||
|
||||
public override void UpdateEditor(Control control)
|
||||
{
|
||||
if (control is ComboBox)
|
||||
(control as ComboBox).DroppedDown = true;
|
||||
}
|
||||
|
||||
protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
var combo = editor as ComboBox;
|
||||
if (combo != null)
|
||||
{
|
||||
if (combo.DropDownStyle == ComboBoxStyle.DropDown)
|
||||
SetValue(node, combo.Text);
|
||||
else
|
||||
SetValue(node, combo.SelectedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
var listBox = editor as CheckedListBox;
|
||||
Type type = GetEnumType(node);
|
||||
if (IsFlags(type))
|
||||
{
|
||||
int res = 0;
|
||||
foreach (object obj in listBox.CheckedItems)
|
||||
res |= (int)obj;
|
||||
object val = Enum.ToObject(type, res);
|
||||
SetValue(node, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
foreach (object obj in listBox.CheckedItems)
|
||||
list.Add(obj);
|
||||
SetValue(node, list.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsFlags(Type type)
|
||||
{
|
||||
object[] atr = type.GetCustomAttributes(typeof(FlagsAttribute), false);
|
||||
return atr.Length == 1;
|
||||
}
|
||||
|
||||
public override void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (args.Node != null && args.Node.IsSelected) //Workaround of specific ComboBox control behavior
|
||||
base.MouseUp(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
[DesignTimeVisible(false), ToolboxItem(false)]
|
||||
public abstract class NodeControl : Component
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private TreeViewAdv _parent;
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public TreeViewAdv Parent
|
||||
{
|
||||
get { return _parent; }
|
||||
set
|
||||
{
|
||||
if (value != _parent)
|
||||
{
|
||||
if (_parent != null)
|
||||
_parent.NodeControls.Remove(this);
|
||||
|
||||
if (value != null)
|
||||
value.NodeControls.Add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IToolTipProvider _toolTipProvider;
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public IToolTipProvider ToolTipProvider
|
||||
{
|
||||
get { return _toolTipProvider; }
|
||||
set { _toolTipProvider = value; }
|
||||
}
|
||||
|
||||
private TreeColumn _parentColumn;
|
||||
public TreeColumn ParentColumn
|
||||
{
|
||||
get { return _parentColumn; }
|
||||
set
|
||||
{
|
||||
_parentColumn = value;
|
||||
if (_parent != null)
|
||||
_parent.FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private VerticalAlignment _verticalAlign = VerticalAlignment.Center;
|
||||
[DefaultValue(VerticalAlignment.Center)]
|
||||
public VerticalAlignment VerticalAlign
|
||||
{
|
||||
get { return _verticalAlign; }
|
||||
set
|
||||
{
|
||||
_verticalAlign = value;
|
||||
if (_parent != null)
|
||||
_parent.FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private int _leftMargin = 0;
|
||||
public int LeftMargin
|
||||
{
|
||||
get { return _leftMargin; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
_leftMargin = value;
|
||||
if (_parent != null)
|
||||
_parent.FullUpdate();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal virtual void AssignParent(TreeViewAdv parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
protected virtual Rectangle GetBounds(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
Rectangle r = context.Bounds;
|
||||
Size s = GetActualSize(node, context);
|
||||
Size bs = new Size(r.Width - LeftMargin, Math.Min(r.Height, s.Height));
|
||||
switch (VerticalAlign)
|
||||
{
|
||||
case VerticalAlignment.Top:
|
||||
return new Rectangle(new Point(r.X + LeftMargin, r.Y), bs);
|
||||
case VerticalAlignment.Bottom:
|
||||
return new Rectangle(new Point(r.X + LeftMargin, r.Bottom - s.Height), bs);
|
||||
default:
|
||||
return new Rectangle(new Point(r.X + LeftMargin, r.Y + (r.Height - s.Height) / 2), bs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CheckThread()
|
||||
{
|
||||
if (Parent != null && Control.CheckForIllegalCrossThreadCalls)
|
||||
if (Parent.InvokeRequired)
|
||||
throw new InvalidOperationException("Cross-thread calls are not allowed");
|
||||
}
|
||||
|
||||
public bool IsVisible(TreeNodeAdv node)
|
||||
{
|
||||
NodeControlValueEventArgs args = new NodeControlValueEventArgs(node);
|
||||
args.Value = true;
|
||||
OnIsVisibleValueNeeded(args);
|
||||
return Convert.ToBoolean(args.Value);
|
||||
}
|
||||
|
||||
internal Size GetActualSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
if (IsVisible(node))
|
||||
{
|
||||
Size s = MeasureSize(node, context);
|
||||
return new Size(s.Width + LeftMargin, s.Height);
|
||||
}
|
||||
else
|
||||
return Size.Empty;
|
||||
}
|
||||
|
||||
public abstract Size MeasureSize(TreeNodeAdv node, DrawContext context);
|
||||
|
||||
public abstract void Draw(TreeNodeAdv node, DrawContext context);
|
||||
|
||||
public virtual string GetToolTip(TreeNodeAdv node)
|
||||
{
|
||||
if (ToolTipProvider != null)
|
||||
return ToolTipProvider.GetToolTip(node, this);
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public virtual void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void MouseUp(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void KeyUp(KeyEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
public event EventHandler<NodeControlValueEventArgs> IsVisibleValueNeeded;
|
||||
protected virtual void OnIsVisibleValueNeeded(NodeControlValueEventArgs args)
|
||||
{
|
||||
if (IsVisibleValueNeeded != null)
|
||||
IsVisibleValueNeeded(this, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeControlValueEventArgs : NodeEventArgs
|
||||
{
|
||||
private object _value;
|
||||
public object Value
|
||||
{
|
||||
get { return _value; }
|
||||
set { _value = value; }
|
||||
}
|
||||
|
||||
public NodeControlValueEventArgs(TreeNodeAdv node)
|
||||
:base(node)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Design;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
internal class NodeControlsCollection : Collection<NodeControl>
|
||||
{
|
||||
private TreeViewAdv _tree;
|
||||
|
||||
public NodeControlsCollection(TreeViewAdv tree)
|
||||
{
|
||||
_tree = tree;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
_tree.BeginUpdate();
|
||||
try
|
||||
{
|
||||
while (this.Count != 0)
|
||||
this.RemoveAt(this.Count - 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_tree.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, NodeControl item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
|
||||
if (item.Parent != _tree)
|
||||
{
|
||||
if (item.Parent != null)
|
||||
{
|
||||
item.Parent.NodeControls.Remove(item);
|
||||
}
|
||||
base.InsertItem(index, item);
|
||||
item.AssignParent(_tree);
|
||||
_tree.FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
NodeControl value = this[index];
|
||||
value.AssignParent(null);
|
||||
base.RemoveItem(index);
|
||||
_tree.FullUpdate();
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, NodeControl item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
|
||||
_tree.BeginUpdate();
|
||||
try
|
||||
{
|
||||
RemoveAt(index);
|
||||
InsertItem(index, item);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_tree.EndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class NodeControlCollectionEditor : CollectionEditor
|
||||
{
|
||||
private Type[] _types;
|
||||
|
||||
public NodeControlCollectionEditor(Type type)
|
||||
: base(type)
|
||||
{
|
||||
_types = new Type[] { typeof(NodeTextBox), typeof(NodeIntegerTextBox), typeof(NodeDecimalTextBox),
|
||||
typeof(NodeComboBox), typeof(NodeCheckBox),
|
||||
typeof(NodeStateIcon), typeof(NodeIcon), typeof(NodeNumericUpDown), typeof(ExpandingIcon) };
|
||||
}
|
||||
|
||||
protected override System.Type[] CreateNewItemTypes()
|
||||
{
|
||||
return _types;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeDecimalTextBox : NodeTextBox
|
||||
{
|
||||
private bool _allowDecimalSeparator = true;
|
||||
[DefaultValue(true)]
|
||||
public bool AllowDecimalSeparator
|
||||
{
|
||||
get { return _allowDecimalSeparator; }
|
||||
set { _allowDecimalSeparator = value; }
|
||||
}
|
||||
|
||||
private bool _allowNegativeSign = true;
|
||||
[DefaultValue(true)]
|
||||
public bool AllowNegativeSign
|
||||
{
|
||||
get { return _allowNegativeSign; }
|
||||
set { _allowNegativeSign = value; }
|
||||
}
|
||||
|
||||
protected NodeDecimalTextBox()
|
||||
{
|
||||
}
|
||||
|
||||
protected override TextBox CreateTextBox()
|
||||
{
|
||||
NumericTextBox textBox = new NumericTextBox();
|
||||
textBox.AllowDecimalSeparator = AllowDecimalSeparator;
|
||||
textBox.AllowNegativeSign = AllowNegativeSign;
|
||||
return textBox;
|
||||
}
|
||||
|
||||
protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
SetValue(node, (editor as NumericTextBox).DecimalValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeEventArgs : EventArgs
|
||||
{
|
||||
private TreeNodeAdv _node;
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
}
|
||||
|
||||
public NodeEventArgs(TreeNodeAdv node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using Aga.Controls.Properties;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeIcon : BindableControl
|
||||
{
|
||||
public NodeIcon()
|
||||
{
|
||||
LeftMargin = 1;
|
||||
}
|
||||
|
||||
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
Image image = GetIcon(node);
|
||||
if (image != null)
|
||||
{
|
||||
int scaledX = node.Tree.GetScaledSize(image.Size.Width, false);
|
||||
int scaledY = node.Tree.GetScaledSize(image.Size.Height);
|
||||
return new Size(scaledX, scaledY); ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Size.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Draw(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
Image image = GetIcon(node);
|
||||
if (image != null)
|
||||
{
|
||||
Rectangle r = GetBounds(node, context);
|
||||
if ( image.Width > 0 && image.Height > 0 )
|
||||
{
|
||||
switch (_scaleMode)
|
||||
{
|
||||
case ImageScaleMode.Fit:
|
||||
context.Graphics.DrawImage(image, r);
|
||||
break;
|
||||
case ImageScaleMode.ScaleDown:
|
||||
{
|
||||
float factor = Math.Min((float)r.Width / (float)image.Width, (float)r.Height / (float)image.Height);
|
||||
if (factor < 1)
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width * factor, image.Height * factor);
|
||||
else
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width, image.Height);
|
||||
} break;
|
||||
case ImageScaleMode.ScaleUp:
|
||||
{
|
||||
float factor = Math.Max((float)r.Width / (float)image.Width, (float)r.Height / (float)image.Height);
|
||||
if (factor > 1)
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width * factor, image.Height * factor);
|
||||
else
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width, image.Height);
|
||||
} break;
|
||||
case ImageScaleMode.AlwaysScale:
|
||||
{
|
||||
float fx = (float)r.Width / (float)image.Width;
|
||||
float fy = (float)r.Height / (float)image.Height;
|
||||
if (Math.Min(fx, fy) < 1)
|
||||
{ //scale down
|
||||
float factor = Math.Min(fx, fy);
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width * factor, image.Height * factor);
|
||||
}
|
||||
else if (Math.Max(fx, fy) > 1)
|
||||
{
|
||||
float factor = Math.Max(fx, fy);
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width * factor, image.Height * factor);
|
||||
}
|
||||
else
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width, image.Height);
|
||||
} break;
|
||||
case ImageScaleMode.Clip:
|
||||
default:
|
||||
context.Graphics.DrawImage(image, r.X, r.Y, image.Width, image.Height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Image GetIcon(TreeNodeAdv node)
|
||||
{
|
||||
return GetValue(node) as Image;
|
||||
}
|
||||
|
||||
private ImageScaleMode _scaleMode = ImageScaleMode.Clip;
|
||||
[DefaultValue("Clip"), Category("Appearance")]
|
||||
public ImageScaleMode ScaleMode
|
||||
{
|
||||
get { return _scaleMode; }
|
||||
set { _scaleMode = value; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
|
||||
public class NodeIntegerTextBox : NodeTextBox
|
||||
{
|
||||
private bool _allowNegativeSign = true;
|
||||
[DefaultValue(true)]
|
||||
public bool AllowNegativeSign
|
||||
{
|
||||
get { return _allowNegativeSign; }
|
||||
set { _allowNegativeSign = value; }
|
||||
}
|
||||
|
||||
public NodeIntegerTextBox()
|
||||
{
|
||||
}
|
||||
|
||||
protected override TextBox CreateTextBox()
|
||||
{
|
||||
NumericTextBox textBox = new NumericTextBox();
|
||||
textBox.AllowDecimalSeparator = false;
|
||||
textBox.AllowNegativeSign = AllowNegativeSign;
|
||||
return textBox;
|
||||
}
|
||||
|
||||
protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
SetValue(node, (editor as NumericTextBox).IntValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing.Design;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeNumericUpDown : BaseTextControl
|
||||
{
|
||||
#region Properties
|
||||
|
||||
private int _editorWidth = 100;
|
||||
[DefaultValue(100)]
|
||||
public int EditorWidth
|
||||
{
|
||||
get { return _editorWidth; }
|
||||
set { _editorWidth = value; }
|
||||
}
|
||||
|
||||
private int _decimalPlaces = 0;
|
||||
[Category("Data"), DefaultValue(0)]
|
||||
public int DecimalPlaces
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._decimalPlaces;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._decimalPlaces = value;
|
||||
}
|
||||
}
|
||||
|
||||
private decimal _increment = 1;
|
||||
[Category("Data"), DefaultValue(1)]
|
||||
public decimal Increment
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._increment;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._increment = value;
|
||||
}
|
||||
}
|
||||
|
||||
private decimal _minimum = 0;
|
||||
[Category("Data"), DefaultValue(0)]
|
||||
public decimal Minimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return _minimum;
|
||||
}
|
||||
set
|
||||
{
|
||||
_minimum = value;
|
||||
}
|
||||
}
|
||||
|
||||
private decimal _maximum = 100;
|
||||
[Category("Data"), DefaultValue(100)]
|
||||
public decimal Maximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._maximum;
|
||||
}
|
||||
set
|
||||
{
|
||||
this._maximum = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public NodeNumericUpDown()
|
||||
{
|
||||
}
|
||||
|
||||
protected override Size CalculateEditorSize(EditorContext context)
|
||||
{
|
||||
if (Parent.UseColumns)
|
||||
return context.Bounds.Size;
|
||||
else
|
||||
return new Size(EditorWidth, context.Bounds.Height);
|
||||
}
|
||||
|
||||
protected override Control CreateEditor(TreeNodeAdv node)
|
||||
{
|
||||
NumericUpDown num = new NumericUpDown();
|
||||
num.Increment = Increment;
|
||||
num.DecimalPlaces = DecimalPlaces;
|
||||
num.Minimum = Minimum;
|
||||
num.Maximum = Maximum;
|
||||
num.Value = (decimal)GetValue(node);
|
||||
SetEditControlProperties(num, node);
|
||||
return num;
|
||||
}
|
||||
|
||||
protected override void DisposeEditor(Control editor)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
SetValue(node, (editor as NumericUpDown).Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Properties;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
internal class NodePlusMinus : NodeControl
|
||||
{
|
||||
public const int ImageSize = 9;
|
||||
public const int Width = 16;
|
||||
private Bitmap _plus;
|
||||
private Bitmap _minus;
|
||||
|
||||
private VisualStyleRenderer _openedRenderer;
|
||||
private VisualStyleRenderer OpenedRenderer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_openedRenderer == null)
|
||||
_openedRenderer = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Opened);
|
||||
return _openedRenderer;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private VisualStyleRenderer _closedRenderer;
|
||||
private VisualStyleRenderer ClosedRenderer
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_closedRenderer == null)
|
||||
_closedRenderer = new VisualStyleRenderer(VisualStyleElement.TreeView.Glyph.Closed);
|
||||
return _closedRenderer;
|
||||
}
|
||||
}
|
||||
|
||||
public NodePlusMinus()
|
||||
{
|
||||
_plus = Resources.plus;
|
||||
_minus = Resources.minus;
|
||||
}
|
||||
|
||||
public override Size MeasureSize(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
int scaledX = node.Tree.GetScaledSize(Width, false);
|
||||
int scaledY = node.Tree.GetScaledSize(Width);
|
||||
return new Size(scaledX, scaledY);
|
||||
}
|
||||
|
||||
public override void Draw(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
if (node.CanExpand)
|
||||
{
|
||||
Rectangle r = context.Bounds;
|
||||
int scaledX = node.Tree.GetScaledSize(ImageSize, false);
|
||||
int scaledY = node.Tree.GetScaledSize(ImageSize);
|
||||
int dy = (int)Math.Round((float)(r.Height - scaledY) / 2);
|
||||
if (TreeViewAdv.CustomPlusMinusRenderFunc != null)
|
||||
{
|
||||
TreeViewAdv.CustomPlusMinusRenderFunc(context.Graphics, r, node.IsExpanded);
|
||||
return;
|
||||
}
|
||||
else if (Application.RenderWithVisualStyles)
|
||||
{
|
||||
VisualStyleRenderer renderer;
|
||||
if (node.IsExpanded)
|
||||
renderer = OpenedRenderer;
|
||||
else
|
||||
renderer = ClosedRenderer;
|
||||
renderer.DrawBackground(context.Graphics, new Rectangle(r.X, r.Y + dy, scaledX, scaledY));
|
||||
}
|
||||
else
|
||||
{
|
||||
Image img;
|
||||
if (node.IsExpanded)
|
||||
img = _minus;
|
||||
else
|
||||
img = _plus;
|
||||
context.Graphics.DrawImageUnscaled(img, new Point(r.X, r.Y + dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDown(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
if (args.Button == MouseButtons.Left)
|
||||
{
|
||||
args.Handled = true;
|
||||
if (args.Node.CanExpand)
|
||||
args.Node.IsExpanded = !args.Node.IsExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
public override void MouseDoubleClick(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
args.Handled = true; // Supress expand/collapse when double click on plus/minus
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Properties;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeStateIcon: NodeIcon
|
||||
{
|
||||
private Image _leaf;
|
||||
private Image _opened;
|
||||
private Image _closed;
|
||||
|
||||
public NodeStateIcon()
|
||||
{
|
||||
_leaf = MakeTransparent(Resources.Leaf);
|
||||
_opened = MakeTransparent(Resources.Folder);
|
||||
_closed = MakeTransparent(Resources.FolderClosed);
|
||||
}
|
||||
|
||||
private static Image MakeTransparent(Bitmap bitmap)
|
||||
{
|
||||
bitmap.MakeTransparent(bitmap.GetPixel(0,0));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
protected override Image GetIcon(TreeNodeAdv node)
|
||||
{
|
||||
Image icon = base.GetIcon(node);
|
||||
if (icon != null)
|
||||
return icon;
|
||||
else if (node.IsLeaf)
|
||||
return _leaf;
|
||||
else if (node.CanExpand && node.IsExpanded)
|
||||
return _opened;
|
||||
else
|
||||
return _closed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Aga.Controls.Tree.NodeControls
|
||||
{
|
||||
public class NodeTextBox : BaseTextControl
|
||||
{
|
||||
private const int MinTextBoxWidth = 30;
|
||||
|
||||
public NodeTextBox()
|
||||
{
|
||||
}
|
||||
|
||||
protected override Size CalculateEditorSize(EditorContext context)
|
||||
{
|
||||
if (Parent.UseColumns)
|
||||
return context.Bounds.Size;
|
||||
else
|
||||
{
|
||||
Size size = GetLabelSize(context.CurrentNode, context.DrawContext, _label);
|
||||
int width = Math.Max(size.Width + Font.Height, MinTextBoxWidth); // reserve a place for new typed character
|
||||
return new Size(width, size.Height);
|
||||
}
|
||||
}
|
||||
|
||||
public override void KeyDown(KeyEventArgs args)
|
||||
{
|
||||
if (args.KeyCode == Keys.F2 && Parent.CurrentNode != null && EditEnabled)
|
||||
{
|
||||
args.Handled = true;
|
||||
BeginEdit();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Control CreateEditor(TreeNodeAdv node)
|
||||
{
|
||||
TextBox textBox = CreateTextBox();
|
||||
textBox.TextAlign = TextAlign;
|
||||
textBox.Text = GetLabel(node);
|
||||
textBox.BorderStyle = BorderStyle.FixedSingle;
|
||||
textBox.TextChanged += EditorTextChanged;
|
||||
textBox.KeyDown += EditorKeyDown;
|
||||
_label = textBox.Text;
|
||||
SetEditControlProperties(textBox, node);
|
||||
return textBox;
|
||||
}
|
||||
|
||||
protected virtual TextBox CreateTextBox()
|
||||
{
|
||||
return new TextBox();
|
||||
}
|
||||
|
||||
protected override void DisposeEditor(Control editor)
|
||||
{
|
||||
var textBox = editor as TextBox;
|
||||
textBox.TextChanged -= EditorTextChanged;
|
||||
textBox.KeyDown -= EditorKeyDown;
|
||||
}
|
||||
|
||||
private void EditorKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
EndEdit(false);
|
||||
else if (e.KeyCode == Keys.Enter)
|
||||
EndEdit(true);
|
||||
}
|
||||
|
||||
private string _label;
|
||||
private void EditorTextChanged(object sender, EventArgs e)
|
||||
{
|
||||
var textBox = sender as TextBox;
|
||||
_label = textBox.Text;
|
||||
Parent.UpdateEditorBounds();
|
||||
}
|
||||
|
||||
protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
|
||||
{
|
||||
var label = (editor as TextBox).Text;
|
||||
string oldLabel = GetLabel(node);
|
||||
if (oldLabel != label)
|
||||
{
|
||||
SetLabel(node, label);
|
||||
OnLabelChanged(node.Tag, oldLabel, label);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Cut(Control control)
|
||||
{
|
||||
(control as TextBox).Cut();
|
||||
}
|
||||
|
||||
public override void Copy(Control control)
|
||||
{
|
||||
(control as TextBox).Copy();
|
||||
}
|
||||
|
||||
public override void Paste(Control control)
|
||||
{
|
||||
(control as TextBox).Paste();
|
||||
}
|
||||
|
||||
public override void Delete(Control control)
|
||||
{
|
||||
var textBox = control as TextBox;
|
||||
int len = Math.Max(textBox.SelectionLength, 1);
|
||||
if (textBox.SelectionStart < textBox.Text.Length)
|
||||
{
|
||||
int start = textBox.SelectionStart;
|
||||
textBox.Text = textBox.Text.Remove(textBox.SelectionStart, len);
|
||||
textBox.SelectionStart = start;
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<LabelEventArgs> LabelChanged;
|
||||
protected void OnLabelChanged(object subject, string oldLabel, string newLabel)
|
||||
{
|
||||
if (LabelChanged != null)
|
||||
LabelChanged(this, new LabelEventArgs(subject, oldLabel, newLabel));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class SortedTreeModel: TreeModelBase
|
||||
{
|
||||
private ITreeModel _innerModel;
|
||||
public ITreeModel InnerModel
|
||||
{
|
||||
get { return _innerModel; }
|
||||
}
|
||||
|
||||
private IComparer _comparer;
|
||||
public IComparer Comparer
|
||||
{
|
||||
get { return _comparer; }
|
||||
set
|
||||
{
|
||||
_comparer = value;
|
||||
OnStructureChanged(new TreePathEventArgs(TreePath.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
public SortedTreeModel(ITreeModel innerModel)
|
||||
{
|
||||
_innerModel = innerModel;
|
||||
_innerModel.NodesChanged += new EventHandler<TreeModelEventArgs>(_innerModel_NodesChanged);
|
||||
_innerModel.NodesInserted += new EventHandler<TreeModelEventArgs>(_innerModel_NodesInserted);
|
||||
_innerModel.NodesRemoved += new EventHandler<TreeModelEventArgs>(_innerModel_NodesRemoved);
|
||||
_innerModel.StructureChanged += new EventHandler<TreePathEventArgs>(_innerModel_StructureChanged);
|
||||
}
|
||||
|
||||
void _innerModel_StructureChanged(object sender, TreePathEventArgs e)
|
||||
{
|
||||
OnStructureChanged(e);
|
||||
}
|
||||
|
||||
void _innerModel_NodesRemoved(object sender, TreeModelEventArgs e)
|
||||
{
|
||||
OnStructureChanged(new TreePathEventArgs(e.Path));
|
||||
}
|
||||
|
||||
void _innerModel_NodesInserted(object sender, TreeModelEventArgs e)
|
||||
{
|
||||
OnStructureChanged(new TreePathEventArgs(e.Path));
|
||||
}
|
||||
|
||||
void _innerModel_NodesChanged(object sender, TreeModelEventArgs e)
|
||||
{
|
||||
OnStructureChanged(new TreePathEventArgs(e.Path));
|
||||
}
|
||||
|
||||
public override IEnumerable GetChildren(TreePath treePath)
|
||||
{
|
||||
if (Comparer != null)
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
IEnumerable res = InnerModel.GetChildren(treePath);
|
||||
if (res != null)
|
||||
{
|
||||
foreach (object obj in res)
|
||||
list.Add(obj);
|
||||
list.Sort(Comparer);
|
||||
return list;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
else
|
||||
return InnerModel.GetChildren(treePath);
|
||||
}
|
||||
|
||||
public override bool IsLeaf(TreePath treePath)
|
||||
{
|
||||
return InnerModel.IsLeaf(treePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
385
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeColumn.cs
Normal file
@@ -0,0 +1,385 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
[TypeConverter(typeof(TreeColumn.TreeColumnConverter)), DesignTimeVisible(false), ToolboxItem(false)]
|
||||
public class TreeColumn : Component
|
||||
{
|
||||
private class TreeColumnConverter : ComponentConverter
|
||||
{
|
||||
public TreeColumnConverter()
|
||||
: base(typeof(TreeColumn))
|
||||
{
|
||||
}
|
||||
|
||||
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private const int HeaderLeftMargin = 5;
|
||||
private const int HeaderRightMargin = 5;
|
||||
private const int SortOrderMarkMargin = 8;
|
||||
|
||||
private TextFormatFlags _headerFlags;
|
||||
private TextFormatFlags _baseHeaderFlags = TextFormatFlags.NoPadding |
|
||||
TextFormatFlags.EndEllipsis |
|
||||
TextFormatFlags.VerticalCenter |
|
||||
TextFormatFlags.PreserveGraphicsTranslateTransform;
|
||||
|
||||
#region Properties
|
||||
|
||||
private TreeColumnCollection _owner;
|
||||
internal TreeColumnCollection Owner
|
||||
{
|
||||
get { return _owner; }
|
||||
set { _owner = value; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public int Index
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Owner != null)
|
||||
return Owner.IndexOf(this);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private string _header;
|
||||
[Localizable(true)]
|
||||
public string Header
|
||||
{
|
||||
get { return _header; }
|
||||
set
|
||||
{
|
||||
_header = value;
|
||||
OnHeaderChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private string _tooltipText;
|
||||
[Localizable(true)]
|
||||
public string TooltipText
|
||||
{
|
||||
get { return _tooltipText; }
|
||||
set { _tooltipText = value; }
|
||||
}
|
||||
|
||||
private int _width;
|
||||
[DefaultValue(50), Localizable(true)]
|
||||
public int Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_width != value)
|
||||
{
|
||||
_width = Math.Max(MinColumnWidth, value);
|
||||
if (_maxColumnWidth > 0)
|
||||
{
|
||||
_width = Math.Min(_width, MaxColumnWidth);
|
||||
}
|
||||
OnWidthChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _minColumnWidth;
|
||||
[DefaultValue(0)]
|
||||
public int MinColumnWidth
|
||||
{
|
||||
get { return _minColumnWidth; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
_minColumnWidth = value;
|
||||
Width = Math.Max(value, Width);
|
||||
}
|
||||
}
|
||||
|
||||
private int _maxColumnWidth;
|
||||
[DefaultValue(0)]
|
||||
public int MaxColumnWidth
|
||||
{
|
||||
get { return _maxColumnWidth; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
_maxColumnWidth = value;
|
||||
if (value > 0)
|
||||
Width = Math.Min(value, _width);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _visible = true;
|
||||
[DefaultValue(true)]
|
||||
public bool IsVisible
|
||||
{
|
||||
get { return _visible; }
|
||||
set
|
||||
{
|
||||
_visible = value;
|
||||
OnIsVisibleChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private HorizontalAlignment _textAlign = HorizontalAlignment.Left;
|
||||
[DefaultValue(HorizontalAlignment.Left)]
|
||||
public HorizontalAlignment TextAlign
|
||||
{
|
||||
get { return _textAlign; }
|
||||
set
|
||||
{
|
||||
if (value != _textAlign)
|
||||
{
|
||||
_textAlign = value;
|
||||
_headerFlags = _baseHeaderFlags | TextHelper.TranslateAligmentToFlag(value);
|
||||
OnHeaderChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _sortable = false;
|
||||
[DefaultValue(false)]
|
||||
public bool Sortable
|
||||
{
|
||||
get { return _sortable; }
|
||||
set { _sortable = value; }
|
||||
}
|
||||
|
||||
private SortOrder _sort_order = SortOrder.None;
|
||||
public SortOrder SortOrder
|
||||
{
|
||||
get { return _sort_order; }
|
||||
set
|
||||
{
|
||||
if (value == _sort_order)
|
||||
return;
|
||||
_sort_order = value;
|
||||
OnSortOrderChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Size SortMarkSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Application.RenderWithVisualStyles)
|
||||
return new Size(9, 5);
|
||||
else
|
||||
return new Size(7, 4);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public TreeColumn():
|
||||
this(string.Empty, 50)
|
||||
{
|
||||
}
|
||||
|
||||
public TreeColumn(string header, int width)
|
||||
{
|
||||
_header = header;
|
||||
_width = width;
|
||||
_headerFlags = _baseHeaderFlags | TextFormatFlags.Left;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Header))
|
||||
return GetType().Name;
|
||||
else
|
||||
return Header;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Draw
|
||||
|
||||
private static VisualStyleRenderer _normalRenderer;
|
||||
private static VisualStyleRenderer _pressedRenderer;
|
||||
private static VisualStyleRenderer _hotRenderer;
|
||||
|
||||
private static void CreateRenderers()
|
||||
{
|
||||
if (Application.RenderWithVisualStyles && _normalRenderer == null)
|
||||
{
|
||||
_normalRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Normal);
|
||||
_pressedRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Pressed);
|
||||
_hotRenderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Hot);
|
||||
}
|
||||
}
|
||||
|
||||
internal Bitmap CreateGhostImage(Rectangle bounds, Font font)
|
||||
{
|
||||
Bitmap b = new Bitmap(bounds.Width, bounds.Height, PixelFormat.Format32bppArgb);
|
||||
Graphics gr = Graphics.FromImage(b);
|
||||
gr.FillRectangle(SystemBrushes.ControlDark, bounds);
|
||||
DrawContent(gr, bounds, font);
|
||||
BitmapHelper.SetAlphaChanelValue(b, 150);
|
||||
return b;
|
||||
}
|
||||
|
||||
internal void Draw(Graphics gr, Rectangle bounds, Font font, bool pressed, bool hot)
|
||||
{
|
||||
DrawBackground(gr, bounds, pressed, hot);
|
||||
DrawContent(gr, bounds, font);
|
||||
}
|
||||
|
||||
private void DrawContent(Graphics gr, Rectangle bounds, Font font)
|
||||
{
|
||||
if (TreeViewAdv.CustomColumnTextRenderFunc != null)
|
||||
{
|
||||
TreeViewAdv.CustomColumnTextRenderFunc(gr, bounds, font, Header);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rectangle innerBounds = new Rectangle(bounds.X + HeaderLeftMargin, bounds.Y,
|
||||
bounds.Width - HeaderLeftMargin - HeaderRightMargin,
|
||||
bounds.Height);
|
||||
|
||||
if (SortOrder != SortOrder.None)
|
||||
innerBounds.Width -= (SortMarkSize.Width + SortOrderMarkMargin);
|
||||
|
||||
Size maxTextSize = TextRenderer.MeasureText(gr, Header, font, innerBounds.Size, TextFormatFlags.NoPadding);
|
||||
Size textSize = TextRenderer.MeasureText(gr, Header, font, innerBounds.Size, _baseHeaderFlags);
|
||||
|
||||
if (SortOrder != SortOrder.None)
|
||||
{
|
||||
int tw = Math.Min(textSize.Width, innerBounds.Size.Width);
|
||||
|
||||
int x = 0;
|
||||
if (TextAlign == HorizontalAlignment.Left)
|
||||
x = innerBounds.X + tw + SortOrderMarkMargin;
|
||||
else if (TextAlign == HorizontalAlignment.Right)
|
||||
x = innerBounds.Right + SortOrderMarkMargin;
|
||||
else
|
||||
x = innerBounds.X + tw + (innerBounds.Width - tw) / 2 + SortOrderMarkMargin;
|
||||
DrawSortMark(gr, bounds, x);
|
||||
}
|
||||
|
||||
if (textSize.Width < maxTextSize.Width)
|
||||
TextRenderer.DrawText(gr, Header, font, innerBounds, SystemColors.ControlText, _baseHeaderFlags | TextFormatFlags.Left);
|
||||
else
|
||||
TextRenderer.DrawText(gr, Header, font, innerBounds, SystemColors.ControlText, _headerFlags);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSortMark(Graphics gr, Rectangle bounds, int x)
|
||||
{
|
||||
int y = bounds.Y + bounds.Height / 2 - 2;
|
||||
x = Math.Max(x, bounds.X + SortOrderMarkMargin);
|
||||
|
||||
int w2 = SortMarkSize.Width / 2;
|
||||
if (SortOrder == SortOrder.Ascending)
|
||||
{
|
||||
Point[] points = new Point[] { new Point(x, y), new Point(x + SortMarkSize.Width, y), new Point(x + w2, y + SortMarkSize.Height) };
|
||||
gr.FillPolygon(SystemBrushes.ControlDark, points);
|
||||
}
|
||||
else if (SortOrder == SortOrder.Descending)
|
||||
{
|
||||
Point[] points = new Point[] { new Point(x - 1, y + SortMarkSize.Height), new Point(x + SortMarkSize.Width, y + SortMarkSize.Height), new Point(x + w2, y - 1) };
|
||||
gr.FillPolygon(SystemBrushes.ControlDark, points);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawDropMark(Graphics gr, Rectangle rect)
|
||||
{
|
||||
gr.FillRectangle(SystemBrushes.HotTrack, rect.X-1, rect.Y, 2, rect.Height);
|
||||
}
|
||||
|
||||
internal static void DrawBackground(Graphics gr, Rectangle bounds, bool pressed, bool hot)
|
||||
{
|
||||
if (TreeViewAdv.CustomColumnBackgroundRenderFunc != null)
|
||||
{
|
||||
TreeViewAdv.CustomColumnBackgroundRenderFunc(gr, bounds, pressed, hot);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Application.RenderWithVisualStyles)
|
||||
{
|
||||
CreateRenderers();
|
||||
if (pressed)
|
||||
_pressedRenderer.DrawBackground(gr, bounds);
|
||||
else if (hot)
|
||||
_hotRenderer.DrawBackground(gr, bounds);
|
||||
else
|
||||
_normalRenderer.DrawBackground(gr, bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
gr.FillRectangle(SystemBrushes.Control, bounds);
|
||||
Pen p1 = SystemPens.ControlLightLight;
|
||||
Pen p2 = SystemPens.ControlDark;
|
||||
Pen p3 = SystemPens.ControlDarkDark;
|
||||
if (pressed)
|
||||
gr.DrawRectangle(p2, bounds.X, bounds.Y, bounds.Width, bounds.Height);
|
||||
else
|
||||
{
|
||||
gr.DrawLine(p1, bounds.X, bounds.Y, bounds.Right, bounds.Y);
|
||||
gr.DrawLine(p3, bounds.X, bounds.Bottom, bounds.Right, bounds.Bottom);
|
||||
gr.DrawLine(p3, bounds.Right - 1, bounds.Y, bounds.Right - 1, bounds.Bottom - 1);
|
||||
gr.DrawLine(p1, bounds.Left, bounds.Y + 1, bounds.Left, bounds.Bottom - 2);
|
||||
gr.DrawLine(p2, bounds.Right - 2, bounds.Y + 1, bounds.Right - 2, bounds.Bottom - 2);
|
||||
gr.DrawLine(p2, bounds.X, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler HeaderChanged;
|
||||
private void OnHeaderChanged()
|
||||
{
|
||||
if (HeaderChanged != null)
|
||||
HeaderChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler SortOrderChanged;
|
||||
private void OnSortOrderChanged()
|
||||
{
|
||||
if (SortOrderChanged != null)
|
||||
SortOrderChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler IsVisibleChanged;
|
||||
private void OnIsVisibleChanged()
|
||||
{
|
||||
if (IsVisibleChanged != null)
|
||||
IsVisibleChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public event EventHandler WidthChanged;
|
||||
private void OnWidthChanged()
|
||||
{
|
||||
if (WidthChanged != null)
|
||||
WidthChanged(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
internal class TreeColumnCollection : Collection<TreeColumn>
|
||||
{
|
||||
private TreeViewAdv _treeView;
|
||||
|
||||
public TreeColumnCollection(TreeViewAdv treeView)
|
||||
{
|
||||
_treeView = treeView;
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, TreeColumn item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
BindEvents(item);
|
||||
_treeView.UpdateColumns();
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
UnbindEvents(this[index]);
|
||||
base.RemoveItem(index);
|
||||
_treeView.UpdateColumns();
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, TreeColumn item)
|
||||
{
|
||||
UnbindEvents(this[index]);
|
||||
base.SetItem(index, item);
|
||||
item.Owner = this;
|
||||
BindEvents(item);
|
||||
_treeView.UpdateColumns();
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
foreach (TreeColumn c in Items)
|
||||
UnbindEvents(c);
|
||||
Items.Clear();
|
||||
_treeView.UpdateColumns();
|
||||
}
|
||||
|
||||
private void BindEvents(TreeColumn item)
|
||||
{
|
||||
item.Owner = this;
|
||||
item.HeaderChanged += HeaderChanged;
|
||||
item.IsVisibleChanged += IsVisibleChanged;
|
||||
item.WidthChanged += WidthChanged;
|
||||
item.SortOrderChanged += SortOrderChanged;
|
||||
}
|
||||
|
||||
private void UnbindEvents(TreeColumn item)
|
||||
{
|
||||
item.Owner = null;
|
||||
item.HeaderChanged -= HeaderChanged;
|
||||
item.IsVisibleChanged -= IsVisibleChanged;
|
||||
item.WidthChanged -= WidthChanged;
|
||||
item.SortOrderChanged -= SortOrderChanged;
|
||||
}
|
||||
|
||||
void SortOrderChanged(object sender, EventArgs e)
|
||||
{
|
||||
TreeColumn changed = sender as TreeColumn;
|
||||
//Only one column at a time can have a sort property set
|
||||
if (changed.SortOrder != SortOrder.None)
|
||||
{
|
||||
foreach (TreeColumn col in this)
|
||||
{
|
||||
if (col != changed)
|
||||
col.SortOrder = SortOrder.None;
|
||||
}
|
||||
}
|
||||
_treeView.UpdateHeaders();
|
||||
}
|
||||
|
||||
void WidthChanged(object sender, EventArgs e)
|
||||
{
|
||||
_treeView.ChangeColumnWidth(sender as TreeColumn);
|
||||
}
|
||||
|
||||
void IsVisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
_treeView.FullUpdate();
|
||||
}
|
||||
|
||||
void HeaderChanged(object sender, EventArgs e)
|
||||
{
|
||||
_treeView.UpdateView();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeColumnEventArgs: EventArgs
|
||||
{
|
||||
private TreeColumn _column;
|
||||
public TreeColumn Column
|
||||
{
|
||||
get { return _column; }
|
||||
}
|
||||
|
||||
public TreeColumnEventArgs(TreeColumn column)
|
||||
{
|
||||
_column = column;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts IEnumerable interface to ITreeModel.
|
||||
/// Allows to display a plain list in the TreeView
|
||||
/// </summary>
|
||||
public class TreeListAdapter : ITreeModel
|
||||
{
|
||||
private System.Collections.IEnumerable _list;
|
||||
|
||||
public TreeListAdapter(System.Collections.IEnumerable list)
|
||||
{
|
||||
_list = list;
|
||||
}
|
||||
|
||||
#region ITreeModel Members
|
||||
|
||||
public System.Collections.IEnumerable GetChildren(TreePath treePath)
|
||||
{
|
||||
if (treePath.IsEmpty())
|
||||
return _list;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsLeaf(TreePath treePath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesChanged;
|
||||
public void OnNodesChanged(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesChanged != null)
|
||||
NodesChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreePathEventArgs> StructureChanged;
|
||||
public void OnStructureChanged(TreePathEventArgs args)
|
||||
{
|
||||
if (StructureChanged != null)
|
||||
StructureChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesInserted;
|
||||
public void OnNodeInserted(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesInserted != null)
|
||||
NodesInserted(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesRemoved;
|
||||
public void OnNodeRemoved(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesRemoved != null)
|
||||
NodesRemoved(this, args);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
127
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeModel.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a simple ready to use implementation of <see cref="ITreeModel"/>. Warning: this class is not optimized
|
||||
/// to work with big amount of data. In this case create you own implementation of <c>ITreeModel</c>, and pay attention
|
||||
/// on GetChildren and IsLeaf methods.
|
||||
/// </summary>
|
||||
public class TreeModel : ITreeModel
|
||||
{
|
||||
private Node _root;
|
||||
public Node Root
|
||||
{
|
||||
get { return _root; }
|
||||
}
|
||||
|
||||
public Collection<Node> Nodes
|
||||
{
|
||||
get { return _root.Nodes; }
|
||||
}
|
||||
|
||||
public TreeModel()
|
||||
{
|
||||
_root = new Node();
|
||||
_root.Model = this;
|
||||
}
|
||||
|
||||
public TreePath GetPath(Node node)
|
||||
{
|
||||
if (node == _root)
|
||||
return TreePath.Empty;
|
||||
else
|
||||
{
|
||||
Stack<object> stack = new Stack<object>();
|
||||
while (node != _root)
|
||||
{
|
||||
stack.Push(node);
|
||||
node = node.Parent;
|
||||
}
|
||||
return new TreePath(stack.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public Node FindNode(TreePath path)
|
||||
{
|
||||
if (path.IsEmpty())
|
||||
return _root;
|
||||
else
|
||||
return FindNode(_root, path, 0);
|
||||
}
|
||||
|
||||
private Node FindNode(Node root, TreePath path, int level)
|
||||
{
|
||||
foreach (Node node in root.Nodes)
|
||||
if (node == path.FullPath[level])
|
||||
{
|
||||
if (level == path.FullPath.Length - 1)
|
||||
return node;
|
||||
else
|
||||
return FindNode(node, path, level + 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region ITreeModel Members
|
||||
|
||||
public System.Collections.IEnumerable GetChildren(TreePath treePath)
|
||||
{
|
||||
Node node = FindNode(treePath);
|
||||
if (node != null)
|
||||
foreach (Node n in node.Nodes)
|
||||
yield return n;
|
||||
else
|
||||
yield break;
|
||||
}
|
||||
|
||||
public bool IsLeaf(TreePath treePath)
|
||||
{
|
||||
Node node = FindNode(treePath);
|
||||
if (node != null)
|
||||
return node.IsLeaf;
|
||||
else
|
||||
throw new ArgumentException("treePath");
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesChanged;
|
||||
internal void OnNodesChanged(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesChanged != null)
|
||||
NodesChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreePathEventArgs> StructureChanged;
|
||||
public void OnStructureChanged(TreePathEventArgs args)
|
||||
{
|
||||
if (StructureChanged != null)
|
||||
StructureChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesInserted;
|
||||
internal void OnNodeInserted(Node parent, int index, Node node)
|
||||
{
|
||||
if (NodesInserted != null)
|
||||
{
|
||||
TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node });
|
||||
NodesInserted(this, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesRemoved;
|
||||
internal void OnNodeRemoved(Node parent, int index, Node node)
|
||||
{
|
||||
if (NodesRemoved != null)
|
||||
{
|
||||
TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node });
|
||||
NodesRemoved(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public abstract class TreeModelBase: ITreeModel
|
||||
{
|
||||
public abstract System.Collections.IEnumerable GetChildren(TreePath treePath);
|
||||
public abstract bool IsLeaf(TreePath treePath);
|
||||
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesChanged;
|
||||
protected void OnNodesChanged(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesChanged != null)
|
||||
NodesChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreePathEventArgs> StructureChanged;
|
||||
protected void OnStructureChanged(TreePathEventArgs args)
|
||||
{
|
||||
if (StructureChanged != null)
|
||||
StructureChanged(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesInserted;
|
||||
protected void OnNodesInserted(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesInserted != null)
|
||||
NodesInserted(this, args);
|
||||
}
|
||||
|
||||
public event EventHandler<TreeModelEventArgs> NodesRemoved;
|
||||
protected void OnNodesRemoved(TreeModelEventArgs args)
|
||||
{
|
||||
if (NodesRemoved != null)
|
||||
NodesRemoved(this, args);
|
||||
}
|
||||
|
||||
public virtual void Refresh()
|
||||
{
|
||||
OnStructureChanged(new TreePathEventArgs(TreePath.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeModelEventArgs: TreePathEventArgs
|
||||
{
|
||||
private object[] _children;
|
||||
public object[] Children
|
||||
{
|
||||
get { return _children; }
|
||||
}
|
||||
|
||||
private int[] _indices;
|
||||
public int[] Indices
|
||||
{
|
||||
get { return _indices; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="parent">Path to a parent node</param>
|
||||
/// <param name="children">Child nodes</param>
|
||||
public TreeModelEventArgs(TreePath parent, object[] children)
|
||||
: this(parent, null, children)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="parent">Path to a parent node</param>
|
||||
/// <param name="indices">Indices of children in parent nodes collection</param>
|
||||
/// <param name="children">Child nodes</param>
|
||||
public TreeModelEventArgs(TreePath parent, int[] indices, object[] children)
|
||||
: base(parent)
|
||||
{
|
||||
if (children == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
if (indices != null && indices.Length != children.Length)
|
||||
throw new ArgumentException("indices and children arrays must have the same length");
|
||||
|
||||
_indices = indices;
|
||||
_children = children;
|
||||
}
|
||||
}
|
||||
}
|
||||
443
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeNodeAdv.cs
Normal file
@@ -0,0 +1,443 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Permissions;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class TreeNodeAdv : ISerializable
|
||||
{
|
||||
#region NodeCollection
|
||||
private class NodeCollection : Collection<TreeNodeAdv>
|
||||
{
|
||||
private TreeNodeAdv _owner;
|
||||
|
||||
public NodeCollection(TreeNodeAdv owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
while (this.Count != 0)
|
||||
this.RemoveAt(this.Count - 1);
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, TreeNodeAdv item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
|
||||
if (item.Parent != _owner)
|
||||
{
|
||||
if (item.Parent != null)
|
||||
item.Parent.Nodes.Remove(item);
|
||||
item._parent = _owner;
|
||||
item._index = index;
|
||||
for (int i = index; i < Count; i++)
|
||||
this[i]._index++;
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
if (_owner.Tree != null && _owner.Tree.Model == null)
|
||||
{
|
||||
_owner.Tree.SmartFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
TreeNodeAdv item = this[index];
|
||||
item._parent = null;
|
||||
item._index = -1;
|
||||
for (int i = index + 1; i < Count; i++)
|
||||
this[i]._index--;
|
||||
base.RemoveItem(index);
|
||||
|
||||
if (_owner.Tree != null && _owner.Tree.Model == null)
|
||||
{
|
||||
_owner.Tree.UpdateSelection();
|
||||
_owner.Tree.SmartFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, TreeNodeAdv item)
|
||||
{
|
||||
if (item == null)
|
||||
throw new ArgumentNullException("item");
|
||||
RemoveAt(index);
|
||||
InsertItem(index, item);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
public event EventHandler<TreeViewAdvEventArgs> Collapsing;
|
||||
internal void OnCollapsing()
|
||||
{
|
||||
if (Collapsing != null)
|
||||
Collapsing(this, new TreeViewAdvEventArgs(this));
|
||||
}
|
||||
|
||||
public event EventHandler<TreeViewAdvEventArgs> Collapsed;
|
||||
internal void OnCollapsed()
|
||||
{
|
||||
if (Collapsed != null)
|
||||
Collapsed(this, new TreeViewAdvEventArgs(this));
|
||||
}
|
||||
|
||||
public event EventHandler<TreeViewAdvEventArgs> Expanding;
|
||||
internal void OnExpanding()
|
||||
{
|
||||
if (Expanding != null)
|
||||
Expanding(this, new TreeViewAdvEventArgs(this));
|
||||
}
|
||||
|
||||
public event EventHandler<TreeViewAdvEventArgs> Expanded;
|
||||
internal void OnExpanded()
|
||||
{
|
||||
if (Expanded != null)
|
||||
Expanded(this, new TreeViewAdvEventArgs(this));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
private TreeViewAdv _tree;
|
||||
public TreeViewAdv Tree
|
||||
{
|
||||
get { return _tree; }
|
||||
}
|
||||
|
||||
private int _row;
|
||||
public int Row
|
||||
{
|
||||
get { return _row; }
|
||||
internal set { _row = value; }
|
||||
}
|
||||
|
||||
private int _index = -1;
|
||||
public int Index
|
||||
{
|
||||
get
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get { return _isSelected; }
|
||||
set
|
||||
{
|
||||
if (_isSelected != value)
|
||||
{
|
||||
if (Tree.IsMyNode(this))
|
||||
{
|
||||
//_tree.OnSelectionChanging
|
||||
if (value)
|
||||
{
|
||||
if (!_tree.Selection.Contains(this))
|
||||
_tree.Selection.Add(this);
|
||||
|
||||
if (_tree.Selection.Count == 1)
|
||||
_tree.CurrentNode = this;
|
||||
}
|
||||
else
|
||||
_tree.Selection.Remove(this);
|
||||
_tree.UpdateView();
|
||||
_tree.OnSelectionChanged();
|
||||
}
|
||||
_isSelected = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all parent nodes of this node are expanded.
|
||||
/// </summary>
|
||||
internal bool IsVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
TreeNodeAdv node = _parent;
|
||||
while (node != null)
|
||||
{
|
||||
if (!node.IsExpanded)
|
||||
return false;
|
||||
node = node.Parent;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isLeaf;
|
||||
public bool IsLeaf
|
||||
{
|
||||
get { return _isLeaf; }
|
||||
internal set { _isLeaf = value; }
|
||||
}
|
||||
|
||||
private bool _isExpandedOnce;
|
||||
public bool IsExpandedOnce
|
||||
{
|
||||
get { return _isExpandedOnce; }
|
||||
internal set { _isExpandedOnce = value; }
|
||||
}
|
||||
|
||||
private bool _isExpanded;
|
||||
public bool IsExpanded
|
||||
{
|
||||
get { return _isExpanded; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
Expand();
|
||||
else
|
||||
Collapse();
|
||||
}
|
||||
}
|
||||
|
||||
internal void AssignIsExpanded(bool value)
|
||||
{
|
||||
_isExpanded = value;
|
||||
}
|
||||
|
||||
private TreeNodeAdv _parent;
|
||||
public TreeNodeAdv Parent
|
||||
{
|
||||
get { return _parent; }
|
||||
}
|
||||
|
||||
public int Level
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parent == null)
|
||||
return 0;
|
||||
else
|
||||
return _parent.Level + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public TreeNodeAdv PreviousNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parent != null)
|
||||
{
|
||||
int index = Index;
|
||||
if (index > 0)
|
||||
return _parent.Nodes[index - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public TreeNodeAdv NextNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parent != null)
|
||||
{
|
||||
int index = Index;
|
||||
if (index < _parent.Nodes.Count - 1)
|
||||
return _parent.Nodes[index + 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal TreeNodeAdv BottomNode
|
||||
{
|
||||
get
|
||||
{
|
||||
TreeNodeAdv parent = this.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
if (parent.NextNode != null)
|
||||
return parent.NextNode;
|
||||
else
|
||||
return parent.BottomNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
internal TreeNodeAdv NextVisibleNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsExpanded && Nodes.Count > 0)
|
||||
return Nodes[0];
|
||||
else
|
||||
{
|
||||
TreeNodeAdv nn = NextNode;
|
||||
if (nn != null)
|
||||
return nn;
|
||||
else
|
||||
return BottomNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExpand
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Nodes.Count > 0 || (!IsExpandedOnce && !IsLeaf));
|
||||
}
|
||||
}
|
||||
|
||||
private object _tag;
|
||||
public object Tag
|
||||
{
|
||||
get { return _tag; }
|
||||
}
|
||||
|
||||
private Collection<TreeNodeAdv> _nodes;
|
||||
internal Collection<TreeNodeAdv> Nodes
|
||||
{
|
||||
get { return _nodes; }
|
||||
}
|
||||
|
||||
private ReadOnlyCollection<TreeNodeAdv> _children;
|
||||
public ReadOnlyCollection<TreeNodeAdv> Children
|
||||
{
|
||||
get
|
||||
{
|
||||
return _children;
|
||||
}
|
||||
}
|
||||
|
||||
private int? _rightBounds;
|
||||
internal int? RightBounds
|
||||
{
|
||||
get { return _rightBounds; }
|
||||
set { _rightBounds = value; }
|
||||
}
|
||||
|
||||
private int? _height;
|
||||
internal int? Height
|
||||
{
|
||||
get { return _height; }
|
||||
set { _height = value; }
|
||||
}
|
||||
|
||||
private bool _isExpandingNow;
|
||||
internal bool IsExpandingNow
|
||||
{
|
||||
get { return _isExpandingNow; }
|
||||
set { _isExpandingNow = value; }
|
||||
}
|
||||
|
||||
private bool _autoExpandOnStructureChanged = true;
|
||||
public bool AutoExpandOnStructureChanged
|
||||
{
|
||||
get { return _autoExpandOnStructureChanged; }
|
||||
set { _autoExpandOnStructureChanged = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public TreeNodeAdv(object tag)
|
||||
: this(null, tag)
|
||||
{
|
||||
}
|
||||
|
||||
internal TreeNodeAdv(TreeViewAdv tree, object tag)
|
||||
{
|
||||
_row = -1;
|
||||
_tree = tree;
|
||||
_nodes = new NodeCollection(this);
|
||||
_children = new ReadOnlyCollection<TreeNodeAdv>(_nodes);
|
||||
_tag = tag;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Tag != null)
|
||||
return Tag.ToString();
|
||||
else
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
public void Collapse()
|
||||
{
|
||||
if (_isExpanded)
|
||||
Collapse(true);
|
||||
}
|
||||
|
||||
public void CollapseAll()
|
||||
{
|
||||
Collapse(false);
|
||||
}
|
||||
|
||||
public void Collapse(bool ignoreChildren)
|
||||
{
|
||||
SetIsExpanded(false, ignoreChildren);
|
||||
}
|
||||
|
||||
public void Expand()
|
||||
{
|
||||
if (!_isExpanded)
|
||||
Expand(true);
|
||||
}
|
||||
|
||||
public void ExpandAll()
|
||||
{
|
||||
Expand(false);
|
||||
}
|
||||
|
||||
public void Expand(bool ignoreChildren)
|
||||
{
|
||||
SetIsExpanded(true, ignoreChildren);
|
||||
}
|
||||
|
||||
private void SetIsExpanded(bool value, bool ignoreChildren)
|
||||
{
|
||||
if (Tree == null)
|
||||
_isExpanded = value;
|
||||
else
|
||||
Tree.SetIsExpanded(this, value, ignoreChildren);
|
||||
}
|
||||
|
||||
#region ISerializable Members
|
||||
|
||||
private TreeNodeAdv(SerializationInfo info, StreamingContext context)
|
||||
: this(null, null)
|
||||
{
|
||||
int nodesCount = 0;
|
||||
nodesCount = info.GetInt32("NodesCount");
|
||||
_isExpanded = info.GetBoolean("IsExpanded");
|
||||
_tag = info.GetValue("Tag", typeof(object));
|
||||
|
||||
for (int i = 0; i < nodesCount; i++)
|
||||
{
|
||||
TreeNodeAdv child = (TreeNodeAdv)info.GetValue("Child" + i, typeof(TreeNodeAdv));
|
||||
Nodes.Add(child);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue("IsExpanded", IsExpanded);
|
||||
info.AddValue("NodesCount", Nodes.Count);
|
||||
if ((Tag != null) && Tag.GetType().IsSerializable)
|
||||
info.AddValue("Tag", Tag, Tag.GetType());
|
||||
|
||||
for (int i = 0; i < Nodes.Count; i++)
|
||||
info.AddValue("Child" + i, Nodes[i], typeof(TreeNodeAdv));
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeNodeAdvMouseEventArgs : MouseEventArgs
|
||||
{
|
||||
private TreeNodeAdv _node;
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
internal set { _node = value; }
|
||||
}
|
||||
|
||||
private NodeControl _control;
|
||||
public NodeControl Control
|
||||
{
|
||||
get { return _control; }
|
||||
internal set { _control = value; }
|
||||
}
|
||||
|
||||
private Point _viewLocation;
|
||||
public Point ViewLocation
|
||||
{
|
||||
get { return _viewLocation; }
|
||||
internal set { _viewLocation = value; }
|
||||
}
|
||||
|
||||
private Keys _modifierKeys;
|
||||
public Keys ModifierKeys
|
||||
{
|
||||
get { return _modifierKeys; }
|
||||
internal set { _modifierKeys = value; }
|
||||
}
|
||||
|
||||
private bool _handled;
|
||||
public bool Handled
|
||||
{
|
||||
get { return _handled; }
|
||||
set { _handled = value; }
|
||||
}
|
||||
|
||||
private Rectangle _controlBounds;
|
||||
public Rectangle ControlBounds
|
||||
{
|
||||
get { return _controlBounds; }
|
||||
internal set { _controlBounds = value; }
|
||||
}
|
||||
|
||||
public TreeNodeAdvMouseEventArgs(MouseEventArgs args)
|
||||
: base(args.Button, args.Clicks, args.X, args.Y, args.Delta)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
68
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreePath.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreePath
|
||||
{
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
|
||||
public static readonly TreePath Empty = new TreePath();
|
||||
|
||||
private object[] _path;
|
||||
public object[] FullPath
|
||||
{
|
||||
get { return _path; }
|
||||
}
|
||||
|
||||
public object LastNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_path.Length > 0)
|
||||
return _path[_path.Length - 1];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public object FirstNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_path.Length > 0)
|
||||
return _path[0];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public TreePath()
|
||||
{
|
||||
_path = new object[0];
|
||||
}
|
||||
|
||||
public TreePath(object node)
|
||||
{
|
||||
_path = new object[] { node };
|
||||
}
|
||||
|
||||
public TreePath(object[] path)
|
||||
{
|
||||
_path = path;
|
||||
}
|
||||
|
||||
public TreePath(TreePath parent, object node)
|
||||
{
|
||||
_path = new object[parent.FullPath.Length + 1];
|
||||
for (int i = 0; i < _path.Length - 1; i++)
|
||||
_path[i] = parent.FullPath[i];
|
||||
_path[_path.Length - 1] = node;
|
||||
}
|
||||
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return (_path.Length == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreePathEventArgs : EventArgs
|
||||
{
|
||||
private TreePath _path;
|
||||
public TreePath Path
|
||||
{
|
||||
get { return _path; }
|
||||
}
|
||||
|
||||
public TreePathEventArgs()
|
||||
{
|
||||
_path = new TreePath();
|
||||
}
|
||||
|
||||
public TreePathEventArgs(TreePath path)
|
||||
{
|
||||
if (path == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
_path = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Designer.cs
generated
Normal file
@@ -0,0 +1,69 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
partial class TreeViewAdv
|
||||
{
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
if (_dragBitmap != null) _dragBitmap.Dispose();
|
||||
if (_dragTimer != null) _dragTimer.Dispose();
|
||||
if (_linePen != null) _linePen.Dispose();
|
||||
if (_markPen != null) _markPen.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this._vScrollBar = new System.Windows.Forms.VScrollBar();
|
||||
this._hScrollBar = new System.Windows.Forms.HScrollBar();
|
||||
this._errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this._errorProvider)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// _vScrollBar
|
||||
//
|
||||
this._vScrollBar.LargeChange = 1;
|
||||
this._vScrollBar.Location = new System.Drawing.Point(0, 0);
|
||||
this._vScrollBar.Maximum = 0;
|
||||
this._vScrollBar.Name = "_vScrollBar";
|
||||
this._vScrollBar.Size = new System.Drawing.Size(13, 80);
|
||||
this._vScrollBar.TabIndex = 1;
|
||||
this._vScrollBar.ValueChanged += new System.EventHandler(this._vScrollBar_ValueChanged);
|
||||
this._vScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this._vScrollBar_Scroll);
|
||||
//
|
||||
// _hScrollBar
|
||||
//
|
||||
this._hScrollBar.LargeChange = 1;
|
||||
this._hScrollBar.Location = new System.Drawing.Point(0, 0);
|
||||
this._hScrollBar.Maximum = 0;
|
||||
this._hScrollBar.Name = "_hScrollBar";
|
||||
this._hScrollBar.Size = new System.Drawing.Size(80, 13);
|
||||
this._hScrollBar.TabIndex = 2;
|
||||
this._hScrollBar.ValueChanged += new System.EventHandler(this._hScrollBar_ValueChanged);
|
||||
this._hScrollBar.Scroll += new System.Windows.Forms.ScrollEventHandler(this._hScrollBar_Scroll);
|
||||
//
|
||||
// TreeViewAdv
|
||||
//
|
||||
this.BackColor = System.Drawing.SystemColors.Window;
|
||||
this.Controls.Add(this._vScrollBar);
|
||||
this.Controls.Add(this._hScrollBar);
|
||||
((System.ComponentModel.ISupportInitialize)(this._errorProvider)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
private VScrollBar _vScrollBar;
|
||||
private HScrollBar _hScrollBar;
|
||||
private ErrorProvider _errorProvider;
|
||||
}
|
||||
}
|
||||
310
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.Draw.cs
Normal file
@@ -0,0 +1,310 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Windows.Forms;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public partial class TreeViewAdv
|
||||
{
|
||||
public void AutoSizeColumn(TreeColumn column)
|
||||
{
|
||||
if (!Columns.Contains(column))
|
||||
throw new ArgumentException("column");
|
||||
|
||||
DrawContext context = new DrawContext();
|
||||
context.Graphics = Graphics.FromImage(new Bitmap(1, 1));
|
||||
context.Font = this.Font;
|
||||
int res = 0;
|
||||
for (int row = 0; row < RowCount; row++)
|
||||
{
|
||||
if (row < RowMap.Count)
|
||||
{
|
||||
int w = 0;
|
||||
TreeNodeAdv node = RowMap[row];
|
||||
foreach (NodeControl nc in NodeControls)
|
||||
{
|
||||
if (nc.ParentColumn == column)
|
||||
w += nc.GetActualSize(node, _measureContext).Width;
|
||||
}
|
||||
res = Math.Max(res, w);
|
||||
}
|
||||
}
|
||||
|
||||
if (res > 0)
|
||||
column.Width = res;
|
||||
}
|
||||
|
||||
private void CreatePens()
|
||||
{
|
||||
CreateLinePen();
|
||||
CreateMarkPen();
|
||||
}
|
||||
|
||||
private void CreateMarkPen()
|
||||
{
|
||||
GraphicsPath path = new GraphicsPath();
|
||||
path.AddLines(new Point[] { new Point(0, 0), new Point(1, 1), new Point(-1, 1), new Point(0, 0) });
|
||||
CustomLineCap cap = new CustomLineCap(null, path);
|
||||
cap.WidthScale = 1.0f;
|
||||
|
||||
_markPen = new Pen(_dragDropMarkColor, _dragDropMarkWidth);
|
||||
_markPen.CustomStartCap = cap;
|
||||
_markPen.CustomEndCap = cap;
|
||||
}
|
||||
|
||||
private void CreateLinePen()
|
||||
{
|
||||
_linePen = new Pen(_lineColor);
|
||||
_linePen.DashStyle = DashStyle.Dot;
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
BeginPerformanceCount();
|
||||
PerformanceAnalyzer.Start("OnPaint");
|
||||
|
||||
DrawContext context = new DrawContext();
|
||||
context.Graphics = e.Graphics;
|
||||
context.Font = this.Font;
|
||||
context.Enabled = Enabled;
|
||||
|
||||
int y = 0;
|
||||
int gridHeight = 0;
|
||||
|
||||
if (UseColumns)
|
||||
{
|
||||
DrawColumnHeaders(e.Graphics);
|
||||
y += ColumnHeaderHeight;
|
||||
if (Columns.Count == 0 || e.ClipRectangle.Height <= y)
|
||||
return;
|
||||
}
|
||||
|
||||
int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
|
||||
y -= firstRowY;
|
||||
|
||||
e.Graphics.ResetTransform();
|
||||
e.Graphics.TranslateTransform(-OffsetX, y);
|
||||
Rectangle displayRect = DisplayRectangle;
|
||||
for (int row = FirstVisibleRow; row < RowCount; row++)
|
||||
{
|
||||
Rectangle rowRect = _rowLayout.GetRowBounds(row);
|
||||
gridHeight += rowRect.Height;
|
||||
if (rowRect.Y + y > displayRect.Bottom)
|
||||
break;
|
||||
else
|
||||
DrawRow(e, ref context, row, rowRect);
|
||||
}
|
||||
|
||||
if ((GridLineStyle & GridLineStyle.Vertical) == GridLineStyle.Vertical && UseColumns)
|
||||
DrawVerticalGridLines(e.Graphics, firstRowY);
|
||||
|
||||
if (_dropPosition.Node != null && DragMode && HighlightDropPosition)
|
||||
DrawDropMark(e.Graphics);
|
||||
|
||||
e.Graphics.ResetTransform();
|
||||
DrawScrollBarsBox(e.Graphics);
|
||||
|
||||
if (DragMode && _dragBitmap != null)
|
||||
e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));
|
||||
|
||||
PerformanceAnalyzer.Finish("OnPaint");
|
||||
EndPerformanceCount(e);
|
||||
}
|
||||
|
||||
private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
|
||||
{
|
||||
TreeNodeAdv node = RowMap[row];
|
||||
context.DrawSelection = DrawSelectionMode.None;
|
||||
context.CurrentEditorOwner = CurrentEditorOwner;
|
||||
if (DragMode)
|
||||
{
|
||||
if ((_dropPosition.Node == node) && _dropPosition.Position == NodePosition.Inside && HighlightDropPosition)
|
||||
context.DrawSelection = DrawSelectionMode.Active;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.IsSelected && Focused)
|
||||
context.DrawSelection = DrawSelectionMode.Active;
|
||||
else if (node.IsSelected && !Focused && !HideSelection)
|
||||
context.DrawSelection = DrawSelectionMode.Inactive;
|
||||
}
|
||||
context.DrawFocus = Focused && CurrentNode == node;
|
||||
|
||||
OnRowDraw(e, node, context, row, rowRect);
|
||||
|
||||
if ((GridLineStyle & GridLineStyle.Horizontal) == GridLineStyle.Horizontal) {
|
||||
e.Graphics.DrawLine(CustomHorizontalLinePen, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);
|
||||
}
|
||||
|
||||
if (FullRowSelect)
|
||||
{
|
||||
context.DrawFocus = false;
|
||||
if (context.DrawSelection == DrawSelectionMode.Active || context.DrawSelection == DrawSelectionMode.Inactive)
|
||||
{
|
||||
Rectangle focusRect = new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
|
||||
if (context.DrawSelection == DrawSelectionMode.Active)
|
||||
{
|
||||
e.Graphics.FillRectangle(CustomSelectedRowBrush, focusRect);
|
||||
context.DrawSelection = DrawSelectionMode.FullRowSelect;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Graphics.FillRectangle(CustomSelectedRowBrush, focusRect);
|
||||
context.DrawSelection = DrawSelectionMode.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowLines)
|
||||
DrawLines(e.Graphics, node, rowRect);
|
||||
|
||||
DrawNode(node, context);
|
||||
}
|
||||
|
||||
private void DrawVerticalGridLines(Graphics gr, int y)
|
||||
{
|
||||
int x = 0;
|
||||
foreach (TreeColumn c in Columns)
|
||||
{
|
||||
if (c.IsVisible)
|
||||
{
|
||||
x += c.Width;
|
||||
gr.DrawLine(SystemPens.InactiveBorder, x - 1, y, x - 1, gr.ClipBounds.Bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawColumnHeaders(Graphics gr)
|
||||
{
|
||||
PerformanceAnalyzer.Start("DrawColumnHeaders");
|
||||
ReorderColumnState reorder = Input as ReorderColumnState;
|
||||
int x = 0;
|
||||
TreeColumn.DrawBackground(gr, new Rectangle(0, 0, ClientRectangle.Width + 2, ColumnHeaderHeight - 1), false, false);
|
||||
gr.TranslateTransform(-OffsetX, 0);
|
||||
foreach (TreeColumn c in Columns)
|
||||
{
|
||||
if (c.IsVisible)
|
||||
{
|
||||
if (x >= OffsetX && x - OffsetX < this.Bounds.Width)// skip invisible columns
|
||||
{
|
||||
Rectangle rect = new Rectangle(x, 0, c.Width, ColumnHeaderHeight - 1);
|
||||
gr.SetClip(rect);
|
||||
bool pressed = ((Input is ClickColumnState || reorder != null) && ((Input as ColumnState).Column == c));
|
||||
c.Draw(gr, rect, Font, pressed, _hotColumn == c);
|
||||
gr.ResetClip();
|
||||
|
||||
if (reorder != null && reorder.DropColumn == c)
|
||||
TreeColumn.DrawDropMark(gr, rect);
|
||||
}
|
||||
x += c.Width;
|
||||
}
|
||||
}
|
||||
|
||||
if (reorder != null)
|
||||
{
|
||||
if (reorder.DropColumn == null)
|
||||
TreeColumn.DrawDropMark(gr, new Rectangle(x, 0, 0, ColumnHeaderHeight));
|
||||
gr.DrawImage(reorder.GhostImage, new Point(reorder.Location.X + + reorder.DragOffset, reorder.Location.Y));
|
||||
}
|
||||
PerformanceAnalyzer.Finish("DrawColumnHeaders");
|
||||
}
|
||||
|
||||
public void DrawNode(TreeNodeAdv node, DrawContext context)
|
||||
{
|
||||
foreach (NodeControlInfo item in GetNodeControls(node))
|
||||
{
|
||||
if (item.Bounds.Right >= OffsetX && item.Bounds.X - OffsetX < this.Bounds.Width)// skip invisible nodes
|
||||
{
|
||||
context.Bounds = item.Bounds;
|
||||
context.Graphics.SetClip(context.Bounds);
|
||||
item.Control.Draw(node, context);
|
||||
context.Graphics.ResetClip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawScrollBarsBox(Graphics gr)
|
||||
{
|
||||
Rectangle r1 = DisplayRectangle;
|
||||
Rectangle r2 = ClientRectangle;
|
||||
gr.FillRectangle(SystemBrushes.Control,
|
||||
new Rectangle(r1.Right, r1.Bottom, r2.Width - r1.Width, r2.Height - r1.Height));
|
||||
}
|
||||
|
||||
private void DrawDropMark(Graphics gr)
|
||||
{
|
||||
if (_dropPosition.Position == NodePosition.Inside)
|
||||
return;
|
||||
|
||||
Rectangle rect = GetNodeBounds(_dropPosition.Node);
|
||||
int right = DisplayRectangle.Right - LeftMargin + OffsetX;
|
||||
int y = rect.Y;
|
||||
if (_dropPosition.Position == NodePosition.After)
|
||||
y = rect.Bottom;
|
||||
gr.DrawLine(_markPen, rect.X, y, right, y);
|
||||
}
|
||||
|
||||
private void DrawLines(Graphics gr, TreeNodeAdv node, Rectangle rowRect)
|
||||
{
|
||||
if (UseColumns && Columns.Count > 0)
|
||||
gr.SetClip(new Rectangle(0, rowRect.Y, Columns[0].Width, rowRect.Bottom));
|
||||
|
||||
TreeNodeAdv curNode = node;
|
||||
while (curNode != _root && curNode != null)
|
||||
{
|
||||
int level = curNode.Level;
|
||||
int scaledIndent = node.Tree.GetScaledSize(_indent, false);
|
||||
int x = (level - 1) * scaledIndent + NodePlusMinus.ImageSize / 2 + LeftMargin;
|
||||
int width = node.Tree.GetScaledSize(NodePlusMinus.Width - NodePlusMinus.ImageSize / 2, false);
|
||||
int y = rowRect.Y;
|
||||
int y2 = y + rowRect.Height;
|
||||
|
||||
if (curNode == node)
|
||||
{
|
||||
int midy = y + rowRect.Height / 2;
|
||||
gr.DrawLine(_linePen, x, midy, x + width, midy);
|
||||
if (curNode.NextNode == null)
|
||||
y2 = y + rowRect.Height / 2;
|
||||
}
|
||||
|
||||
if (node.Row == 0)
|
||||
y = rowRect.Height / 2;
|
||||
if (curNode.NextNode != null || curNode == node)
|
||||
gr.DrawLine(_linePen, x, y, x, y2);
|
||||
|
||||
curNode = curNode.Parent;
|
||||
}
|
||||
|
||||
gr.ResetClip();
|
||||
}
|
||||
|
||||
#region Performance
|
||||
|
||||
private double _totalTime;
|
||||
private int _paintCount;
|
||||
|
||||
[Conditional("PERF_TEST")]
|
||||
private void BeginPerformanceCount()
|
||||
{
|
||||
_paintCount++;
|
||||
TimeCounter.Start();
|
||||
}
|
||||
|
||||
[Conditional("PERF_TEST")]
|
||||
private void EndPerformanceCount(PaintEventArgs e)
|
||||
{
|
||||
double time = TimeCounter.Finish();
|
||||
_totalTime += time;
|
||||
string debugText = string.Format("FPS {0:0.0}; Avg. FPS {1:0.0}",
|
||||
1 / time, 1 / (_totalTime / _paintCount));
|
||||
e.Graphics.FillRectangle(Brushes.White, new Rectangle(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20, 150, 20));
|
||||
e.Graphics.DrawString(debugText, Control.DefaultFont, Brushes.Gray,
|
||||
new PointF(DisplayRectangle.Width - 150, DisplayRectangle.Height - 20));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
partial class TreeViewAdv
|
||||
{
|
||||
private TreeNodeAdv _editingNode;
|
||||
|
||||
public EditableControl CurrentEditorOwner { get; private set; }
|
||||
public Control CurrentEditor { get; private set; }
|
||||
|
||||
public void HideEditor()
|
||||
{
|
||||
if (CurrentEditorOwner != null)
|
||||
CurrentEditorOwner.EndEdit(false);
|
||||
}
|
||||
|
||||
internal void DisplayEditor(Control editor, EditableControl owner)
|
||||
{
|
||||
if (editor == null || owner == null || CurrentNode == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
HideEditor(false);
|
||||
|
||||
CurrentEditor = editor;
|
||||
CurrentEditorOwner = owner;
|
||||
_editingNode = CurrentNode;
|
||||
|
||||
editor.Validating += EditorValidating;
|
||||
UpdateEditorBounds();
|
||||
UpdateView();
|
||||
editor.Parent = this;
|
||||
editor.Focus();
|
||||
owner.UpdateEditor(editor);
|
||||
}
|
||||
|
||||
internal bool HideEditor(bool applyChanges)
|
||||
{
|
||||
if (CurrentEditor != null)
|
||||
{
|
||||
if (applyChanges)
|
||||
{
|
||||
if (!ApplyChanges())
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check once more if editor was closed in ApplyChanges
|
||||
if (CurrentEditor != null)
|
||||
{
|
||||
CurrentEditor.Validating -= EditorValidating;
|
||||
CurrentEditorOwner.DoDisposeEditor(CurrentEditor);
|
||||
|
||||
CurrentEditor.Parent = null;
|
||||
CurrentEditor.Dispose();
|
||||
|
||||
CurrentEditor = null;
|
||||
CurrentEditorOwner = null;
|
||||
_editingNode = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ApplyChanges()
|
||||
{
|
||||
try
|
||||
{
|
||||
CurrentEditorOwner.ApplyChanges(_editingNode, CurrentEditor);
|
||||
_errorProvider.Clear();
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
_errorProvider.SetError(CurrentEditor, ex.Message);
|
||||
/*CurrentEditor.Validating -= EditorValidating;
|
||||
MessageBox.Show(this, ex.Message, "Value is not valid", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
CurrentEditor.Focus();
|
||||
CurrentEditor.Validating += EditorValidating;*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void EditorValidating(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
e.Cancel = !ApplyChanges();
|
||||
}
|
||||
|
||||
public void UpdateEditorBounds()
|
||||
{
|
||||
if (CurrentEditor != null)
|
||||
{
|
||||
EditorContext context = new EditorContext();
|
||||
context.Owner = CurrentEditorOwner;
|
||||
context.CurrentNode = CurrentNode;
|
||||
context.Editor = CurrentEditor;
|
||||
context.DrawContext = _measureContext;
|
||||
SetEditorBounds(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetEditorBounds(EditorContext context)
|
||||
{
|
||||
foreach (NodeControlInfo info in GetNodeControls(context.CurrentNode))
|
||||
{
|
||||
if (context.Owner == info.Control && info.Control is EditableControl)
|
||||
{
|
||||
Point p = info.Bounds.Location;
|
||||
p.X += info.Control.LeftMargin;
|
||||
p.X -= OffsetX;
|
||||
p.Y -= (_rowLayout.GetRowBounds(FirstVisibleRow).Y - ColumnHeaderHeight);
|
||||
int width = DisplayRectangle.Width - p.X;
|
||||
if (UseColumns && info.Control.ParentColumn != null && Columns.Contains(info.Control.ParentColumn))
|
||||
{
|
||||
Rectangle rect = GetColumnBounds(info.Control.ParentColumn.Index);
|
||||
width = rect.Right - OffsetX - p.X;
|
||||
}
|
||||
context.Bounds = new Rectangle(p.X, p.Y, width, info.Bounds.Height);
|
||||
((EditableControl)info.Control).SetEditorBounds(context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle GetColumnBounds(int column)
|
||||
{
|
||||
int x = 0;
|
||||
for (int i = 0; i < Columns.Count; i++)
|
||||
{
|
||||
if (Columns[i].IsVisible)
|
||||
{
|
||||
if (i < column)
|
||||
x += Columns[i].Width;
|
||||
else
|
||||
return new Rectangle(x, 0, Columns[i].Width, 0);
|
||||
}
|
||||
}
|
||||
return Rectangle.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Threading;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public partial class TreeViewAdv
|
||||
{
|
||||
#region Keys
|
||||
|
||||
protected override bool IsInputChar(char charCode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool IsInputKey(Keys keyData)
|
||||
{
|
||||
if (((keyData & Keys.Up) == Keys.Up)
|
||||
|| ((keyData & Keys.Down) == Keys.Down)
|
||||
|| ((keyData & Keys.Left) == Keys.Left)
|
||||
|| ((keyData & Keys.Right) == Keys.Right))
|
||||
return true;
|
||||
else
|
||||
return base.IsInputKey(keyData);
|
||||
}
|
||||
|
||||
internal void ChangeInput()
|
||||
{
|
||||
if ((ModifierKeys & Keys.Shift) == Keys.Shift)
|
||||
{
|
||||
if (!(Input is InputWithShift))
|
||||
Input = new InputWithShift(this);
|
||||
}
|
||||
else if ((ModifierKeys & Keys.Control) == Keys.Control)
|
||||
{
|
||||
if (!(Input is InputWithControl))
|
||||
Input = new InputWithControl(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(Input.GetType() == typeof(NormalInputState)))
|
||||
Input = new NormalInputState(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyDown(e);
|
||||
if (!e.Handled)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)
|
||||
ChangeInput();
|
||||
Input.KeyDown(e);
|
||||
if (!e.Handled)
|
||||
{
|
||||
foreach (NodeControlInfo item in GetNodeControls(CurrentNode))
|
||||
{
|
||||
item.Control.KeyDown(e);
|
||||
if (e.Handled)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyUp(KeyEventArgs e)
|
||||
{
|
||||
base.OnKeyUp(e);
|
||||
if (!e.Handled)
|
||||
{
|
||||
if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)
|
||||
ChangeInput();
|
||||
if (!e.Handled)
|
||||
{
|
||||
foreach (NodeControlInfo item in GetNodeControls(CurrentNode))
|
||||
{
|
||||
item.Control.KeyUp(e);
|
||||
if (e.Handled)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
||||
{
|
||||
base.OnKeyPress(e);
|
||||
if (!e.Handled)
|
||||
_search.Search(e.KeyChar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Mouse
|
||||
|
||||
private TreeNodeAdvMouseEventArgs CreateMouseArgs(MouseEventArgs e)
|
||||
{
|
||||
TreeNodeAdvMouseEventArgs args = new TreeNodeAdvMouseEventArgs(e);
|
||||
args.ViewLocation = new Point(e.X + OffsetX,
|
||||
e.Y + _rowLayout.GetRowBounds(FirstVisibleRow).Y - ColumnHeaderHeight);
|
||||
args.ModifierKeys = ModifierKeys;
|
||||
args.Node = GetNodeAt(e.Location);
|
||||
NodeControlInfo info = GetNodeControlInfoAt(args.Node, e.Location);
|
||||
args.ControlBounds = info.Bounds;
|
||||
args.Control = info.Control;
|
||||
return args;
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseEventArgs e)
|
||||
{
|
||||
_search.EndSearch();
|
||||
if (SystemInformation.MouseWheelScrollLines > 0)
|
||||
{
|
||||
int lines = e.Delta / 120 * SystemInformation.MouseWheelScrollLines;
|
||||
int newValue = _vScrollBar.Value - lines;
|
||||
newValue = Math.Min(_vScrollBar.Maximum - _vScrollBar.LargeChange + 1, newValue);
|
||||
newValue = Math.Min(_vScrollBar.Maximum, newValue);
|
||||
_vScrollBar.Value = Math.Max(_vScrollBar.Minimum, newValue);
|
||||
}
|
||||
base.OnMouseWheel(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
if (CurrentEditorOwner != null)
|
||||
{
|
||||
CurrentEditorOwner.EndEdit(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Focused)
|
||||
Focus();
|
||||
|
||||
_search.EndSearch();
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
TreeColumn c;
|
||||
c = GetColumnDividerAt(e.Location);
|
||||
if (c != null)
|
||||
{
|
||||
Input = new ResizeColumnState(this, c, e.Location);
|
||||
return;
|
||||
}
|
||||
c = GetColumnAt(e.Location);
|
||||
if (c != null)
|
||||
{
|
||||
Input = new ClickColumnState(this, c, e.Location);
|
||||
UpdateView();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeInput();
|
||||
TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
|
||||
|
||||
if (args.Node != null && args.Control != null)
|
||||
args.Control.MouseDown(args);
|
||||
|
||||
if (!args.Handled)
|
||||
Input.MouseDown(args);
|
||||
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseClick(MouseEventArgs e)
|
||||
{
|
||||
//TODO: Disable when click on plusminus icon
|
||||
TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
|
||||
if (args.Node != null)
|
||||
OnNodeMouseClick(args);
|
||||
|
||||
base.OnMouseClick(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseDoubleClick(MouseEventArgs e)
|
||||
{
|
||||
TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
|
||||
|
||||
if (args.Node != null && args.Control != null)
|
||||
args.Control.MouseDoubleClick(args);
|
||||
|
||||
if (!args.Handled)
|
||||
{
|
||||
if (args.Node != null)
|
||||
OnNodeMouseDoubleClick(args);
|
||||
else
|
||||
Input.MouseDoubleClick(args);
|
||||
|
||||
if (!args.Handled)
|
||||
{
|
||||
if (args.Node != null && args.Button == MouseButtons.Left)
|
||||
args.Node.IsExpanded = !args.Node.IsExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMouseDoubleClick(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
{
|
||||
TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
|
||||
if (Input is ResizeColumnState)
|
||||
Input.MouseUp(args);
|
||||
else
|
||||
{
|
||||
if (args.Node != null && args.Control != null)
|
||||
args.Control.MouseUp(args);
|
||||
if (!args.Handled)
|
||||
Input.MouseUp(args);
|
||||
|
||||
base.OnMouseUp(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
if (Input.MouseMove(e))
|
||||
return;
|
||||
|
||||
base.OnMouseMove(e);
|
||||
SetCursor(e);
|
||||
UpdateToolTip(e);
|
||||
if (ItemDragMode && Dist(e.Location, ItemDragStart) > ItemDragSensivity
|
||||
&& CurrentNode != null && CurrentNode.IsSelected)
|
||||
{
|
||||
ItemDragMode = false;
|
||||
_toolTip.Active = false;
|
||||
OnItemDrag(e.Button, Selection.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseLeave(EventArgs e)
|
||||
{
|
||||
_hotColumn = null;
|
||||
UpdateHeaders();
|
||||
base.OnMouseLeave(e);
|
||||
}
|
||||
|
||||
private void SetCursor(MouseEventArgs e)
|
||||
{
|
||||
TreeColumn col;
|
||||
col = GetColumnDividerAt(e.Location);
|
||||
if (col == null)
|
||||
_innerCursor = null;
|
||||
else
|
||||
{
|
||||
if (col.Width == 0)
|
||||
_innerCursor = ResourceHelper.DVSplitCursor;
|
||||
else
|
||||
_innerCursor = Cursors.VSplit;
|
||||
}
|
||||
|
||||
col = GetColumnAt(e.Location);
|
||||
if (col != _hotColumn)
|
||||
{
|
||||
_hotColumn = col;
|
||||
UpdateHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
internal TreeColumn GetColumnAt(Point p)
|
||||
{
|
||||
if (p.Y > ColumnHeaderHeight)
|
||||
return null;
|
||||
|
||||
int x = -OffsetX;
|
||||
foreach (TreeColumn col in Columns)
|
||||
{
|
||||
if (col.IsVisible)
|
||||
{
|
||||
Rectangle rect = new Rectangle(x, 0, col.Width, ColumnHeaderHeight);
|
||||
x += col.Width;
|
||||
if (rect.Contains(p))
|
||||
return col;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal int GetColumnX(TreeColumn column)
|
||||
{
|
||||
int x = -OffsetX;
|
||||
foreach (TreeColumn col in Columns)
|
||||
{
|
||||
if (col.IsVisible)
|
||||
{
|
||||
if (column == col)
|
||||
return x;
|
||||
else
|
||||
x += col.Width;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
internal TreeColumn GetColumnDividerAt(Point p)
|
||||
{
|
||||
if (p.Y > ColumnHeaderHeight)
|
||||
return null;
|
||||
|
||||
int x = -OffsetX;
|
||||
TreeColumn prevCol = null;
|
||||
Rectangle left, right;
|
||||
foreach (TreeColumn col in Columns)
|
||||
{
|
||||
if (col.IsVisible)
|
||||
{
|
||||
if (col.Width > 0)
|
||||
{
|
||||
left = new Rectangle(x, 0, DividerWidth / 2, ColumnHeaderHeight);
|
||||
right = new Rectangle(x + col.Width - (DividerWidth / 2), 0, DividerWidth / 2, ColumnHeaderHeight);
|
||||
if (left.Contains(p) && prevCol != null)
|
||||
return prevCol;
|
||||
else if (right.Contains(p))
|
||||
return col;
|
||||
}
|
||||
prevCol = col;
|
||||
x += col.Width;
|
||||
}
|
||||
}
|
||||
|
||||
left = new Rectangle(x, 0, DividerWidth / 2, ColumnHeaderHeight);
|
||||
if (left.Contains(p) && prevCol != null)
|
||||
return prevCol;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
TreeColumn _tooltipColumn;
|
||||
private void UpdateToolTip(MouseEventArgs e)
|
||||
{
|
||||
TreeColumn col = GetColumnAt(e.Location);
|
||||
if (col != null)
|
||||
{
|
||||
if (col != _tooltipColumn)
|
||||
SetTooltip(col.TooltipText);
|
||||
}
|
||||
else
|
||||
DisplayNodesTooltip(e);
|
||||
_tooltipColumn = col;
|
||||
}
|
||||
|
||||
TreeNodeAdv _hotNode;
|
||||
NodeControl _hotControl;
|
||||
private void DisplayNodesTooltip(MouseEventArgs e)
|
||||
{
|
||||
if (ShowNodeToolTips)
|
||||
{
|
||||
TreeNodeAdvMouseEventArgs args = CreateMouseArgs(e);
|
||||
if (args.Node != null && args.Control != null)
|
||||
{
|
||||
if (args.Node != _hotNode || args.Control != _hotControl)
|
||||
SetTooltip(GetNodeToolTip(args));
|
||||
}
|
||||
else
|
||||
_toolTip.SetToolTip(this, null);
|
||||
|
||||
_hotControl = args.Control;
|
||||
_hotNode = args.Node;
|
||||
}
|
||||
else
|
||||
_toolTip.SetToolTip(this, null);
|
||||
}
|
||||
|
||||
private void SetTooltip(string text)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(text))
|
||||
{
|
||||
_toolTip.Active = false;
|
||||
_toolTip.SetToolTip(this, text);
|
||||
_toolTip.Active = true;
|
||||
}
|
||||
else
|
||||
_toolTip.SetToolTip(this, null);
|
||||
}
|
||||
|
||||
private string GetNodeToolTip(TreeNodeAdvMouseEventArgs args)
|
||||
{
|
||||
string msg = args.Control.GetToolTip(args.Node);
|
||||
|
||||
BaseTextControl btc = args.Control as BaseTextControl;
|
||||
if (btc != null && btc.DisplayHiddenContentInToolTip && String.IsNullOrEmpty(msg))
|
||||
{
|
||||
Size ms = btc.GetActualSize(args.Node, _measureContext);
|
||||
if (ms.Width > args.ControlBounds.Size.Width || ms.Height > args.ControlBounds.Size.Height
|
||||
|| args.ControlBounds.Right - OffsetX > DisplayRectangle.Width)
|
||||
msg = btc.GetLabel(args.Node);
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(msg) && DefaultToolTipProvider != null)
|
||||
msg = DefaultToolTipProvider.GetToolTip(args.Node, args.Control);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DragDrop
|
||||
|
||||
private bool _dragAutoScrollFlag = false;
|
||||
private Bitmap _dragBitmap = null;
|
||||
private System.Threading.Timer _dragTimer;
|
||||
|
||||
private void StartDragTimer()
|
||||
{
|
||||
if (_dragTimer == null)
|
||||
_dragTimer = new System.Threading.Timer(new TimerCallback(DragTimerTick), null, 0, 100);
|
||||
}
|
||||
|
||||
private void StopDragTimer()
|
||||
{
|
||||
if (_dragTimer != null)
|
||||
{
|
||||
_dragTimer.Dispose();
|
||||
_dragTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDropPosition(Point pt)
|
||||
{
|
||||
TreeNodeAdv node = GetNodeAt(pt);
|
||||
OnDropNodeValidating(pt, ref node);
|
||||
_dropPosition.Node = node;
|
||||
if (node != null)
|
||||
{
|
||||
Rectangle first = _rowLayout.GetRowBounds(FirstVisibleRow);
|
||||
Rectangle bounds = _rowLayout.GetRowBounds(node.Row);
|
||||
float pos = (pt.Y + first.Y - ColumnHeaderHeight - bounds.Y) / (float)bounds.Height;
|
||||
if (pos < TopEdgeSensivity)
|
||||
_dropPosition.Position = NodePosition.Before;
|
||||
else if (pos > (1 - BottomEdgeSensivity))
|
||||
_dropPosition.Position = NodePosition.After;
|
||||
else
|
||||
_dropPosition.Position = NodePosition.Inside;
|
||||
}
|
||||
}
|
||||
|
||||
private void DragTimerTick(object state)
|
||||
{
|
||||
_dragAutoScrollFlag = true;
|
||||
}
|
||||
|
||||
private void DragAutoScroll()
|
||||
{
|
||||
_dragAutoScrollFlag = false;
|
||||
Point pt = PointToClient(MousePosition);
|
||||
if (pt.Y < 20 && _vScrollBar.Value > 0)
|
||||
_vScrollBar.Value--;
|
||||
else if (pt.Y > Height - 20 && _vScrollBar.Value <= _vScrollBar.Maximum - _vScrollBar.LargeChange)
|
||||
_vScrollBar.Value++;
|
||||
}
|
||||
|
||||
public void DoDragDropSelectedNodes(DragDropEffects allowedEffects)
|
||||
{
|
||||
if (SelectedNodes.Count > 0)
|
||||
{
|
||||
TreeNodeAdv[] nodes = new TreeNodeAdv[SelectedNodes.Count];
|
||||
SelectedNodes.CopyTo(nodes, 0);
|
||||
DoDragDrop(nodes, allowedEffects);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDragBitmap(IDataObject data)
|
||||
{
|
||||
if (UseColumns || !DisplayDraggingNodes)
|
||||
return;
|
||||
|
||||
TreeNodeAdv[] nodes = data.GetData(typeof(TreeNodeAdv[])) as TreeNodeAdv[];
|
||||
if (nodes != null && nodes.Length > 0)
|
||||
{
|
||||
Rectangle rect = DisplayRectangle;
|
||||
Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
|
||||
using (Graphics gr = Graphics.FromImage(bitmap))
|
||||
{
|
||||
gr.Clear(BackColor);
|
||||
DrawContext context = new DrawContext();
|
||||
context.Graphics = gr;
|
||||
context.Font = Font;
|
||||
context.Enabled = true;
|
||||
int y = 0;
|
||||
int maxWidth = 0;
|
||||
foreach (TreeNodeAdv node in nodes)
|
||||
{
|
||||
if (node.Tree == this)
|
||||
{
|
||||
int x = 0;
|
||||
int height = _rowLayout.GetRowBounds(node.Row).Height;
|
||||
foreach (NodeControl c in NodeControls)
|
||||
{
|
||||
Size s = c.GetActualSize(node, context);
|
||||
if (!s.IsEmpty)
|
||||
{
|
||||
int width = s.Width;
|
||||
rect = new Rectangle(x, y, width, height);
|
||||
x += (width + 1);
|
||||
context.Bounds = rect;
|
||||
c.Draw(node, context);
|
||||
}
|
||||
}
|
||||
y += height;
|
||||
maxWidth = Math.Max(maxWidth, x);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxWidth > 0 && y > 0)
|
||||
{
|
||||
_dragBitmap = new Bitmap(maxWidth, y, PixelFormat.Format32bppArgb);
|
||||
using (Graphics tgr = Graphics.FromImage(_dragBitmap))
|
||||
tgr.DrawImage(bitmap, Point.Empty);
|
||||
BitmapHelper.SetAlphaChanelValue(_dragBitmap, 150);
|
||||
}
|
||||
else
|
||||
_dragBitmap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDragOver(DragEventArgs drgevent)
|
||||
{
|
||||
ItemDragMode = false;
|
||||
Point pt = PointToClient(new Point(drgevent.X, drgevent.Y));
|
||||
if (_dragAutoScrollFlag)
|
||||
DragAutoScroll();
|
||||
SetDropPosition(pt);
|
||||
UpdateView();
|
||||
base.OnDragOver(drgevent);
|
||||
}
|
||||
|
||||
protected override void OnDragEnter(DragEventArgs drgevent)
|
||||
{
|
||||
_search.EndSearch();
|
||||
DragMode = true;
|
||||
CreateDragBitmap(drgevent.Data);
|
||||
base.OnDragEnter(drgevent);
|
||||
}
|
||||
|
||||
protected override void OnDragLeave(EventArgs e)
|
||||
{
|
||||
DragMode = false;
|
||||
UpdateView();
|
||||
base.OnDragLeave(e);
|
||||
}
|
||||
|
||||
protected override void OnDragDrop(DragEventArgs drgevent)
|
||||
{
|
||||
DragMode = false;
|
||||
UpdateView();
|
||||
base.OnDragDrop(drgevent);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,727 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Design;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using Aga.Controls.Tree.NodeControls;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public partial class TreeViewAdv
|
||||
{
|
||||
private Cursor _innerCursor = null;
|
||||
|
||||
public override Cursor Cursor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_innerCursor != null)
|
||||
return _innerCursor;
|
||||
else
|
||||
return base.Cursor;
|
||||
}
|
||||
set
|
||||
{
|
||||
base.Cursor = value;
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal Properties
|
||||
|
||||
private IRowLayout _rowLayout;
|
||||
|
||||
private bool _dragMode;
|
||||
private bool DragMode
|
||||
{
|
||||
get { return _dragMode; }
|
||||
set
|
||||
{
|
||||
_dragMode = value;
|
||||
if (!value)
|
||||
{
|
||||
StopDragTimer();
|
||||
if (_dragBitmap != null)
|
||||
_dragBitmap.Dispose();
|
||||
_dragBitmap = null;
|
||||
}
|
||||
else
|
||||
StartDragTimer();
|
||||
}
|
||||
}
|
||||
|
||||
internal int ColumnHeaderHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UseColumns)
|
||||
return _columnHeaderHeight;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns all nodes, which parent is expanded
|
||||
/// </summary>
|
||||
private IEnumerable<TreeNodeAdv> VisibleNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
TreeNodeAdv node = Root;
|
||||
while (node != null)
|
||||
{
|
||||
node = node.NextVisibleNode;
|
||||
if (node != null)
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _suspendSelectionEvent;
|
||||
internal bool SuspendSelectionEvent
|
||||
{
|
||||
get { return _suspendSelectionEvent; }
|
||||
set
|
||||
{
|
||||
if (value != _suspendSelectionEvent)
|
||||
{
|
||||
_suspendSelectionEvent = value;
|
||||
if (!_suspendSelectionEvent && _fireSelectionEvent)
|
||||
OnSelectionChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<TreeNodeAdv> _rowMap;
|
||||
internal List<TreeNodeAdv> RowMap
|
||||
{
|
||||
get { return _rowMap; }
|
||||
}
|
||||
|
||||
private TreeNodeAdv _selectionStart;
|
||||
internal TreeNodeAdv SelectionStart
|
||||
{
|
||||
get { return _selectionStart; }
|
||||
set { _selectionStart = value; }
|
||||
}
|
||||
|
||||
private InputState _input;
|
||||
internal InputState Input
|
||||
{
|
||||
get { return _input; }
|
||||
set
|
||||
{
|
||||
_input = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _itemDragMode;
|
||||
internal bool ItemDragMode
|
||||
{
|
||||
get { return _itemDragMode; }
|
||||
set { _itemDragMode = value; }
|
||||
}
|
||||
|
||||
private Point _itemDragStart;
|
||||
internal Point ItemDragStart
|
||||
{
|
||||
get { return _itemDragStart; }
|
||||
set { _itemDragStart = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Number of rows fits to the current page
|
||||
/// </summary>
|
||||
internal int CurrentPageSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return _rowLayout.CurrentPageSize;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of all visible nodes (which parent is expanded)
|
||||
/// </summary>
|
||||
internal int RowCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return RowMap.Count;
|
||||
}
|
||||
}
|
||||
|
||||
private int _contentWidth = 0;
|
||||
private int ContentWidth
|
||||
{
|
||||
get
|
||||
{
|
||||
return _contentWidth;
|
||||
}
|
||||
}
|
||||
|
||||
private int _firstVisibleRow;
|
||||
internal int FirstVisibleRow
|
||||
{
|
||||
get { return _firstVisibleRow; }
|
||||
set
|
||||
{
|
||||
HideEditor();
|
||||
_firstVisibleRow = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private int _offsetX;
|
||||
public int OffsetX
|
||||
{
|
||||
get { return _offsetX; }
|
||||
private set
|
||||
{
|
||||
HideEditor();
|
||||
_offsetX = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
public override Rectangle DisplayRectangle
|
||||
{
|
||||
get
|
||||
{
|
||||
Rectangle r = ClientRectangle;
|
||||
//r.Y += ColumnHeaderHeight;
|
||||
//r.Height -= ColumnHeaderHeight;
|
||||
int w = _vScrollBar.Visible ? _vScrollBar.Width : 0;
|
||||
int h = _hScrollBar.Visible ? _hScrollBar.Height : 0;
|
||||
return new Rectangle(r.X, r.Y, r.Width - w, r.Height - h);
|
||||
}
|
||||
}
|
||||
|
||||
private List<TreeNodeAdv> _selection;
|
||||
internal List<TreeNodeAdv> Selection
|
||||
{
|
||||
get { return _selection; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Properties
|
||||
|
||||
#region DesignTime
|
||||
|
||||
private bool _shiftFirstNode;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool ShiftFirstNode
|
||||
{
|
||||
get { return _shiftFirstNode; }
|
||||
set { _shiftFirstNode = value; }
|
||||
}
|
||||
|
||||
private bool _displayDraggingNodes;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool DisplayDraggingNodes
|
||||
{
|
||||
get { return _displayDraggingNodes; }
|
||||
set { _displayDraggingNodes = value; }
|
||||
}
|
||||
|
||||
private bool _fullRowSelect;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool FullRowSelect
|
||||
{
|
||||
get { return _fullRowSelect; }
|
||||
set
|
||||
{
|
||||
_fullRowSelect = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _useColumns;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool UseColumns
|
||||
{
|
||||
get { return _useColumns; }
|
||||
set
|
||||
{
|
||||
_useColumns = value;
|
||||
FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _allowColumnReorder;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool AllowColumnReorder
|
||||
{
|
||||
get { return _allowColumnReorder; }
|
||||
set { _allowColumnReorder = value; }
|
||||
}
|
||||
|
||||
private bool _showLines = true;
|
||||
[DefaultValue(true), Category("Behavior")]
|
||||
public bool ShowLines
|
||||
{
|
||||
get { return _showLines; }
|
||||
set
|
||||
{
|
||||
_showLines = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _showPlusMinus = true;
|
||||
[DefaultValue(true), Category("Behavior")]
|
||||
public bool ShowPlusMinus
|
||||
{
|
||||
get { return _showPlusMinus; }
|
||||
set
|
||||
{
|
||||
_showPlusMinus = value;
|
||||
FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _showNodeToolTips = false;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool ShowNodeToolTips
|
||||
{
|
||||
get { return _showNodeToolTips; }
|
||||
set { _showNodeToolTips = value; }
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic"), DefaultValue(true), Category("Behavior"), Obsolete("No longer used")]
|
||||
public bool KeepNodesExpanded
|
||||
{
|
||||
get { return true; }
|
||||
set {}
|
||||
}
|
||||
|
||||
private ITreeModel _model;
|
||||
/// <Summary>
|
||||
/// The model associated with this <see cref="TreeViewAdv"/>.
|
||||
/// </Summary>
|
||||
/// <seealso cref="ITreeModel"/>
|
||||
/// <seealso cref="TreeModel"/>
|
||||
[Browsable(false)]
|
||||
public ITreeModel Model
|
||||
{
|
||||
get { return _model; }
|
||||
set
|
||||
{
|
||||
if (_model != value)
|
||||
{
|
||||
AbortBackgroundExpandingThreads();
|
||||
if (_model != null)
|
||||
UnbindModelEvents();
|
||||
_model = value;
|
||||
CreateNodes();
|
||||
FullUpdate();
|
||||
if (_model != null)
|
||||
BindModelEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Font _font = SystemFonts.MessageBoxFont;
|
||||
/// <summary>
|
||||
/// The font to render <see cref="TreeViewAdv"/> content in.
|
||||
/// </summary>
|
||||
[Category("Appearance"), Description("The font to render TreeViewAdv content in.")]
|
||||
public override Font Font
|
||||
{
|
||||
get
|
||||
{
|
||||
return (base.Font);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
base.Font = _font;
|
||||
else
|
||||
{
|
||||
if (value == DefaultFont)
|
||||
base.Font = _font;
|
||||
else
|
||||
base.Font = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void ResetFont()
|
||||
{
|
||||
Font = null;
|
||||
}
|
||||
private bool ShouldSerializeFont()
|
||||
{
|
||||
return (!Font.Equals(_font));
|
||||
}
|
||||
// End font property
|
||||
|
||||
private BorderStyle _borderStyle = BorderStyle.Fixed3D;
|
||||
[DefaultValue(BorderStyle.Fixed3D), Category("Appearance")]
|
||||
public BorderStyle BorderStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._borderStyle;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_borderStyle != value)
|
||||
{
|
||||
_borderStyle = value;
|
||||
base.UpdateStyles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _autoRowHeight = false;
|
||||
/// <summary>
|
||||
/// Set to true to expand each row's height to fit the text of it's largest column.
|
||||
/// </summary>
|
||||
[DefaultValue(false), Category("Appearance"), Description("Expand each row's height to fit the text of it's largest column.")]
|
||||
public bool AutoRowHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return _autoRowHeight;
|
||||
}
|
||||
set
|
||||
{
|
||||
_autoRowHeight = value;
|
||||
if (value)
|
||||
_rowLayout = new AutoRowHeightLayout(this, RowHeight);
|
||||
else
|
||||
_rowLayout = new FixedRowHeightLayout(this, RowHeight);
|
||||
FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private GridLineStyle _gridLineStyle = GridLineStyle.None;
|
||||
[DefaultValue(GridLineStyle.None), Category("Appearance")]
|
||||
public GridLineStyle GridLineStyle
|
||||
{
|
||||
get
|
||||
{
|
||||
return _gridLineStyle;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _gridLineStyle)
|
||||
{
|
||||
_gridLineStyle = value;
|
||||
UpdateView();
|
||||
OnGridLineStyleChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _rowHeight = 16;
|
||||
[DefaultValue(16), Category("Appearance")]
|
||||
public int RowHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return _rowHeight;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentOutOfRangeException("value");
|
||||
|
||||
_rowHeight = value;
|
||||
_rowLayout.PreferredRowHeight = value;
|
||||
FullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private TreeSelectionMode _selectionMode = TreeSelectionMode.Single;
|
||||
[DefaultValue(TreeSelectionMode.Single), Category("Behavior")]
|
||||
public TreeSelectionMode SelectionMode
|
||||
{
|
||||
get { return _selectionMode; }
|
||||
set { _selectionMode = value; }
|
||||
}
|
||||
|
||||
private bool _hideSelection;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool HideSelection
|
||||
{
|
||||
get { return _hideSelection; }
|
||||
set
|
||||
{
|
||||
_hideSelection = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private float _topEdgeSensivity = 0.3f;
|
||||
[DefaultValue(0.3f), Category("Behavior")]
|
||||
public float TopEdgeSensivity
|
||||
{
|
||||
get { return _topEdgeSensivity; }
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > 1)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
_topEdgeSensivity = value;
|
||||
}
|
||||
}
|
||||
|
||||
private float _bottomEdgeSensivity = 0.3f;
|
||||
[DefaultValue(0.3f), Category("Behavior")]
|
||||
public float BottomEdgeSensivity
|
||||
{
|
||||
get { return _bottomEdgeSensivity; }
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > 1)
|
||||
throw new ArgumentOutOfRangeException("value should be from 0 to 1");
|
||||
_bottomEdgeSensivity = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _loadOnDemand;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool LoadOnDemand
|
||||
{
|
||||
get { return _loadOnDemand; }
|
||||
set { _loadOnDemand = value; }
|
||||
}
|
||||
|
||||
private bool _unloadCollapsedOnReload = false;
|
||||
[DefaultValue(false), Category("Behavior")]
|
||||
public bool UnloadCollapsedOnReload
|
||||
{
|
||||
get { return _unloadCollapsedOnReload; }
|
||||
set { _unloadCollapsedOnReload = value; }
|
||||
}
|
||||
|
||||
private int _indent = 19;
|
||||
[DefaultValue(19), Category("Behavior")]
|
||||
public int Indent
|
||||
{
|
||||
get { return _indent; }
|
||||
set
|
||||
{
|
||||
_indent = value;
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private Color _lineColor = SystemColors.ControlDark;
|
||||
[Category("Behavior")]
|
||||
public Color LineColor
|
||||
{
|
||||
get { return _lineColor; }
|
||||
set
|
||||
{
|
||||
_lineColor = value;
|
||||
CreateLinePen();
|
||||
UpdateView();
|
||||
}
|
||||
}
|
||||
|
||||
private Color _dragDropMarkColor = Color.Black;
|
||||
[Category("Behavior")]
|
||||
public Color DragDropMarkColor
|
||||
{
|
||||
get { return _dragDropMarkColor; }
|
||||
set
|
||||
{
|
||||
_dragDropMarkColor = value;
|
||||
CreateMarkPen();
|
||||
}
|
||||
}
|
||||
|
||||
private float _dragDropMarkWidth = 3.0f;
|
||||
[DefaultValue(3.0f), Category("Behavior")]
|
||||
public float DragDropMarkWidth
|
||||
{
|
||||
get { return _dragDropMarkWidth; }
|
||||
set
|
||||
{
|
||||
_dragDropMarkWidth = value;
|
||||
CreateMarkPen();
|
||||
}
|
||||
}
|
||||
|
||||
private bool _highlightDropPosition = true;
|
||||
[DefaultValue(true), Category("Behavior")]
|
||||
public bool HighlightDropPosition
|
||||
{
|
||||
get { return _highlightDropPosition; }
|
||||
set { _highlightDropPosition = value; }
|
||||
}
|
||||
|
||||
private TreeColumnCollection _columns;
|
||||
[Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
public Collection<TreeColumn> Columns
|
||||
{
|
||||
get { return _columns; }
|
||||
}
|
||||
|
||||
private NodeControlsCollection _controls;
|
||||
[Category("Behavior"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
|
||||
[Editor(typeof(NodeControlCollectionEditor), typeof(UITypeEditor))]
|
||||
public Collection<NodeControl> NodeControls
|
||||
{
|
||||
get
|
||||
{
|
||||
return _controls;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _asyncExpanding;
|
||||
/// <summary>
|
||||
/// When set to true, node contents will be read in background thread.
|
||||
/// </summary>
|
||||
[Category("Behavior"), DefaultValue(false), Description("Read children in a background thread when expanding.")]
|
||||
public bool AsyncExpanding
|
||||
{
|
||||
get { return _asyncExpanding; }
|
||||
set { _asyncExpanding = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RunTime
|
||||
|
||||
private IToolTipProvider _defaultToolTipProvider = null;
|
||||
[Browsable(false)]
|
||||
public IToolTipProvider DefaultToolTipProvider
|
||||
{
|
||||
get { return _defaultToolTipProvider; }
|
||||
set { _defaultToolTipProvider = value; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public IEnumerable<TreeNodeAdv> AllNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_root.Nodes.Count > 0)
|
||||
{
|
||||
TreeNodeAdv node = _root.Nodes[0];
|
||||
while (node != null)
|
||||
{
|
||||
yield return node;
|
||||
if (node.Nodes.Count > 0)
|
||||
node = node.Nodes[0];
|
||||
else if (node.NextNode != null)
|
||||
node = node.NextNode;
|
||||
else
|
||||
node = node.BottomNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DropPosition _dropPosition;
|
||||
[Browsable(false)]
|
||||
public DropPosition DropPosition
|
||||
{
|
||||
get { return _dropPosition; }
|
||||
set { _dropPosition = value; }
|
||||
}
|
||||
|
||||
private TreeNodeAdv _root;
|
||||
[Browsable(false)]
|
||||
public TreeNodeAdv Root
|
||||
{
|
||||
get { return _root; }
|
||||
}
|
||||
|
||||
private ReadOnlyCollection<TreeNodeAdv> _readonlySelection;
|
||||
[Browsable(false)]
|
||||
public ReadOnlyCollection<TreeNodeAdv> SelectedNodes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _readonlySelection;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public TreeNodeAdv SelectedNode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Selection.Count > 0)
|
||||
{
|
||||
if (CurrentNode != null && CurrentNode.IsSelected)
|
||||
return CurrentNode;
|
||||
else
|
||||
return Selection[0];
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (SelectedNode == value)
|
||||
return;
|
||||
|
||||
BeginUpdate();
|
||||
try
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
ClearSelectionInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsMyNode(value))
|
||||
throw new ArgumentException();
|
||||
|
||||
ClearSelectionInternal();
|
||||
value.IsSelected = true;
|
||||
CurrentNode = value;
|
||||
EnsureVisible(value);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
EndUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TreeNodeAdv _currentNode;
|
||||
[Browsable(false)]
|
||||
public TreeNodeAdv CurrentNode
|
||||
{
|
||||
get { return _currentNode; }
|
||||
internal set { _currentNode = value; }
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
public int ItemCount
|
||||
{
|
||||
get { return RowMap.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates the distance the content is scrolled to the left
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public int HorizontalScrollPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hScrollBar.Visible)
|
||||
return _hScrollBar.Value;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
1254
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.cs
Normal file
132
LibreHardwareMonitor-0.9.4/Aga.Controls/Tree/TreeViewAdv.resx
Normal file
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="_vScrollBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>127, 17</value>
|
||||
</metadata>
|
||||
<metadata name="_hScrollBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="_errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>236, 17</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeViewAdvCancelEventArgs : TreeViewAdvEventArgs
|
||||
{
|
||||
private bool _cancel;
|
||||
|
||||
public bool Cancel
|
||||
{
|
||||
get { return _cancel; }
|
||||
set { _cancel = value; }
|
||||
}
|
||||
|
||||
public TreeViewAdvCancelEventArgs(TreeNodeAdv node)
|
||||
: base(node)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeViewAdvEventArgs : EventArgs
|
||||
{
|
||||
private TreeNodeAdv _node;
|
||||
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
}
|
||||
|
||||
public TreeViewAdvEventArgs(TreeNodeAdv node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Aga.Controls.Tree
|
||||
{
|
||||
public class TreeViewRowDrawEventArgs: PaintEventArgs
|
||||
{
|
||||
TreeNodeAdv _node;
|
||||
DrawContext _context;
|
||||
int _row;
|
||||
Rectangle _rowRect;
|
||||
|
||||
public TreeViewRowDrawEventArgs(Graphics graphics, Rectangle clipRectangle, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect)
|
||||
: base(graphics, clipRectangle)
|
||||
{
|
||||
_node = node;
|
||||
_context = context;
|
||||
_row = row;
|
||||
_rowRect = rowRect;
|
||||
}
|
||||
|
||||
public TreeNodeAdv Node
|
||||
{
|
||||
get { return _node; }
|
||||
}
|
||||
|
||||
public DrawContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
|
||||
public int Row
|
||||
{
|
||||
get { return _row; }
|
||||
}
|
||||
|
||||
public Rectangle RowRect
|
||||
{
|
||||
get { return _rowRect; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
25
LibreHardwareMonitor-0.9.4/Aga.Controls/license.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
The BSD License
|
||||
|
||||
Copyright (c) 2009, Andrey Gliznetsov (a.gliznetsov@gmail.com)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||
and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation andor other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||